cleanup drag handle example

This commit is contained in:
Philipp Kühn
2020-11-25 17:58:53 +01:00
parent b7ca33aeae
commit fd94e321ea
9 changed files with 80 additions and 118 deletions

View File

@@ -0,0 +1,57 @@
<template>
<node-view-wrapper class="draggable-item">
<div class="drag-handle" contenteditable="false" data-drag-handle />
<node-view-content class="content" />
</node-view-wrapper>
</template>
<script>
export default {
props: {
editor: {
type: Object,
required: true,
},
node: {
type: Object,
required: true,
},
updateAttributes: {
type: Function,
required: true,
},
},
}
</script>
<style lang="scss" scoped>
.draggable-item {
display: flex;
padding: 0.5rem;
margin: 0.5rem 0;
border-radius: 0.5rem;
box-shadow:
0 0 0 1px rgba(0, 0, 0, 0.1),
0px 10px 20px rgba(0, 0, 0, 0.1),
;
.drag-handle {
position: relative;
width: 1rem;
height: 1rem;
top: 0.3rem;
margin-right: 0.5rem;
cursor: grab;
background-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 16"><path fill-opacity="0.2" d="M4 14c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zM2 6C.9 6 0 6.9 0 8s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6C.9 0 0 .9 0 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" /></svg>');
background-repeat: no-repeat;
background-size: contain;
background-position: center;
}
.content {
flex: 1 1 auto;
}
}
</style>

View File

@@ -3,11 +3,10 @@ import { VueRenderer } from '@tiptap/vue'
import Component from './Component.vue' import Component from './Component.vue'
export default Node.create({ export default Node.create({
name: 'test', name: 'draggableItem',
group: 'block', group: 'block',
// content: 'inline*',
content: 'block*', content: 'block*',
draggable: true, draggable: true,
@@ -25,13 +24,13 @@ export default Node.create({
parseHTML() { parseHTML() {
return [ return [
{ {
tag: 'div[data-type="test"]', tag: 'div[data-type="draggable-item"]',
}, },
] ]
}, },
renderHTML({ HTMLAttributes }) { renderHTML({ HTMLAttributes }) {
return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'test' }), 0] return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'draggable-item' }), 0]
}, },
addNodeView() { addNodeView() {

View File

@@ -7,11 +7,11 @@
<script> <script>
import { Editor } from '@tiptap/core' import { Editor } from '@tiptap/core'
import { EditorContent } from '@tiptap/vue' import { EditorContent } from '@tiptap/vue'
import Dropcursor from '@tiptap/extension-dropcursor'
import Document from '@tiptap/extension-document' import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph' import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text' import Text from '@tiptap/extension-text'
import Test from './Test.ts' import Dropcursor from '@tiptap/extension-dropcursor'
import DraggableItem from './DraggableItem.js'
export default { export default {
components: { components: {
@@ -27,28 +27,28 @@ export default {
mounted() { mounted() {
this.editor = new Editor({ this.editor = new Editor({
extensions: [ extensions: [
Dropcursor,
Document, Document,
Paragraph, Paragraph,
Text, Text,
Test, Dropcursor,
DraggableItem,
], ],
content: ` content: `
<p>paragraph</p> <p>paragraph</p>
<div data-type="test"> <div data-type="draggable-item">
<p>paragraph</p> <p>draggable item</p>
<div data-type="test">
<p>paragraph</p>
</div>
</div> </div>
<div data-type="test"> <div data-type="draggable-item">
<p>paragraph</p> <p>another one</p>
<div data-type="draggable-item">
<p>can be nested too</p>
<div data-type="draggable-item">
<p>but can we go deeper?</p>
</div>
</div>
</div> </div>
<p>paragraph</p> <p>paragraph</p>
`, `,
onUpdate: () => {
console.log(this.editor.getHTML())
},
}) })
}, },
@@ -57,20 +57,3 @@ export default {
}, },
} }
</script> </script>
<style lang="scss">
ul[data-type="taskList"] {
list-style: none;
padding: 0;
li {
display: flex;
align-items: center;
> input {
flex: 0 0 auto;
margin-right: 0.5rem;
}
}
}
</style>

View File

@@ -1,78 +0,0 @@
<template>
<node-view-wrapper class="item">
<!-- <button @click="toggleChecked" contenteditable="false">
toggle checked
</button>
<div contenteditable="false">
checked: {{ node.attrs.checked }}
</div> -->
<div data-drag-handle class="drag-handle" contenteditable="false" />
<node-view-content />
</node-view-wrapper>
</template>
<script>
export default {
props: {
editor: {
type: Object,
required: true,
},
node: {
type: Object,
required: true,
},
updateAttributes: {
type: Function,
required: true,
},
},
data() {
return {
// random: 'foo',
}
},
methods: {
toggleChecked() {
// this.editor.commands.focus()
this.updateAttributes({
checked: !this.node.attrs.checked,
})
},
},
mounted() {
console.log('MOUNTED')
// setInterval(() => {
// this.random = `foo${Math.random()}`
// }, 1000)
},
}
</script>
<style lang="scss">
.item {
padding: 0.5rem;
margin: 1rem 0;
border-radius: 0.5rem;
box-shadow:
0 0 0 1px rgba(0, 0, 0, 0.1),
0px 10px 20px rgba(0, 0, 0, 0.1),
;
}
.drag-handle {
width: 1rem;
height: 1rem;
cursor: grab;
background-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 16"><path fill-opacity="0.4" d="M4 14c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zM2 6C.9 6 0 6.9 0 8s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6C.9 0 0 .9 0 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" /></svg>');
background-repeat: no-repeat;
background-size: contain;
background-position: center;
}
</style>

View File

@@ -25,7 +25,7 @@ export default {
} }
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.content { .content {
padding: 1rem 0 0; padding: 1rem 0 0;

View File

@@ -1,3 +1,3 @@
# Drag Handle # Drag Handle
<demo name="Examples/DragHandle" /> <demo name="Examples/DragHandle" />

View File

@@ -1,3 +0,0 @@
# Node View
<demo name="Examples/NodeView" />

View File

@@ -34,6 +34,9 @@
link: /examples/minimalist link: /examples/minimalist
- title: Use with v-model - title: Use with v-model
link: /examples/v-model link: /examples/v-model
- title: Drag handle
link: /examples/drag-handle
draft: true
- title: Export HTML or JSON - title: Export HTML or JSON
link: /examples/export-html-or-json link: /examples/export-html-or-json
- title: Feedback - title: Feedback

View File

@@ -71,6 +71,7 @@ class VueNodeView implements NodeView {
return return
} }
// sometimes `event.target` is not the `dom` element
event.dataTransfer?.setDragImage(this.dom, 0, 0) event.dataTransfer?.setDragImage(this.dom, 0, 0)
const selection = NodeSelection.create(view.state.doc, this.getPos()) const selection = NodeSelection.create(view.state.doc, this.getPos())