@@ -24,6 +24,19 @@ function abbreviateHome(dir: string, home: string): string {
2424 return dir ;
2525}
2626
27+ // ── Tooltip wrapper ────────────────────────────────────────────────────────
28+
29+ function Tip ( { label, children } : { label : string ; children : React . ReactNode } ) {
30+ return (
31+ < div className = "group relative flex items-stretch" >
32+ { children }
33+ < span className = "pointer-events-none absolute left-1/2 top-full z-50 mt-1 -translate-x-1/2 whitespace-nowrap rounded bg-surface-raised px-2 py-1 text-[10px] text-foreground opacity-0 shadow-md border border-border transition-opacity group-hover:opacity-100" >
34+ { label }
35+ </ span >
36+ </ div >
37+ ) ;
38+ }
39+
2740// ── Windows/Linux window buttons ───────────────────────────────────────────
2841
2942function WinControls ( ) {
@@ -39,29 +52,35 @@ function WinControls() {
3952
4053 return (
4154 < div className = "flex items-stretch self-stretch" >
42- < button
43- className = "flex w-11 items-center justify-center text-muted transition-colors hover:bg-surface-raised hover:text-foreground"
44- onClick = { ( ) => appWindow . minimize ( ) }
45- aria-label = "Minimize"
46- >
47- < MinusIcon size = { 12 } weight = "bold" />
48- </ button >
49- < button
50- className = "flex w-11 items-center justify-center text-muted transition-colors hover:bg-surface-raised hover:text-foreground"
51- onClick = { ( ) => { appWindow . toggleMaximize ( ) ; } }
52- aria-label = { maximized ? 'Restore' : 'Maximize' }
53- >
54- { maximized
55- ? < CornersInIcon size = { 12 } weight = "bold" />
56- : < CornersOutIcon size = { 12 } weight = "bold" /> }
57- </ button >
58- < button
59- className = "flex w-11 items-center justify-center text-muted transition-colors hover:bg-error/90 hover:text-white"
60- onClick = { ( ) => appWindow . close ( ) }
61- aria-label = "Close"
62- >
63- < XIcon size = { 12 } weight = "bold" />
64- </ button >
55+ < Tip label = "Minimize" >
56+ < button
57+ className = "flex w-11 items-center justify-center text-muted transition-colors hover:bg-surface-raised hover:text-foreground"
58+ onClick = { ( ) => appWindow . minimize ( ) }
59+ aria-label = "Minimize"
60+ >
61+ < MinusIcon size = { 12 } weight = "bold" />
62+ </ button >
63+ </ Tip >
64+ < Tip label = { maximized ? 'Restore' : 'Maximize' } >
65+ < button
66+ className = "flex w-11 items-center justify-center text-muted transition-colors hover:bg-surface-raised hover:text-foreground"
67+ onClick = { ( ) => { appWindow . toggleMaximize ( ) ; } }
68+ aria-label = { maximized ? 'Restore' : 'Maximize' }
69+ >
70+ { maximized
71+ ? < CornersInIcon size = { 12 } weight = "bold" />
72+ : < CornersOutIcon size = { 12 } weight = "bold" /> }
73+ </ button >
74+ </ Tip >
75+ < Tip label = "Close" >
76+ < button
77+ className = "flex w-11 items-center justify-center text-muted transition-colors hover:bg-error/90 hover:text-white"
78+ onClick = { ( ) => appWindow . close ( ) }
79+ aria-label = "Close"
80+ >
81+ < XIcon size = { 12 } weight = "bold" />
82+ </ button >
83+ </ Tip >
6584 </ div >
6685 ) ;
6786}
@@ -71,6 +90,7 @@ function WinControls() {
7190function ShellDropdown ( { shells } : { shells : ShellEntry [ ] } ) {
7291 const [ open , setOpen ] = useState ( false ) ;
7392 const ref = useRef < HTMLDivElement > ( null ) ;
93+ const defaultShell = shells [ 0 ] ;
7494
7595 const handleSelect = useCallback ( ( shell : ShellEntry ) => {
7696 setOpen ( false ) ;
@@ -98,21 +118,35 @@ function ShellDropdown({ shells }: { shells: ShellEntry[] }) {
98118 } , [ open ] ) ;
99119
100120 return (
101- < div ref = { ref } className = "relative" >
102- < button
103- className = "flex h-6 items-center gap-1 rounded px-2 text-xs text-muted transition-colors hover:bg-surface-raised hover:text-foreground"
104- onClick = { ( ) => setOpen ( ! open ) }
105- aria-expanded = { open }
106- aria-haspopup = "menu"
107- >
108- < PlusIcon size = { 12 } weight = "bold" />
109- < CaretDownIcon size = { 10 } weight = "bold" />
110- </ button >
121+ < div ref = { ref } className = "relative flex items-center" >
122+ { /* Primary action: click to open a new terminal with the default shell */ }
123+ < Tip label = "New terminal" >
124+ < button
125+ className = "flex h-6 items-center gap-1.5 rounded-l px-2 text-xs text-muted transition-colors hover:bg-surface-raised hover:text-foreground"
126+ onClick = { ( ) => defaultShell && handleSelect ( defaultShell ) }
127+ aria-label = { `New ${ defaultShell ?. name ?? 'terminal' } ` }
128+ >
129+ < PlusIcon size = { 12 } weight = "bold" />
130+ < span className = "font-mono text-[11px]" > { defaultShell ?. name ?? 'shell' } </ span >
131+ </ button >
132+ </ Tip >
133+ { /* Dropdown caret: pick a different shell type */ }
134+ < Tip label = "Choose shell" >
135+ < button
136+ className = "flex h-6 items-center rounded-r px-1 text-xs text-muted transition-colors hover:bg-surface-raised hover:text-foreground"
137+ onClick = { ( ) => setOpen ( ! open ) }
138+ aria-expanded = { open }
139+ aria-haspopup = "menu"
140+ >
141+ < CaretDownIcon size = { 10 } weight = "bold" />
142+ </ button >
143+ </ Tip >
111144 { open && (
112- < div className = "absolute right-0 top-full z-50 mt-1 min-w-[140px] rounded border border-border bg-surface-raised py-1 shadow-lg " >
145+ < div className = "absolute right-0 top-full z-50 mt-1 min-w-[140px] rounded border border-border bg-surface-raised py-1 shadow-md" role = "menu ">
113146 { shells . map ( ( shell ) => (
114147 < button
115148 key = { shell . path }
149+ role = "menuitem"
116150 className = "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-foreground transition-colors hover:bg-surface-alt"
117151 onClick = { ( ) => handleSelect ( shell ) }
118152 >
0 commit comments