From 29aef69f00906a7ef973bd68df7a56c7a212206f Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sun, 7 Jun 2026 14:49:30 +0900 Subject: feat(tabs): polish new-chat button — stuck-only square edge, New Chat label MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - isStuckToEnd (pure): square the sticky '+' right edge only while it floats over scrolled tabs; rounded at rest. Edge-measured in TabBar via a disposed scroll + ResizeObserver effect (RO guarded for non-browser envs). - Show a temporary 'New Chat' title when the draft is selected, with the '+' moved to the trailing close-button slot for consistency with real tabs. --- src/features/tabs/ui.test.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/features/tabs/ui.test.ts') diff --git a/src/features/tabs/ui.test.ts b/src/features/tabs/ui.test.ts index 53df0be..1ae18c8 100644 --- a/src/features/tabs/ui.test.ts +++ b/src/features/tabs/ui.test.ts @@ -145,4 +145,34 @@ describe("TabBar", () => { const newChat = screen.getByRole("button", { name: "New chat" }); expect(newChat).toHaveClass("sticky"); }); + + it("shows visible 'New Chat' text when activeConversationId is null", () => { + render(TabBar, { + props: { + tabs: sampleTabs, + activeConversationId: null, + onSelect: vi.fn(), + onClose: vi.fn(), + onNewDraft: vi.fn(), + }, + }); + + const newChat = screen.getByRole("button", { name: "New chat" }); + expect(newChat).toHaveTextContent("New Chat"); + }); + + it("does not show 'New Chat' text when a real tab is active", () => { + render(TabBar, { + props: { + tabs: sampleTabs, + activeConversationId: "c1", + onSelect: vi.fn(), + onClose: vi.fn(), + onNewDraft: vi.fn(), + }, + }); + + const newChat = screen.getByRole("button", { name: "New chat" }); + expect(newChat).not.toHaveTextContent("New Chat"); + }); }); -- cgit v1.2.3