From 41744bc59bd373bea8aa865ccd2e5aaa3bf78851 Mon Sep 17 00:00:00 2001 From: Andy Chen <44120813+achen5671@users.noreply.github.com> Date: Mon, 1 Jul 2024 09:50:46 -0400 Subject: [PATCH] studio: fix context menu (#10475) * dont overflow menu on the right side of the screen * use anchor el if provided * revert Toolbar2 * pass copy * add anchorEl as an additional prop * revert anchorEvent.set * cleanup --------- Co-authored-by: aditya-mitra <55396651+aditya-mitra@users.noreply.github.com> --- .../components/editor/layout/ContextMenu.tsx | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/components/editor/layout/ContextMenu.tsx b/packages/ui/src/components/editor/layout/ContextMenu.tsx index 811362fbd4..2147e93774 100644 --- a/packages/ui/src/components/editor/layout/ContextMenu.tsx +++ b/packages/ui/src/components/editor/layout/ContextMenu.tsx @@ -33,6 +33,7 @@ type ContextMenuProps = { anchorPosition?: undefined | { left: number; top: number } onClose: () => void className?: string + anchorEl?: HTMLElement } export const ContextMenu = ({ @@ -41,12 +42,15 @@ export const ContextMenu = ({ panelId, anchorPosition: propAnchorPosition, onClose, - className + className, + ...prop }: React.PropsWithChildren) => { const [open, setOpen] = React.useState(false) const panel = document.getElementById(panelId) const menuRef = useRef(null) + const { anchorEl } = prop + // use custom anchorPosition if explicity provided, otherwise use default anchor position when anchorEvent is defined const anchorPosition = propAnchorPosition ? propAnchorPosition @@ -59,7 +63,12 @@ export const ContextMenu = ({ // Calculate the Y position of the context menu based on the menu height and space to the bottom of the viewport in order to avoid overflow const calculatePositionY = () => { - let positionY = anchorPosition ? anchorPosition.top - panel?.getBoundingClientRect().top! : 0 + let positionY = anchorPosition + ? anchorPosition.top - panel?.getBoundingClientRect().top! + : anchorEl + ? anchorEl.getBoundingClientRect().bottom! + : 0 + // let positionY = if (open && menuRef.current) { const menuHeight = menuRef.current.offsetHeight @@ -69,6 +78,16 @@ export const ContextMenu = ({ if (offset < 0) { positionY = positionY + offset } + + const viewportHeight = window.innerHeight + + // Adjust Y position to avoid overflow + if (positionY + menuHeight > viewportHeight) { + positionY = viewportHeight - menuHeight - 10 // 10px for padding + } + if (positionY < 0) { + positionY = 10 // 10px for padding + } } return positionY @@ -76,7 +95,11 @@ export const ContextMenu = ({ // Calculate the X position of the context menu based on the menu width and space to the right of the panel in order to avoid overflow const calculatePositionX = () => { - let positionX = anchorPosition ? anchorPosition.left - panel?.getBoundingClientRect().left! : 0 + let positionX = anchorPosition + ? anchorPosition.left - panel?.getBoundingClientRect().left! + : anchorEl + ? anchorEl.getBoundingClientRect().left! + : 0 if (open && menuRef.current) { const menuWidth = menuRef.current.offsetWidth @@ -86,6 +109,16 @@ export const ContextMenu = ({ if (offset < 0) { positionX = positionX + offset } + + const viewportWidth = window.innerWidth + + // Adjust X position to avoid overflow + if (positionX + menuWidth > viewportWidth) { + positionX = viewportWidth - menuWidth - 10 // 10px for padding + } + if (positionX < 0) { + positionX = 10 // 10px for padding + } } return positionX