Move worktree palette search to top of sidebar nav

The Cmd+J search button is now displayed as the first item in the
sidebar navigation, improving discoverability. Styling is simplified
to match the nav item layout with flex-based display and consistent
spacing.
This commit is contained in:
Jinjing
2026-08-21 21:32:21 -07:00
parent e7b047f53a
commit be92dada71
2 changed files with 45 additions and 31 deletions
@@ -429,6 +429,20 @@ describe('SidebarNav', () => {
expect(mocks.updateSettings).toHaveBeenCalledWith({ showMobileButton: false })
})
it('places the worktree palette search above the sidebar nav rows', async () => {
const container = await renderSidebarNav()
const nav = container.querySelector('[data-contextual-tour-target="sidebar-navigation"]')
const searchButton = container.querySelector(
'button[aria-label="Search worktrees and browser tabs"]'
)
const tasksButton = getButtonByText(container, 'Tasks')
expect(nav?.firstElementChild).toBe(searchButton)
expect(
searchButton?.compareDocumentPosition(tasksButton) & Node.DOCUMENT_POSITION_FOLLOWING
).toBeTruthy()
})
it('hides the worktree palette shortcut until the search field is hovered or focused', async () => {
const container = await renderSidebarNav()
@@ -439,8 +453,8 @@ describe('SidebarNav', () => {
const shortcuts = searchButton?.querySelector('span.hidden')
expect(shortcuts?.className).toContain('hidden')
expect(shortcuts?.className).toContain('group-hover:inline-flex')
expect(shortcuts?.className).toContain('group-focus-within:inline-flex')
expect(shortcuts?.className).toContain('group-hover:flex')
expect(shortcuts?.className).toContain('group-focus-within:flex')
expect(shortcuts?.textContent).toContain('⌘')
expect(shortcuts?.textContent).toContain('J')
expect(searchButton?.querySelector('kbd')).toBeNull()
@@ -106,6 +106,35 @@ const SidebarNav = React.memo(function SidebarNav() {
className="flex flex-col gap-0.5 px-2 pt-2 pb-1"
data-contextual-tour-target="sidebar-navigation"
>
<button
type="button"
onClick={() => openModal('worktree-palette')}
aria-label={translate(
'auto.components.sidebar.SidebarNav.0c3395fd32',
'Search worktrees and browser tabs'
)}
className="group flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] font-medium tracking-tight text-worktree-sidebar-foreground/60 transition-colors hover:bg-worktree-sidebar-foreground/8"
>
<Search
className="size-4 shrink-0 text-worktree-sidebar-foreground/30"
strokeWidth={1.75}
/>
<span className="flex-1">
{translate('auto.components.sidebar.SidebarNav.80611a8b10', 'Search')}
</span>
<span className="pointer-events-none hidden shrink-0 items-center gap-1 group-hover:flex group-focus-within:flex">
{worktreePaletteShortcutCombos.map((combo) => (
<ShortcutKeyCombo
key={combo.keys.join('-')}
keys={combo.keys}
doubleTap={combo.doubleTap}
className="inline-flex gap-0.5"
keyCapClassName="min-w-4 border-worktree-sidebar-border/80 bg-worktree-sidebar-foreground/8 px-1 py-px text-[9px] text-worktree-sidebar-foreground/55 shadow-none"
separatorClassName="text-[9px] text-worktree-sidebar-foreground/45"
/>
))}
</span>
</button>
<SetupGuideSidebarEntry />
<SidebarTaskNavButton />
{showArtifactsButton ? (
@@ -302,35 +331,6 @@ const SidebarNav = React.memo(function SidebarNav() {
<HideSidebarMenu onHide={hideMobileButton} />
</ContextMenu>
) : null}
<button
type="button"
onClick={() => openModal('worktree-palette')}
aria-label={translate(
'auto.components.sidebar.SidebarNav.0c3395fd32',
'Search worktrees and browser tabs'
)}
className="group relative flex h-7 w-full items-center rounded-md border border-worktree-sidebar-border/70 bg-worktree-sidebar-foreground/5 pl-7 pr-1.5 text-left text-[12px] font-medium tracking-tight text-worktree-sidebar-foreground/45 transition-colors hover:border-worktree-sidebar-border hover:bg-worktree-sidebar-foreground/8 hover:text-worktree-sidebar-foreground/60 focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-worktree-sidebar-ring/50"
>
<Search
className="pointer-events-none absolute left-2 top-1/2 size-3 -translate-y-1/2 text-worktree-sidebar-foreground/30"
strokeWidth={1.75}
/>
<span className="min-w-0 flex-1 truncate">
{translate('auto.components.sidebar.SidebarNav.80611a8b10', 'Search')}
</span>
<span className="pointer-events-none ml-1.5 hidden shrink-0 items-center gap-1.5 group-hover:inline-flex group-focus-within:inline-flex">
{worktreePaletteShortcutCombos.map((combo) => (
<ShortcutKeyCombo
key={combo.keys.join('-')}
keys={combo.keys}
doubleTap={combo.doubleTap}
className="inline-flex gap-0.5"
keyCapClassName="min-w-4 border-worktree-sidebar-border/80 bg-worktree-sidebar-foreground/8 px-1 py-px text-[9px] text-worktree-sidebar-foreground/55 shadow-none"
separatorClassName="text-[9px] text-worktree-sidebar-foreground/45"
/>
))}
</span>
</button>
</div>
)
})