feat(home): no right sidebar beside the first-run welcome; underline the home-folder link

This commit is contained in:
Neil
2026-11-12 13:39:08 -08:00
parent 381275ad46
commit c5700ad326
4 changed files with 50 additions and 3 deletions
@@ -1,7 +1,10 @@
import { useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'
import { useShallow } from 'zustand/react/shallow'
import { SYNC_FIT_PANES_EVENT } from '@/constants/terminal'
import { canShowRightSidebarForView } from '@/components/right-sidebar/visibility/right-sidebar-visibility'
import {
canShowRightSidebarForView,
isFirstRunWelcomeShown
} from '@/components/right-sidebar/visibility/right-sidebar-visibility'
import { resolveLeftSidebarStyleVariables } from '@/app-shell/appearance/left-sidebar-appearance'
import { resolveLeftTitlebarChromeLayout } from '@/app-shell/chrome/titlebar-left-chrome'
import { selectWorktreeCreationSurfaceShown } from '@/lib/workspace/creation/worktree-creation-surface'
@@ -63,6 +66,13 @@ export function useAppChromeLayout() {
const creationLayoutActive = useAppStore(selectWorktreeCreationSurfaceShown)
const workspaceChromeActive =
activeView === 'terminal' && hasActiveWorktree && !creationLayoutActive
const projectCount = useAppStore((s) => s.repos.length)
const firstRunWelcomeShown = isFirstRunWelcomeShown({
activeView,
hasActiveWorktree,
creationLayoutActive,
projectCount
})
// Activity/Space own full pages and hide the workspace sidebar.
const showSidebar =
activeView !== 'settings' && activeView !== 'activity' && activeView !== 'space'
@@ -124,7 +134,7 @@ export function useAppChromeLayout() {
shouldMountTerminalWorkbench,
showSidebar,
// Keep the pending composer in the same viewport as the workspace it hands off to.
showRightSidebarControls: canShowRightSidebarForView(activeView),
showRightSidebarControls: canShowRightSidebarForView(activeView) && !firstRunWelcomeShown,
showTitlebarAppName: settings?.showTitlebarAppName !== false,
showTitlebarExpandButton: workspaceChromeActive && !hasTabBar && effectiveActiveTabExpanded,
sidebarOpen,
@@ -74,7 +74,7 @@ export function LandingFirstRunWelcome({
</Button>
<button
type="button"
className="cursor-pointer text-xs text-muted-foreground underline-offset-4 transition-colors hover:text-foreground hover:underline disabled:cursor-default disabled:opacity-60"
className="cursor-pointer rounded-sm text-xs text-muted-foreground underline decoration-muted-foreground/50 underline-offset-4 transition-colors outline-none hover:text-foreground hover:decoration-foreground focus-visible:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-default disabled:opacity-60"
onClick={() => void openHome()}
disabled={openingHome}
>
@@ -0,0 +1,19 @@
import { describe, expect, it } from 'vitest'
import { isFirstRunWelcomeShown } from './right-sidebar-visibility'
const home = {
activeView: 'terminal' as const,
hasActiveWorktree: false,
creationLayoutActive: false,
projectCount: 0
}
describe('first-run welcome hides the right sidebar', () => {
it('only on Home with no project, no workspace and no creation in progress', () => {
expect(isFirstRunWelcomeShown(home)).toBe(true)
expect(isFirstRunWelcomeShown({ ...home, projectCount: 1 })).toBe(false)
expect(isFirstRunWelcomeShown({ ...home, hasActiveWorktree: true })).toBe(false)
expect(isFirstRunWelcomeShown({ ...home, creationLayoutActive: true })).toBe(false)
expect(isFirstRunWelcomeShown({ ...home, activeView: 'tasks' })).toBe(false)
})
})
@@ -21,6 +21,24 @@ export function canShowRightSidebarForView(activeView: ActiveView): boolean {
return !RIGHT_SIDEBAR_SUPPRESSED_VIEWS.has(activeView)
}
/**
* Home's first-run welcome (no project yet, nothing selected) has nothing to browse, so the right
* sidebar stays out of it; it returns as before once a project exists.
*/
export function isFirstRunWelcomeShown(layout: {
activeView: ActiveView
hasActiveWorktree: boolean
creationLayoutActive: boolean
projectCount: number
}): boolean {
return (
layout.activeView === 'terminal' &&
!layout.hasActiveWorktree &&
!layout.creationLayoutActive &&
layout.projectCount === 0
)
}
/** Workspace and creation surfaces have no titlebar strip, so the closed sidebar needs its own toggle there. */
export function showsFloatingRightSidebarToggle(layout: {
activeView: ActiveView