From 7b09bdcc18da4ac99d1a43527fc223f8a7856472 Mon Sep 17 00:00:00 2001 From: morgmart <98432065+morgmart@users.noreply.github.com> Date: Thu, 2 Apr 2026 10:45:08 -0700 Subject: [PATCH] add project colors and icon support to chat input toolbar (#83) * feat(chat): enhance chat input components with project color and icon support - Added optional `color` property to `ProjectOption` interface for project color representation. - Updated `ChatInputSelectorItem` to include an optional `icon` property for enhanced item display. - Introduced `ProjectDot` component in `ChatInputToolbar` to visually represent project colors. - Modified `ChatView` and `HomeScreen` to utilize the new `color` property for projects. - Improved button components to support left and right icons for better UI flexibility. * fix: apply biome formatting and guard asChild against icon props --- ui/goose2/src/features/chat/ui/ChatInput.tsx | 1 + .../features/chat/ui/ChatInputSelector.tsx | 10 +- .../src/features/chat/ui/ChatInputToolbar.tsx | 174 +++++++++--------- ui/goose2/src/features/chat/ui/ChatView.tsx | 1 + .../src/features/chat/ui/PersonaPicker.tsx | 8 +- ui/goose2/src/features/home/ui/HomeScreen.tsx | 1 + ui/goose2/src/shared/ui/AGENTS.md | 51 +++++ ui/goose2/src/shared/ui/button.tsx | 88 +++++++-- 8 files changed, 231 insertions(+), 103 deletions(-) create mode 100644 ui/goose2/src/shared/ui/AGENTS.md diff --git a/ui/goose2/src/features/chat/ui/ChatInput.tsx b/ui/goose2/src/features/chat/ui/ChatInput.tsx index 049c410a9b..6e6e388e94 100644 --- a/ui/goose2/src/features/chat/ui/ChatInput.tsx +++ b/ui/goose2/src/features/chat/ui/ChatInput.tsx @@ -33,6 +33,7 @@ export interface ProjectOption { id: string; name: string; workingDir?: string | null; + color?: string | null; } interface ChatInputProps { diff --git a/ui/goose2/src/features/chat/ui/ChatInputSelector.tsx b/ui/goose2/src/features/chat/ui/ChatInputSelector.tsx index 458978c100..180db6fedc 100644 --- a/ui/goose2/src/features/chat/ui/ChatInputSelector.tsx +++ b/ui/goose2/src/features/chat/ui/ChatInputSelector.tsx @@ -16,6 +16,7 @@ export interface ChatInputSelectorItem { value: string; label: string; description?: string; + icon?: ReactNode; disabled?: boolean; } @@ -65,14 +66,14 @@ export function ChatInputSelector({ aria-label={ariaLabel} title={triggerTitle} disabled={disabled} + leftIcon={icon} + rightIcon={} className={cn( "min-w-0", triggerVariant === "default" && "justify-between", )} > - {icon} {triggerLabel} - onValueChange(item.value)} - className="items-start justify-between" + className="gap-2 items-start justify-between" > + {item.icon ? ( + {item.icon} + ) : null}
{item.label} diff --git a/ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx b/ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx index d621b6719c..f677d62849 100644 --- a/ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx +++ b/ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx @@ -4,6 +4,7 @@ import { ChevronDown, Check, ArrowUp, + Sparkles, Square, } from "lucide-react"; import type { AcpProvider } from "@/shared/api/acp"; @@ -28,6 +29,19 @@ const NO_PROJECT_VALUE = "__no_project__"; const CREATE_PROJECT_VALUE = "__create_project__"; const CREATE_PROJECT_FROM_FOLDER_VALUE = "__create_project_from_folder__"; +function ProjectDot({ color }: { color?: string | null }) { + return ( +
{/* Right side: actions */} -
- {personas.length > 0 && ( - onPersonaChange?.(id)} - onCreatePersona={onCreatePersona} - triggerVariant="icon" - /> - )} +
+
+ {personas.length > 0 && ( + onPersonaChange?.(id)} + onCreatePersona={onCreatePersona} + triggerVariant="icon" + /> + )} - {contextLimit > 0 && ( - - - - - - {contextTokens.toLocaleString()} / {contextLimit.toLocaleString()}{" "} - tokens - - - )} - - - + {contextLimit > 0 && ( - - Voice input (coming soon) - + )} - - - - - Attach file - - - {isStreaming ? ( - ) : ( - - )} + + + + + + + + Voice input (coming soon) + +
+ +
+ {isStreaming ? ( + + ) : ( + + )} +
); diff --git a/ui/goose2/src/features/chat/ui/ChatView.tsx b/ui/goose2/src/features/chat/ui/ChatView.tsx index 1ddf1c83aa..7c3c262d67 100644 --- a/ui/goose2/src/features/chat/ui/ChatView.tsx +++ b/ui/goose2/src/features/chat/ui/ChatView.tsx @@ -84,6 +84,7 @@ export function ChatView({ id: projectInfo.id, name: projectInfo.name, workingDir: projectInfo.workingDirs[0] ?? null, + color: projectInfo.color, })), [projects], ); diff --git a/ui/goose2/src/features/chat/ui/PersonaPicker.tsx b/ui/goose2/src/features/chat/ui/PersonaPicker.tsx index fde73e2d87..8620281c80 100644 --- a/ui/goose2/src/features/chat/ui/PersonaPicker.tsx +++ b/ui/goose2/src/features/chat/ui/PersonaPicker.tsx @@ -59,13 +59,11 @@ export function PersonaPicker({ type="button" variant="ghost" size="icon-sm" - className={cn( - "rounded-lg text-foreground-secondary hover:bg-background-tertiary hover:text-foreground", - className, - )} + className={className} aria-label="Choose assistant" + title="Choose assistant" > - + ) : (