Kanzo UI
The design of Kanzo UI

The shell's dock

Why a page switches its side panels with one part, an activity bar of icons named by their tooltips — and what would reverse it.

One dock switcher, an activity bar

A page whose side panel holds one of several tools switches them with ShellDockSwitcher: an icon per panel, named by its tooltip and its accessible name, checked while its panel is open, and pressed again to collapse it. It is a single-select ToggleGroup, so Ark makes the switcher a radiogroup and each icon a radio with aria-checked — not a toggle button with aria-pressed. The panel's own title says what it is in words. The reference is VS Code's activity bar. Keasy's Discover (Info · Ask · Rules · Settings) and its studio (Sources) draw the same part.

<ShellDockSwitcher aria-label="Side panels" value={panel} onValueChange={setPanel}>
  <ShellDockItem value="info" label="Info" icon={InfoIcon} />
  <ShellDockItem value="ask" label="Ask" icon={MessageCircleIcon} />
</ShellDockSwitcher>

It replaced two ways of doing one thing: Discover's ToggleGroup of bare icons in its footer, and the studio's Toggle with an icon and the word Sources in a status bar of its own. A reader learnt each, and a test found each differently.

What would reverse it: a dock with panels a reader cannot tell apart by icon, as tested with readers. Then the item draws its label beside the icon everywhere, not in one page.

Held by packages/ui/src/layouts/shell.test.tsx, "an item is named by its label, pressed while open, and collapses its panel when pressed again".

The page names the switcher, and its panels keep their type

ShellDockSwitcher requires an accessible name and is generic over the page's panel id. It is a radiogroup, whose name WAI-ARIA 1.2 requires, and the name it used to default to, Panels, misnamed the studio's dock of one, Sources: only the page knows what its panels are, so the type asks for aria-label or aria-labelledby, as ButtonGroup's does. value and onValueChange are typed by the page's id, inferred from value, because a page that keeps its panel in a union had to narrow a string back to it — keasy's Discover with a find over its panels. The items stay string: a child cannot carry a type to its parent in JSX, so typing them would check nothing.

What would reverse it: a name derivable from what the switcher holds that readers hear as right on a dock of one and of many — then it returns as a default. A way for the items to type the group would let the id be inferred from them instead.

Held by packages/ui/src/layouts/shell.test.tsx, "is a radiogroup named by the page, and hands back the page's own panel type".

On this page