11import React , { useEffect , useMemo , useCallback , useState , type ReactNode } from "react" ;
2- import { Command as CommandIcon } from "lucide-react" ;
2+ import { Command as CommandIcon , Search } from "lucide-react" ;
33import { resolveIcon } from "../utils/icons" ;
44import { CommandPalette } from "./CommandPalette" ;
55import { Sidebar } from "./Sidebar" ;
@@ -60,9 +60,39 @@ function EmptyState({ categories, onOpen }: {
6060 ) ;
6161}
6262
63+ // ── Top bar ──
64+
65+ function TopBar ( { title, description, onSearch } : {
66+ readonly title : string ;
67+ readonly description : string ;
68+ readonly onSearch : ( ) => void ;
69+ } ) : React . ReactElement {
70+ const label = description ? `${ title } — ${ description } ` : title ;
71+
72+ return (
73+ < div className = "h-10 shrink-0 flex items-center justify-center border-b border-border/20 bg-background relative" >
74+ < button
75+ onClick = { onSearch }
76+ className = "flex items-center gap-2 px-3 py-1 rounded-md border border-border/30 bg-card/40 hover:bg-card/70 transition-colors cursor-pointer text-muted-foreground/50 hover:text-muted-foreground/70 max-w-[400px] min-w-[260px]"
77+ >
78+ < Search size = { 12 } className = "shrink-0" />
79+ < span className = "text-[12px] truncate flex-1 text-left" > Search { label } ...</ span >
80+ < div className = "flex items-center gap-0.5 shrink-0" >
81+ < kbd className = "text-[10px] bg-background/60 px-1 py-px rounded border border-border/30 font-mono" >
82+ < CommandIcon size = { 9 } className = "inline" />
83+ </ kbd >
84+ < kbd className = "text-[10px] bg-background/60 px-1 py-px rounded border border-border/30 font-mono" > K</ kbd >
85+ </ div >
86+ </ button >
87+ </ div >
88+ ) ;
89+ }
90+
6391// ── Main component ──
6492
6593export function WmuxApp ( props : {
94+ readonly title : string ;
95+ readonly description : string ;
6696 readonly categories : ReadonlyArray < CategoryInfo > ;
6797 readonly activeCategory : string ;
6898 readonly activeTabId : string ;
@@ -76,7 +106,7 @@ export function WmuxApp(props: {
76106 readonly onOpenFile : { readonly mutate : ( path : string ) => void } ;
77107 readonly onCloseFile : { readonly mutate : ( path : string ) => void } ;
78108} ) : React . ReactElement {
79- const { categories, activeCategory, activeTabId, children } = props ;
109+ const { title , description , categories, activeCategory, activeTabId, children } = props ;
80110 const selectCategory = props . onSelectCategory . mutate ;
81111 const selectTab = props . onSelectTab . mutate ;
82112 const startProcess = props . onStartProcess . mutate ;
@@ -169,20 +199,23 @@ export function WmuxApp(props: {
169199 } , [ ] ) ;
170200
171201 return (
172- < div className = "flex h-screen w-screen bg-background text-foreground font-sans" >
173- < Sidebar
174- categories = { categories }
175- activeCategory = { activeCategory }
176- activeTabId = { activeTabId }
177- collapsedCategories = { collapsedCategories }
178- onSelectCategory = { selectCategory }
179- onToggleCollapse = { toggleCollapse }
180- onSelectTab = { selectTab }
181- onToggleDir = { toggleDir }
182- onOpenFile = { openFile }
183- />
202+ < div className = "flex flex-col h-screen w-screen bg-background text-foreground font-sans" >
203+ < TopBar title = { title } description = { description } onSearch = { ( ) => setCmdkOpen ( true ) } />
204+
205+ < div className = "flex flex-1 min-h-0" >
206+ < Sidebar
207+ categories = { categories }
208+ activeCategory = { activeCategory }
209+ activeTabId = { activeTabId }
210+ collapsedCategories = { collapsedCategories }
211+ onSelectCategory = { selectCategory }
212+ onToggleCollapse = { toggleCollapse }
213+ onSelectTab = { selectTab }
214+ onToggleDir = { toggleDir }
215+ onOpenFile = { openFile }
216+ />
184217
185- < div className = "flex-1 flex flex-col min-w-0 relative" >
218+ < div className = "flex-1 flex flex-col min-w-0 relative" >
186219 { activeCategory && hasTabs && (
187220 < TabBar
188221 tabs = { orderedTabs }
0 commit comments