From 430fcd1cfc00ed26db974eb0e3bd2a4cb814dc35 Mon Sep 17 00:00:00 2001 From: Hayden Bleasel Date: Fri, 15 Mar 2024 22:46:57 -0400 Subject: [PATCH 1/5] Resolves #234 --- .../headless/src/extensions/drag-and-drop.tsx | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/headless/src/extensions/drag-and-drop.tsx b/packages/headless/src/extensions/drag-and-drop.tsx index 20e0fd699..3a14cfa1b 100644 --- a/packages/headless/src/extensions/drag-and-drop.tsx +++ b/packages/headless/src/extensions/drag-and-drop.tsx @@ -12,6 +12,17 @@ export interface DragHandleOptions { } function absoluteRect(node: Element) { const data = node.getBoundingClientRect(); + const modal = node.closest('[role="dialog"]'); + + if (modal && window.getComputedStyle(modal).transform !== "none") { + const modalRect = modal.getBoundingClientRect(); + + return { + top: data.top - modalRect.top, + left: data.left - modalRect.left, + width: data.width, + }; + } return { top: data.top, @@ -38,15 +49,11 @@ function nodeDOMAtCoords(coords: { x: number; y: number }) { ); } -function nodePosAtDOM( - node: Element, - view: EditorView, - options: DragHandleOptions -) { +function nodePosAtDOM(node: Element, view: EditorView) { const boundingRect = node.getBoundingClientRect(); return view.posAtCoords({ - left: boundingRect.left + 50 + options.dragHandleWidth, + left: boundingRect.left + 1, top: boundingRect.top + 1, })?.inside; } @@ -64,7 +71,7 @@ function DragHandle(options: DragHandleOptions) { if (!(node instanceof Element)) return; - const nodePos = nodePosAtDOM(node, view, options); + const nodePos = nodePosAtDOM(node, view); if (nodePos == null || nodePos < 0) return; view.dispatch( @@ -96,7 +103,7 @@ function DragHandle(options: DragHandleOptions) { if (!(node instanceof Element)) return; - const nodePos = nodePosAtDOM(node, view, options); + const nodePos = nodePosAtDOM(node, view); if (!nodePos) return; view.dispatch( @@ -154,7 +161,7 @@ function DragHandle(options: DragHandleOptions) { y: event.clientY, }); - if (!(node instanceof Element)) { + if (!(node instanceof Element) || node.matches("ul, ol")) { hideDragHandle(); return; } @@ -191,7 +198,6 @@ function DragHandle(options: DragHandleOptions) { }, drop: (view) => { view.dom.classList.remove("dragging"); - hideDragHandle(); }, dragend: (view) => { view.dom.classList.remove("dragging"); From ba822b3cf6829a709933227529c195e9b67a88eb Mon Sep 17 00:00:00 2001 From: Hayden Bleasel Date: Sat, 16 Mar 2024 14:21:32 -0400 Subject: [PATCH 2/5] Misc fix --- packages/headless/src/extensions/drag-and-drop.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/headless/src/extensions/drag-and-drop.tsx b/packages/headless/src/extensions/drag-and-drop.tsx index 3a14cfa1b..93d0aa871 100644 --- a/packages/headless/src/extensions/drag-and-drop.tsx +++ b/packages/headless/src/extensions/drag-and-drop.tsx @@ -198,6 +198,7 @@ function DragHandle(options: DragHandleOptions) { }, drop: (view) => { view.dom.classList.remove("dragging"); + hideDragHandle(); }, dragend: (view) => { view.dom.classList.remove("dragging"); From f016ded51aaff523b3117c090f661d20bbc2af84 Mon Sep 17 00:00:00 2001 From: Hayden Bleasel Date: Sat, 16 Mar 2024 14:47:59 -0400 Subject: [PATCH 3/5] Restore unnecessary changes --- packages/headless/src/extensions/drag-and-drop.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/headless/src/extensions/drag-and-drop.tsx b/packages/headless/src/extensions/drag-and-drop.tsx index 93d0aa871..a54c387b5 100644 --- a/packages/headless/src/extensions/drag-and-drop.tsx +++ b/packages/headless/src/extensions/drag-and-drop.tsx @@ -49,11 +49,15 @@ function nodeDOMAtCoords(coords: { x: number; y: number }) { ); } -function nodePosAtDOM(node: Element, view: EditorView) { +function nodePosAtDOM( + node: Element, + view: EditorView, + options: DragHandleOptions, +) { const boundingRect = node.getBoundingClientRect(); return view.posAtCoords({ - left: boundingRect.left + 1, + left: boundingRect.left + 50 + options.dragHandleWidth, top: boundingRect.top + 1, })?.inside; } @@ -71,7 +75,7 @@ function DragHandle(options: DragHandleOptions) { if (!(node instanceof Element)) return; - const nodePos = nodePosAtDOM(node, view); + const nodePos = nodePosAtDOM(node, view, options); if (nodePos == null || nodePos < 0) return; view.dispatch( @@ -103,7 +107,7 @@ function DragHandle(options: DragHandleOptions) { if (!(node instanceof Element)) return; - const nodePos = nodePosAtDOM(node, view); + const nodePos = nodePosAtDOM(node, view, options); if (!nodePos) return; view.dispatch( From a8300225f3d00ab653fe2dcb711907b17d417426 Mon Sep 17 00:00:00 2001 From: Hayden Bleasel Date: Sat, 16 Mar 2024 14:48:45 -0400 Subject: [PATCH 4/5] Update drag-and-drop.tsx --- packages/headless/src/extensions/drag-and-drop.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/headless/src/extensions/drag-and-drop.tsx b/packages/headless/src/extensions/drag-and-drop.tsx index a54c387b5..eedd90bc1 100644 --- a/packages/headless/src/extensions/drag-and-drop.tsx +++ b/packages/headless/src/extensions/drag-and-drop.tsx @@ -52,7 +52,7 @@ function nodeDOMAtCoords(coords: { x: number; y: number }) { function nodePosAtDOM( node: Element, view: EditorView, - options: DragHandleOptions, + options: DragHandleOptions ) { const boundingRect = node.getBoundingClientRect(); From d04495a885b71c22aa1c29c5d2e941e35df5af56 Mon Sep 17 00:00:00 2001 From: Hayden Bleasel Date: Mon, 18 Mar 2024 12:26:40 -0400 Subject: [PATCH 5/5] Add a note about dialogs --- apps/docs/guides/tailwind/setup.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/docs/guides/tailwind/setup.mdx b/apps/docs/guides/tailwind/setup.mdx index 3f0a79714..4dfb7a37b 100644 --- a/apps/docs/guides/tailwind/setup.mdx +++ b/apps/docs/guides/tailwind/setup.mdx @@ -14,7 +14,7 @@ description: "Follow this guide to set up Novel with Tailwindcss" href="https://ui.shadcn.com/docs/installation" > You can find more info about installing shadcn-ui here. You will need to add - the following components: Button, Separator, Popover, Command, Dialog, + the following components: Button, Separator, Popover, Command, Dialog This example will use the same stucture from here: [Anatomy](/quickstart#anatomy)\ @@ -339,3 +339,7 @@ import { defaultEditorProps, EditorContent } from "novel"; You need `require("@tailwindcss/typography")` for the prose styling + +## Usage within Dialogs + +Novel has been designed to work automatically within Radix Dialogs, namely by looking for the closest parent attribute `[role="dialog"]`. If you're using a different implementation for popups and dialogs, ensure you add this attribute above the editor so the drag handle calculates the correct position.