Skip to content

Commit caabe65

Browse files
nedtwiggclaude
andcommitted
Improve AppBar button discoverability and add tooltips.
- Split shell dropdown into a primary "new terminal" button showing the shell name (e.g. "+ zsh") and a separate dropdown caret for choosing a different shell type - Add tooltip component that appears on hover for all AppBar buttons (window controls, new terminal, choose shell) - Add proper ARIA roles (role="menu", role="menuitem") to the dropdown Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 11a09b8 commit caabe65

1 file changed

Lines changed: 68 additions & 34 deletions

File tree

standalone/src/AppBar.tsx

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2942
function 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() {
7190
function 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

Comments
 (0)