diff --git a/packages/web/src/javascripts/Components/Popover/GetPositionedPopoverStyles.ts b/packages/web/src/javascripts/Components/Popover/GetPositionedPopoverStyles.ts index d70dadb5b..db064f63e 100644 --- a/packages/web/src/javascripts/Components/Popover/GetPositionedPopoverStyles.ts +++ b/packages/web/src/javascripts/Components/Popover/GetPositionedPopoverStyles.ts @@ -47,7 +47,7 @@ type Options = { popoverRect?: DOMRect side: PopoverSide disableMobileFullscreenTakeover?: boolean - maxHeightFunction?: (calculatedMaxHeight: number) => number + maxHeightFunction?: (calculatedMaxHeight: number) => number | 'none' offset?: number } diff --git a/packages/web/src/javascripts/Components/Popover/Utils/movePopoverToFitInsideRect.ts b/packages/web/src/javascripts/Components/Popover/Utils/movePopoverToFitInsideRect.ts new file mode 100644 index 000000000..75e71a132 --- /dev/null +++ b/packages/web/src/javascripts/Components/Popover/Utils/movePopoverToFitInsideRect.ts @@ -0,0 +1,24 @@ +import { getOverflows } from './Collisions' + +export const movePopoverToFitInsideRect = (popoverElement: HTMLElement, rect: DOMRect) => { + const popoverRect = popoverElement.getBoundingClientRect() + const x = parseInt(popoverElement.style.getPropertyValue('--translate-x')) || 0 + const y = parseInt(popoverElement.style.getPropertyValue('--translate-y')) || 0 + const overflows = getOverflows(popoverRect, rect) + + if (overflows['top'] > 0) { + popoverElement.style.setProperty('--translate-y', `${y + overflows['top']}px`) + } + + if (overflows['bottom'] > 0) { + popoverElement.style.setProperty('--translate-y', `${y - overflows['bottom']}px`) + } + + if (overflows['left'] > 0) { + popoverElement.style.setProperty('--translate-x', `${x + overflows['left']}px`) + } + + if (overflows['right'] > 0) { + popoverElement.style.setProperty('--translate-x', `${x - overflows['right']}px`) + } +} diff --git a/packages/web/src/javascripts/Components/SuperEditor/Plugins/FloatingTextFormatToolbarPlugin/index.tsx b/packages/web/src/javascripts/Components/SuperEditor/Plugins/FloatingTextFormatToolbarPlugin/index.tsx index 18fadaae9..1cf889ca1 100644 --- a/packages/web/src/javascripts/Components/SuperEditor/Plugins/FloatingTextFormatToolbarPlugin/index.tsx +++ b/packages/web/src/javascripts/Components/SuperEditor/Plugins/FloatingTextFormatToolbarPlugin/index.tsx @@ -55,6 +55,7 @@ import { getDOMRangeRect } from '../../Lexical/Utils/getDOMRangeRect' import { getPositionedPopoverStyles } from '@/Components/Popover/GetPositionedPopoverStyles' import { getAdjustedStylesForNonPortalPopover } from '@/Components/Popover/Utils/getAdjustedStylesForNonPortal' import LinkEditor from '../FloatingLinkEditorPlugin/LinkEditor' +import { movePopoverToFitInsideRect } from '@/Components/Popover/Utils/movePopoverToFitInsideRect' const blockTypeToBlockName = { bullet: 'Bulleted List', @@ -198,7 +199,8 @@ function TextFormatFloatingToolbar({ anchorRect: rangeRect, popoverRect: toolbarRect, documentRect: rootElementRect, - offset: 8, + offset: 12, + maxHeightFunction: () => 'none', }) if (calculatedStyles) { @@ -206,6 +208,7 @@ function TextFormatFloatingToolbar({ const adjustedStyles = getAdjustedStylesForNonPortalPopover(toolbarElement, calculatedStyles, rootElement) toolbarElement.style.setProperty('--translate-x', adjustedStyles['--translate-x']) toolbarElement.style.setProperty('--translate-y', adjustedStyles['--translate-y']) + movePopoverToFitInsideRect(toolbarElement, rootElementRect) } } else if (!activeElement || activeElement.id !== 'link-input') { setLastSelection(null) @@ -217,7 +220,7 @@ function TextFormatFloatingToolbar({ }, [editor]) useEffect(() => { - const scrollerElem = anchorElem.parentElement + const scrollerElem = editor.getRootElement() const update = () => { editor.getEditorState().read(() => {