mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
Prevent memory activity from clashing with desktop themes
Memory tool activity inherited the global warm brand treatment, which made the new desktop memory surface feel detached from white and dark themes. The component now uses memory-specific tokens with a quieter teal family, and the sidebar settings dock is made opaque so scrolling sessions cannot show through it. Constraint: Desktop memory activity must remain readable across light, white, and dark themes without reusing the classic warm brand surface Rejected: Keep using color-mix with --color-brand | preserves the original warm tint mismatch in white theme Confidence: high Scope-risk: narrow Directive: Keep memory activity colors on memory-specific tokens instead of generic brand tokens Tested: cd desktop && bun run test src/components/chat/MessageList.test.tsx --run Tested: cd desktop && bun run test src/components/layout/Sidebar.test.tsx --run Tested: cd desktop && bun run lint Tested: cd desktop && bun run build Tested: Browser smoke screenshots for light, white, and dark memory activity previews
This commit is contained in:
parent
e070c4a0d0
commit
667b86303f
@ -264,6 +264,9 @@ describe('MessageList nested tool calls', () => {
|
||||
expect(screen.getByText('Saved 1 memory item(s)')).toBeTruthy()
|
||||
expect(screen.getByText('preferences.md')).toBeTruthy()
|
||||
expect(screen.getByText('Tool details')).toBeTruthy()
|
||||
const memoryCardClassName = screen.getByTestId('memory-tool-activity-card').className
|
||||
expect(memoryCardClassName).toContain('border-[var(--color-memory-border)]')
|
||||
expect(memoryCardClassName).toContain('bg-[var(--color-memory-surface)]')
|
||||
})
|
||||
|
||||
it('promotes memory file reads into collapsible memory references', () => {
|
||||
|
||||
@ -195,7 +195,10 @@ function MemoryToolActivityGroup({
|
||||
|
||||
return (
|
||||
<div className="mb-2">
|
||||
<div className="overflow-hidden rounded-lg border border-[color-mix(in_srgb,var(--color-brand)_22%,var(--color-border))] bg-[color-mix(in_srgb,var(--color-brand)_6%,var(--color-surface-container-lowest))]">
|
||||
<div
|
||||
data-testid="memory-tool-activity-card"
|
||||
className="overflow-hidden rounded-lg border border-[var(--color-memory-border)] bg-[var(--color-memory-surface)]"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setExpanded((value) => !value)}
|
||||
@ -206,12 +209,12 @@ function MemoryToolActivityGroup({
|
||||
) : (
|
||||
<ChevronRight size={15} className="shrink-0 text-[var(--color-text-tertiary)]" aria-hidden="true" />
|
||||
)}
|
||||
<BookMarked size={15} className="shrink-0 text-[var(--color-brand)]" aria-hidden="true" />
|
||||
<BookMarked size={15} className="shrink-0 text-[var(--color-memory-accent)]" aria-hidden="true" />
|
||||
<span className="min-w-0 flex-1 truncate text-[13px] font-medium text-[var(--color-text-primary)]">
|
||||
{t(titleKey, { count: activity.files.length })}
|
||||
</span>
|
||||
{isStreaming ? (
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[var(--color-brand)] animate-pulse-dot" />
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[var(--color-memory-accent)] animate-pulse-dot" />
|
||||
) : null}
|
||||
</button>
|
||||
|
||||
@ -226,7 +229,7 @@ function MemoryToolActivityGroup({
|
||||
onClick={() => openMemorySettings(file.path)}
|
||||
className="group flex w-full items-start gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-[var(--color-surface-hover)] focus:outline-none focus-visible:shadow-[var(--shadow-focus-ring)]"
|
||||
>
|
||||
<span className="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-sm border border-[var(--color-border)] bg-[var(--color-surface)] text-[var(--color-text-tertiary)] group-hover:text-[var(--color-brand)]">
|
||||
<span className="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-sm border border-[var(--color-memory-border)] bg-[var(--color-memory-icon-bg)] text-[var(--color-text-tertiary)] group-hover:text-[var(--color-memory-accent)]">
|
||||
<Settings size={12} aria-hidden="true" />
|
||||
</span>
|
||||
<span className="min-w-0 flex-1">
|
||||
|
||||
@ -348,6 +348,13 @@ describe('Sidebar', () => {
|
||||
expect(screen.getByTestId('sidebar-session-list-section')).toHaveClass('flex', 'flex-1', 'min-h-0', 'flex-col')
|
||||
})
|
||||
|
||||
it('keeps the settings dock opaque above the scrolling session list', () => {
|
||||
render(<Sidebar />)
|
||||
|
||||
expect(screen.getByTestId('sidebar-settings-dock')).toHaveClass('sidebar-settings-dock')
|
||||
expect(screen.getByTestId('sidebar-settings-dock')).toHaveClass('absolute', 'bottom-0')
|
||||
})
|
||||
|
||||
it('keeps mobile navigation focused on chat sessions', async () => {
|
||||
const onRequestClose = vi.fn()
|
||||
createSession.mockResolvedValue('session-mobile-new')
|
||||
|
||||
@ -593,7 +593,10 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
|
||||
)}
|
||||
|
||||
{!isMobile && (
|
||||
<div className={`absolute bottom-0 left-0 right-0 border-t border-[var(--color-border)] p-3 ${expanded ? '' : 'flex justify-center'}`}>
|
||||
<div
|
||||
data-testid="sidebar-settings-dock"
|
||||
className={`sidebar-settings-dock absolute bottom-0 left-0 right-0 border-t border-[var(--color-border)] p-3 ${expanded ? '' : 'flex justify-center'}`}
|
||||
>
|
||||
<NavItem
|
||||
active={activeTabId === SETTINGS_TAB_ID}
|
||||
collapsed={!expanded}
|
||||
|
||||
@ -177,6 +177,10 @@
|
||||
--color-surface-sidebar: var(--color-surface-container-low);
|
||||
--color-surface-hover: var(--color-surface-container-high);
|
||||
--color-surface-selected: var(--color-surface-container);
|
||||
--color-memory-accent: #3B7068;
|
||||
--color-memory-surface: color-mix(in srgb, var(--color-memory-accent) 7%, var(--color-surface-container-lowest));
|
||||
--color-memory-border: color-mix(in srgb, var(--color-memory-accent) 26%, var(--color-border));
|
||||
--color-memory-icon-bg: color-mix(in srgb, var(--color-memory-accent) 10%, var(--color-surface-container-lowest));
|
||||
--color-model-option-selected-bg: var(--color-primary-fixed);
|
||||
--color-model-option-selected-border: rgba(143, 72, 47, 0.2);
|
||||
--color-activity-heat-0: var(--color-surface-container);
|
||||
@ -374,6 +378,10 @@
|
||||
--color-surface-sidebar: #F1F4F7;
|
||||
--color-surface-hover: #F2F5F8;
|
||||
--color-surface-selected: #E9EEF3;
|
||||
--color-memory-accent: #0F766E;
|
||||
--color-memory-surface: color-mix(in srgb, var(--color-memory-accent) 5%, #FFFFFF);
|
||||
--color-memory-border: color-mix(in srgb, var(--color-memory-accent) 24%, var(--color-border));
|
||||
--color-memory-icon-bg: color-mix(in srgb, var(--color-memory-accent) 8%, #FFFFFF);
|
||||
--color-model-option-selected-bg: #FFF0EA;
|
||||
--color-model-option-selected-border: rgba(143, 72, 47, 0.2);
|
||||
--color-activity-heat-0: #EEF2F6;
|
||||
@ -548,6 +556,10 @@
|
||||
--color-surface-sidebar: #171615;
|
||||
--color-surface-hover: var(--color-surface-container-highest);
|
||||
--color-surface-selected: var(--color-surface-container);
|
||||
--color-memory-accent: #7DD3C7;
|
||||
--color-memory-surface: color-mix(in srgb, var(--color-memory-accent) 9%, var(--color-surface-container-lowest));
|
||||
--color-memory-border: color-mix(in srgb, var(--color-memory-accent) 26%, var(--color-border));
|
||||
--color-memory-icon-bg: color-mix(in srgb, var(--color-memory-accent) 12%, var(--color-surface-container-lowest));
|
||||
--color-model-option-selected-bg: rgba(255, 181, 159, 0.13);
|
||||
--color-model-option-selected-border: rgba(255, 181, 159, 0.34);
|
||||
--color-activity-heat-0: #242322;
|
||||
@ -967,10 +979,19 @@ button, input, textarea, select, a, [role="button"] {
|
||||
::-webkit-scrollbar-thumb:hover { opacity: 0.6; }
|
||||
|
||||
.sidebar-scroll-area {
|
||||
padding-bottom: 72px;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--color-outline-a72) transparent;
|
||||
}
|
||||
|
||||
.sidebar-settings-dock {
|
||||
z-index: 30;
|
||||
background-color: var(--color-surface-sidebar);
|
||||
background-image: var(--sidebar-panel-bg-image);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
}
|
||||
|
||||
.sidebar-scroll-area::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user