From a0c4e7d749f0a987a8baf8ae88211331e0ea3103 Mon Sep 17 00:00:00 2001 From: VipinDevelops Date: Fri, 26 Sep 2025 18:31:23 +0530 Subject: [PATCH 1/3] fix: block close --- .../src/core/components/menus/block-menu.tsx | 25 ++++++++++--------- .../editor/src/core/extensions/utility.ts | 1 + 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/editor/src/core/components/menus/block-menu.tsx b/packages/editor/src/core/components/menus/block-menu.tsx index e8a644c1fa7..504718cf6ec 100644 --- a/packages/editor/src/core/components/menus/block-menu.tsx +++ b/packages/editor/src/core/components/menus/block-menu.tsx @@ -71,26 +71,30 @@ export const BlockMenu = (props: Props) => { } // Show the menu setIsOpen(true); + editor.commands.addActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); return; } // If clicking outside and not on a menu item, hide the menu if (menuRef.current && !menuRef.current.contains(target)) { + editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); setIsOpen(false); } }, - [refs] + [editor.commands, refs] ); useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { setIsOpen(false); + editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); } }; const handleScroll = () => { setIsOpen(false); + editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); }; document.addEventListener("click", handleClickDragHandle); document.addEventListener("contextmenu", handleClickDragHandle); @@ -103,7 +107,7 @@ export const BlockMenu = (props: Props) => { document.removeEventListener("keydown", handleKeyDown); document.removeEventListener("scroll", handleScroll, true); }; - }, [handleClickDragHandle]); + }, [editor.commands, handleClickDragHandle]); // Animation effect useEffect(() => { @@ -134,13 +138,8 @@ export const BlockMenu = (props: Props) => { key: "delete", label: "Delete", onClick: (e) => { - e.preventDefault(); - e.stopPropagation(); - // Execute the delete action editor.chain().deleteSelection().focus().run(); - - setIsOpen(false); }, }, { @@ -151,9 +150,6 @@ export const BlockMenu = (props: Props) => { editor.state.selection.content().content.firstChild?.type.name === CORE_EXTENSIONS.IMAGE || editor.isActive(CORE_EXTENSIONS.CUSTOM_IMAGE), onClick: (e) => { - e.preventDefault(); - e.stopPropagation(); - try { const { state } = editor; const { selection } = state; @@ -187,7 +183,6 @@ export const BlockMenu = (props: Props) => { console.error(error.message); } } - setIsOpen(false); }, }, ]; @@ -225,7 +220,13 @@ export const BlockMenu = (props: Props) => { key={item.key} type="button" className="flex w-full items-center gap-1.5 truncate rounded px-1 py-1.5 text-xs text-custom-text-200 hover:bg-custom-background-90" - onClick={item.onClick} + onClick={(e) => { + item.onClick(e); + e.preventDefault(); + e.stopPropagation(); + setIsOpen(false); + editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); + }} disabled={item.isDisabled} > diff --git a/packages/editor/src/core/extensions/utility.ts b/packages/editor/src/core/extensions/utility.ts index 77fdcc9125b..e996a694daf 100644 --- a/packages/editor/src/core/extensions/utility.ts +++ b/packages/editor/src/core/extensions/utility.ts @@ -16,6 +16,7 @@ type TActiveDropbarExtensions = | CORE_EXTENSIONS.EMOJI | CORE_EXTENSIONS.SLASH_COMMANDS | CORE_EXTENSIONS.TABLE + | CORE_EXTENSIONS.SIDE_MENU | TAdditionalActiveDropbarExtensions; declare module "@tiptap/core" { From 152a4dcd8954ceb3ef691651140fed4f02e343ab Mon Sep 17 00:00:00 2001 From: VipinDevelops Date: Mon, 29 Sep 2025 15:10:58 +0530 Subject: [PATCH 2/3] chore : add toggle option in block menu --- .../src/core/components/menus/block-menu.tsx | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/editor/src/core/components/menus/block-menu.tsx b/packages/editor/src/core/components/menus/block-menu.tsx index 504718cf6ec..a84195599d8 100644 --- a/packages/editor/src/core/components/menus/block-menu.tsx +++ b/packages/editor/src/core/components/menus/block-menu.tsx @@ -43,6 +43,16 @@ export const BlockMenu = (props: Props) => { const dismiss = useDismiss(context); const { getFloatingProps } = useInteractions([dismiss]); + const toggleBlockMenu = useCallback(() => { + if (isOpen) { + setIsOpen(false); + editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); + } else { + setIsOpen(true); + editor.commands.addActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); + } + }, [editor, isOpen]); + // Handle click on drag handle const handleClickDragHandle = useCallback( (event: MouseEvent) => { @@ -70,31 +80,27 @@ export const BlockMenu = (props: Props) => { editor.chain().setNodeSelection(nodePos).run(); } // Show the menu - setIsOpen(true); - editor.commands.addActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); + toggleBlockMenu(); return; } // If clicking outside and not on a menu item, hide the menu if (menuRef.current && !menuRef.current.contains(target)) { - editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); - setIsOpen(false); + toggleBlockMenu(); } }, - [editor.commands, refs] + [editor, refs, toggleBlockMenu] ); useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { - setIsOpen(false); - editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); + toggleBlockMenu(); } }; const handleScroll = () => { - setIsOpen(false); - editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); + toggleBlockMenu(); }; document.addEventListener("click", handleClickDragHandle); document.addEventListener("contextmenu", handleClickDragHandle); @@ -107,7 +113,7 @@ export const BlockMenu = (props: Props) => { document.removeEventListener("keydown", handleKeyDown); document.removeEventListener("scroll", handleScroll, true); }; - }, [editor.commands, handleClickDragHandle]); + }, [editor.commands, handleClickDragHandle, toggleBlockMenu]); // Animation effect useEffect(() => { @@ -224,8 +230,7 @@ export const BlockMenu = (props: Props) => { item.onClick(e); e.preventDefault(); e.stopPropagation(); - setIsOpen(false); - editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); + toggleBlockMenu(); }} disabled={item.isDisabled} > From 6fbca9bae18c639551be517c8495b0d3a654753b Mon Sep 17 00:00:00 2001 From: VipinDevelops Date: Mon, 29 Sep 2025 15:18:38 +0530 Subject: [PATCH 3/3] fix: separate methods --- .../src/core/components/menus/block-menu.tsx | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/editor/src/core/components/menus/block-menu.tsx b/packages/editor/src/core/components/menus/block-menu.tsx index a84195599d8..18a4b827312 100644 --- a/packages/editor/src/core/components/menus/block-menu.tsx +++ b/packages/editor/src/core/components/menus/block-menu.tsx @@ -43,13 +43,17 @@ export const BlockMenu = (props: Props) => { const dismiss = useDismiss(context); const { getFloatingProps } = useInteractions([dismiss]); - const toggleBlockMenu = useCallback(() => { + const openBlockMenu = useCallback(() => { + if (!isOpen) { + setIsOpen(true); + editor.commands.addActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); + } + }, [editor, isOpen]); + + const closeBlockMenu = useCallback(() => { if (isOpen) { setIsOpen(false); editor.commands.removeActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); - } else { - setIsOpen(true); - editor.commands.addActiveDropbarExtension(CORE_EXTENSIONS.SIDE_MENU); } }, [editor, isOpen]); @@ -80,27 +84,27 @@ export const BlockMenu = (props: Props) => { editor.chain().setNodeSelection(nodePos).run(); } // Show the menu - toggleBlockMenu(); + openBlockMenu(); return; } // If clicking outside and not on a menu item, hide the menu if (menuRef.current && !menuRef.current.contains(target)) { - toggleBlockMenu(); + closeBlockMenu(); } }, - [editor, refs, toggleBlockMenu] + [editor, refs, openBlockMenu, closeBlockMenu] ); useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { - toggleBlockMenu(); + closeBlockMenu(); } }; const handleScroll = () => { - toggleBlockMenu(); + closeBlockMenu(); }; document.addEventListener("click", handleClickDragHandle); document.addEventListener("contextmenu", handleClickDragHandle); @@ -113,7 +117,7 @@ export const BlockMenu = (props: Props) => { document.removeEventListener("keydown", handleKeyDown); document.removeEventListener("scroll", handleScroll, true); }; - }, [editor.commands, handleClickDragHandle, toggleBlockMenu]); + }, [editor.commands, handleClickDragHandle, closeBlockMenu]); // Animation effect useEffect(() => { @@ -143,7 +147,7 @@ export const BlockMenu = (props: Props) => { icon: Trash2, key: "delete", label: "Delete", - onClick: (e) => { + onClick: (_e) => { // Execute the delete action editor.chain().deleteSelection().focus().run(); }, @@ -155,7 +159,7 @@ export const BlockMenu = (props: Props) => { isDisabled: editor.state.selection.content().content.firstChild?.type.name === CORE_EXTENSIONS.IMAGE || editor.isActive(CORE_EXTENSIONS.CUSTOM_IMAGE), - onClick: (e) => { + onClick: (_e) => { try { const { state } = editor; const { selection } = state; @@ -230,7 +234,7 @@ export const BlockMenu = (props: Props) => { item.onClick(e); e.preventDefault(); e.stopPropagation(); - toggleBlockMenu(); + closeBlockMenu(); }} disabled={item.isDisabled} >