From 4196db175933f4081cd4481ee58ed28420d4319d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20T=C3=A4kker?= Date: Fri, 25 Sep 2026 19:45:55 +0200 Subject: [PATCH] Fixed dropdown clipping --- app/ui/DropdownMenu.vue | 45 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/app/ui/DropdownMenu.vue b/app/ui/DropdownMenu.vue index 306301f..b9c8d9f 100644 --- a/app/ui/DropdownMenu.vue +++ b/app/ui/DropdownMenu.vue @@ -14,6 +14,7 @@ const props = defineProps() const open = ref(false) const placement = ref<"bottom" | "top">("bottom") const root = useTemplateRef("root") +const menuPosition = ref({ top: 0, left: 0 }) const toggle = async () => { open.value = !open.value @@ -37,16 +38,12 @@ const updatePlacement = () => { // TODO: Calculate height instead const menuHeight = 220 - console.log( - spaceBelow, - menuHeight, - spaceAbove, - spaceBelow < menuHeight && spaceAbove > spaceBelow, - spaceBelow < menuHeight && spaceAbove > spaceBelow ? "top" : "bottom", - ) - - placement.value = - spaceBelow < menuHeight && spaceAbove > spaceBelow ? "top" : "bottom" + const showAbove = spaceBelow < menuHeight && spaceAbove > spaceBelow + placement.value = showAbove ? "top" : "bottom" + menuPosition.value = { + top: showAbove ? rect.top : rect.bottom, + left: rect.right, + } } const handleOutsideClick = (e: MouseEvent) => { @@ -84,7 +81,16 @@ onBeforeMount(() => { - + @@ -116,10 +123,11 @@ onBeforeMount(() => { .dropdown { position: relative; display: inline-block; +} - .menu { - position: absolute; - right: 0; +.dropdown-menu { + position: fixed; + z-index: 1000; padding: 0.5rem; min-width: 180px; @@ -131,18 +139,17 @@ onBeforeMount(() => { display: flex; flex-direction: column; - z-index: 1000; + transform: translateX(-100%); &.bottom { - top: calc(100% + 0.5rem); + transform: translate(-100%, 0.5rem); transform-origin: top right; } &.top { - bottom: calc(100% + 0.5rem); + transform: translate(-100%, calc(-100% - 0.5rem)); transform-origin: bottom right; } - } .group { width: 100%;