From fc0c71ea7dcd8cdb14ec76363ae6515853fc3f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Tue, 24 Mar 2026 12:37:23 +0400 Subject: [PATCH] Fix block and options menu triggers alignment with hovered block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Émile Ré --- packages/ui/src/RichEditor/BlockMenu.tsx | 7 ++++++- packages/ui/src/RichEditor/OptionsMenu.tsx | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/RichEditor/BlockMenu.tsx b/packages/ui/src/RichEditor/BlockMenu.tsx index e127f2af5..0bdd7bddb 100644 --- a/packages/ui/src/RichEditor/BlockMenu.tsx +++ b/packages/ui/src/RichEditor/BlockMenu.tsx @@ -51,6 +51,8 @@ const blockMenuVariants = tv({ const { trigger, menu } = blockMenuVariants(); +const TRIGGER_HEIGHT = 24; + function findClosestRootBlock(element: Element, editorDom: Element): HTMLElement | null { let current: Element | null = element; @@ -198,13 +200,16 @@ export function BlockMenu({ editor }: BlockMenuProps) { }; }, [editor, slashState.active, slashState.query, filteredItems, slashActiveIndex, handleSlashAction]); + const blockHeight = hoveredBlock?.getBoundingClientRect().height ?? 0; + const triggerPlacement = blockHeight > 2 * TRIGGER_HEIGHT ? "left-start" as const : "left" as const; + const { refs: triggerRefs, floatingStyles: triggerStyles, isPositioned, } = useFloating({ strategy: "fixed", - placement: "left-start", + placement: triggerPlacement, middleware: [offset(32)], whileElementsMounted: autoUpdate, }); diff --git a/packages/ui/src/RichEditor/OptionsMenu.tsx b/packages/ui/src/RichEditor/OptionsMenu.tsx index afb62c0db..e749c8850 100644 --- a/packages/ui/src/RichEditor/OptionsMenu.tsx +++ b/packages/ui/src/RichEditor/OptionsMenu.tsx @@ -34,6 +34,8 @@ const optionsMenuVariants = tv({ const { trigger, menu } = optionsMenuVariants(); +const TRIGGER_HEIGHT = 24; + function findClosestRootBlock(element: Element, editorDom: Element): HTMLElement | null { let current: Element | null = element; @@ -59,13 +61,16 @@ export function OptionsMenu({ editor }: OptionsMenuProps) { const [hoveredBlock, setHoveredBlock] = useState(null); const rafId = useRef(null); + const blockHeight = hoveredBlock?.getBoundingClientRect().height ?? 0; + const triggerPlacement = blockHeight > 2 * TRIGGER_HEIGHT ? "left-start" as const : "left" as const; + const { refs: triggerRefs, floatingStyles: triggerStyles, isPositioned, } = useFloating({ strategy: "fixed", - placement: "left-start", + placement: triggerPlacement, middleware: [offset(8)], whileElementsMounted: autoUpdate, });