diff --git a/src/lib/components/admin/SelectDropdown.svelte b/src/lib/components/admin/SelectDropdown.svelte index 2b1c302..4a5f49f 100644 --- a/src/lib/components/admin/SelectDropdown.svelte +++ b/src/lib/components/admin/SelectDropdown.svelte @@ -28,6 +28,12 @@ let triggerElement = $state(); let menuElement = $state(); + let menuTop = $state(0); + let menuBottom = $state(0); + let menuLeft = $state(0); + let menuWidth = $state(0); + let openUpwards = $state(false); + let selectedOption = $derived(options.find((option) => String(option.value) === String(value))); let selectedLabel = $derived(selectedOption?.label ?? emptyLabel); @@ -46,10 +52,37 @@ } function openMenu(preferLast = false) { + if (triggerElement) { + const rect = triggerElement.getBoundingClientRect(); + const spaceBelow = window.innerHeight - rect.bottom; + const spaceAbove = rect.top; + + if (spaceBelow < 240 && spaceAbove > spaceBelow) { + openUpwards = true; + menuBottom = window.innerHeight - rect.top; + } else { + openUpwards = false; + menuTop = rect.bottom; + } + menuLeft = rect.left; + menuWidth = rect.width; + } isOpen = true; focusOption(preferLast); } + function preventScroll(node: HTMLElement) { + const handler = (e: Event) => e.preventDefault(); + node.addEventListener('wheel', handler, { passive: false }); + node.addEventListener('touchmove', handler, { passive: false }); + return { + destroy() { + node.removeEventListener('wheel', handler); + node.removeEventListener('touchmove', handler); + } + }; + } + function closeMenu(restoreFocus = false) { isOpen = false; if (restoreFocus) triggerElement?.focus(); @@ -95,6 +128,8 @@ } + isOpen && closeMenu()} /> +