From b1db287f2a27b4c311e7a5ff4ae477c948ec2d81 Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Wed, 26 Aug 2026 21:06:35 +0530 Subject: [PATCH] fix(ui): allow trigger-anchored dropdowns on mobile --- bun.lock | 2 +- packages/ui/components/Dropdown.wrn | 4 +++- packages/ui/package.json | 2 +- .../ui/test/account-shell-regressions.test.ts | 23 ++++++++++++++++++- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/bun.lock b/bun.lock index 9ea8e008..a422adda 100644 --- a/bun.lock +++ b/bun.lock @@ -688,7 +688,7 @@ }, "packages/ui": { "name": "@wrnexus/ui", - "version": "0.8.64", + "version": "0.8.65", "dependencies": { "@wrnexus/core": "workspace:*", }, diff --git a/packages/ui/components/Dropdown.wrn b/packages/ui/components/Dropdown.wrn index 73575bfe..7ac748b5 100644 --- a/packages/ui/components/Dropdown.wrn +++ b/packages/ui/components/Dropdown.wrn @@ -17,6 +17,7 @@ items: unknown[] = [] showChevron: boolean = true menuLabel: string = "Dropdown menu" placement: string = "bottom-start" + mobilePanel: string = "sheet" width: string = "md" size: string = "default" color: string = "primary" @@ -151,6 +152,7 @@ items: unknown[] = [] data-ui-component="Dropdown" data-open='{open || visible ? "true" : "false"}' data-placement='{placement}' + data-mobile-panel='{mobilePanel}' data-width='{width}' data-size='{size}' data-color='{color}' @@ -572,7 +574,7 @@ items: unknown[] = [] } @media (max-width: 639px) { - .wrn-dropdown[data-placement] .wrn-dropdown__panel { + .wrn-dropdown[data-placement][data-mobile-panel="sheet"] .wrn-dropdown__panel { position: fixed; right: 0.75rem; bottom: 0.75rem; diff --git a/packages/ui/package.json b/packages/ui/package.json index 5c6c1d91..0b8ae288 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ui", - "version": "0.8.64", + "version": "0.8.65", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/ui/test/account-shell-regressions.test.ts b/packages/ui/test/account-shell-regressions.test.ts index 9a23094e..681b8b0e 100644 --- a/packages/ui/test/account-shell-regressions.test.ts +++ b/packages/ui/test/account-shell-regressions.test.ts @@ -8,6 +8,25 @@ import { Window } from "happy-dom"; const source = (name: string) => readFileSync(uiComponentPath(name), "utf8"); describe("account shell UI regressions", () => { + test("Dropdown allows anchored mobile menus without changing existing sheet defaults", async () => { + for (const mobilePanel of [undefined, "dropdown", "sheet"]) { + const dom = mountHtml( + await renderComponent(source("Dropdown"), { + label: "User", + placement: "bottom-end", + ...(mobilePanel ? { mobilePanel } : {}), + }), + ); + expect(dom.querySelector(".wrn-dropdown")?.getAttribute("data-mobile-panel")).toBe( + mobilePanel ?? "sheet", + ); + (dom.querySelector(".wrn-dropdown__trigger") as HTMLButtonElement).click(); + expect(dom.querySelector(".wrn-dropdown__panel")?.hasAttribute("hidden")).toBe(false); + } + expect(source("Dropdown")).not.toContain( + ".wrn-dropdown[data-placement] .wrn-dropdown__panel {", + ); + }); test("Dropdown is natively hidden before CSS or hydration and still toggles afterward", async () => { for (const props of [{}, { open: true }, { defaultOpen: true }]) { const html = await renderComponent(source("Dropdown"), { label: "User", ...props }); @@ -189,7 +208,9 @@ describe("account shell UI regressions", () => { /\.wrn-sidebar__icon\s*\{[^}]*width: 1.05rem;[^}]*height: 1.05rem;/s, ); expect(source("Sidebar")).toContain("margin-inline-start"); - expect(source("Dropdown")).toContain(".wrn-dropdown[data-placement] .wrn-dropdown__panel"); + expect(source("Dropdown")).toContain( + '.wrn-dropdown[data-placement][data-mobile-panel="sheet"] .wrn-dropdown__panel', + ); expect(source("Footer")).toMatch(/\.wrn-footer__copyright-left\s*\{\s*grid-column: 1;/); expect(source("Footer")).toMatch(/\.wrn-footer__copyright-right\s*\{\s*grid-column: 3;/); });