Fix workspace sidebar appearance setting (#5725)

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo Hong
2026-06-18 12:10:27 -07:00
committed by GitHub
co-authored by Orca
parent 99bc04609d
commit 93345e331b
2 changed files with 126 additions and 1 deletions
@@ -0,0 +1,115 @@
import type { CSSProperties, ReactNode } from 'react'
import { renderToStaticMarkup } from 'react-dom/server'
import { describe, expect, it, vi } from 'vitest'
import { getDefaultSettings } from '../../../../shared/constants'
import type { GlobalSettings } from '../../../../shared/types'
const mocks = vi.hoisted(() => ({
state: {} as Record<string, unknown>
}))
vi.mock('@/store', () => ({
useAppStore: (selector: (state: Record<string, unknown>) => unknown) => selector(mocks.state)
}))
vi.mock('@/hooks/useSidebarResize', () => ({
useSidebarResize: () => ({
containerRef: { current: null },
isResizing: false,
onResizeStart: vi.fn()
})
}))
vi.mock('@/components/ui/tooltip', () => ({
TooltipProvider: ({ children }: { children: ReactNode }) => <>{children}</>
}))
vi.mock('./SidebarHeader', () => ({
default: () => <div data-testid="sidebar-header" />
}))
vi.mock('./SidebarNav', () => ({
default: () => <div data-testid="sidebar-nav" />
}))
vi.mock('./SetupScriptPromptCard', () => ({
default: () => <div data-testid="setup-script-prompt-card" />
}))
vi.mock('./WorktreeList', () => ({
default: () => <div data-testid="worktree-list" />
}))
vi.mock('./SidebarToolbar', () => ({
default: () => <div data-testid="sidebar-toolbar" />
}))
vi.mock('./WorkspaceKanbanDrawer', () => ({
default: ({ leftSidebarStyle }: { leftSidebarStyle?: CSSProperties }) => (
<div data-testid="workspace-kanban-drawer" style={leftSidebarStyle} />
)
}))
vi.mock('./useSidebarProjectDrop', () => ({
useSidebarProjectDrop: () => ({
nativeDropTarget: undefined,
dropHandlers: {},
affordance: { visible: false }
})
}))
vi.mock('./useWorkspaceBoardPanel', () => ({
useWorkspaceBoardPanel: () => ({
workspaceBoardOpen: false,
workspaceBoardRenderedOpen: true,
workspaceBoardDragPreviewOpen: false,
workspaceBoardMenuOpen: false,
toggleWorkspaceBoard: vi.fn(),
handleWorkspaceBoardOpenChange: vi.fn(),
setWorkspaceBoardMenuOpen: vi.fn(),
closeWorkspaceBoard: vi.fn(),
previewWorkspaceBoardFromDrag: vi.fn(),
solidifyWorkspaceBoardFromDrag: vi.fn(),
cancelWorkspaceBoardDragPreview: vi.fn()
})
}))
import Sidebar from './index'
function setSidebarState(settings: GlobalSettings): void {
mocks.state = {
activeModal: null,
fetchAllWorktrees: vi.fn(),
repos: [],
setSidebarWidth: vi.fn(),
settings,
sidebarOpen: true,
sidebarWidth: 320
}
}
function renderSidebar(): string {
return renderToStaticMarkup(
<Sidebar worktreeScrollOffsetRef={{ current: 0 }} worktreeScrollAnchorRef={{ current: null }} />
)
}
describe('Sidebar', () => {
it('applies left sidebar appearance variables to the workspace sidebar surface', () => {
setSidebarState({
...getDefaultSettings('/tmp'),
leftSidebarAppearanceMode: 'match-terminal',
terminalColorOverrides: {
background: '#101820',
foreground: '#f0f4f8'
}
})
const markup = renderSidebar()
expect(markup).toContain('--worktree-sidebar:#101820')
expect(markup).toContain('--worktree-sidebar-foreground:#f0f4f8')
expect(markup).toContain('data-testid="workspace-kanban-drawer"')
expect(markup.match(/--worktree-sidebar:#101820/g)).toHaveLength(2)
})
})
+11 -1
View File
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react'
import React, { useEffect, useMemo } from 'react'
import { useAppStore } from '@/store'
import { TooltipProvider } from '@/components/ui/tooltip'
import { useSidebarResize } from '@/hooks/useSidebarResize'
@@ -13,6 +13,8 @@ import { cn } from '@/lib/utils'
import { FolderPlus, Loader2 } from 'lucide-react'
import { useSidebarProjectDrop } from './useSidebarProjectDrop'
import { useWorkspaceBoardPanel } from './useWorkspaceBoardPanel'
import { resolveLeftSidebarStyleVariables } from '@/lib/left-sidebar-appearance'
import { useSystemPrefersDark } from '@/components/terminal-pane/use-system-prefers-dark'
const WorktreeMetaDialog = React.lazy(() => import('./WorktreeMetaDialog'))
const RemoveFolderDialog = React.lazy(() => import('./RemoveFolderDialog'))
@@ -38,8 +40,14 @@ function Sidebar({
const sidebarWidth = useAppStore((s) => s.sidebarWidth)
const setSidebarWidth = useAppStore((s) => s.setSidebarWidth)
const repos = useAppStore((s) => s.repos)
const settings = useAppStore((s) => s.settings)
const fetchAllWorktrees = useAppStore((s) => s.fetchAllWorktrees)
const activeModal = useAppStore((s) => s.activeModal)
const systemPrefersDark = useSystemPrefersDark()
const leftSidebarStyle = useMemo(
() => resolveLeftSidebarStyleVariables(settings, systemPrefersDark),
[settings, systemPrefersDark]
) as React.CSSProperties | undefined
const { nativeDropTarget, dropHandlers, affordance } = useSidebarProjectDrop()
const {
workspaceBoardOpen,
@@ -89,6 +97,7 @@ function Sidebar({
ref={containerRef}
data-native-file-drop-target={sidebarOpen ? nativeDropTarget : undefined}
className="relative min-h-0 flex-shrink-0 bg-worktree-sidebar flex flex-col overflow-hidden scrollbar-sleek-parent"
style={leftSidebarStyle}
{...dropHandlers}
>
{sidebarOpen && (
@@ -155,6 +164,7 @@ function Sidebar({
</React.Suspense>
{sidebarOpen ? (
<WorkspaceKanbanDrawer
leftSidebarStyle={leftSidebarStyle}
open={workspaceBoardRenderedOpen}
dragPreview={workspaceBoardDragPreviewOpen}
preserveOpenForMenu={workspaceBoardMenuOpen}