tiptap
tiptap copied to clipboard
Node view in React isn't draggable
What’s the bug you are facing?
Can't drag node with custom node view in React.
How can we reproduce the bug on our side?
I made simple code to demonstrate error. You can drag if node view written with vanilla JS but you can't drag node view written with React.
- Screencast:
https://user-images.githubusercontent.com/2762678/156736536-0f3b5084-6578-4c46-b14a-cfbe6a3168b3.mp4
I checked the document https://tiptap.dev/guide/node-views/react/ but I can't find what's wrong here.
Can you provide a CodeSandbox?
React: https://codesandbox.io/s/tiptap-drag-and-drop-4uv0we?file=/src/App.tsx:494-513
What did you expect to happen?
React node view should be draggable.
Anything to add? (optional)
No response
Did you update your dependencies?
- [X] Yes, I’ve updated my dependencies to use the latest version of all packages.
Are you sponsoring us?
- [ ] Yes, I’m a sponsor. 💖
It seems like I have to set draggable="true"
beside data-drag-handle=""
in the DOM element to make it works. Setting draggable="true"
in the ancestor node of the handle also works.
Link: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable
I also had to add it to the node extension
. So in total it was:
- add
draggable="true"
anddata-drag-handle=""
on the DOM element you want to drag (or its parent) - add
draggable=true
to yournode-extension.js
file. Here's my node extension which I use to importvue
components:
import {Node, mergeAttributes} from '@tiptap/core'
import {VueNodeViewRenderer} from '@tiptap/vue-3'
import Component from './Component.vue'
export const VueComponent = Node.create({
name: 'vueComponent',
group: 'block',
atom: true,
draggable: true,
addAttributes() {
return {
src: String
}
},
parseHTML() {
return [{ tag: 'vue-component' }]
},
renderHTML({ HTMLAttributes }) {
return ['vue-component', mergeAttributes(HTMLAttributes)]
},
addNodeView() {
return VueNodeViewRenderer(Component)
},
})
This issue is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 7 days
I have the same problem. I've already set draggable: true
in my node and added draggable="true"
and data-drag-handle
to the parent element of the component but it didn't help. For some reason, removing content: "inline*"
from the node solves the problem. Any idea what's happening? I really need to have content in my NodeView.
@ahhshm do you have an example codesandbox for your issue?
@bdbch https://codesandbox.io/s/react-typescript-forked-8v0ljl?file=/src/App.tsx
When you remove content: "inline*"
in the Figure
node (as well as the content hole in <figcaption>
) you can drag the image normally.
I have the same issue with React. All nodes with the content hole in the renderHTML
are not draggable. 😟
// Extension
export const MyCustomExtension = Node.create({
name: "myCustomExtension",
group: "block",
content: "inline*",
draggable: true,
// ...
parseHTML() {
return [{ tag: `div[data-type="${this.name}"]` }];
},
renderHTML({ HTMLAttributes }) {
return ["div", mergeAttributes(HTMLAttributes, { "data-type": this.name }), 0];
},
addNodeView() {
return ReactNodeViewRenderer(MyCustomExtensionComponent);
},
});
// React component
export const MyCustomExtensionComponent = ({ node }) => (
<NodeViewWrapper>
{node.type.spec.draggable ? (
<div draggable="true" data-drag-handle="">
<DragIcon />
</div>
) : null}
<NodeViewContent />
</NodeViewWrapper>
);
+1, I have the same issue
@tuan3w If you managed to get it working is it possible to update the issue with an example? I've tried adding the attributes as you suggested, but haven't had much luck.
Thanks!
I'm not sure if this is what you meant, but it put me on the right path for an approach that worked for me: https://codesandbox.io/s/twilight-field-7kkytq?file=/src/styles.css:58-939
The bit I had been missing was:
<NodeViewWrapper class="draggable-item">
<div
class="drag-handle"
contentEditable="false"
draggable="true"
data-drag-handle
/>
<NodeViewContent class="content" />
</NodeViewWrapper>
I.e. the extra div inside the wrapper which acts as the drag handle.
@yarrichar thanks a lot! contentEditable="false"
fixed the problem
draggable="true"
is the important bit here. Let me know if you think we should improve the documentation on this one!
contentEditable="false"
fixed my problem too but I had to explicitly add contentEditable="true"
to NodeViewContent
so it can be edited.
<NodeViewWrapper>
<figure
data-drag-handle
draggable={true}
contentEditable={false}
>
{node.attrs.src && <img src={node.attrs.src as string} alt="Image" />}
<NodeViewContent contentEditable={true} />
</figure>
</NodeViewWrapper>
@tuan3w I'll close this issue for now as it seems we were able to find out what the issue was (primarily the missing draggable="true"
and the contentEditable
option not being used correctly).
Feel free to reopen if you still have those issues.
@yarrichar
I'm not sure if this is what you meant, but it put me on the right path for an approach that worked for me: https://codesandbox.io/s/twilight-field-7kkytq?file=/src/styles.css:58-939
in the above sandbox , if you add multiple p tags and try to drag from top to below it doesnt seem to work . but when you drag from below to top it works . ive added a sandbox for the same below . https://codesandbox.io/s/condescending-mendeleev-4ytzmj?file=/src/Tiptap.jsx
@surajmn1
I have this same issue.
- Create two draggable node views.
- Drag 2 -> 1 works fine as long as its dropped in a normal place.
- Drag 1 -> 2 does not work unless there are line breaks or other 'empty' nodes below the node view.
In my opinion we should be able to drag from above to below without needing additional content below the bottom node view.
Any thoughts on this issue?