diff --git a/packages/editor/core/src/ui/components/editor-container.tsx b/packages/editor/core/src/ui/components/editor-container.tsx index 8de6298b5..4be5c9843 100644 --- a/packages/editor/core/src/ui/components/editor-container.tsx +++ b/packages/editor/core/src/ui/components/editor-container.tsx @@ -5,14 +5,18 @@ interface EditorContainerProps { editor: Editor | null; editorClassNames: string; children: ReactNode; + hideDragHandle?: () => void; } -export const EditorContainer = ({ editor, editorClassNames, children }: EditorContainerProps) => ( +export const EditorContainer = ({ editor, editorClassNames, hideDragHandle, children }: EditorContainerProps) => (
{ editor?.chain().focus().run(); }} + onMouseLeave={() => { + hideDragHandle?.(); + }} className={`cursor-text ${editorClassNames}`} > {children} diff --git a/packages/editor/extensions/src/extensions/drag-drop.tsx b/packages/editor/extensions/src/extensions/drag-drop.tsx index acdc99cf4..af99fec61 100644 --- a/packages/editor/extensions/src/extensions/drag-drop.tsx +++ b/packages/editor/extensions/src/extensions/drag-drop.tsx @@ -3,6 +3,7 @@ import { Extension } from "@tiptap/core"; import { PluginKey, NodeSelection, Plugin } from "@tiptap/pm/state"; // @ts-ignore import { __serializeForClipboard, EditorView } from "@tiptap/pm/view"; +import React from "react"; function createDragHandleElement(): HTMLElement { const dragHandleElement = document.createElement("div"); @@ -30,6 +31,7 @@ function createDragHandleElement(): HTMLElement { export interface DragHandleOptions { dragHandleWidth: number; + setHideDragHandle?: (hideDragHandlerFromDragDrop: () => void) => void; } function absoluteRect(node: Element) { @@ -151,6 +153,8 @@ function DragHandle(options: DragHandleOptions) { } } + options.setHideDragHandle?.(hideDragHandle); + return new Plugin({ key: new PluginKey("dragHandle"), view: (view) => { @@ -238,14 +242,16 @@ function DragHandle(options: DragHandleOptions) { }); } -export const DragAndDrop = Extension.create({ - name: "dragAndDrop", +export const DragAndDrop = (setHideDragHandle?: (hideDragHandlerFromDragDrop: () => void) => void) => + Extension.create({ + name: "dragAndDrop", - addProseMirrorPlugins() { - return [ - DragHandle({ - dragHandleWidth: 24, - }), - ]; - }, -}); + addProseMirrorPlugins() { + return [ + DragHandle({ + dragHandleWidth: 24, + setHideDragHandle, + }), + ]; + }, + }); diff --git a/packages/editor/rich-text-editor/src/ui/extensions/index.tsx b/packages/editor/rich-text-editor/src/ui/extensions/index.tsx index 1e81c8173..3d1da6cda 100644 --- a/packages/editor/rich-text-editor/src/ui/extensions/index.tsx +++ b/packages/editor/rich-text-editor/src/ui/extensions/index.tsx @@ -1,14 +1,15 @@ -import { SlashCommand, DragAndDrop } from "@plane/editor-extensions"; -import Placeholder from "@tiptap/extension-placeholder"; import { UploadImage } from "@plane/editor-core"; +import { DragAndDrop, SlashCommand } from "@plane/editor-extensions"; +import Placeholder from "@tiptap/extension-placeholder"; export const RichTextEditorExtensions = ( uploadFile: UploadImage, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void, - dragDropEnabled?: boolean + dragDropEnabled?: boolean, + setHideDragHandle?: (hideDragHandlerFromDragDrop: () => void) => void ) => [ SlashCommand(uploadFile, setIsSubmitting), - dragDropEnabled === true && DragAndDrop, + dragDropEnabled === true && DragAndDrop(setHideDragHandle), Placeholder.configure({ placeholder: ({ node }) => { if (node.type.name === "heading") { diff --git a/packages/editor/rich-text-editor/src/ui/index.tsx b/packages/editor/rich-text-editor/src/ui/index.tsx index 17d701600..43c3f8f34 100644 --- a/packages/editor/rich-text-editor/src/ui/index.tsx +++ b/packages/editor/rich-text-editor/src/ui/index.tsx @@ -1,5 +1,4 @@ "use client"; -import * as React from "react"; import { DeleteImage, EditorContainer, @@ -10,8 +9,9 @@ import { UploadImage, useEditor, } from "@plane/editor-core"; -import { EditorBubbleMenu } from "src/ui/menus/bubble-menu"; +import * as React from "react"; import { RichTextEditorExtensions } from "src/ui/extensions"; +import { EditorBubbleMenu } from "src/ui/menus/bubble-menu"; export type IRichTextEditor = { value: string; @@ -66,6 +66,14 @@ const RichTextEditor = ({ rerenderOnPropsChange, mentionSuggestions, }: RichTextEditorProps) => { + const [hideDragHandleOnMouseLeave, setHideDragHandleOnMouseLeave] = React.useState<() => void>(() => {}); + + // this essentially sets the hideDragHandle function from the DragAndDrop extension as the Plugin + // loads such that we can invoke it from react when the cursor leaves the container + const setHideDragHandleFunction = (hideDragHandlerFromDragDrop: () => void) => { + setHideDragHandleOnMouseLeave(() => hideDragHandlerFromDragDrop); + }; + const editor = useEditor({ onChange, debouncedUpdatesEnabled, @@ -78,7 +86,7 @@ const RichTextEditor = ({ restoreFile, forwardedRef, rerenderOnPropsChange, - extensions: RichTextEditorExtensions(uploadFile, setIsSubmitting, dragDropEnabled), + extensions: RichTextEditorExtensions(uploadFile, setIsSubmitting, dragDropEnabled, setHideDragHandleFunction), mentionHighlights, mentionSuggestions, }); @@ -92,7 +100,7 @@ const RichTextEditor = ({ if (!editor) return null; return ( - + {editor && }