refactor(desktop): migrate workspace member list onto the design system
Merged
CH
5d ago+92+92+01234567890123456789-63-63-01234567890123456789
D18 of the design-system migration (Desktop stack, base feature/desktop-d17-workspace-identity-form, #3393).
What
- Settings › Workspace › Members uses
@luke/ui'sSettingsSection, titled "Members", in place of the desktopSettingsGroup. The section's search anchor (SETTINGS_SECTION.MEMBERS, which search results and the person page's link land on) is now on a wrapperdivaround the section, becauseSettingsSectiontakes no anchor. - Each member is a
SettingsRowthroughMenuRow'srowform (added in D16), replacing the hand-built.settings-copymarkup:leading: their face, at the card size, as before- label: their name, with You on the reader's own row inside the person card's
.actor-card-namewrapper, as before - description: their email, kept to one line by
OneLine(ellipsis, with a pill showing the whole address when it is cut short) - control: their role, then the ⋯, or the ⋯'s empty space on a row with no actions so every role ends in the same column
- Behaviour is unchanged:
- who is offered Open profile, Make admin, Make member, Make owner and Remove from workspace (
memberActs) - Make admin and Make member apply at once
- Make owner and Remove ask first through
ConfirmDialog, and the question goes away with its subject - a refused role change is shown under the row (
role="alert") - the members read and Retry are unchanged
- who is offered Open profile, Make admin, Make member, Make owner and Remove from workspace (
- No
@luke/ui/compatcallers lived on this surface.
Selectors
- New
.workspace-memberwrapper (row plus its refusal). It joins the existing API keys and identity rules:.api-key, .workspace-identity, .workspace-memberand… > .error-message. .settings-row-valueand.settings-act-slotnow use the contract's tokens (--luke-color-text-muted, the body size and leading,--luke-control-height) instead of the legacy aliases. Both resolve to the same values as before.- Nothing became unused.
SettingsGroup,.settings-copy,.settings-rowand.actor-card-namestill have other callers.
Visible changes
- The name uses the label role (13/18, 500) instead of
strong(13/1.35, 500). The email uses the caption role in the subtle colour (12/16) instead ofsmall(12/1.4, tertiary). This matches the identity row above it and the other migrated rows. - "Members" uses the shared section heading, which matches the other headings on the page.
- Below a 380px row, the role and the ⋯ drop below the words to the row's end, as the shared row contract requires.
Tests
- In
workspace-page.test.ts, member rows are now found with amemberNamedhelper: aMenuRowinside.workspace-member, matched by its label. The email is read from the row's description instead of the retiredsmall.rowNamedstays for the GitHub and Linear rows, which are still on the old markup. No assertion about behaviour changed. - No new tests, because no behaviour changed.
pnpm check:affectedexits 0.
Evidence
Captured on Linux with headless Chrome at 1280×840. The real WorkspacePage was rendered in jsdom by a throwaway, uncommitted copy of the page's test, using a synthetic workspace "acme" with Dana (owner, the reader), Ola (admin) and Sam (member). The output was placed in the built desktop stylesheet inside the SettingsPage frame.
| Light | Dark | |
|---|---|---|
| Owner's view, with a long address cut short | ![]() | ![]() |
| Role change refused, shown under the row | ![]() | ![]() |
Not verified on a Mac
- SF Pro rendering of the rows, faces and You badge
- Role changes, transfer and removal against a live workspace, which were tested only through the tests
- The search-result ring landing on the Members wrapper in the real window
🤖 Generated with Claude Code



