diff options
| author | Adam Malczewski <[email protected]> | 2026-10-15 14:48:19 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-10-15 14:48:19 +0900 |
| commit | c23aa41d1ffa71ac905da8ac9488b07322327695 (patch) | |
| tree | 1b8ca4699b991e462093c287bb40164cff6de76f /src | |
| parent | c4c1d76fec972e5d902a669f0cb1953eaa528f16 (diff) | |
| download | dispatch-web-c23aa41d1ffa71ac905da8ac9488b07322327695.tar.gz dispatch-web-c23aa41d1ffa71ac905da8ac9488b07322327695.zip | |
fix(tabs): even group-box padding on all sides + 50% black background; test parent reverts to half width when its subagents close
Diffstat (limited to 'src')
| -rw-r--r-- | src/features/tabs/ui.test.ts | 58 | ||||
| -rw-r--r-- | src/features/tabs/ui/TabGroupBox.svelte | 7 |
2 files changed, 59 insertions, 6 deletions
diff --git a/src/features/tabs/ui.test.ts b/src/features/tabs/ui.test.ts index 7c8b0db..49d70f2 100644 --- a/src/features/tabs/ui.test.ts +++ b/src/features/tabs/ui.test.ts @@ -371,11 +371,63 @@ describe("TabList", () => { expect(inner?.contains(card("g"))).toBe(true); // Inner boxes bleed less than outer ones, so nested edges stay visible // while the cards keep identical widths. - const pad = (el: HTMLElement | null) => el?.style.getPropertyValue("padding-inline") ?? ""; - const bleed = (el: HTMLElement | null) => Number.parseFloat(pad(el)); + const bleed = (el: HTMLElement | null) => Number.parseFloat(el?.style.paddingLeft ?? ""); expect(bleed(inner)).toBeGreaterThan(0); expect(bleed(outer)).toBeGreaterThan(bleed(inner)); - expect(outer?.style.getPropertyValue("margin-inline")).toBe(`-${pad(outer)}`); + // Equal internal padding on all four sides (an even-looking box). + for (const box of [outer, inner]) { + const s = box?.style; + expect([s?.paddingTop, s?.paddingRight, s?.paddingBottom]).toEqual([ + s?.paddingLeft, + s?.paddingLeft, + s?.paddingLeft, + ]); + expect(box).toHaveClass("bg-black/50"); + } + expect(outer?.style.getPropertyValue("margin-inline")).toBe(`-${outer?.style.paddingLeft}`); + }); + + it("returns the group parent to a half-width card once all its subagent tabs close", async () => { + const props = { + tabs: grouped, + activeConversationId: "p", + onSelect: vi.fn(), + onClose: vi.fn(), + onNewDraft: vi.fn(), + onSetTabGroup: vi.fn(), + }; + const { rerender } = render(TabList, { props }); + expect(card("p")).toHaveClass("col-span-2"); + + // Close one subagent: still a group (1 left). + await rerender({ ...props, tabs: grouped.filter((t) => t.conversationId !== "c2") }); + expect(card("p")).toHaveClass("col-span-2"); + expect(card("p")).toHaveTextContent("1 subagent"); + + // Close the rest (c1 + its own subagent g): back to a plain half-width card. + await rerender({ + ...props, + tabs: grouped.filter((t) => ["p", "solo"].includes(t.conversationId)), + }); + expect(card("p")).not.toHaveClass("col-span-2"); + expect(card("p")).not.toHaveTextContent("subagent"); + expect(document.querySelector("[data-tab-group]")).toBeNull(); + }); + + it("keeps the parent wide while a nested descendant's own parent remains open", async () => { + const props = { + tabs: grouped, + activeConversationId: "p", + onSelect: vi.fn(), + onClose: vi.fn(), + onNewDraft: vi.fn(), + }; + const { rerender } = render(TabList, { props }); + // Close the grandchild only: c1 goes back to half width, p stays a group. + await rerender({ ...props, tabs: grouped.filter((t) => t.conversationId !== "g") }); + expect(card("c1")).not.toHaveClass("col-span-2"); + expect(document.querySelector('[data-tab-group="c1"]')).toBeNull(); + expect(card("p")).toHaveClass("col-span-2"); }); it("right-click opens the menu; 'Remove from group' ungroups the tab", async () => { diff --git a/src/features/tabs/ui/TabGroupBox.svelte b/src/features/tabs/ui/TabGroupBox.svelte index 5cbfb27..0bf3ad2 100644 --- a/src/features/tabs/ui/TabGroupBox.svelte +++ b/src/features/tabs/ui/TabGroupBox.svelte @@ -11,7 +11,8 @@ * a subagent with its own subagents renders a nested box. The box BLEEDS * outward (negative margin + equal padding, `groupBleedPx`) so the cards * inside stay on the same two columns as top-level cards: every card keeps - * identical dimensions at every depth. The translucent black background + * identical dimensions at every depth. The padding is EQUAL on all four + * sides (= the bleed) so the box looks even. The 50%-black background * compounds, so each nesting level reads darker than the one around it. */ let { @@ -32,9 +33,9 @@ </script> <div - class="col-span-2 rounded-lg border border-black/50 bg-black/40 py-1.5 shadow-inner" + class="col-span-2 rounded-lg bg-black/50" style:margin-inline="-{bleed}px" - style:padding-inline="{bleed}px" + style:padding="{bleed}px" role="group" aria-label={`Subagents of ${node.tab.title}`} data-tab-group={node.tab.conversationId} |
