@tiptap/extension-drag-handle 3.4.5 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -83,6 +83,17 @@ var findElementNextToCoords = (options) => {
83
83
  if (candidatePos === -1) {
84
84
  return { resultElement: finalCandidate, resultNode: null, pos: null };
85
85
  }
86
+ const $pos = editor.state.doc.resolve(candidatePos);
87
+ if ($pos.nodeAfter) {
88
+ const nodeAfterDom = editor.view.nodeDOM($pos.pos);
89
+ if (nodeAfterDom && nodeAfterDom === finalCandidate) {
90
+ return {
91
+ resultElement: finalCandidate,
92
+ resultNode: $pos.nodeAfter,
93
+ pos: candidatePos
94
+ };
95
+ }
96
+ }
86
97
  const candidateNode = editor.state.doc.nodeAt(candidatePos - 1);
87
98
  return { resultElement: finalCandidate, resultNode: candidateNode, pos: candidatePos };
88
99
  };
@@ -240,6 +251,7 @@ var DragHandlePlugin = ({
240
251
  element,
241
252
  editor,
242
253
  computePositionConfig,
254
+ getReferencedVirtualElement,
243
255
  onNodeChange,
244
256
  onElementDragStart,
245
257
  onElementDragEnd
@@ -270,7 +282,7 @@ var DragHandlePlugin = ({
270
282
  element.style.pointerEvents = "auto";
271
283
  }
272
284
  function repositionDragHandle(dom) {
273
- const virtualElement = {
285
+ const virtualElement = (getReferencedVirtualElement == null ? void 0 : getReferencedVirtualElement()) || {
274
286
  getBoundingClientRect: () => dom.getBoundingClientRect()
275
287
  };
276
288
  (0, import_dom.computePosition)(virtualElement, element, computePositionConfig).then((val) => {
@@ -524,6 +536,7 @@ var DragHandle = import_core.Extension.create({
524
536
  return [
525
537
  DragHandlePlugin({
526
538
  computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },
539
+ getReferencedVirtualElement: this.options.getReferencedVirtualElement,
527
540
  element,
528
541
  editor: this.editor,
529
542
  onNodeChange: this.options.onNodeChange
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/drag-handle.ts","../src/drag-handle-plugin.ts","../src/helpers/dragHandler.ts","../src/helpers/cloneElement.ts","../src/helpers/findNextElementFromCursor.ts","../src/helpers/getComputedStyle.ts","../src/helpers/minMax.ts","../src/helpers/getInnerCoords.ts","../src/helpers/removeNode.ts","../src/helpers/getOuterNode.ts"],"sourcesContent":["import { DragHandle } from './drag-handle.js'\n\nexport * from './drag-handle.js'\nexport * from './drag-handle-plugin.js'\n\nexport default DragHandle\n","import type { ComputePositionConfig } from '@floating-ui/dom'\nimport { type Editor, Extension } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\n\nimport { DragHandlePlugin } from './drag-handle-plugin.js'\n\nexport const defaultComputePositionConfig: ComputePositionConfig = {\n placement: 'left-start',\n strategy: 'absolute',\n}\n\nexport interface DragHandleOptions {\n /**\n * Renders an element that is positioned with the floating-ui/dom package\n */\n render(): HTMLElement\n /**\n * Configuration for position computation of the drag handle\n * using the floating-ui/dom package\n */\n computePositionConfig?: ComputePositionConfig\n /**\n * Locks the draghandle in place and visibility\n */\n locked?: boolean\n /**\n * Returns a node or null when a node is hovered over\n */\n onNodeChange?: (options: { node: Node | null; editor: Editor }) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n dragHandle: {\n /**\n * Locks the draghandle in place and visibility\n */\n lockDragHandle: () => ReturnType\n /**\n * Unlocks the draghandle\n */\n unlockDragHandle: () => ReturnType\n /**\n * Toggle draghandle lock state\n */\n toggleDragHandle: () => ReturnType\n }\n }\n}\n\nexport const DragHandle = Extension.create<DragHandleOptions>({\n name: 'dragHandle',\n\n addOptions() {\n return {\n render() {\n const element = document.createElement('div')\n\n element.classList.add('drag-handle')\n\n return element\n },\n computePositionConfig: {},\n locked: false,\n onNodeChange: () => {\n return null\n },\n }\n },\n\n addCommands() {\n return {\n lockDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = true\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n unlockDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = false\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n toggleDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = !this.options.locked\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n }\n },\n\n addProseMirrorPlugins() {\n const element = this.options.render()\n\n return [\n DragHandlePlugin({\n computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },\n element,\n editor: this.editor,\n onNodeChange: this.options.onNodeChange,\n }).plugin,\n ]\n },\n})\n","import { type ComputePositionConfig, computePosition } from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { isChangeOrigin } from '@tiptap/extension-collaboration'\nimport type { Node } from '@tiptap/pm/model'\nimport { type EditorState, type Transaction, Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n ySyncPluginKey,\n} from '@tiptap/y-tiptap'\n\nimport { dragHandler } from './helpers/dragHandler.js'\nimport { findElementNextToCoords } from './helpers/findNextElementFromCursor.js'\nimport { getOuterNode, getOuterNodePos } from './helpers/getOuterNode.js'\nimport { removeNode } from './helpers/removeNode.js'\n\ntype PluginState = {\n locked: boolean\n}\n\nconst getRelativePos = (state: EditorState, absolutePos: number) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return null\n }\n\n return absolutePositionToRelativePosition(absolutePos, ystate.type, ystate.binding.mapping)\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: y-prosemirror (and y-tiptap by extension) does not have types for relative positions\nconst getAbsolutePos = (state: EditorState, relativePos: any) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return -1\n }\n\n return relativePositionToAbsolutePosition(ystate.doc, ystate.type, relativePos, ystate.binding.mapping) || 0\n}\n\nconst getOuterDomNode = (view: EditorView, domNode: HTMLElement) => {\n let tmpDomNode = domNode\n\n // Traverse to top level node.\n while (tmpDomNode?.parentNode) {\n if (tmpDomNode.parentNode === view.dom) {\n break\n }\n\n tmpDomNode = tmpDomNode.parentNode as HTMLElement\n }\n\n return tmpDomNode\n}\n\nexport interface DragHandlePluginProps {\n pluginKey?: PluginKey | string\n editor: Editor\n element: HTMLElement\n onNodeChange?: (data: { editor: Editor; node: Node | null; pos: number }) => void\n onElementDragStart?: (e: DragEvent) => void\n onElementDragEnd?: (e: DragEvent) => void\n computePositionConfig?: ComputePositionConfig\n}\n\nexport const dragHandlePluginDefaultKey = new PluginKey('dragHandle')\n\nexport const DragHandlePlugin = ({\n pluginKey = dragHandlePluginDefaultKey,\n element,\n editor,\n computePositionConfig,\n onNodeChange,\n onElementDragStart,\n onElementDragEnd,\n}: DragHandlePluginProps) => {\n const wrapper = document.createElement('div')\n let locked = false\n let currentNode: Node | null = null\n let currentNodePos = -1\n // biome-ignore lint/suspicious/noExplicitAny: See above - relative positions in y-prosemirror are not typed\n let currentNodeRelPos: any\n let rafId: number | null = null\n let pendingMouseCoords: { x: number; y: number } | null = null\n\n function hideHandle() {\n if (!element) {\n return\n }\n\n element.style.visibility = 'hidden'\n element.style.pointerEvents = 'none'\n }\n\n function showHandle() {\n if (!element) {\n return\n }\n\n if (!editor.isEditable) {\n hideHandle()\n return\n }\n\n element.style.visibility = ''\n element.style.pointerEvents = 'auto'\n }\n\n function repositionDragHandle(dom: Element) {\n const virtualElement = {\n getBoundingClientRect: () => dom.getBoundingClientRect(),\n }\n\n computePosition(virtualElement, element, computePositionConfig).then(val => {\n Object.assign(element.style, {\n position: val.strategy,\n left: `${val.x}px`,\n top: `${val.y}px`,\n })\n })\n }\n\n function onDragStart(e: DragEvent) {\n onElementDragStart?.(e)\n // Push this to the end of the event cue\n // Fixes bug where incorrect drag pos is returned if drag handle has position: absolute\n // @ts-ignore\n dragHandler(e, editor)\n\n setTimeout(() => {\n if (element) {\n element.style.pointerEvents = 'none'\n }\n }, 0)\n }\n\n function onDragEnd(e: DragEvent) {\n onElementDragEnd?.(e)\n hideHandle()\n if (element) {\n element.style.pointerEvents = 'auto'\n }\n }\n\n element.addEventListener('dragstart', onDragStart)\n element.addEventListener('dragend', onDragEnd)\n\n wrapper.appendChild(element)\n\n return {\n unbind() {\n element.removeEventListener('dragstart', onDragStart)\n element.removeEventListener('dragend', onDragEnd)\n if (rafId) {\n cancelAnimationFrame(rafId)\n rafId = null\n pendingMouseCoords = null\n }\n },\n plugin: new Plugin({\n key: typeof pluginKey === 'string' ? new PluginKey(pluginKey) : pluginKey,\n\n state: {\n init() {\n return { locked: false }\n },\n apply(tr: Transaction, value: PluginState, _oldState: EditorState, state: EditorState) {\n const isLocked = tr.getMeta('lockDragHandle')\n const hideDragHandle = tr.getMeta('hideDragHandle')\n\n if (isLocked !== undefined) {\n locked = isLocked\n }\n\n if (hideDragHandle) {\n hideHandle()\n\n locked = false\n currentNode = null\n currentNodePos = -1\n\n onNodeChange?.({ editor, node: null, pos: -1 })\n\n return value\n }\n\n // Something has changed and drag handler is visible…\n if (tr.docChanged && currentNodePos !== -1 && element) {\n // Yjs replaces the entire document on every incoming change and needs a special handling.\n // If change comes from another user …\n if (isChangeOrigin(tr)) {\n // https://discuss.yjs.dev/t/y-prosemirror-mapping-a-single-relative-position-when-doc-changes/851/3\n const newPos = getAbsolutePos(state, currentNodeRelPos)\n\n if (newPos !== currentNodePos) {\n // Set the new position for our current node.\n currentNodePos = newPos\n\n // We will get the outer node with data and position in views update method.\n }\n } else {\n // … otherwise use ProseMirror mapping to update the position.\n const newPos = tr.mapping.map(currentNodePos)\n\n if (newPos !== currentNodePos) {\n // TODO: Remove\n // console.log('Position has changed …', { old: currentNodePos, new: newPos }, tr);\n\n // Set the new position for our current node.\n currentNodePos = newPos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(state, currentNodePos)\n\n // We will get the outer node with data and position in views update method.\n }\n }\n }\n\n return value\n },\n },\n\n view: view => {\n element.draggable = true\n element.style.pointerEvents = 'auto'\n\n editor.view.dom.parentElement?.appendChild(wrapper)\n\n wrapper.style.pointerEvents = 'none'\n wrapper.style.position = 'absolute'\n wrapper.style.top = '0'\n wrapper.style.left = '0'\n\n return {\n update(_, oldState) {\n if (!element) {\n return\n }\n\n if (!editor.isEditable) {\n hideHandle()\n return\n }\n\n // Prevent element being draggend while being open.\n if (locked) {\n element.draggable = false\n } else {\n element.draggable = true\n }\n\n // Recalculate popup position if doc has changend and drag handler is visible.\n if (view.state.doc.eq(oldState.doc) || currentNodePos === -1) {\n return\n }\n\n // Get domNode from (new) position.\n let domNode = view.nodeDOM(currentNodePos) as HTMLElement\n\n // Since old element could have been wrapped, we need to find\n // the outer node and take its position and node data.\n domNode = getOuterDomNode(view, domNode)\n\n // Skip if domNode is editor dom.\n if (domNode === view.dom) {\n return\n }\n\n // We only want `Element`.\n if (domNode?.nodeType !== 1) {\n return\n }\n\n const domNodePos = view.posAtDOM(domNode, 0)\n const outerNode = getOuterNode(editor.state.doc, domNodePos)\n const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos) // TODO: needed?\n\n currentNode = outerNode\n currentNodePos = outerNodePos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n repositionDragHandle(domNode as Element)\n },\n\n // TODO: Kills even on hot reload\n destroy() {\n if (rafId) {\n cancelAnimationFrame(rafId)\n rafId = null\n pendingMouseCoords = null\n }\n\n if (element) {\n removeNode(wrapper)\n }\n },\n }\n },\n\n props: {\n handleDOMEvents: {\n keydown(view) {\n if (!element || locked) {\n return false\n }\n\n if (view.hasFocus()) {\n hideHandle()\n currentNode = null\n currentNodePos = -1\n onNodeChange?.({ editor, node: null, pos: -1 })\n\n // We want to still continue with other keydown events.\n return false\n }\n\n return false\n },\n mouseleave(_view, e) {\n // Do not hide open popup on mouseleave.\n if (locked) {\n return false\n }\n\n // If e.target is not inside the wrapper, hide.\n if (e.target && !wrapper.contains(e.relatedTarget as HTMLElement)) {\n hideHandle()\n\n currentNode = null\n currentNodePos = -1\n\n onNodeChange?.({ editor, node: null, pos: -1 })\n }\n\n return false\n },\n\n mousemove(view, e) {\n // Do not continue if popup is not initialized or open.\n if (!element || locked) {\n return false\n }\n\n // Store latest mouse coords and schedule a single RAF per frame\n pendingMouseCoords = { x: e.clientX, y: e.clientY }\n\n if (rafId) {\n return false\n }\n\n rafId = requestAnimationFrame(() => {\n rafId = null\n\n if (!pendingMouseCoords) {\n return\n }\n\n const { x, y } = pendingMouseCoords\n pendingMouseCoords = null\n\n const nodeData = findElementNextToCoords({\n x,\n y,\n direction: 'right',\n editor,\n })\n\n // Skip if there is no node next to coords\n if (!nodeData.resultElement) {\n return\n }\n\n let domNode = nodeData.resultElement as HTMLElement\n\n domNode = getOuterDomNode(view, domNode)\n\n // Skip if domNode is editor dom.\n if (domNode === view.dom) {\n return\n }\n\n // We only want `Element`.\n if (domNode?.nodeType !== 1) {\n return\n }\n\n const domNodePos = view.posAtDOM(domNode, 0)\n const outerNode = getOuterNode(editor.state.doc, domNodePos)\n\n if (outerNode !== currentNode) {\n const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos)\n\n currentNode = outerNode\n currentNodePos = outerNodePos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n // Set nodes clientRect.\n repositionDragHandle(domNode as Element)\n\n showHandle()\n }\n })\n\n return false\n },\n },\n },\n }),\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { getSelectionRanges, NodeRangeSelection } from '@tiptap/extension-node-range'\nimport type { SelectionRange } from '@tiptap/pm/state'\n\nimport { cloneElement } from './cloneElement.js'\nimport { findElementNextToCoords } from './findNextElementFromCursor.js'\nimport { getInnerCoords } from './getInnerCoords.js'\nimport { removeNode } from './removeNode.js'\n\nfunction getDragHandleRanges(event: DragEvent, editor: Editor): SelectionRange[] {\n const { doc } = editor.view.state\n\n const result = findElementNextToCoords({\n editor,\n x: event.clientX,\n y: event.clientY,\n direction: 'right',\n })\n\n if (!result.resultNode || result.pos === null) {\n return []\n }\n\n const x = event.clientX\n\n // @ts-ignore\n const coords = getInnerCoords(editor.view, x, event.clientY)\n const posAtCoords = editor.view.posAtCoords(coords)\n\n if (!posAtCoords) {\n return []\n }\n\n const { pos } = posAtCoords\n const nodeAt = doc.resolve(pos).parent\n\n if (!nodeAt) {\n return []\n }\n\n const $from = doc.resolve(result.pos)\n const $to = doc.resolve(result.pos + 1)\n\n return getSelectionRanges($from, $to, 0)\n}\n\nexport function dragHandler(event: DragEvent, editor: Editor) {\n const { view } = editor\n\n if (!event.dataTransfer) {\n return\n }\n\n const { empty, $from, $to } = view.state.selection\n\n const dragHandleRanges = getDragHandleRanges(event, editor)\n\n const selectionRanges = getSelectionRanges($from, $to, 0)\n const isDragHandleWithinSelection = selectionRanges.some(range => {\n return dragHandleRanges.find(dragHandleRange => {\n return dragHandleRange.$from === range.$from && dragHandleRange.$to === range.$to\n })\n })\n\n const ranges = empty || !isDragHandleWithinSelection ? dragHandleRanges : selectionRanges\n\n if (!ranges.length) {\n return\n }\n\n const { tr } = view.state\n const wrapper = document.createElement('div')\n const from = ranges[0].$from.pos\n const to = ranges[ranges.length - 1].$to.pos\n\n const selection = NodeRangeSelection.create(view.state.doc, from, to)\n const slice = selection.content()\n\n ranges.forEach(range => {\n const element = view.nodeDOM(range.$from.pos) as HTMLElement\n const clonedElement = cloneElement(element)\n\n wrapper.append(clonedElement)\n })\n\n wrapper.style.position = 'absolute'\n wrapper.style.top = '-10000px'\n document.body.append(wrapper)\n\n event.dataTransfer.clearData()\n event.dataTransfer.setDragImage(wrapper, 0, 0)\n\n // tell ProseMirror the dragged content\n view.dragging = { slice, move: true }\n\n tr.setSelection(selection)\n\n view.dispatch(tr)\n\n // clean up\n document.addEventListener('drop', () => removeNode(wrapper), { once: true })\n}\n","function getCSSText(element: Element) {\n let value = ''\n const style = getComputedStyle(element)\n\n for (let i = 0; i < style.length; i += 1) {\n value += `${style[i]}:${style.getPropertyValue(style[i])};`\n }\n\n return value\n}\n\nexport function cloneElement(node: HTMLElement) {\n const clonedNode = node.cloneNode(true) as HTMLElement\n const sourceElements = [node, ...Array.from(node.getElementsByTagName('*'))] as HTMLElement[]\n const targetElements = [clonedNode, ...Array.from(clonedNode.getElementsByTagName('*'))] as HTMLElement[]\n\n sourceElements.forEach((sourceElement, index) => {\n targetElements[index].style.cssText = getCSSText(sourceElement)\n })\n\n return clonedNode\n}\n","import type { Editor } from '@tiptap/core'\n\nexport type FindElementNextToCoords = {\n x: number\n y: number\n direction?: 'left' | 'right'\n editor: Editor\n bandHeight?: number\n}\n\nexport const findElementNextToCoords = (options: FindElementNextToCoords) => {\n const { x, y, direction = 'right', editor, bandHeight = 5 } = options\n\n const rect = {\n top: y - bandHeight,\n bottom: y + bandHeight,\n left: direction === 'right' ? x : 0,\n right: direction === 'right' ? window.innerWidth - x : x,\n }\n\n const root = editor.view.dom as HTMLElement\n\n // Get potential candidates from prosemirror child elements and filter\n // by removing decorations and non prosemirror-elements\n const candidates = [...root.querySelectorAll<HTMLElement>('*')]\n .filter(candidate => {\n return editor.view.posAtDOM(candidate, 0) >= 0\n })\n .filter(candidate => {\n const candidateRect = candidate.getBoundingClientRect()\n return !(\n candidateRect.bottom < rect.top ||\n candidateRect.top > rect.bottom ||\n candidateRect.right < rect.left ||\n candidateRect.left > rect.right\n )\n })\n\n if (!candidates || candidates.length === 0) {\n return { resultElement: null, resultNode: null, pos: null }\n }\n\n const finalCandidate = candidates[0]\n const candidatePos = editor.view.posAtDOM(finalCandidate, 0)\n if (candidatePos === -1) {\n return { resultElement: finalCandidate, resultNode: null, pos: null }\n }\n\n const candidateNode = editor.state.doc.nodeAt(candidatePos - 1)\n\n return { resultElement: finalCandidate, resultNode: candidateNode, pos: candidatePos }\n}\n","export function getComputedStyle(node: Element, property: keyof CSSStyleDeclaration): any {\n const style = window.getComputedStyle(node)\n\n return style[property]\n}\n","export function minMax(value = 0, min = 0, max = 0): number {\n return Math.min(Math.max(value, min), max)\n}\n","import type { EditorView } from '@tiptap/pm/view'\n\nimport { getComputedStyle } from './getComputedStyle.js'\nimport { minMax } from './minMax.js'\n\nexport function getInnerCoords(view: EditorView, x: number, y: number): { left: number; top: number } {\n const paddingLeft = parseInt(getComputedStyle(view.dom, 'paddingLeft'), 10)\n const paddingRight = parseInt(getComputedStyle(view.dom, 'paddingRight'), 10)\n const borderLeft = parseInt(getComputedStyle(view.dom, 'borderLeftWidth'), 10)\n const borderRight = parseInt(getComputedStyle(view.dom, 'borderLeftWidth'), 10)\n const bounds = view.dom.getBoundingClientRect()\n const coords = {\n left: minMax(x, bounds.left + paddingLeft + borderLeft, bounds.right - paddingRight - borderRight),\n top: y,\n }\n\n return coords\n}\n","export function removeNode(node: HTMLElement) {\n node.parentNode?.removeChild(node)\n}\n","import type { Node } from '@tiptap/pm/model'\n\nexport const getOuterNodePos = (doc: Node, pos: number): number => {\n const resolvedPos = doc.resolve(pos)\n const { depth } = resolvedPos\n\n if (depth === 0) {\n return pos\n }\n\n const a = resolvedPos.pos - resolvedPos.parentOffset\n\n return a - 1\n}\n\nexport const getOuterNode = (doc: Node, pos: number): Node | null => {\n const node = doc.nodeAt(pos)\n const resolvedPos = doc.resolve(pos)\n\n let { depth } = resolvedPos\n let parent = node\n\n while (depth > 0) {\n const currentNode = resolvedPos.node(depth)\n\n depth -= 1\n\n if (depth === 0) {\n parent = currentNode\n }\n }\n\n return parent\n}\n"],"mappings":"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","names":["getComputedStyle","getComputedStyle"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/drag-handle.ts","../src/drag-handle-plugin.ts","../src/helpers/dragHandler.ts","../src/helpers/cloneElement.ts","../src/helpers/findNextElementFromCursor.ts","../src/helpers/getComputedStyle.ts","../src/helpers/minMax.ts","../src/helpers/getInnerCoords.ts","../src/helpers/removeNode.ts","../src/helpers/getOuterNode.ts"],"sourcesContent":["import { DragHandle } from './drag-handle.js'\n\nexport * from './drag-handle.js'\nexport * from './drag-handle-plugin.js'\n\nexport default DragHandle\n","import type { ComputePositionConfig, VirtualElement } from '@floating-ui/dom'\nimport { type Editor, Extension } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\n\nimport { DragHandlePlugin } from './drag-handle-plugin.js'\n\nexport const defaultComputePositionConfig: ComputePositionConfig = {\n placement: 'left-start',\n strategy: 'absolute',\n}\n\nexport interface DragHandleOptions {\n /**\n * Renders an element that is positioned with the floating-ui/dom package\n */\n render(): HTMLElement\n /**\n * Configuration for position computation of the drag handle\n * using the floating-ui/dom package\n */\n computePositionConfig?: ComputePositionConfig\n /**\n * A function that returns the virtual element for the drag handle.\n * This is useful when the menu needs to be positioned relative to a specific DOM element.\n */\n getReferencedVirtualElement?: () => VirtualElement | null\n /**\n * Locks the draghandle in place and visibility\n */\n locked?: boolean\n /**\n * Returns a node or null when a node is hovered over\n */\n onNodeChange?: (options: { node: Node | null; editor: Editor }) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n dragHandle: {\n /**\n * Locks the draghandle in place and visibility\n */\n lockDragHandle: () => ReturnType\n /**\n * Unlocks the draghandle\n */\n unlockDragHandle: () => ReturnType\n /**\n * Toggle draghandle lock state\n */\n toggleDragHandle: () => ReturnType\n }\n }\n}\n\nexport const DragHandle = Extension.create<DragHandleOptions>({\n name: 'dragHandle',\n\n addOptions() {\n return {\n render() {\n const element = document.createElement('div')\n\n element.classList.add('drag-handle')\n\n return element\n },\n computePositionConfig: {},\n locked: false,\n onNodeChange: () => {\n return null\n },\n }\n },\n\n addCommands() {\n return {\n lockDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = true\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n unlockDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = false\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n toggleDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = !this.options.locked\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n }\n },\n\n addProseMirrorPlugins() {\n const element = this.options.render()\n\n return [\n DragHandlePlugin({\n computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },\n getReferencedVirtualElement: this.options.getReferencedVirtualElement,\n element,\n editor: this.editor,\n onNodeChange: this.options.onNodeChange,\n }).plugin,\n ]\n },\n})\n","import { type ComputePositionConfig, type VirtualElement, computePosition } from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { isChangeOrigin } from '@tiptap/extension-collaboration'\nimport type { Node } from '@tiptap/pm/model'\nimport { type EditorState, type Transaction, Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n ySyncPluginKey,\n} from '@tiptap/y-tiptap'\n\nimport { dragHandler } from './helpers/dragHandler.js'\nimport { findElementNextToCoords } from './helpers/findNextElementFromCursor.js'\nimport { getOuterNode, getOuterNodePos } from './helpers/getOuterNode.js'\nimport { removeNode } from './helpers/removeNode.js'\n\ntype PluginState = {\n locked: boolean\n}\n\nconst getRelativePos = (state: EditorState, absolutePos: number) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return null\n }\n\n return absolutePositionToRelativePosition(absolutePos, ystate.type, ystate.binding.mapping)\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: y-prosemirror (and y-tiptap by extension) does not have types for relative positions\nconst getAbsolutePos = (state: EditorState, relativePos: any) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return -1\n }\n\n return relativePositionToAbsolutePosition(ystate.doc, ystate.type, relativePos, ystate.binding.mapping) || 0\n}\n\nconst getOuterDomNode = (view: EditorView, domNode: HTMLElement) => {\n let tmpDomNode = domNode\n\n // Traverse to top level node.\n while (tmpDomNode?.parentNode) {\n if (tmpDomNode.parentNode === view.dom) {\n break\n }\n\n tmpDomNode = tmpDomNode.parentNode as HTMLElement\n }\n\n return tmpDomNode\n}\n\nexport interface DragHandlePluginProps {\n pluginKey?: PluginKey | string\n editor: Editor\n element: HTMLElement\n onNodeChange?: (data: { editor: Editor; node: Node | null; pos: number }) => void\n onElementDragStart?: (e: DragEvent) => void\n onElementDragEnd?: (e: DragEvent) => void\n computePositionConfig?: ComputePositionConfig\n getReferencedVirtualElement?: () => VirtualElement | null\n}\n\nexport const dragHandlePluginDefaultKey = new PluginKey('dragHandle')\n\nexport const DragHandlePlugin = ({\n pluginKey = dragHandlePluginDefaultKey,\n element,\n editor,\n computePositionConfig,\n getReferencedVirtualElement,\n onNodeChange,\n onElementDragStart,\n onElementDragEnd,\n}: DragHandlePluginProps) => {\n const wrapper = document.createElement('div')\n let locked = false\n let currentNode: Node | null = null\n let currentNodePos = -1\n // biome-ignore lint/suspicious/noExplicitAny: See above - relative positions in y-prosemirror are not typed\n let currentNodeRelPos: any\n let rafId: number | null = null\n let pendingMouseCoords: { x: number; y: number } | null = null\n\n function hideHandle() {\n if (!element) {\n return\n }\n\n element.style.visibility = 'hidden'\n element.style.pointerEvents = 'none'\n }\n\n function showHandle() {\n if (!element) {\n return\n }\n\n if (!editor.isEditable) {\n hideHandle()\n return\n }\n\n element.style.visibility = ''\n element.style.pointerEvents = 'auto'\n }\n\n function repositionDragHandle(dom: Element) {\n const virtualElement = getReferencedVirtualElement?.() || {\n getBoundingClientRect: () => dom.getBoundingClientRect(),\n }\n\n computePosition(virtualElement, element, computePositionConfig).then(val => {\n Object.assign(element.style, {\n position: val.strategy,\n left: `${val.x}px`,\n top: `${val.y}px`,\n })\n })\n }\n\n function onDragStart(e: DragEvent) {\n onElementDragStart?.(e)\n // Push this to the end of the event cue\n // Fixes bug where incorrect drag pos is returned if drag handle has position: absolute\n // @ts-ignore\n dragHandler(e, editor)\n\n setTimeout(() => {\n if (element) {\n element.style.pointerEvents = 'none'\n }\n }, 0)\n }\n\n function onDragEnd(e: DragEvent) {\n onElementDragEnd?.(e)\n hideHandle()\n if (element) {\n element.style.pointerEvents = 'auto'\n }\n }\n\n element.addEventListener('dragstart', onDragStart)\n element.addEventListener('dragend', onDragEnd)\n\n wrapper.appendChild(element)\n\n return {\n unbind() {\n element.removeEventListener('dragstart', onDragStart)\n element.removeEventListener('dragend', onDragEnd)\n if (rafId) {\n cancelAnimationFrame(rafId)\n rafId = null\n pendingMouseCoords = null\n }\n },\n plugin: new Plugin({\n key: typeof pluginKey === 'string' ? new PluginKey(pluginKey) : pluginKey,\n\n state: {\n init() {\n return { locked: false }\n },\n apply(tr: Transaction, value: PluginState, _oldState: EditorState, state: EditorState) {\n const isLocked = tr.getMeta('lockDragHandle')\n const hideDragHandle = tr.getMeta('hideDragHandle')\n\n if (isLocked !== undefined) {\n locked = isLocked\n }\n\n if (hideDragHandle) {\n hideHandle()\n\n locked = false\n currentNode = null\n currentNodePos = -1\n\n onNodeChange?.({ editor, node: null, pos: -1 })\n\n return value\n }\n\n // Something has changed and drag handler is visible…\n if (tr.docChanged && currentNodePos !== -1 && element) {\n // Yjs replaces the entire document on every incoming change and needs a special handling.\n // If change comes from another user …\n if (isChangeOrigin(tr)) {\n // https://discuss.yjs.dev/t/y-prosemirror-mapping-a-single-relative-position-when-doc-changes/851/3\n const newPos = getAbsolutePos(state, currentNodeRelPos)\n\n if (newPos !== currentNodePos) {\n // Set the new position for our current node.\n currentNodePos = newPos\n\n // We will get the outer node with data and position in views update method.\n }\n } else {\n // … otherwise use ProseMirror mapping to update the position.\n const newPos = tr.mapping.map(currentNodePos)\n\n if (newPos !== currentNodePos) {\n // TODO: Remove\n // console.log('Position has changed …', { old: currentNodePos, new: newPos }, tr);\n\n // Set the new position for our current node.\n currentNodePos = newPos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(state, currentNodePos)\n\n // We will get the outer node with data and position in views update method.\n }\n }\n }\n\n return value\n },\n },\n\n view: view => {\n element.draggable = true\n element.style.pointerEvents = 'auto'\n\n editor.view.dom.parentElement?.appendChild(wrapper)\n\n wrapper.style.pointerEvents = 'none'\n wrapper.style.position = 'absolute'\n wrapper.style.top = '0'\n wrapper.style.left = '0'\n\n return {\n update(_, oldState) {\n if (!element) {\n return\n }\n\n if (!editor.isEditable) {\n hideHandle()\n return\n }\n\n // Prevent element being draggend while being open.\n if (locked) {\n element.draggable = false\n } else {\n element.draggable = true\n }\n\n // Recalculate popup position if doc has changend and drag handler is visible.\n if (view.state.doc.eq(oldState.doc) || currentNodePos === -1) {\n return\n }\n\n // Get domNode from (new) position.\n let domNode = view.nodeDOM(currentNodePos) as HTMLElement\n\n // Since old element could have been wrapped, we need to find\n // the outer node and take its position and node data.\n domNode = getOuterDomNode(view, domNode)\n\n // Skip if domNode is editor dom.\n if (domNode === view.dom) {\n return\n }\n\n // We only want `Element`.\n if (domNode?.nodeType !== 1) {\n return\n }\n\n const domNodePos = view.posAtDOM(domNode, 0)\n const outerNode = getOuterNode(editor.state.doc, domNodePos)\n const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos) // TODO: needed?\n\n currentNode = outerNode\n currentNodePos = outerNodePos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n repositionDragHandle(domNode as Element)\n },\n\n // TODO: Kills even on hot reload\n destroy() {\n if (rafId) {\n cancelAnimationFrame(rafId)\n rafId = null\n pendingMouseCoords = null\n }\n\n if (element) {\n removeNode(wrapper)\n }\n },\n }\n },\n\n props: {\n handleDOMEvents: {\n keydown(view) {\n if (!element || locked) {\n return false\n }\n\n if (view.hasFocus()) {\n hideHandle()\n currentNode = null\n currentNodePos = -1\n onNodeChange?.({ editor, node: null, pos: -1 })\n\n // We want to still continue with other keydown events.\n return false\n }\n\n return false\n },\n mouseleave(_view, e) {\n // Do not hide open popup on mouseleave.\n if (locked) {\n return false\n }\n\n // If e.target is not inside the wrapper, hide.\n if (e.target && !wrapper.contains(e.relatedTarget as HTMLElement)) {\n hideHandle()\n\n currentNode = null\n currentNodePos = -1\n\n onNodeChange?.({ editor, node: null, pos: -1 })\n }\n\n return false\n },\n\n mousemove(view, e) {\n // Do not continue if popup is not initialized or open.\n if (!element || locked) {\n return false\n }\n\n // Store latest mouse coords and schedule a single RAF per frame\n pendingMouseCoords = { x: e.clientX, y: e.clientY }\n\n if (rafId) {\n return false\n }\n\n rafId = requestAnimationFrame(() => {\n rafId = null\n\n if (!pendingMouseCoords) {\n return\n }\n\n const { x, y } = pendingMouseCoords\n pendingMouseCoords = null\n\n const nodeData = findElementNextToCoords({\n x,\n y,\n direction: 'right',\n editor,\n })\n\n // Skip if there is no node next to coords\n if (!nodeData.resultElement) {\n return\n }\n\n let domNode = nodeData.resultElement as HTMLElement\n\n domNode = getOuterDomNode(view, domNode)\n\n // Skip if domNode is editor dom.\n if (domNode === view.dom) {\n return\n }\n\n // We only want `Element`.\n if (domNode?.nodeType !== 1) {\n return\n }\n\n const domNodePos = view.posAtDOM(domNode, 0)\n const outerNode = getOuterNode(editor.state.doc, domNodePos)\n\n if (outerNode !== currentNode) {\n const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos)\n\n currentNode = outerNode\n currentNodePos = outerNodePos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n // Set nodes clientRect.\n repositionDragHandle(domNode as Element)\n\n showHandle()\n }\n })\n\n return false\n },\n },\n },\n }),\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { getSelectionRanges, NodeRangeSelection } from '@tiptap/extension-node-range'\nimport type { SelectionRange } from '@tiptap/pm/state'\n\nimport { cloneElement } from './cloneElement.js'\nimport { findElementNextToCoords } from './findNextElementFromCursor.js'\nimport { getInnerCoords } from './getInnerCoords.js'\nimport { removeNode } from './removeNode.js'\n\nfunction getDragHandleRanges(event: DragEvent, editor: Editor): SelectionRange[] {\n const { doc } = editor.view.state\n\n const result = findElementNextToCoords({\n editor,\n x: event.clientX,\n y: event.clientY,\n direction: 'right',\n })\n\n if (!result.resultNode || result.pos === null) {\n return []\n }\n\n const x = event.clientX\n\n // @ts-ignore\n const coords = getInnerCoords(editor.view, x, event.clientY)\n const posAtCoords = editor.view.posAtCoords(coords)\n\n if (!posAtCoords) {\n return []\n }\n\n const { pos } = posAtCoords\n const nodeAt = doc.resolve(pos).parent\n\n if (!nodeAt) {\n return []\n }\n\n const $from = doc.resolve(result.pos)\n const $to = doc.resolve(result.pos + 1)\n\n return getSelectionRanges($from, $to, 0)\n}\n\nexport function dragHandler(event: DragEvent, editor: Editor) {\n const { view } = editor\n\n if (!event.dataTransfer) {\n return\n }\n\n const { empty, $from, $to } = view.state.selection\n\n const dragHandleRanges = getDragHandleRanges(event, editor)\n\n const selectionRanges = getSelectionRanges($from, $to, 0)\n const isDragHandleWithinSelection = selectionRanges.some(range => {\n return dragHandleRanges.find(dragHandleRange => {\n return dragHandleRange.$from === range.$from && dragHandleRange.$to === range.$to\n })\n })\n\n const ranges = empty || !isDragHandleWithinSelection ? dragHandleRanges : selectionRanges\n\n if (!ranges.length) {\n return\n }\n\n const { tr } = view.state\n const wrapper = document.createElement('div')\n const from = ranges[0].$from.pos\n const to = ranges[ranges.length - 1].$to.pos\n\n const selection = NodeRangeSelection.create(view.state.doc, from, to)\n const slice = selection.content()\n\n ranges.forEach(range => {\n const element = view.nodeDOM(range.$from.pos) as HTMLElement\n const clonedElement = cloneElement(element)\n\n wrapper.append(clonedElement)\n })\n\n wrapper.style.position = 'absolute'\n wrapper.style.top = '-10000px'\n document.body.append(wrapper)\n\n event.dataTransfer.clearData()\n event.dataTransfer.setDragImage(wrapper, 0, 0)\n\n // tell ProseMirror the dragged content\n view.dragging = { slice, move: true }\n\n tr.setSelection(selection)\n\n view.dispatch(tr)\n\n // clean up\n document.addEventListener('drop', () => removeNode(wrapper), { once: true })\n}\n","function getCSSText(element: Element) {\n let value = ''\n const style = getComputedStyle(element)\n\n for (let i = 0; i < style.length; i += 1) {\n value += `${style[i]}:${style.getPropertyValue(style[i])};`\n }\n\n return value\n}\n\nexport function cloneElement(node: HTMLElement) {\n const clonedNode = node.cloneNode(true) as HTMLElement\n const sourceElements = [node, ...Array.from(node.getElementsByTagName('*'))] as HTMLElement[]\n const targetElements = [clonedNode, ...Array.from(clonedNode.getElementsByTagName('*'))] as HTMLElement[]\n\n sourceElements.forEach((sourceElement, index) => {\n targetElements[index].style.cssText = getCSSText(sourceElement)\n })\n\n return clonedNode\n}\n","import type { Editor } from '@tiptap/core'\n\nexport type FindElementNextToCoords = {\n x: number\n y: number\n direction?: 'left' | 'right'\n editor: Editor\n bandHeight?: number\n}\n\nexport const findElementNextToCoords = (options: FindElementNextToCoords) => {\n const { x, y, direction = 'right', editor, bandHeight = 5 } = options\n\n const rect = {\n top: y - bandHeight,\n bottom: y + bandHeight,\n left: direction === 'right' ? x : 0,\n right: direction === 'right' ? window.innerWidth - x : x,\n }\n\n const root = editor.view.dom as HTMLElement\n\n // Get potential candidates from prosemirror child elements and filter\n // by removing decorations and non prosemirror-elements\n const candidates = [...root.querySelectorAll<HTMLElement>('*')]\n .filter(candidate => {\n return editor.view.posAtDOM(candidate, 0) >= 0\n })\n .filter(candidate => {\n const candidateRect = candidate.getBoundingClientRect()\n return !(\n candidateRect.bottom < rect.top ||\n candidateRect.top > rect.bottom ||\n candidateRect.right < rect.left ||\n candidateRect.left > rect.right\n )\n })\n\n if (!candidates || candidates.length === 0) {\n return { resultElement: null, resultNode: null, pos: null }\n }\n\n const finalCandidate = candidates[0]\n const candidatePos = editor.view.posAtDOM(finalCandidate, 0)\n if (candidatePos === -1) {\n return { resultElement: finalCandidate, resultNode: null, pos: null }\n }\n\n const $pos = editor.state.doc.resolve(candidatePos)\n\n if ($pos.nodeAfter) {\n const nodeAfterDom = editor.view.nodeDOM($pos.pos)\n\n if (nodeAfterDom && nodeAfterDom === finalCandidate) {\n return {\n resultElement: finalCandidate,\n resultNode: $pos.nodeAfter,\n pos: candidatePos,\n }\n }\n }\n\n const candidateNode = editor.state.doc.nodeAt(candidatePos - 1)\n\n return { resultElement: finalCandidate, resultNode: candidateNode, pos: candidatePos }\n}\n","export function getComputedStyle(node: Element, property: keyof CSSStyleDeclaration): any {\n const style = window.getComputedStyle(node)\n\n return style[property]\n}\n","export function minMax(value = 0, min = 0, max = 0): number {\n return Math.min(Math.max(value, min), max)\n}\n","import type { EditorView } from '@tiptap/pm/view'\n\nimport { getComputedStyle } from './getComputedStyle.js'\nimport { minMax } from './minMax.js'\n\nexport function getInnerCoords(view: EditorView, x: number, y: number): { left: number; top: number } {\n const paddingLeft = parseInt(getComputedStyle(view.dom, 'paddingLeft'), 10)\n const paddingRight = parseInt(getComputedStyle(view.dom, 'paddingRight'), 10)\n const borderLeft = parseInt(getComputedStyle(view.dom, 'borderLeftWidth'), 10)\n const borderRight = parseInt(getComputedStyle(view.dom, 'borderLeftWidth'), 10)\n const bounds = view.dom.getBoundingClientRect()\n const coords = {\n left: minMax(x, bounds.left + paddingLeft + borderLeft, bounds.right - paddingRight - borderRight),\n top: y,\n }\n\n return coords\n}\n","export function removeNode(node: HTMLElement) {\n node.parentNode?.removeChild(node)\n}\n","import type { Node } from '@tiptap/pm/model'\n\nexport const getOuterNodePos = (doc: Node, pos: number): number => {\n const resolvedPos = doc.resolve(pos)\n const { depth } = resolvedPos\n\n if (depth === 0) {\n return pos\n }\n\n const a = resolvedPos.pos - resolvedPos.parentOffset\n\n return a - 1\n}\n\nexport const getOuterNode = (doc: Node, pos: number): Node | null => {\n const node = doc.nodeAt(pos)\n const resolvedPos = doc.resolve(pos)\n\n let { depth } = resolvedPos\n let parent = node\n\n while (depth > 0) {\n const currentNode = resolvedPos.node(depth)\n\n depth -= 1\n\n if (depth === 0) {\n parent = currentNode\n }\n }\n\n return parent\n}\n"],"mappings":"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","names":["getComputedStyle","getComputedStyle"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ComputePositionConfig } from '@floating-ui/dom';
1
+ import { ComputePositionConfig, VirtualElement } from '@floating-ui/dom';
2
2
  import { Editor, Extension } from '@tiptap/core';
3
3
  import { Node } from '@tiptap/pm/model';
4
4
  import { PluginKey, Plugin } from '@tiptap/pm/state';
@@ -14,6 +14,11 @@ interface DragHandleOptions {
14
14
  * using the floating-ui/dom package
15
15
  */
16
16
  computePositionConfig?: ComputePositionConfig;
17
+ /**
18
+ * A function that returns the virtual element for the drag handle.
19
+ * This is useful when the menu needs to be positioned relative to a specific DOM element.
20
+ */
21
+ getReferencedVirtualElement?: () => VirtualElement | null;
17
22
  /**
18
23
  * Locks the draghandle in place and visibility
19
24
  */
@@ -58,9 +63,10 @@ interface DragHandlePluginProps {
58
63
  onElementDragStart?: (e: DragEvent) => void;
59
64
  onElementDragEnd?: (e: DragEvent) => void;
60
65
  computePositionConfig?: ComputePositionConfig;
66
+ getReferencedVirtualElement?: () => VirtualElement | null;
61
67
  }
62
68
  declare const dragHandlePluginDefaultKey: PluginKey<any>;
63
- declare const DragHandlePlugin: ({ pluginKey, element, editor, computePositionConfig, onNodeChange, onElementDragStart, onElementDragEnd, }: DragHandlePluginProps) => {
69
+ declare const DragHandlePlugin: ({ pluginKey, element, editor, computePositionConfig, getReferencedVirtualElement, onNodeChange, onElementDragStart, onElementDragEnd, }: DragHandlePluginProps) => {
64
70
  unbind(): void;
65
71
  plugin: Plugin<{
66
72
  locked: boolean;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ComputePositionConfig } from '@floating-ui/dom';
1
+ import { ComputePositionConfig, VirtualElement } from '@floating-ui/dom';
2
2
  import { Editor, Extension } from '@tiptap/core';
3
3
  import { Node } from '@tiptap/pm/model';
4
4
  import { PluginKey, Plugin } from '@tiptap/pm/state';
@@ -14,6 +14,11 @@ interface DragHandleOptions {
14
14
  * using the floating-ui/dom package
15
15
  */
16
16
  computePositionConfig?: ComputePositionConfig;
17
+ /**
18
+ * A function that returns the virtual element for the drag handle.
19
+ * This is useful when the menu needs to be positioned relative to a specific DOM element.
20
+ */
21
+ getReferencedVirtualElement?: () => VirtualElement | null;
17
22
  /**
18
23
  * Locks the draghandle in place and visibility
19
24
  */
@@ -58,9 +63,10 @@ interface DragHandlePluginProps {
58
63
  onElementDragStart?: (e: DragEvent) => void;
59
64
  onElementDragEnd?: (e: DragEvent) => void;
60
65
  computePositionConfig?: ComputePositionConfig;
66
+ getReferencedVirtualElement?: () => VirtualElement | null;
61
67
  }
62
68
  declare const dragHandlePluginDefaultKey: PluginKey<any>;
63
- declare const DragHandlePlugin: ({ pluginKey, element, editor, computePositionConfig, onNodeChange, onElementDragStart, onElementDragEnd, }: DragHandlePluginProps) => {
69
+ declare const DragHandlePlugin: ({ pluginKey, element, editor, computePositionConfig, getReferencedVirtualElement, onNodeChange, onElementDragStart, onElementDragEnd, }: DragHandlePluginProps) => {
64
70
  unbind(): void;
65
71
  plugin: Plugin<{
66
72
  locked: boolean;
package/dist/index.js CHANGED
@@ -57,6 +57,17 @@ var findElementNextToCoords = (options) => {
57
57
  if (candidatePos === -1) {
58
58
  return { resultElement: finalCandidate, resultNode: null, pos: null };
59
59
  }
60
+ const $pos = editor.state.doc.resolve(candidatePos);
61
+ if ($pos.nodeAfter) {
62
+ const nodeAfterDom = editor.view.nodeDOM($pos.pos);
63
+ if (nodeAfterDom && nodeAfterDom === finalCandidate) {
64
+ return {
65
+ resultElement: finalCandidate,
66
+ resultNode: $pos.nodeAfter,
67
+ pos: candidatePos
68
+ };
69
+ }
70
+ }
60
71
  const candidateNode = editor.state.doc.nodeAt(candidatePos - 1);
61
72
  return { resultElement: finalCandidate, resultNode: candidateNode, pos: candidatePos };
62
73
  };
@@ -214,6 +225,7 @@ var DragHandlePlugin = ({
214
225
  element,
215
226
  editor,
216
227
  computePositionConfig,
228
+ getReferencedVirtualElement,
217
229
  onNodeChange,
218
230
  onElementDragStart,
219
231
  onElementDragEnd
@@ -244,7 +256,7 @@ var DragHandlePlugin = ({
244
256
  element.style.pointerEvents = "auto";
245
257
  }
246
258
  function repositionDragHandle(dom) {
247
- const virtualElement = {
259
+ const virtualElement = (getReferencedVirtualElement == null ? void 0 : getReferencedVirtualElement()) || {
248
260
  getBoundingClientRect: () => dom.getBoundingClientRect()
249
261
  };
250
262
  computePosition(virtualElement, element, computePositionConfig).then((val) => {
@@ -498,6 +510,7 @@ var DragHandle = Extension.create({
498
510
  return [
499
511
  DragHandlePlugin({
500
512
  computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },
513
+ getReferencedVirtualElement: this.options.getReferencedVirtualElement,
501
514
  element,
502
515
  editor: this.editor,
503
516
  onNodeChange: this.options.onNodeChange
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/drag-handle.ts","../src/drag-handle-plugin.ts","../src/helpers/dragHandler.ts","../src/helpers/cloneElement.ts","../src/helpers/findNextElementFromCursor.ts","../src/helpers/getComputedStyle.ts","../src/helpers/minMax.ts","../src/helpers/getInnerCoords.ts","../src/helpers/removeNode.ts","../src/helpers/getOuterNode.ts","../src/index.ts"],"sourcesContent":["import type { ComputePositionConfig } from '@floating-ui/dom'\nimport { type Editor, Extension } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\n\nimport { DragHandlePlugin } from './drag-handle-plugin.js'\n\nexport const defaultComputePositionConfig: ComputePositionConfig = {\n placement: 'left-start',\n strategy: 'absolute',\n}\n\nexport interface DragHandleOptions {\n /**\n * Renders an element that is positioned with the floating-ui/dom package\n */\n render(): HTMLElement\n /**\n * Configuration for position computation of the drag handle\n * using the floating-ui/dom package\n */\n computePositionConfig?: ComputePositionConfig\n /**\n * Locks the draghandle in place and visibility\n */\n locked?: boolean\n /**\n * Returns a node or null when a node is hovered over\n */\n onNodeChange?: (options: { node: Node | null; editor: Editor }) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n dragHandle: {\n /**\n * Locks the draghandle in place and visibility\n */\n lockDragHandle: () => ReturnType\n /**\n * Unlocks the draghandle\n */\n unlockDragHandle: () => ReturnType\n /**\n * Toggle draghandle lock state\n */\n toggleDragHandle: () => ReturnType\n }\n }\n}\n\nexport const DragHandle = Extension.create<DragHandleOptions>({\n name: 'dragHandle',\n\n addOptions() {\n return {\n render() {\n const element = document.createElement('div')\n\n element.classList.add('drag-handle')\n\n return element\n },\n computePositionConfig: {},\n locked: false,\n onNodeChange: () => {\n return null\n },\n }\n },\n\n addCommands() {\n return {\n lockDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = true\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n unlockDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = false\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n toggleDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = !this.options.locked\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n }\n },\n\n addProseMirrorPlugins() {\n const element = this.options.render()\n\n return [\n DragHandlePlugin({\n computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },\n element,\n editor: this.editor,\n onNodeChange: this.options.onNodeChange,\n }).plugin,\n ]\n },\n})\n","import { type ComputePositionConfig, computePosition } from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { isChangeOrigin } from '@tiptap/extension-collaboration'\nimport type { Node } from '@tiptap/pm/model'\nimport { type EditorState, type Transaction, Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n ySyncPluginKey,\n} from '@tiptap/y-tiptap'\n\nimport { dragHandler } from './helpers/dragHandler.js'\nimport { findElementNextToCoords } from './helpers/findNextElementFromCursor.js'\nimport { getOuterNode, getOuterNodePos } from './helpers/getOuterNode.js'\nimport { removeNode } from './helpers/removeNode.js'\n\ntype PluginState = {\n locked: boolean\n}\n\nconst getRelativePos = (state: EditorState, absolutePos: number) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return null\n }\n\n return absolutePositionToRelativePosition(absolutePos, ystate.type, ystate.binding.mapping)\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: y-prosemirror (and y-tiptap by extension) does not have types for relative positions\nconst getAbsolutePos = (state: EditorState, relativePos: any) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return -1\n }\n\n return relativePositionToAbsolutePosition(ystate.doc, ystate.type, relativePos, ystate.binding.mapping) || 0\n}\n\nconst getOuterDomNode = (view: EditorView, domNode: HTMLElement) => {\n let tmpDomNode = domNode\n\n // Traverse to top level node.\n while (tmpDomNode?.parentNode) {\n if (tmpDomNode.parentNode === view.dom) {\n break\n }\n\n tmpDomNode = tmpDomNode.parentNode as HTMLElement\n }\n\n return tmpDomNode\n}\n\nexport interface DragHandlePluginProps {\n pluginKey?: PluginKey | string\n editor: Editor\n element: HTMLElement\n onNodeChange?: (data: { editor: Editor; node: Node | null; pos: number }) => void\n onElementDragStart?: (e: DragEvent) => void\n onElementDragEnd?: (e: DragEvent) => void\n computePositionConfig?: ComputePositionConfig\n}\n\nexport const dragHandlePluginDefaultKey = new PluginKey('dragHandle')\n\nexport const DragHandlePlugin = ({\n pluginKey = dragHandlePluginDefaultKey,\n element,\n editor,\n computePositionConfig,\n onNodeChange,\n onElementDragStart,\n onElementDragEnd,\n}: DragHandlePluginProps) => {\n const wrapper = document.createElement('div')\n let locked = false\n let currentNode: Node | null = null\n let currentNodePos = -1\n // biome-ignore lint/suspicious/noExplicitAny: See above - relative positions in y-prosemirror are not typed\n let currentNodeRelPos: any\n let rafId: number | null = null\n let pendingMouseCoords: { x: number; y: number } | null = null\n\n function hideHandle() {\n if (!element) {\n return\n }\n\n element.style.visibility = 'hidden'\n element.style.pointerEvents = 'none'\n }\n\n function showHandle() {\n if (!element) {\n return\n }\n\n if (!editor.isEditable) {\n hideHandle()\n return\n }\n\n element.style.visibility = ''\n element.style.pointerEvents = 'auto'\n }\n\n function repositionDragHandle(dom: Element) {\n const virtualElement = {\n getBoundingClientRect: () => dom.getBoundingClientRect(),\n }\n\n computePosition(virtualElement, element, computePositionConfig).then(val => {\n Object.assign(element.style, {\n position: val.strategy,\n left: `${val.x}px`,\n top: `${val.y}px`,\n })\n })\n }\n\n function onDragStart(e: DragEvent) {\n onElementDragStart?.(e)\n // Push this to the end of the event cue\n // Fixes bug where incorrect drag pos is returned if drag handle has position: absolute\n // @ts-ignore\n dragHandler(e, editor)\n\n setTimeout(() => {\n if (element) {\n element.style.pointerEvents = 'none'\n }\n }, 0)\n }\n\n function onDragEnd(e: DragEvent) {\n onElementDragEnd?.(e)\n hideHandle()\n if (element) {\n element.style.pointerEvents = 'auto'\n }\n }\n\n element.addEventListener('dragstart', onDragStart)\n element.addEventListener('dragend', onDragEnd)\n\n wrapper.appendChild(element)\n\n return {\n unbind() {\n element.removeEventListener('dragstart', onDragStart)\n element.removeEventListener('dragend', onDragEnd)\n if (rafId) {\n cancelAnimationFrame(rafId)\n rafId = null\n pendingMouseCoords = null\n }\n },\n plugin: new Plugin({\n key: typeof pluginKey === 'string' ? new PluginKey(pluginKey) : pluginKey,\n\n state: {\n init() {\n return { locked: false }\n },\n apply(tr: Transaction, value: PluginState, _oldState: EditorState, state: EditorState) {\n const isLocked = tr.getMeta('lockDragHandle')\n const hideDragHandle = tr.getMeta('hideDragHandle')\n\n if (isLocked !== undefined) {\n locked = isLocked\n }\n\n if (hideDragHandle) {\n hideHandle()\n\n locked = false\n currentNode = null\n currentNodePos = -1\n\n onNodeChange?.({ editor, node: null, pos: -1 })\n\n return value\n }\n\n // Something has changed and drag handler is visible…\n if (tr.docChanged && currentNodePos !== -1 && element) {\n // Yjs replaces the entire document on every incoming change and needs a special handling.\n // If change comes from another user …\n if (isChangeOrigin(tr)) {\n // https://discuss.yjs.dev/t/y-prosemirror-mapping-a-single-relative-position-when-doc-changes/851/3\n const newPos = getAbsolutePos(state, currentNodeRelPos)\n\n if (newPos !== currentNodePos) {\n // Set the new position for our current node.\n currentNodePos = newPos\n\n // We will get the outer node with data and position in views update method.\n }\n } else {\n // … otherwise use ProseMirror mapping to update the position.\n const newPos = tr.mapping.map(currentNodePos)\n\n if (newPos !== currentNodePos) {\n // TODO: Remove\n // console.log('Position has changed …', { old: currentNodePos, new: newPos }, tr);\n\n // Set the new position for our current node.\n currentNodePos = newPos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(state, currentNodePos)\n\n // We will get the outer node with data and position in views update method.\n }\n }\n }\n\n return value\n },\n },\n\n view: view => {\n element.draggable = true\n element.style.pointerEvents = 'auto'\n\n editor.view.dom.parentElement?.appendChild(wrapper)\n\n wrapper.style.pointerEvents = 'none'\n wrapper.style.position = 'absolute'\n wrapper.style.top = '0'\n wrapper.style.left = '0'\n\n return {\n update(_, oldState) {\n if (!element) {\n return\n }\n\n if (!editor.isEditable) {\n hideHandle()\n return\n }\n\n // Prevent element being draggend while being open.\n if (locked) {\n element.draggable = false\n } else {\n element.draggable = true\n }\n\n // Recalculate popup position if doc has changend and drag handler is visible.\n if (view.state.doc.eq(oldState.doc) || currentNodePos === -1) {\n return\n }\n\n // Get domNode from (new) position.\n let domNode = view.nodeDOM(currentNodePos) as HTMLElement\n\n // Since old element could have been wrapped, we need to find\n // the outer node and take its position and node data.\n domNode = getOuterDomNode(view, domNode)\n\n // Skip if domNode is editor dom.\n if (domNode === view.dom) {\n return\n }\n\n // We only want `Element`.\n if (domNode?.nodeType !== 1) {\n return\n }\n\n const domNodePos = view.posAtDOM(domNode, 0)\n const outerNode = getOuterNode(editor.state.doc, domNodePos)\n const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos) // TODO: needed?\n\n currentNode = outerNode\n currentNodePos = outerNodePos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n repositionDragHandle(domNode as Element)\n },\n\n // TODO: Kills even on hot reload\n destroy() {\n if (rafId) {\n cancelAnimationFrame(rafId)\n rafId = null\n pendingMouseCoords = null\n }\n\n if (element) {\n removeNode(wrapper)\n }\n },\n }\n },\n\n props: {\n handleDOMEvents: {\n keydown(view) {\n if (!element || locked) {\n return false\n }\n\n if (view.hasFocus()) {\n hideHandle()\n currentNode = null\n currentNodePos = -1\n onNodeChange?.({ editor, node: null, pos: -1 })\n\n // We want to still continue with other keydown events.\n return false\n }\n\n return false\n },\n mouseleave(_view, e) {\n // Do not hide open popup on mouseleave.\n if (locked) {\n return false\n }\n\n // If e.target is not inside the wrapper, hide.\n if (e.target && !wrapper.contains(e.relatedTarget as HTMLElement)) {\n hideHandle()\n\n currentNode = null\n currentNodePos = -1\n\n onNodeChange?.({ editor, node: null, pos: -1 })\n }\n\n return false\n },\n\n mousemove(view, e) {\n // Do not continue if popup is not initialized or open.\n if (!element || locked) {\n return false\n }\n\n // Store latest mouse coords and schedule a single RAF per frame\n pendingMouseCoords = { x: e.clientX, y: e.clientY }\n\n if (rafId) {\n return false\n }\n\n rafId = requestAnimationFrame(() => {\n rafId = null\n\n if (!pendingMouseCoords) {\n return\n }\n\n const { x, y } = pendingMouseCoords\n pendingMouseCoords = null\n\n const nodeData = findElementNextToCoords({\n x,\n y,\n direction: 'right',\n editor,\n })\n\n // Skip if there is no node next to coords\n if (!nodeData.resultElement) {\n return\n }\n\n let domNode = nodeData.resultElement as HTMLElement\n\n domNode = getOuterDomNode(view, domNode)\n\n // Skip if domNode is editor dom.\n if (domNode === view.dom) {\n return\n }\n\n // We only want `Element`.\n if (domNode?.nodeType !== 1) {\n return\n }\n\n const domNodePos = view.posAtDOM(domNode, 0)\n const outerNode = getOuterNode(editor.state.doc, domNodePos)\n\n if (outerNode !== currentNode) {\n const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos)\n\n currentNode = outerNode\n currentNodePos = outerNodePos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n // Set nodes clientRect.\n repositionDragHandle(domNode as Element)\n\n showHandle()\n }\n })\n\n return false\n },\n },\n },\n }),\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { getSelectionRanges, NodeRangeSelection } from '@tiptap/extension-node-range'\nimport type { SelectionRange } from '@tiptap/pm/state'\n\nimport { cloneElement } from './cloneElement.js'\nimport { findElementNextToCoords } from './findNextElementFromCursor.js'\nimport { getInnerCoords } from './getInnerCoords.js'\nimport { removeNode } from './removeNode.js'\n\nfunction getDragHandleRanges(event: DragEvent, editor: Editor): SelectionRange[] {\n const { doc } = editor.view.state\n\n const result = findElementNextToCoords({\n editor,\n x: event.clientX,\n y: event.clientY,\n direction: 'right',\n })\n\n if (!result.resultNode || result.pos === null) {\n return []\n }\n\n const x = event.clientX\n\n // @ts-ignore\n const coords = getInnerCoords(editor.view, x, event.clientY)\n const posAtCoords = editor.view.posAtCoords(coords)\n\n if (!posAtCoords) {\n return []\n }\n\n const { pos } = posAtCoords\n const nodeAt = doc.resolve(pos).parent\n\n if (!nodeAt) {\n return []\n }\n\n const $from = doc.resolve(result.pos)\n const $to = doc.resolve(result.pos + 1)\n\n return getSelectionRanges($from, $to, 0)\n}\n\nexport function dragHandler(event: DragEvent, editor: Editor) {\n const { view } = editor\n\n if (!event.dataTransfer) {\n return\n }\n\n const { empty, $from, $to } = view.state.selection\n\n const dragHandleRanges = getDragHandleRanges(event, editor)\n\n const selectionRanges = getSelectionRanges($from, $to, 0)\n const isDragHandleWithinSelection = selectionRanges.some(range => {\n return dragHandleRanges.find(dragHandleRange => {\n return dragHandleRange.$from === range.$from && dragHandleRange.$to === range.$to\n })\n })\n\n const ranges = empty || !isDragHandleWithinSelection ? dragHandleRanges : selectionRanges\n\n if (!ranges.length) {\n return\n }\n\n const { tr } = view.state\n const wrapper = document.createElement('div')\n const from = ranges[0].$from.pos\n const to = ranges[ranges.length - 1].$to.pos\n\n const selection = NodeRangeSelection.create(view.state.doc, from, to)\n const slice = selection.content()\n\n ranges.forEach(range => {\n const element = view.nodeDOM(range.$from.pos) as HTMLElement\n const clonedElement = cloneElement(element)\n\n wrapper.append(clonedElement)\n })\n\n wrapper.style.position = 'absolute'\n wrapper.style.top = '-10000px'\n document.body.append(wrapper)\n\n event.dataTransfer.clearData()\n event.dataTransfer.setDragImage(wrapper, 0, 0)\n\n // tell ProseMirror the dragged content\n view.dragging = { slice, move: true }\n\n tr.setSelection(selection)\n\n view.dispatch(tr)\n\n // clean up\n document.addEventListener('drop', () => removeNode(wrapper), { once: true })\n}\n","function getCSSText(element: Element) {\n let value = ''\n const style = getComputedStyle(element)\n\n for (let i = 0; i < style.length; i += 1) {\n value += `${style[i]}:${style.getPropertyValue(style[i])};`\n }\n\n return value\n}\n\nexport function cloneElement(node: HTMLElement) {\n const clonedNode = node.cloneNode(true) as HTMLElement\n const sourceElements = [node, ...Array.from(node.getElementsByTagName('*'))] as HTMLElement[]\n const targetElements = [clonedNode, ...Array.from(clonedNode.getElementsByTagName('*'))] as HTMLElement[]\n\n sourceElements.forEach((sourceElement, index) => {\n targetElements[index].style.cssText = getCSSText(sourceElement)\n })\n\n return clonedNode\n}\n","import type { Editor } from '@tiptap/core'\n\nexport type FindElementNextToCoords = {\n x: number\n y: number\n direction?: 'left' | 'right'\n editor: Editor\n bandHeight?: number\n}\n\nexport const findElementNextToCoords = (options: FindElementNextToCoords) => {\n const { x, y, direction = 'right', editor, bandHeight = 5 } = options\n\n const rect = {\n top: y - bandHeight,\n bottom: y + bandHeight,\n left: direction === 'right' ? x : 0,\n right: direction === 'right' ? window.innerWidth - x : x,\n }\n\n const root = editor.view.dom as HTMLElement\n\n // Get potential candidates from prosemirror child elements and filter\n // by removing decorations and non prosemirror-elements\n const candidates = [...root.querySelectorAll<HTMLElement>('*')]\n .filter(candidate => {\n return editor.view.posAtDOM(candidate, 0) >= 0\n })\n .filter(candidate => {\n const candidateRect = candidate.getBoundingClientRect()\n return !(\n candidateRect.bottom < rect.top ||\n candidateRect.top > rect.bottom ||\n candidateRect.right < rect.left ||\n candidateRect.left > rect.right\n )\n })\n\n if (!candidates || candidates.length === 0) {\n return { resultElement: null, resultNode: null, pos: null }\n }\n\n const finalCandidate = candidates[0]\n const candidatePos = editor.view.posAtDOM(finalCandidate, 0)\n if (candidatePos === -1) {\n return { resultElement: finalCandidate, resultNode: null, pos: null }\n }\n\n const candidateNode = editor.state.doc.nodeAt(candidatePos - 1)\n\n return { resultElement: finalCandidate, resultNode: candidateNode, pos: candidatePos }\n}\n","export function getComputedStyle(node: Element, property: keyof CSSStyleDeclaration): any {\n const style = window.getComputedStyle(node)\n\n return style[property]\n}\n","export function minMax(value = 0, min = 0, max = 0): number {\n return Math.min(Math.max(value, min), max)\n}\n","import type { EditorView } from '@tiptap/pm/view'\n\nimport { getComputedStyle } from './getComputedStyle.js'\nimport { minMax } from './minMax.js'\n\nexport function getInnerCoords(view: EditorView, x: number, y: number): { left: number; top: number } {\n const paddingLeft = parseInt(getComputedStyle(view.dom, 'paddingLeft'), 10)\n const paddingRight = parseInt(getComputedStyle(view.dom, 'paddingRight'), 10)\n const borderLeft = parseInt(getComputedStyle(view.dom, 'borderLeftWidth'), 10)\n const borderRight = parseInt(getComputedStyle(view.dom, 'borderLeftWidth'), 10)\n const bounds = view.dom.getBoundingClientRect()\n const coords = {\n left: minMax(x, bounds.left + paddingLeft + borderLeft, bounds.right - paddingRight - borderRight),\n top: y,\n }\n\n return coords\n}\n","export function removeNode(node: HTMLElement) {\n node.parentNode?.removeChild(node)\n}\n","import type { Node } from '@tiptap/pm/model'\n\nexport const getOuterNodePos = (doc: Node, pos: number): number => {\n const resolvedPos = doc.resolve(pos)\n const { depth } = resolvedPos\n\n if (depth === 0) {\n return pos\n }\n\n const a = resolvedPos.pos - resolvedPos.parentOffset\n\n return a - 1\n}\n\nexport const getOuterNode = (doc: Node, pos: number): Node | null => {\n const node = doc.nodeAt(pos)\n const resolvedPos = doc.resolve(pos)\n\n let { depth } = resolvedPos\n let parent = node\n\n while (depth > 0) {\n const currentNode = resolvedPos.node(depth)\n\n depth -= 1\n\n if (depth === 0) {\n parent = currentNode\n }\n }\n\n return parent\n}\n","import { DragHandle } from './drag-handle.js'\n\nexport * from './drag-handle.js'\nexport * from './drag-handle-plugin.js'\n\nexport default DragHandle\n"],"mappings":"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","names":["getComputedStyle","getComputedStyle"]}
1
+ {"version":3,"sources":["../src/drag-handle.ts","../src/drag-handle-plugin.ts","../src/helpers/dragHandler.ts","../src/helpers/cloneElement.ts","../src/helpers/findNextElementFromCursor.ts","../src/helpers/getComputedStyle.ts","../src/helpers/minMax.ts","../src/helpers/getInnerCoords.ts","../src/helpers/removeNode.ts","../src/helpers/getOuterNode.ts","../src/index.ts"],"sourcesContent":["import type { ComputePositionConfig, VirtualElement } from '@floating-ui/dom'\nimport { type Editor, Extension } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\n\nimport { DragHandlePlugin } from './drag-handle-plugin.js'\n\nexport const defaultComputePositionConfig: ComputePositionConfig = {\n placement: 'left-start',\n strategy: 'absolute',\n}\n\nexport interface DragHandleOptions {\n /**\n * Renders an element that is positioned with the floating-ui/dom package\n */\n render(): HTMLElement\n /**\n * Configuration for position computation of the drag handle\n * using the floating-ui/dom package\n */\n computePositionConfig?: ComputePositionConfig\n /**\n * A function that returns the virtual element for the drag handle.\n * This is useful when the menu needs to be positioned relative to a specific DOM element.\n */\n getReferencedVirtualElement?: () => VirtualElement | null\n /**\n * Locks the draghandle in place and visibility\n */\n locked?: boolean\n /**\n * Returns a node or null when a node is hovered over\n */\n onNodeChange?: (options: { node: Node | null; editor: Editor }) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n dragHandle: {\n /**\n * Locks the draghandle in place and visibility\n */\n lockDragHandle: () => ReturnType\n /**\n * Unlocks the draghandle\n */\n unlockDragHandle: () => ReturnType\n /**\n * Toggle draghandle lock state\n */\n toggleDragHandle: () => ReturnType\n }\n }\n}\n\nexport const DragHandle = Extension.create<DragHandleOptions>({\n name: 'dragHandle',\n\n addOptions() {\n return {\n render() {\n const element = document.createElement('div')\n\n element.classList.add('drag-handle')\n\n return element\n },\n computePositionConfig: {},\n locked: false,\n onNodeChange: () => {\n return null\n },\n }\n },\n\n addCommands() {\n return {\n lockDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = true\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n unlockDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = false\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n toggleDragHandle:\n () =>\n ({ editor }) => {\n this.options.locked = !this.options.locked\n return editor.commands.setMeta('lockDragHandle', this.options.locked)\n },\n }\n },\n\n addProseMirrorPlugins() {\n const element = this.options.render()\n\n return [\n DragHandlePlugin({\n computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },\n getReferencedVirtualElement: this.options.getReferencedVirtualElement,\n element,\n editor: this.editor,\n onNodeChange: this.options.onNodeChange,\n }).plugin,\n ]\n },\n})\n","import { type ComputePositionConfig, type VirtualElement, computePosition } from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { isChangeOrigin } from '@tiptap/extension-collaboration'\nimport type { Node } from '@tiptap/pm/model'\nimport { type EditorState, type Transaction, Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n ySyncPluginKey,\n} from '@tiptap/y-tiptap'\n\nimport { dragHandler } from './helpers/dragHandler.js'\nimport { findElementNextToCoords } from './helpers/findNextElementFromCursor.js'\nimport { getOuterNode, getOuterNodePos } from './helpers/getOuterNode.js'\nimport { removeNode } from './helpers/removeNode.js'\n\ntype PluginState = {\n locked: boolean\n}\n\nconst getRelativePos = (state: EditorState, absolutePos: number) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return null\n }\n\n return absolutePositionToRelativePosition(absolutePos, ystate.type, ystate.binding.mapping)\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: y-prosemirror (and y-tiptap by extension) does not have types for relative positions\nconst getAbsolutePos = (state: EditorState, relativePos: any) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return -1\n }\n\n return relativePositionToAbsolutePosition(ystate.doc, ystate.type, relativePos, ystate.binding.mapping) || 0\n}\n\nconst getOuterDomNode = (view: EditorView, domNode: HTMLElement) => {\n let tmpDomNode = domNode\n\n // Traverse to top level node.\n while (tmpDomNode?.parentNode) {\n if (tmpDomNode.parentNode === view.dom) {\n break\n }\n\n tmpDomNode = tmpDomNode.parentNode as HTMLElement\n }\n\n return tmpDomNode\n}\n\nexport interface DragHandlePluginProps {\n pluginKey?: PluginKey | string\n editor: Editor\n element: HTMLElement\n onNodeChange?: (data: { editor: Editor; node: Node | null; pos: number }) => void\n onElementDragStart?: (e: DragEvent) => void\n onElementDragEnd?: (e: DragEvent) => void\n computePositionConfig?: ComputePositionConfig\n getReferencedVirtualElement?: () => VirtualElement | null\n}\n\nexport const dragHandlePluginDefaultKey = new PluginKey('dragHandle')\n\nexport const DragHandlePlugin = ({\n pluginKey = dragHandlePluginDefaultKey,\n element,\n editor,\n computePositionConfig,\n getReferencedVirtualElement,\n onNodeChange,\n onElementDragStart,\n onElementDragEnd,\n}: DragHandlePluginProps) => {\n const wrapper = document.createElement('div')\n let locked = false\n let currentNode: Node | null = null\n let currentNodePos = -1\n // biome-ignore lint/suspicious/noExplicitAny: See above - relative positions in y-prosemirror are not typed\n let currentNodeRelPos: any\n let rafId: number | null = null\n let pendingMouseCoords: { x: number; y: number } | null = null\n\n function hideHandle() {\n if (!element) {\n return\n }\n\n element.style.visibility = 'hidden'\n element.style.pointerEvents = 'none'\n }\n\n function showHandle() {\n if (!element) {\n return\n }\n\n if (!editor.isEditable) {\n hideHandle()\n return\n }\n\n element.style.visibility = ''\n element.style.pointerEvents = 'auto'\n }\n\n function repositionDragHandle(dom: Element) {\n const virtualElement = getReferencedVirtualElement?.() || {\n getBoundingClientRect: () => dom.getBoundingClientRect(),\n }\n\n computePosition(virtualElement, element, computePositionConfig).then(val => {\n Object.assign(element.style, {\n position: val.strategy,\n left: `${val.x}px`,\n top: `${val.y}px`,\n })\n })\n }\n\n function onDragStart(e: DragEvent) {\n onElementDragStart?.(e)\n // Push this to the end of the event cue\n // Fixes bug where incorrect drag pos is returned if drag handle has position: absolute\n // @ts-ignore\n dragHandler(e, editor)\n\n setTimeout(() => {\n if (element) {\n element.style.pointerEvents = 'none'\n }\n }, 0)\n }\n\n function onDragEnd(e: DragEvent) {\n onElementDragEnd?.(e)\n hideHandle()\n if (element) {\n element.style.pointerEvents = 'auto'\n }\n }\n\n element.addEventListener('dragstart', onDragStart)\n element.addEventListener('dragend', onDragEnd)\n\n wrapper.appendChild(element)\n\n return {\n unbind() {\n element.removeEventListener('dragstart', onDragStart)\n element.removeEventListener('dragend', onDragEnd)\n if (rafId) {\n cancelAnimationFrame(rafId)\n rafId = null\n pendingMouseCoords = null\n }\n },\n plugin: new Plugin({\n key: typeof pluginKey === 'string' ? new PluginKey(pluginKey) : pluginKey,\n\n state: {\n init() {\n return { locked: false }\n },\n apply(tr: Transaction, value: PluginState, _oldState: EditorState, state: EditorState) {\n const isLocked = tr.getMeta('lockDragHandle')\n const hideDragHandle = tr.getMeta('hideDragHandle')\n\n if (isLocked !== undefined) {\n locked = isLocked\n }\n\n if (hideDragHandle) {\n hideHandle()\n\n locked = false\n currentNode = null\n currentNodePos = -1\n\n onNodeChange?.({ editor, node: null, pos: -1 })\n\n return value\n }\n\n // Something has changed and drag handler is visible…\n if (tr.docChanged && currentNodePos !== -1 && element) {\n // Yjs replaces the entire document on every incoming change and needs a special handling.\n // If change comes from another user …\n if (isChangeOrigin(tr)) {\n // https://discuss.yjs.dev/t/y-prosemirror-mapping-a-single-relative-position-when-doc-changes/851/3\n const newPos = getAbsolutePos(state, currentNodeRelPos)\n\n if (newPos !== currentNodePos) {\n // Set the new position for our current node.\n currentNodePos = newPos\n\n // We will get the outer node with data and position in views update method.\n }\n } else {\n // … otherwise use ProseMirror mapping to update the position.\n const newPos = tr.mapping.map(currentNodePos)\n\n if (newPos !== currentNodePos) {\n // TODO: Remove\n // console.log('Position has changed …', { old: currentNodePos, new: newPos }, tr);\n\n // Set the new position for our current node.\n currentNodePos = newPos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(state, currentNodePos)\n\n // We will get the outer node with data and position in views update method.\n }\n }\n }\n\n return value\n },\n },\n\n view: view => {\n element.draggable = true\n element.style.pointerEvents = 'auto'\n\n editor.view.dom.parentElement?.appendChild(wrapper)\n\n wrapper.style.pointerEvents = 'none'\n wrapper.style.position = 'absolute'\n wrapper.style.top = '0'\n wrapper.style.left = '0'\n\n return {\n update(_, oldState) {\n if (!element) {\n return\n }\n\n if (!editor.isEditable) {\n hideHandle()\n return\n }\n\n // Prevent element being draggend while being open.\n if (locked) {\n element.draggable = false\n } else {\n element.draggable = true\n }\n\n // Recalculate popup position if doc has changend and drag handler is visible.\n if (view.state.doc.eq(oldState.doc) || currentNodePos === -1) {\n return\n }\n\n // Get domNode from (new) position.\n let domNode = view.nodeDOM(currentNodePos) as HTMLElement\n\n // Since old element could have been wrapped, we need to find\n // the outer node and take its position and node data.\n domNode = getOuterDomNode(view, domNode)\n\n // Skip if domNode is editor dom.\n if (domNode === view.dom) {\n return\n }\n\n // We only want `Element`.\n if (domNode?.nodeType !== 1) {\n return\n }\n\n const domNodePos = view.posAtDOM(domNode, 0)\n const outerNode = getOuterNode(editor.state.doc, domNodePos)\n const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos) // TODO: needed?\n\n currentNode = outerNode\n currentNodePos = outerNodePos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n repositionDragHandle(domNode as Element)\n },\n\n // TODO: Kills even on hot reload\n destroy() {\n if (rafId) {\n cancelAnimationFrame(rafId)\n rafId = null\n pendingMouseCoords = null\n }\n\n if (element) {\n removeNode(wrapper)\n }\n },\n }\n },\n\n props: {\n handleDOMEvents: {\n keydown(view) {\n if (!element || locked) {\n return false\n }\n\n if (view.hasFocus()) {\n hideHandle()\n currentNode = null\n currentNodePos = -1\n onNodeChange?.({ editor, node: null, pos: -1 })\n\n // We want to still continue with other keydown events.\n return false\n }\n\n return false\n },\n mouseleave(_view, e) {\n // Do not hide open popup on mouseleave.\n if (locked) {\n return false\n }\n\n // If e.target is not inside the wrapper, hide.\n if (e.target && !wrapper.contains(e.relatedTarget as HTMLElement)) {\n hideHandle()\n\n currentNode = null\n currentNodePos = -1\n\n onNodeChange?.({ editor, node: null, pos: -1 })\n }\n\n return false\n },\n\n mousemove(view, e) {\n // Do not continue if popup is not initialized or open.\n if (!element || locked) {\n return false\n }\n\n // Store latest mouse coords and schedule a single RAF per frame\n pendingMouseCoords = { x: e.clientX, y: e.clientY }\n\n if (rafId) {\n return false\n }\n\n rafId = requestAnimationFrame(() => {\n rafId = null\n\n if (!pendingMouseCoords) {\n return\n }\n\n const { x, y } = pendingMouseCoords\n pendingMouseCoords = null\n\n const nodeData = findElementNextToCoords({\n x,\n y,\n direction: 'right',\n editor,\n })\n\n // Skip if there is no node next to coords\n if (!nodeData.resultElement) {\n return\n }\n\n let domNode = nodeData.resultElement as HTMLElement\n\n domNode = getOuterDomNode(view, domNode)\n\n // Skip if domNode is editor dom.\n if (domNode === view.dom) {\n return\n }\n\n // We only want `Element`.\n if (domNode?.nodeType !== 1) {\n return\n }\n\n const domNodePos = view.posAtDOM(domNode, 0)\n const outerNode = getOuterNode(editor.state.doc, domNodePos)\n\n if (outerNode !== currentNode) {\n const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos)\n\n currentNode = outerNode\n currentNodePos = outerNodePos\n\n // Memorize relative position to retrieve absolute position in case of collaboration\n currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n // Set nodes clientRect.\n repositionDragHandle(domNode as Element)\n\n showHandle()\n }\n })\n\n return false\n },\n },\n },\n }),\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { getSelectionRanges, NodeRangeSelection } from '@tiptap/extension-node-range'\nimport type { SelectionRange } from '@tiptap/pm/state'\n\nimport { cloneElement } from './cloneElement.js'\nimport { findElementNextToCoords } from './findNextElementFromCursor.js'\nimport { getInnerCoords } from './getInnerCoords.js'\nimport { removeNode } from './removeNode.js'\n\nfunction getDragHandleRanges(event: DragEvent, editor: Editor): SelectionRange[] {\n const { doc } = editor.view.state\n\n const result = findElementNextToCoords({\n editor,\n x: event.clientX,\n y: event.clientY,\n direction: 'right',\n })\n\n if (!result.resultNode || result.pos === null) {\n return []\n }\n\n const x = event.clientX\n\n // @ts-ignore\n const coords = getInnerCoords(editor.view, x, event.clientY)\n const posAtCoords = editor.view.posAtCoords(coords)\n\n if (!posAtCoords) {\n return []\n }\n\n const { pos } = posAtCoords\n const nodeAt = doc.resolve(pos).parent\n\n if (!nodeAt) {\n return []\n }\n\n const $from = doc.resolve(result.pos)\n const $to = doc.resolve(result.pos + 1)\n\n return getSelectionRanges($from, $to, 0)\n}\n\nexport function dragHandler(event: DragEvent, editor: Editor) {\n const { view } = editor\n\n if (!event.dataTransfer) {\n return\n }\n\n const { empty, $from, $to } = view.state.selection\n\n const dragHandleRanges = getDragHandleRanges(event, editor)\n\n const selectionRanges = getSelectionRanges($from, $to, 0)\n const isDragHandleWithinSelection = selectionRanges.some(range => {\n return dragHandleRanges.find(dragHandleRange => {\n return dragHandleRange.$from === range.$from && dragHandleRange.$to === range.$to\n })\n })\n\n const ranges = empty || !isDragHandleWithinSelection ? dragHandleRanges : selectionRanges\n\n if (!ranges.length) {\n return\n }\n\n const { tr } = view.state\n const wrapper = document.createElement('div')\n const from = ranges[0].$from.pos\n const to = ranges[ranges.length - 1].$to.pos\n\n const selection = NodeRangeSelection.create(view.state.doc, from, to)\n const slice = selection.content()\n\n ranges.forEach(range => {\n const element = view.nodeDOM(range.$from.pos) as HTMLElement\n const clonedElement = cloneElement(element)\n\n wrapper.append(clonedElement)\n })\n\n wrapper.style.position = 'absolute'\n wrapper.style.top = '-10000px'\n document.body.append(wrapper)\n\n event.dataTransfer.clearData()\n event.dataTransfer.setDragImage(wrapper, 0, 0)\n\n // tell ProseMirror the dragged content\n view.dragging = { slice, move: true }\n\n tr.setSelection(selection)\n\n view.dispatch(tr)\n\n // clean up\n document.addEventListener('drop', () => removeNode(wrapper), { once: true })\n}\n","function getCSSText(element: Element) {\n let value = ''\n const style = getComputedStyle(element)\n\n for (let i = 0; i < style.length; i += 1) {\n value += `${style[i]}:${style.getPropertyValue(style[i])};`\n }\n\n return value\n}\n\nexport function cloneElement(node: HTMLElement) {\n const clonedNode = node.cloneNode(true) as HTMLElement\n const sourceElements = [node, ...Array.from(node.getElementsByTagName('*'))] as HTMLElement[]\n const targetElements = [clonedNode, ...Array.from(clonedNode.getElementsByTagName('*'))] as HTMLElement[]\n\n sourceElements.forEach((sourceElement, index) => {\n targetElements[index].style.cssText = getCSSText(sourceElement)\n })\n\n return clonedNode\n}\n","import type { Editor } from '@tiptap/core'\n\nexport type FindElementNextToCoords = {\n x: number\n y: number\n direction?: 'left' | 'right'\n editor: Editor\n bandHeight?: number\n}\n\nexport const findElementNextToCoords = (options: FindElementNextToCoords) => {\n const { x, y, direction = 'right', editor, bandHeight = 5 } = options\n\n const rect = {\n top: y - bandHeight,\n bottom: y + bandHeight,\n left: direction === 'right' ? x : 0,\n right: direction === 'right' ? window.innerWidth - x : x,\n }\n\n const root = editor.view.dom as HTMLElement\n\n // Get potential candidates from prosemirror child elements and filter\n // by removing decorations and non prosemirror-elements\n const candidates = [...root.querySelectorAll<HTMLElement>('*')]\n .filter(candidate => {\n return editor.view.posAtDOM(candidate, 0) >= 0\n })\n .filter(candidate => {\n const candidateRect = candidate.getBoundingClientRect()\n return !(\n candidateRect.bottom < rect.top ||\n candidateRect.top > rect.bottom ||\n candidateRect.right < rect.left ||\n candidateRect.left > rect.right\n )\n })\n\n if (!candidates || candidates.length === 0) {\n return { resultElement: null, resultNode: null, pos: null }\n }\n\n const finalCandidate = candidates[0]\n const candidatePos = editor.view.posAtDOM(finalCandidate, 0)\n if (candidatePos === -1) {\n return { resultElement: finalCandidate, resultNode: null, pos: null }\n }\n\n const $pos = editor.state.doc.resolve(candidatePos)\n\n if ($pos.nodeAfter) {\n const nodeAfterDom = editor.view.nodeDOM($pos.pos)\n\n if (nodeAfterDom && nodeAfterDom === finalCandidate) {\n return {\n resultElement: finalCandidate,\n resultNode: $pos.nodeAfter,\n pos: candidatePos,\n }\n }\n }\n\n const candidateNode = editor.state.doc.nodeAt(candidatePos - 1)\n\n return { resultElement: finalCandidate, resultNode: candidateNode, pos: candidatePos }\n}\n","export function getComputedStyle(node: Element, property: keyof CSSStyleDeclaration): any {\n const style = window.getComputedStyle(node)\n\n return style[property]\n}\n","export function minMax(value = 0, min = 0, max = 0): number {\n return Math.min(Math.max(value, min), max)\n}\n","import type { EditorView } from '@tiptap/pm/view'\n\nimport { getComputedStyle } from './getComputedStyle.js'\nimport { minMax } from './minMax.js'\n\nexport function getInnerCoords(view: EditorView, x: number, y: number): { left: number; top: number } {\n const paddingLeft = parseInt(getComputedStyle(view.dom, 'paddingLeft'), 10)\n const paddingRight = parseInt(getComputedStyle(view.dom, 'paddingRight'), 10)\n const borderLeft = parseInt(getComputedStyle(view.dom, 'borderLeftWidth'), 10)\n const borderRight = parseInt(getComputedStyle(view.dom, 'borderLeftWidth'), 10)\n const bounds = view.dom.getBoundingClientRect()\n const coords = {\n left: minMax(x, bounds.left + paddingLeft + borderLeft, bounds.right - paddingRight - borderRight),\n top: y,\n }\n\n return coords\n}\n","export function removeNode(node: HTMLElement) {\n node.parentNode?.removeChild(node)\n}\n","import type { Node } from '@tiptap/pm/model'\n\nexport const getOuterNodePos = (doc: Node, pos: number): number => {\n const resolvedPos = doc.resolve(pos)\n const { depth } = resolvedPos\n\n if (depth === 0) {\n return pos\n }\n\n const a = resolvedPos.pos - resolvedPos.parentOffset\n\n return a - 1\n}\n\nexport const getOuterNode = (doc: Node, pos: number): Node | null => {\n const node = doc.nodeAt(pos)\n const resolvedPos = doc.resolve(pos)\n\n let { depth } = resolvedPos\n let parent = node\n\n while (depth > 0) {\n const currentNode = resolvedPos.node(depth)\n\n depth -= 1\n\n if (depth === 0) {\n parent = currentNode\n }\n }\n\n return parent\n}\n","import { DragHandle } from './drag-handle.js'\n\nexport * from './drag-handle.js'\nexport * from './drag-handle-plugin.js'\n\nexport default DragHandle\n"],"mappings":"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","names":["getComputedStyle","getComputedStyle"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/extension-drag-handle",
3
3
  "description": "drag handle extension for tiptap",
4
- "version": "3.4.5",
4
+ "version": "3.5.0",
5
5
  "homepage": "https://tiptap.dev/docs/editor/extensions/functionality/drag-handle",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -37,10 +37,10 @@
37
37
  ],
38
38
  "peerDependencies": {
39
39
  "@tiptap/y-tiptap": "^3.0.0-beta.3",
40
- "@tiptap/extension-node-range": "^3.4.5",
41
- "@tiptap/core": "^3.4.5",
42
- "@tiptap/extension-collaboration": "^3.4.5",
43
- "@tiptap/pm": "^3.4.5"
40
+ "@tiptap/extension-node-range": "^3.5.0",
41
+ "@tiptap/core": "^3.5.0",
42
+ "@tiptap/extension-collaboration": "^3.5.0",
43
+ "@tiptap/pm": "^3.5.0"
44
44
  },
45
45
  "dependencies": {
46
46
  "@floating-ui/dom": "^1.6.13"
@@ -48,10 +48,10 @@
48
48
  "devDependencies": {
49
49
  "@floating-ui/dom": "^1.6.13",
50
50
  "@tiptap/y-tiptap": "^3.0.0-beta.3",
51
- "@tiptap/extension-node-range": "^3.4.5",
52
- "@tiptap/core": "^3.4.5",
53
- "@tiptap/extension-collaboration": "^3.4.5",
54
- "@tiptap/pm": "^3.4.5"
51
+ "@tiptap/extension-node-range": "^3.5.0",
52
+ "@tiptap/core": "^3.5.0",
53
+ "@tiptap/extension-collaboration": "^3.5.0",
54
+ "@tiptap/pm": "^3.5.0"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "tsup",
@@ -1,4 +1,4 @@
1
- import { type ComputePositionConfig, computePosition } from '@floating-ui/dom'
1
+ import { type ComputePositionConfig, type VirtualElement, computePosition } from '@floating-ui/dom'
2
2
  import type { Editor } from '@tiptap/core'
3
3
  import { isChangeOrigin } from '@tiptap/extension-collaboration'
4
4
  import type { Node } from '@tiptap/pm/model'
@@ -63,6 +63,7 @@ export interface DragHandlePluginProps {
63
63
  onElementDragStart?: (e: DragEvent) => void
64
64
  onElementDragEnd?: (e: DragEvent) => void
65
65
  computePositionConfig?: ComputePositionConfig
66
+ getReferencedVirtualElement?: () => VirtualElement | null
66
67
  }
67
68
 
68
69
  export const dragHandlePluginDefaultKey = new PluginKey('dragHandle')
@@ -72,6 +73,7 @@ export const DragHandlePlugin = ({
72
73
  element,
73
74
  editor,
74
75
  computePositionConfig,
76
+ getReferencedVirtualElement,
75
77
  onNodeChange,
76
78
  onElementDragStart,
77
79
  onElementDragEnd,
@@ -109,7 +111,7 @@ export const DragHandlePlugin = ({
109
111
  }
110
112
 
111
113
  function repositionDragHandle(dom: Element) {
112
- const virtualElement = {
114
+ const virtualElement = getReferencedVirtualElement?.() || {
113
115
  getBoundingClientRect: () => dom.getBoundingClientRect(),
114
116
  }
115
117
 
@@ -1,4 +1,4 @@
1
- import type { ComputePositionConfig } from '@floating-ui/dom'
1
+ import type { ComputePositionConfig, VirtualElement } from '@floating-ui/dom'
2
2
  import { type Editor, Extension } from '@tiptap/core'
3
3
  import type { Node } from '@tiptap/pm/model'
4
4
 
@@ -19,6 +19,11 @@ export interface DragHandleOptions {
19
19
  * using the floating-ui/dom package
20
20
  */
21
21
  computePositionConfig?: ComputePositionConfig
22
+ /**
23
+ * A function that returns the virtual element for the drag handle.
24
+ * This is useful when the menu needs to be positioned relative to a specific DOM element.
25
+ */
26
+ getReferencedVirtualElement?: () => VirtualElement | null
22
27
  /**
23
28
  * Locks the draghandle in place and visibility
24
29
  */
@@ -97,6 +102,7 @@ export const DragHandle = Extension.create<DragHandleOptions>({
97
102
  return [
98
103
  DragHandlePlugin({
99
104
  computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },
105
+ getReferencedVirtualElement: this.options.getReferencedVirtualElement,
100
106
  element,
101
107
  editor: this.editor,
102
108
  onNodeChange: this.options.onNodeChange,
@@ -46,6 +46,20 @@ export const findElementNextToCoords = (options: FindElementNextToCoords) => {
46
46
  return { resultElement: finalCandidate, resultNode: null, pos: null }
47
47
  }
48
48
 
49
+ const $pos = editor.state.doc.resolve(candidatePos)
50
+
51
+ if ($pos.nodeAfter) {
52
+ const nodeAfterDom = editor.view.nodeDOM($pos.pos)
53
+
54
+ if (nodeAfterDom && nodeAfterDom === finalCandidate) {
55
+ return {
56
+ resultElement: finalCandidate,
57
+ resultNode: $pos.nodeAfter,
58
+ pos: candidatePos,
59
+ }
60
+ }
61
+ }
62
+
49
63
  const candidateNode = editor.state.doc.nodeAt(candidatePos - 1)
50
64
 
51
65
  return { resultElement: finalCandidate, resultNode: candidateNode, pos: candidatePos }