From 04b2214bf2b9dc04bf178a205427c565bb7c9e27 Mon Sep 17 00:00:00 2001 From: "M. Palanikannan" <73993394+Palanikannan1437@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:43:43 +0530 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Hide=20drag=20handle=20wh?= =?UTF-8?q?en=20cursor=20leaves=20the=20editor=20container=20(#3401)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fix adds support for hiding the drag handle when the cursor leaves the editor container. It improves the user experience by providing a cleaner interface and removing unnecessary visual elements especially while scrolling. - Add `hideDragHandle` prop to `EditorContainer` component in `editor-container.tsx`. - Implement `onMouseLeave` event handler in `EditorContainer` to invoke `hideDragHandle` function. - Update `DragAndDrop` extension in `drag-drop.tsx` to accept a `setHideDragHandle` function as an optional parameter. - Pass the `setHideDragHandle` function from `RichTextEditor` component to `DragAndDrop` extension in `RichTextEditorExtensions` function in `index.tsx`. - Set `hideDragHandleOnMouseLeave` state in `RichTextEditor` component to store the `hideDragHandlerFromDragDrop` function. - Create `setHideDragHandleFunction` callback function in `RichTextEditor` to update the `hideDragHandleOnMouseLeave` state. - Pass `hideDragHandleOnMouseLeave` as `hideDragHandle` prop to `EditorContainer` component in `RichTextEditor`. --- .../src/ui/components/editor-container.tsx | 6 ++++- .../extensions/src/extensions/drag-drop.tsx | 26 ++++++++++++------- .../src/ui/extensions/index.tsx | 9 ++++--- .../editor/rich-text-editor/src/ui/index.tsx | 16 +++++++++--- 4 files changed, 38 insertions(+), 19 deletions(-) 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 && }