From 1be30f70015d441f96a2c1d965c9da5f1c460e6f Mon Sep 17 00:00:00 2001 From: koji Date: Wed, 8 May 2024 14:31:01 -0400 Subject: [PATCH] fix(app): Fix dropdown menu open direction issue (#15091) * fix(app): Fix dropdown menu open direction issue --- app/src/atoms/MenuList/DropdownMenu.tsx | 44 ++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/app/src/atoms/MenuList/DropdownMenu.tsx b/app/src/atoms/MenuList/DropdownMenu.tsx index 992b39073f3..c2dd1ed9c3d 100644 --- a/app/src/atoms/MenuList/DropdownMenu.tsx +++ b/app/src/atoms/MenuList/DropdownMenu.tsx @@ -64,6 +64,47 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element { } = props const [targetProps, tooltipProps] = useHoverTooltip() const [showDropdownMenu, setShowDropdownMenu] = React.useState(false) + + const [dropdownPosition, setDropdownPosition] = React.useState< + 'top' | 'bottom' + >('bottom') + + React.useEffect(() => { + const handlePositionCalculation = (): void => { + const dropdownRect = dropDownMenuWrapperRef.current?.getBoundingClientRect() + if (dropdownRect != null) { + const parentElement = dropDownMenuWrapperRef?.current?.parentElement + const grandParentElement = parentElement?.parentElement?.parentElement + let availableHeight = window.innerHeight + let scrollOffset = 0 + + if (grandParentElement != null) { + const grandParentRect = grandParentElement.getBoundingClientRect() + availableHeight = grandParentRect.bottom - grandParentRect.top + scrollOffset = grandParentRect.top + } else if (parentElement != null) { + const parentRect = parentElement.getBoundingClientRect() + availableHeight = parentRect.bottom - parentRect.top + scrollOffset = parentRect.top + } + + const dropdownBottom = + dropdownRect.bottom + (filterOptions.length + 1) * 34 - scrollOffset + + setDropdownPosition(dropdownBottom > availableHeight ? 'top' : 'bottom') + } + } + + window.addEventListener('resize', handlePositionCalculation) + window.addEventListener('scroll', handlePositionCalculation) + handlePositionCalculation() + + return () => { + window.removeEventListener('resize', handlePositionCalculation) + window.removeEventListener('scroll', handlePositionCalculation) + } + }, [filterOptions.length, window.innerHeight]) + const toggleSetShowDropdownMenu = (): void => { setShowDropdownMenu(!showDropdownMenu) } @@ -170,7 +211,8 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element { backgroundColor={COLORS.white} flexDirection={DIRECTION_COLUMN} width={width} - top="2.5rem" + top={dropdownPosition === 'bottom' ? '2.5rem' : undefined} + bottom={dropdownPosition === 'top' ? '2.5rem' : undefined} > {filterOptions.map((option, index) => (