From b4a6569d0d3fdc1de4d86ed7fdf1e5682b063ea2 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Fri, 25 Sep 2026 01:40:45 +0200 Subject: [PATCH] fix(design): the saved-view chip on one line, one Escape per layer, the /watch action row (E28 S3d) - SelectTrigger lays its toolbar value out as a row; the saved-view chip passes its glyph and modified dot through the icon/trailing slots (an is display:block and broke the chip in two). - One Escape in a dialog's open list closed the list AND the dialog: the list's close flushes synchronously and pops its layer before the dialog's window listener runs. takeEscape() is the one close-on-Escape test (topmost AND not yet taken); Modal, the Welcome lightbox and useLayer use it, and keymap.dispatch ignores a taken Escape. - /watch: the Download sits on the toolbar rung, level with the Repeat chip. --- .../components/SavedViewsPopover.dom.test.tsx | 21 +++++++++ frontend/src/components/SavedViewsPopover.tsx | 7 +++ frontend/src/components/SelectedViewChip.tsx | 22 +++++----- .../src/components/WatchPage.dom.test.tsx | 19 ++++++++ frontend/src/components/WatchPage.tsx | 3 +- frontend/src/components/Welcome.tsx | 4 +- frontend/src/components/ui/Modal.dom.test.tsx | 43 ++++++++++++++++++- frontend/src/components/ui/Modal.tsx | 4 +- frontend/src/components/ui/SelectTrigger.tsx | 12 +++++- frontend/src/lib/keymap.test.ts | 11 +++++ frontend/src/lib/keymap.ts | 5 ++- frontend/src/lib/layerStack.ts | 19 +++++--- 12 files changed, 144 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/SavedViewsPopover.dom.test.tsx b/frontend/src/components/SavedViewsPopover.dom.test.tsx index 4de6ad92..1cbc9685 100644 --- a/frontend/src/components/SavedViewsPopover.dom.test.tsx +++ b/frontend/src/components/SavedViewsPopover.dom.test.tsx @@ -49,3 +49,24 @@ describe("SavedViewsPopover · Manage views…", () => { await vi.waitFor(() => expect(openModal).toHaveBeenCalledTimes(1)); }); }); + +// E28: the toolbar chip's glyph sat INSIDE the value text, and an is display:block under the +// preflight, so the chip broke onto two lines (the bookmark above "gaming ▾"). The glyph and the +// modified dot ride in the trigger's own slots; the value is a row. +describe("SavedViewsPopover · toolbar chip", () => { + it("puts the glyph in the trigger's icon slot, not inside the value", () => { + render( + + } + trigger={gaming} + ariaLabel="View chip" + /> + , + ); + const button = screen.getByRole("button", { name: "View chip" }); + expect(screen.getByTestId("glyph").parentElement).toBe(button); + expect(screen.getByText("gaming").parentElement!.className).toContain("flex"); + }); +}); diff --git a/frontend/src/components/SavedViewsPopover.tsx b/frontend/src/components/SavedViewsPopover.tsx index a4b15732..c372fd20 100644 --- a/frontend/src/components/SavedViewsPopover.tsx +++ b/frontend/src/components/SavedViewsPopover.tsx @@ -14,12 +14,17 @@ import { SelectTrigger } from "./ui/SelectTrigger"; export default function SavedViewsPopover({ trigger, toolbar = false, + icon, + trailing, ariaLabel, placement = "bottom-start", }: { trigger: ReactNode; /** The toolbar's view chip: the A5 dropdown trigger around `trigger`, instead of a glyph. */ toolbar?: boolean; + /** Toolbar only: the trigger's leading glyph and its after-the-value mark, in their own slots. */ + icon?: ReactNode; + trailing?: ReactNode; ariaLabel?: string; placement?: "bottom-start" | "bottom-end"; }) { @@ -34,6 +39,8 @@ export default function SavedViewsPopover({ -