cleanup drag handle example
This commit is contained in:
57
docs/src/demos/Examples/DragHandle/Component.vue
Normal file
57
docs/src/demos/Examples/DragHandle/Component.vue
Normal 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>
|
||||||
@@ -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() {
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# Drag Handle
|
# Drag Handle
|
||||||
|
|
||||||
<demo name="Examples/DragHandle" />
|
<demo name="Examples/DragHandle" />
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# Node View
|
|
||||||
|
|
||||||
<demo name="Examples/NodeView" />
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
Reference in New Issue
Block a user