diff --git a/packages/react-ui-lib/src/editor/common/editor-inline-toolbar.tsx b/packages/react-ui-lib/src/editor/common/editor-inline-toolbar.tsx index ce844c2ad..c936496b8 100644 --- a/packages/react-ui-lib/src/editor/common/editor-inline-toolbar.tsx +++ b/packages/react-ui-lib/src/editor/common/editor-inline-toolbar.tsx @@ -16,30 +16,45 @@ export const EditorInlineToolbar = memo(({ children }: EditorInlineToolbarProps) } if (selection && selection.focus.offset !== selection.anchor.offset) { + const borderWidth = 1 const domRange = ReactEditor.toDOMRange(editor, selection) - const domRect = domRange.getBoundingClientRect() - toolbar.style.top = `${domRect.top + window.scrollY - toolbar.offsetHeight}px` - toolbar.style.left = `${Math.min( + let parent = toolbar.parentElement + while (parent && getComputedStyle(parent).position !== 'relative') { + parent = parent.parentElement + } + + if (!parent) { + return + } + + const parentRect = parent.getBoundingClientRect() + const rangeRect = domRange.getBoundingClientRect() + const toolbarRect = toolbar.getBoundingClientRect() + + const top = rangeRect.top - parentRect.top - toolbarRect.height + const left = Math.min( Math.max(0, document.documentElement.clientWidth - toolbar.offsetWidth), - Math.max(0, domRect.left + window.scrollX - toolbar.offsetWidth / 2 + domRect.width / 2), + Math.max( + 0, + Math.min(parentRect.width - toolbar.offsetWidth - borderWidth * 2, rangeRect.left - parentRect.left - toolbar.offsetWidth / 2 + rangeRect.width / 2), + ), ) - }px` + toolbar.style.top = `${top}px` + toolbar.style.left = `${left}px` + toolbar.style.maxWidth = `${document.documentElement.clientWidth}px` } else { toolbar.style.top = '-1000vh' toolbar.style.left = '-1000vw' toolbar.style.maxWidth = 'unset' } - }, [editor, selection]) return ( <> -
-
- {children} -
-
+
+
{children}
+
) })