From 53d8f54b0fcee32f4d3b4f9559fbfdd3f2251c87 Mon Sep 17 00:00:00 2001 From: dawn Date: Tue, 25 Aug 2026 22:08:42 +0900 Subject: [PATCH] web: fix mobile popover menu layout Signed-off-by: dawn web: preserve intrinsic mobile menu height Signed-off-by: dawn --- web/src/lib/components/ui/Combobox.svelte | 4 ++-- web/src/lib/components/ui/Dropdown.svelte | 6 ++++-- web/src/lib/components/ui/Hovercard.svelte | 2 +- web/src/lib/components/ui/TagInput.svelte | 4 ++-- web/src/lib/components/ui/Tooltip.svelte | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/web/src/lib/components/ui/Combobox.svelte b/web/src/lib/components/ui/Combobox.svelte index d187c8629..e52137bb2 100644 --- a/web/src/lib/components/ui/Combobox.svelte +++ b/web/src/lib/components/ui/Combobox.svelte @@ -8,9 +8,9 @@ root: "relative inline-block w-full", trigger: "flex min-h-9 cursor-pointer items-center gap-2 px-2.5 py-1", value: "min-w-0 flex-1 truncate text-left typography-paragraph-regular", - panel: "combobox-panel fixed z-50 m-0 hidden max-h-[min(24rem,calc(100dvh-1rem))] w-80 max-w-[calc(100vw-1rem)] popover-transition flex-col overflow-hidden rounded-sm border border-border-default bg-background-default p-0 text-foreground-default shadow-regular open:flex dark:shadow-none", + panel: "combobox-panel fixed inset-auto z-50 m-0 hidden h-fit max-h-[min(24rem,calc(100dvh-1rem))] w-80 max-w-[calc(100vw-1rem)] popover-transition flex-col overflow-hidden rounded-sm border border-border-default bg-background-default p-0 text-foreground-default shadow-regular open:flex dark:shadow-none", search: "shrink-0 border-b border-border-default p-2", - list: "min-h-0 flex-1 overflow-y-auto p-1", + list: "min-h-0 flex-auto overflow-y-auto p-1", groupHeading: "px-2 pt-2 pb-1 font-semibold text-foreground-muted first:pt-1", option: "flex w-full cursor-pointer items-center gap-2 rounded-sm bg-transparent px-2 py-1.5 text-left aria-disabled:cursor-not-allowed aria-disabled:text-foreground-disabled data-active:bg-background-subtle dark:data-active:bg-background-subtle", check: "size-4 shrink-0 text-foreground-default", diff --git a/web/src/lib/components/ui/Dropdown.svelte b/web/src/lib/components/ui/Dropdown.svelte index 07b654fdd..27be2a781 100644 --- a/web/src/lib/components/ui/Dropdown.svelte +++ b/web/src/lib/components/ui/Dropdown.svelte @@ -9,7 +9,7 @@ root: "relative inline-flex", plainTrigger: "min-h-0 gap-1 border-0 bg-transparent p-0 text-inherit hover:bg-transparent", - menu: "dropdown-menu fixed z-50 m-0 max-h-[calc(100dvh-1rem)] w-56 max-w-[calc(100vw-1rem)] popover-transition divide-y divide-border-default overflow-auto rounded-sm border border-border-default bg-background-default text-foreground-default shadow-regular" + menu: "dropdown-menu fixed inset-auto z-50 m-0 h-fit max-h-[calc(100dvh-1rem)] w-56 max-w-[calc(100vw-1rem)] popover-transition divide-y divide-border-default overflow-auto rounded-sm border border-border-default bg-background-default text-foreground-default shadow-regular" }, variants: { align: { @@ -94,6 +94,7 @@ let menuElement = $state(); const fallbackId = $props.id(); const menuId = $derived(id ?? fallbackId); + const anchorName = $derived(`--dropdown-${menuId.replace(/[^a-zA-Z0-9_-]/g, "-")}`); const focusTrigger = () => { triggerElement?.focus(); @@ -194,6 +195,7 @@ class={variant === "button" ? undefined : classes.plainTrigger()} popovertarget={menuId} popovertargetaction="toggle" + style="anchor-name: {anchorName}" onkeydown={onTriggerKeydown} aria-haspopup="menu" aria-expanded={open} @@ -215,7 +217,7 @@ role="menu" tabindex={-1} onkeydown={onMenuKeydown} - style="transform: translateX({xOffset}px)" + style="position-anchor: {anchorName}; transform: translateX({xOffset}px)" {@attach popoverExit()} > {@render children()} diff --git a/web/src/lib/components/ui/Hovercard.svelte b/web/src/lib/components/ui/Hovercard.svelte index ba65a5a5e..65fa95df2 100644 --- a/web/src/lib/components/ui/Hovercard.svelte +++ b/web/src/lib/components/ui/Hovercard.svelte @@ -7,7 +7,7 @@ // lines up with it rather than with a full-width box wrapper: "inline-flex", // overflow-visible so the card's own content (e.g. a nested popover) isn't clipped - card: "hovercard-card fixed z-50 m-0 overflow-visible rounded-sm border border-border-default bg-background-default text-foreground-default shadow-regular" + card: "hovercard-card fixed inset-auto z-50 m-0 h-fit overflow-visible rounded-sm border border-border-default bg-background-default text-foreground-default shadow-regular" } }); diff --git a/web/src/lib/components/ui/TagInput.svelte b/web/src/lib/components/ui/TagInput.svelte index fbeef70ba..e48959100 100644 --- a/web/src/lib/components/ui/TagInput.svelte +++ b/web/src/lib/components/ui/TagInput.svelte @@ -21,8 +21,8 @@ label: "truncate", remove: "text-foreground-inherit -mr-0.5 flex min-h-0 shrink-0 rounded-xs p-0 transition-colors focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-border-focus", draft: "w-full min-w-0 bg-transparent outline-none placeholder:text-foreground-placeholder placeholder:transition-opacity placeholder:duration-200 disabled:cursor-not-allowed motion-reduce:placeholder:transition-none", - panel: "tag-panel fixed z-50 m-0 hidden max-h-[min(18rem,calc(100dvh-1rem))] w-72 max-w-[calc(100vw-1rem)] popover-transition flex-col overflow-hidden rounded-sm border border-border-default bg-background-default p-0 text-foreground-default open:flex", - options: "min-h-0 flex-1 overflow-y-auto p-1", + panel: "tag-panel fixed inset-auto z-50 m-0 hidden h-fit max-h-[min(18rem,calc(100dvh-1rem))] w-72 max-w-[calc(100vw-1rem)] popover-transition flex-col overflow-hidden rounded-sm border border-border-default bg-background-default p-0 text-foreground-default open:flex", + options: "min-h-0 flex-auto overflow-y-auto p-1", option: "flex w-full cursor-pointer items-center gap-2 rounded-sm bg-transparent px-2 py-1.5 text-left data-active:bg-background-subtle", optionLabel: "min-w-0 flex-1 truncate", empty: "px-2 py-6 text-center text-foreground-muted", diff --git a/web/src/lib/components/ui/Tooltip.svelte b/web/src/lib/components/ui/Tooltip.svelte index feb05a234..747e97885 100644 --- a/web/src/lib/components/ui/Tooltip.svelte +++ b/web/src/lib/components/ui/Tooltip.svelte @@ -8,7 +8,7 @@ wrapper: "inline-flex", // overflow-visible undoes the UA stylesheet's `overflow: auto` on [popover], which // would otherwise clip the arrow off at the bubble's padding box - bubble: "tooltip-bubble fixed z-50 m-0 w-max max-w-64 overflow-visible rounded-sm bg-background-emphasis px-2 pt-1.5 pb-1 typography-paragraph-small text-foreground-inverted shadow-regular" + bubble: "tooltip-bubble fixed inset-auto z-50 m-0 h-fit w-max max-w-64 overflow-visible rounded-sm bg-background-emphasis px-2 pt-1.5 pb-1 typography-paragraph-small text-foreground-inverted shadow-regular" }, variants: { side: { -- 2.54.0