fix(vscode): preserve activity colors in selected and portalled views

This commit is contained in:
marius-kilocode
2026-08-27 13:16:50 +02:00
parent f293ecbba8
commit cdcf69e0d8
4 changed files with 92 additions and 33 deletions
@@ -160,22 +160,30 @@ html[data-theme="kilo-vscode"]
flex-shrink: 0;
}
[data-activity="waiting"] [data-component="icon"],
[data-activity="waiting"] [data-slot="icon-svg"],
.am-sidebar-search-status[data-activity="waiting"] {
color: var(--icon-warning-base, var(--vscode-notificationsWarningIcon-foreground, #d9a13a));
:is(
.am-tab-icon,
.am-wt-icon,
.am-local-status,
.search-menu-icon,
.am-sidebar-search-status
)[data-activity="waiting"] {
--icon-base: var(--icon-warning-base, var(--vscode-notificationsWarningIcon-foreground, #d9a13a));
color: var(--icon-base);
}
[data-activity="error"] [data-component="icon"],
[data-activity="error"] [data-slot="icon-svg"],
.am-sidebar-search-status[data-activity="error"] {
color: var(--icon-critical-base, var(--vscode-errorForeground, #f14c4c));
:is(.am-tab-icon, .am-wt-icon, .am-local-status, .search-menu-icon, .am-sidebar-search-status)[data-activity="error"] {
--icon-base: var(--icon-critical-base, var(--vscode-errorForeground, #f14c4c));
color: var(--icon-base);
}
[data-activity="done"] [data-component="icon"],
[data-activity="done"] [data-slot="icon-svg"],
.am-sidebar-search-status[data-activity="done"] {
color: var(--icon-success-base, var(--vscode-testing-iconPassed, #73c991));
:is(.am-tab-icon, .am-wt-icon, .am-local-status, .search-menu-icon, .am-sidebar-search-status)[data-activity="done"] {
--icon-base: var(--icon-success-base, var(--vscode-testing-iconPassed, #73c991));
color: var(--icon-base);
}
:is(.am-tab-icon, .am-wt-icon, .am-local-status, .search-menu-icon)[data-activity]:not([data-activity="idle"])
[data-component="icon"] {
color: var(--icon-base);
}
.am-local-text {
@@ -10,6 +10,7 @@ import { FileTree } from "../../diff-viewer/FileTree"
import { DiffPanel } from "../../agent-manager/DiffPanel"
import { FullScreenDiffView } from "../../diff-viewer/FullScreenDiffView"
import { WorktreeItem } from "../../agent-manager/WorktreeItem"
import { SessionTab } from "../components/chat/SessionTab"
import { ChatView } from "../components/chat/ChatView"
import { registerVscodeToolOverrides } from "../components/chat/VscodeToolOverrides"
import { SessionContext } from "../context/session"
@@ -566,24 +567,22 @@ const defaultProps = {
// WorktreeItem stories
// ---------------------------------------------------------------------------
const activityStates = [
["busy", "Running"],
["waiting", "Needs input"],
["done", "Completed"],
["retry", "Retrying"],
["error", "Error"],
["idle", "Idle"],
] as const
export const WorktreeActivityStates: Story = {
name: "Worktree cards - all activity states",
render: () => (
render: (args: { active?: boolean }) => (
<StoryProviders noPadding>
<div data-activity-story style={{ padding: "12px", background: "var(--surface-base)" }}>
<style>{'[data-activity-story] [data-component="spinner"] rect { animation: none !important; }'}</style>
<For
each={
[
["busy", "Running"],
["waiting", "Needs input"],
["done", "Completed"],
["retry", "Retrying"],
["error", "Error"],
["idle", "Idle"],
] as const
}
>
<For each={activityStates}>
{([state, title]) => (
<WorktreeItem
{...defaultProps}
@@ -595,6 +594,7 @@ export const WorktreeActivityStates: Story = {
}}
label={title}
subtitle={`feature/${state}`}
active={args.active === true}
activity={state}
stats={{ ...baseStats, worktreeId: `wt-${state}` }}
shortcut={0}
@@ -606,6 +606,42 @@ export const WorktreeActivityStates: Story = {
),
}
export const WorktreeActivityStatesActive: Story = {
...WorktreeActivityStates,
name: "Worktree cards - selected activity states",
args: { active: true },
}
export const SessionTabActivityStates: Story = {
name: "Agent Manager session tabs - activity states",
render: () => (
<StoryProviders noPadding>
<div data-activity-story style={{ padding: "12px", background: "var(--surface-base)" }}>
<style>{'[data-activity-story] [data-component="spinner"] rect { animation: none !important; }'}</style>
<For each={activityStates}>
{([state, title]) => (
<div class="am-tab-bar" role="tablist" aria-label={title}>
<SessionTab
title={title}
active
state={state}
stateLabel={title}
closeTitle="Close tab"
closeLabel="Close tab"
role="tab"
selected
onSelect={noop}
onMiddleClick={noop}
onClose={noop}
/>
</div>
)}
</For>
</div>
</StoryProviders>
),
}
export const WorktreeItemDefault: Story = {
name: "WorktreeItem — default",
render: () => (
@@ -24,6 +24,22 @@ const rows = [
stateLabel: "Running",
pending: false,
},
{
id: "waiting",
title: "Approve a pending command",
active: false,
state: "waiting" as const,
stateLabel: "Needs input",
pending: false,
},
{
id: "error",
title: "Review the failed session",
active: false,
state: "error" as const,
stateLabel: "Error",
pending: false,
},
{
id: "pending",
title: "Untitled session",
@@ -124,7 +140,7 @@ export const SwitcherOpen: Story = {
<div
style={{
display: "flex",
"min-height": "420px",
"min-height": "560px",
"justify-content": "flex-end",
"align-items": "flex-start",
padding: "16px",
@@ -146,7 +162,6 @@ export const SwitcherOpen: Story = {
onRestore={focus}
onClose={noop}
defaultOpen
portal={false}
/>
</div>
</div>
@@ -178,22 +178,22 @@
}
.session-tab-bar .am-tab-icon[data-activity="waiting"],
.session-tab-bar .search-menu-icon[data-activity="waiting"],
.session-tab-bar .session-tab-switcher-meta[data-activity="waiting"] {
.session-tab-switcher-popover .search-menu-icon[data-activity="waiting"],
.session-tab-switcher-popover .session-tab-switcher-meta[data-activity="waiting"] {
--icon-base: var(--icon-warning-base);
color: var(--icon-warning-base);
}
.session-tab-bar .am-tab-icon[data-activity="error"],
.session-tab-bar .search-menu-icon[data-activity="error"],
.session-tab-bar .session-tab-switcher-meta[data-activity="error"] {
.session-tab-switcher-popover .search-menu-icon[data-activity="error"],
.session-tab-switcher-popover .session-tab-switcher-meta[data-activity="error"] {
--icon-base: var(--icon-critical-base);
color: var(--icon-critical-base);
}
.session-tab-bar .am-tab-icon[data-activity="done"],
.session-tab-bar .search-menu-icon[data-activity="done"],
.session-tab-bar .session-tab-switcher-meta[data-activity="done"] {
.session-tab-switcher-popover .search-menu-icon[data-activity="done"],
.session-tab-switcher-popover .session-tab-switcher-meta[data-activity="done"] {
--icon-base: var(--icon-success-base);
color: var(--icon-success-base);
}