How to make child `node` a drag handle for parent

I have a figure node whose content is image figcaption. Both image and figcaption have draggable: false. My figure is draggable and has custom node view which on click, selects this node. Whe the node is selected, I’d like to allow user to drag it by dragging any part of it, especially image on its own. Is it possible to do? Below is how my figure node looks like when selected (purple outline). Now I can’t drag it when drag image. How to fix that?

image

Does turning off pointer events on the image help?

Nothing has change, but maybe this is because of some specifics of tiptap react node views. I will try to investigate but just wanted to confirm whether data-drag-handle attribute is something ProseMirror specific or it’s introduced by Tiptap?

That’s Tiptap.

@marijn when dragging in ProseMirror is in general stopped? Because I have a mathPanel node like this:

export const MathPanel = Node.create<MathPanelOptions>({
  name: 'mathPanel',
  content: 'mathPanelName mathPanelBody',
  group: 'block',
  draggable: true,
  selectable: true,

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

  parseHTML() {
    return [
      {
        tag: `div[data-type="${this.name}"]`,
        contentElement: `div[data-type="${this.name}Content"]`,
      },
    ];
  },

  addAttributes() {
    return {
      variant: {
        default: 'definition',
        renderHTML: (attributes) => ({
          'data-variant': attributes.variant,
        }),
        parseHTML: (element: HTMLImageElement) =>
          element.getAttribute('data-variant'),
      },
    };
  },

  renderHTML({ HTMLAttributes, node }) {
    const variant = node.attrs.variant;

    let { label } = MATH_PANELS.find((el) => el.value === variant)!;
    label +=
      ' ' +
      getNodeNumber(node, this.editor!, (n) => n.attrs.variant === variant);

    const attrs = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
      'data-type': this.name,
    });

    return [
      'div',
      attrs,
      [
        'div',
        {
          'data-type': `${this.name}Label`,
        },
        label,
      ],
      [
        'div',
        {
          'data-type': `${this.name}Content`,
        },
        0,
      ],
    ];
  },

});

When I select it, I can drag it only when I start dragging from its content. When I start dragging in

  [
        'div',
        {
          'data-type': `${this.name}Label`,
        },
        label,
      ],

then nothing happens and I dont understand why is that a case. Is that something prose mirror specific? Addding pointer-events-none to the div does not help.

I don’t know of a reason why one part of the node supports dragging and another doesn’t (unless you have a custom node view that messes with the events). If you can reproduce this without TipTap, I could take a look.

Could you please point me to the point in ProseMirror code where I could find what logic is run when node is being dropped? Now I have a problem with my custom node that is being cloned on drop instaed of being moved.

EDIT I tried to deug and I noticed that for that particular node, the dragstart event from here is not fired and then view.dragging is empty. What might be the reason?

One possibility is that TipTap is interfering. Again, if you can boil this down to a simple pure-ProseMirror example script, I can probably say more.

Indeed, I had to add stopEvent: () => false to node view to make it work :slight_smile: