From bd14186214724d7689274bac81f8bbb03fba3c7c Mon Sep 17 00:00:00 2001 From: morgmart <98432065+morgmart@users.noreply.github.com> Date: Thu, 16 Apr 2026 12:28:32 -0700 Subject: [PATCH] polish: refine sidebar activity indicators, add placeholder token, and tidy search field (#8606) Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com> --- ui/goose2/src/features/sidebar/ui/Sidebar.tsx | 63 ++++++++----------- .../features/sidebar/ui/SidebarChatRow.tsx | 10 ++- .../ui/__tests__/SidebarChatRow.test.tsx | 31 +++++++++ ui/goose2/src/shared/styles/globals.css | 4 ++ .../ui/SessionActivityIndicator.test.tsx | 13 ++-- .../shared/ui/SessionActivityIndicator.tsx | 25 +++++--- ui/goose2/src/shared/ui/command.tsx | 2 +- ui/goose2/src/shared/ui/input.tsx | 2 +- ui/goose2/src/shared/ui/textarea.tsx | 2 +- 9 files changed, 95 insertions(+), 57 deletions(-) diff --git a/ui/goose2/src/features/sidebar/ui/Sidebar.tsx b/ui/goose2/src/features/sidebar/ui/Sidebar.tsx index 56dae4b7..7f09bff3 100644 --- a/ui/goose2/src/features/sidebar/ui/Sidebar.tsx +++ b/ui/goose2/src/features/sidebar/ui/Sidebar.tsx @@ -315,7 +315,7 @@ export function Sidebar({ collapsed ? "justify-center" : "justify-between", )} > - + {!collapsed && ( diff --git a/ui/goose2/src/features/sidebar/ui/__tests__/SidebarChatRow.test.tsx b/ui/goose2/src/features/sidebar/ui/__tests__/SidebarChatRow.test.tsx index bd81f815..29c8a067 100644 --- a/ui/goose2/src/features/sidebar/ui/__tests__/SidebarChatRow.test.tsx +++ b/ui/goose2/src/features/sidebar/ui/__tests__/SidebarChatRow.test.tsx @@ -108,6 +108,37 @@ describe("SidebarChatRow", () => { expect(screen.getByLabelText(/unread messages/i)).toBeInTheDocument(); }); + it("does not reserve activity space by default when idle", () => { + const { container } = render( + , + ); + + expect( + container.querySelector(".h-3.w-3.shrink-0.items-center.justify-center"), + ).toBeNull(); + }); + + it("reserves activity space only once activity exists", () => { + const { container, rerender } = render( + , + ); + + expect( + container.querySelector(".h-3.w-3.shrink-0.items-center.justify-center"), + ).toBeNull(); + + rerender( + , + ); + + expect(screen.getByLabelText(/unread messages/i)).toBeInTheDocument(); + }); + it("keeps the localized default title in rename mode without persisting it", async () => { const user = userEvent.setup(); const onRename = vi.fn(); diff --git a/ui/goose2/src/shared/styles/globals.css b/ui/goose2/src/shared/styles/globals.css index 9f7216a2..d1fffb34 100644 --- a/ui/goose2/src/shared/styles/globals.css +++ b/ui/goose2/src/shared/styles/globals.css @@ -122,6 +122,7 @@ --text-success: var(--color-green-300); --text-warning: var(--color-yellow-200); --text-info: var(--color-blue-200); + --text-placeholder: var(--color-gray-400); --ring: color-mix(in srgb, var(--border-strong) 20%, transparent); @@ -304,6 +305,7 @@ --text-success: var(--color-green-100); --text-warning: var(--color-yellow-100); --text-info: var(--color-blue-100); + --text-placeholder: var(--color-gray-600); --ring: color-mix(in srgb, var(--border-strong) 20%, transparent); @@ -356,6 +358,7 @@ --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); + --color-placeholder: var(--text-placeholder); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); @@ -407,6 +410,7 @@ --color-text-success: var(--text-success); --color-text-warning: var(--text-warning); --color-text-info: var(--text-info); + --color-text-placeholder: var(--text-placeholder); /* alpha variants */ --color-dark-10: var(--dark-10); diff --git a/ui/goose2/src/shared/ui/SessionActivityIndicator.test.tsx b/ui/goose2/src/shared/ui/SessionActivityIndicator.test.tsx index 2999424b..818f0497 100644 --- a/ui/goose2/src/shared/ui/SessionActivityIndicator.test.tsx +++ b/ui/goose2/src/shared/ui/SessionActivityIndicator.test.tsx @@ -3,25 +3,22 @@ import { describe, expect, it } from "vitest"; import { SessionActivityIndicator } from "./SessionActivityIndicator"; describe("SessionActivityIndicator", () => { - it("renders a brand-colored inline spinner for running sessions", () => { + it("renders an inline spinner for running sessions", () => { render(); - expect(screen.getByLabelText(/chat active/i)).toHaveClass("text-brand"); + expect(screen.getByLabelText(/chat active/i)).toBeInTheDocument(); }); - it("renders a brand-colored inline dot for unread sessions", () => { + it("renders an inline dot for unread sessions", () => { render(); - expect(screen.getByLabelText(/unread messages/i)).toHaveClass("bg-brand"); + expect(screen.getByLabelText(/unread messages/i)).toBeInTheDocument(); }); it("renders an overlay spinner variant for running sessions", () => { - const { container } = render( - , - ); + render(); expect(screen.getByLabelText(/chat active/i)).toBeInTheDocument(); - expect(container.querySelector(".text-brand")).toBeTruthy(); }); it("renders nothing when the session is idle and read", () => { diff --git a/ui/goose2/src/shared/ui/SessionActivityIndicator.tsx b/ui/goose2/src/shared/ui/SessionActivityIndicator.tsx index a18a1b10..854c0b90 100644 --- a/ui/goose2/src/shared/ui/SessionActivityIndicator.tsx +++ b/ui/goose2/src/shared/ui/SessionActivityIndicator.tsx @@ -21,24 +21,32 @@ export function SessionActivityIndicator({ role="status" aria-label="Chat active" className={cn( - "absolute -right-1 -top-1 flex h-3.5 w-3.5 items-center justify-center rounded-full border border-background bg-background shadow-sm", + "absolute -right-1 -top-1 flex h-3.5 w-3.5 items-center justify-center rounded-full border border-background bg-background shadow-sm transition-opacity duration-200 ease-out animate-in fade-in-0", className, )} >