refactor(desktop): migrate bespoke settings-row adapters onto the design system

Merged
CH
7d ago
+282-175

D14 of the design-system migration (Desktop stack, base feature/desktop-d13-settings-navigation-and-page-frame, #3382).

What

  • SwitchRow, SelectRow and PickerRow render through @luke/ui's SettingsRow. The row owns the name, the changed mark, the description and the last write's refusal. The refusal now describes the control and marks it aria-invalid in the row's polite live region; before, it was a separate role="alert" paragraph under the row. Schema rows got the same change in F40. Write behaviour, rests and search anchors are unchanged.
  • SwitchRow draws the barrel Switch. The search anchor is passed as its data- attribute, the way the schema rows pass it.
  • Picker's chip is the barrel Chip + ChipName, so it no longer goes through CompatChip. Its 200px column width (--luke-select-field-width) is now container layout on .settings-picker > .luke-chip. The automation form, new-task dialog and issue-properties overrides now target that selector as well as .settings-picker-chip, which the repository and server chips still use. Menu placement, Escape handling, focus return and anchors are unchanged.
  • MenuRow's ⋯ is the barrel quiet IconButton. Its label, tooltip, right-click and the menu are unchanged. The row's own frame is still the page's children, because its callers (API keys, workspace members/Linear/leave, integrations, voice keys) supply marks and values and belong to D16–D28.
  • PickerRow's API changes from a hand-built copy node to detail / changed / error / density. Its five callers (coding agents' Model, the diff theme rows, and the automation editor's Owner, Time zone and Agent) were updated mechanically.
  • New shared variant (approved by the orchestrator): SETTINGS_ROW_DENSITY = { CARD, COMPACT } on SettingsRow, default CARD. A COMPACT row has no padding and a 32px minimum height, from the new role tokens --luke-settings-row-compact-block, -inline and -min-height. It keeps its controls beside its words at any width, wrapping only through normal flex wrap, whereas CARD keeps the contract's 380px stack. The design comment explains the difference. The diff settings popover (about 308px of content) uses COMPACT. The catalog's Settings row example has a new "Compact, in a popover" section.
  • The coding agents Fast note's "Request access" link uses the existing .settings-detail-act link style. The description no longer lives inside .settings-copy small, so it can't inherit that style from there.

Visible changes

  • Descriptions under switch, select and picker rows use the contract's caption type and subtle colour (12/16 instead of 12/1.4 tertiary). The same change already applies to schema rows.
  • A refused write's line now sits inside its row, under the description, in the danger colour. Before, it sat as a separate line under the row.
  • The diff settings popover's rows match their old layout: no padding, 32px minimum, controls beside the label.
  • Nothing else is intended. The ⋯ button was already 30px square, quiet and muted, and the field chip was already 200px.

Tests

  • coding-agents-page.test.ts: the Fast refusal is now read the way a screen reader gets it. The switch is aria-invalid, its description includes the refusal, and the page announces it once. The Fast note is read through the switch's aria-describedby. These replace checks that used role="alert" and .settings-row small.
  • agent-changes-tab.test.ts: the popover's refused write is read the same way.
  • issues-page.test.ts: the new-issue chips are found by button[aria-haspopup=dialog], not by the retired class.
  • apps/desktop/src/renderer and packages/ui/src/components/settings-row: 172 files, 1639 tests pass. pnpm check:affected exits 0.

Evidence

These come from the smoke fixture on Linux under Xvfb, driven over CDP at 1280×840. The fixture is signed out, so Coding agents, Experimental and the automation editor show no rows. The diff popover needs a coding agent with changes, which the fixture doesn't have, so the compact rows are shown through the catalog example instead.

LightDark
Voice: MenuRow ⋯ (IconButton)
Voice: ⋯ menu open
Appearance › Diffs: Picker chips (themes) beside Selects and Switches
Appearance: Picker/Select menu open
This Mac: switch row with a wrapping description
Catalog: Settings row, incl. new Compact, in a popover

Not verified on a Mac

  • SF Pro rendering of the rows, chips and ⋯
  • the diff settings popover in a real agent's Changes tab (compact rows checked only in the catalog)
  • the automation editor's picker rows, and the signed-in Coding agents and Experimental pages

🤖 Generated with Claude Code