ueberdosis / tiptap

The headless rich text editor framework for web artisans.
https://tiptap.dev
MIT License
27.01k stars 2.25k forks source link

Standard drag&drop behaviour not working inside an interactive node view component #3199

Open pingworker opened 2 years ago

pingworker commented 2 years ago

What’s the bug you are facing?

I have a List component with Drag & Drop sorting functionality, which I use within tiptap using a VueNodeViewRenderer. The component works perfectly outside Tiptap, but if I use it inside the editor, the standard drag&drop functionality is not working and no events are fired. Is there a way to maintain this functionality?

Which browser was this experienced in? Are any special extensions installed?

Chrome, Edge, standard Versions, no Extensions

How can we reproduce the bug on our side?

Add "draggable=true" to a standard DIV inside a Vue Component linked with a NodeViewRenderer in Tiptap. The dragging does not work, when inserted in the editor.

Can you provide a CodeSandbox?

No response

What did you expect to happen?

I'd expect the normal drag drop behaviour working...

Anything to add? (optional)

No response

Did you update your dependencies?

Are you sponsoring us?

ralphschindler commented 1 year ago

We are experiencing this too, does anyone have any solutions or hacks to ensure vuedraggable (and the like) will work inside a node-view-wrapper with drag handles?

ralphschindler commented 1 year ago

This demonstrates the issue we are seeing, with reproduction steps: https://codesandbox.io/p/github/ralphschindler/demo-tiptap-drag-issue/master?file=%2Freadme.md

bdbch commented 1 year ago

I had a quick look for now into this issue and the Codesandbox and on the first glance it looks weird. There are multiple things breaking.

  1. As soon as the vuedraggable elements inside the nodeview are dragged, drag events will only be fired on those elements, everything else doesn't fire drag events anymore.
  2. At the same time, mouse selection of text is broken (I guess also because something is happening with mouse events and this is not canceled?)
  3. Drag events inside a vue node are not resulting in the content being dragged.

I think those are the results of a combination of how vuedraggable is managing events + how Tiptap (or even Prosemirror) is handling draggable events inside the editor view. I can't promise a quick fix or a quick hack for this issue as I have to play around with those combinations (and also without a 3rd party library) first before I can say something more concrete

pingworker commented 1 year ago

Hi Dominik. Thanks for looking into the problem. I think the source of the problems might be, that the draggable attribute gets completely ommited by Tiptap or Prosemirror. Unlike Ralph, I'm handling the dragging myself and can't get it to run inside a node view. Perhaps this helps a bit...

github-actions[bot] commented 1 year ago

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

ralphschindler commented 1 year ago

Please remove stale label, waiting for this issue to be prioritized.

barclayadam commented 1 year ago

I have started to work on an editor using tiptap and experiencing issues with drag and drop and a custom node view. I want a component that has text as the inline content, but it should not be editable directly:

export const TextBlock = Node.create<TextBlockOptions>({
    name: 'textBlock',

    priority: 1000,

    addOptions() {
        return {
            HTMLAttributes: {},
        };
    },

    group: 'block',

    content: 'inline*',

    draggable: true,
    selectable: true,

    atom: true,

    parseHTML() {
        return [
            { tag: 'text' },
        ];
    },

    renderHTML({ HTMLAttributes }) {
        return ['text', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
    },

    addNodeView() {
        return VueNodeViewRenderer(TextBlockComponent, {
            stopEvent() { return false; },
        });
    },
});

The custom component is, for now, simple:

<template>
    <node-view-wrapper draggable data-drag-handle>
        <node-view-content contenteditable="false" as="div" />
    </node-view-wrapper>
</template>

<script lang="ts">
    import Vue from 'vue';

    import { nodeViewProps, NodeViewWrapper, NodeViewContent } from '@tiptap/vue-2';

    export default Vue.extend({
        components: {
            NodeViewWrapper,
            NodeViewContent,
        },

        props: nodeViewProps,
    });
</script>

The issue is that dragging that component often does not allow the built-in dragstart handling to kick in, even though the actual dragging does start.

This means that the editor view's dragging property is not set, and then when the drop handler fires it does apply a drop but move is incorrectly false because it dragging property of the editor is null. The result is that a drag and drop interaction does complete, but it can be seen as a copy and not a move as intended.

As you can see in the above component I override the stopEvent handler to return false which appears to do exactly as required, meaning the built-in ProseMirror drag and drop works and does as expected

tsl1127 commented 1 year ago

@barclayadam thank you ! I have the same issue with Vue; "stopEvent() { return false; }" fixed the problem