calculate available height

This commit is contained in:
Bernt Christian Egeland 2023-04-11 19:50:23 +02:00
parent cbb99f70e4
commit bfa462b31e
2 changed files with 18 additions and 9 deletions

View File

@ -17,6 +17,8 @@ export default function MultiSelect({ className, title, options, selection, onTo
return selection == 'all' || selection.split(',').indexOf(item) > -1; return selection == 'all' || selection.split(',').indexOf(item) > -1;
}; };
const menuHeight = Math.round(window.innerHeight * 0.55);
return ( return (
<div className={`${className} p-2`} ref={popupRef}> <div className={`${className} p-2`} ref={popupRef}>
<div className="flex justify-between min-w-[120px]" onClick={() => setState({ showMenu: true })}> <div className="flex justify-between min-w-[120px]" onClick={() => setState({ showMenu: true })}>
@ -24,7 +26,11 @@ export default function MultiSelect({ className, title, options, selection, onTo
<ArrowDropdown className="w-6" /> <ArrowDropdown className="w-6" />
</div> </div>
{state.showMenu ? ( {state.showMenu ? (
<Menu className={`overflow-auto`} relativeTo={popupRef} onDismiss={() => setState({ showMenu: false })}> <Menu
className={`max-h-[${menuHeight}px] overflow-auto`}
relativeTo={popupRef}
onDismiss={() => setState({ showMenu: false })}
>
<div className="flex flex-wrap justify-between items-center"> <div className="flex flex-wrap justify-between items-center">
<Heading className="p-4 justify-center" size="md"> <Heading className="p-4 justify-center" size="md">
{title} {title}

View File

@ -57,7 +57,7 @@ export default function RelativeModal({
x: relativeToX, x: relativeToX,
y: relativeToY, y: relativeToY,
width: relativeToWidth, width: relativeToWidth,
// height: relativeToHeight, height: relativeToHeight,
} = relativeTo.current.getBoundingClientRect(); } = relativeTo.current.getBoundingClientRect();
const _width = widthRelative ? relativeToWidth : menuWidth; const _width = widthRelative ? relativeToWidth : menuWidth;
@ -78,10 +78,13 @@ export default function RelativeModal({
newLeft = windowWidth - width - WINDOW_PADDING; newLeft = windowWidth - width - WINDOW_PADDING;
} }
// too close to bottom // This condition checks if the menu overflows the bottom of the page and
if (top + menuHeight > windowHeight - WINDOW_PADDING + window.scrollY) { // if there's enough space to position the menu above the clicked icon.
// If the pop-up modal would extend beyond the bottom of the visible window, // If both conditions are met, the menu will be positioned above the clicked icon
// reposition the modal to appear above the clicked icon instead if (
top + menuHeight > windowHeight - WINDOW_PADDING + window.scrollY &&
top - menuHeight - relativeToHeight >= WINDOW_PADDING
) {
newTop = top - menuHeight; newTop = top - menuHeight;
} }
@ -89,10 +92,10 @@ export default function RelativeModal({
newTop = WINDOW_PADDING; newTop = WINDOW_PADDING;
} }
// This calculation checks if there's enough space to display the menu. // This calculation checks if there's enough space below the clicked icon for the menu to fit.
// If there is, it sets the maxHeight to null(meaning no height constraint). If not, it calculates the maxHeight based on the remaining space in the window // If there is, it sets the maxHeight to null(meaning no height constraint). If not, it calculates the maxHeight based on the remaining space in the window
const maxHeight = const maxHeight =
windowHeight - WINDOW_PADDING * 2 > menuHeight windowHeight - WINDOW_PADDING * 2 - top > menuHeight
? null ? null
: windowHeight - WINDOW_PADDING * 2 - top + window.scrollY; : windowHeight - WINDOW_PADDING * 2 - top + window.scrollY;
@ -121,7 +124,7 @@ export default function RelativeModal({
<div data-testid="scrim" key="scrim" className="fixed inset-0 z-10" onClick={handleDismiss} /> <div data-testid="scrim" key="scrim" className="fixed inset-0 z-10" onClick={handleDismiss} />
<div <div
key="menu" key="menu"
className={`z-10 bg-white dark:bg-gray-700 dark:text-white absolute shadow-lg rounded w-auto h-auto transition-transform transition-opacity duration-75 transform scale-90 opacity-0 overflow-x-hidden overflow-y-auto ${ className={`z-10 bg-white dark:bg-gray-700 dark:text-white absolute shadow-lg rounded w-auto h-auto transition-transform duration-75 transform scale-90 opacity-0 overflow-x-hidden overflow-y-auto ${
show ? 'scale-100 opacity-100' : '' show ? 'scale-100 opacity-100' : ''
} ${className}`} } ${className}`}
onKeyDown={handleKeydown} onKeyDown={handleKeydown}