Role switcher
The "Clerk | Manager" toggle. A small primitive for switching between two or three roles in dev tools, demo previews, and the permission-gate recipe. Generic over any role enum.
Usage
A pill-shaped segmented control. One button per role; the active role carries aria-pressed="true". Use it in dev banners, demo shells, and the permission-gate recipe — not in production UI where role is set by the back end.
Variants
Two or three roles work cleanly; four becomes a regular segmented control and you should reach for p-segmented-control instead.
Parts
| Property | Value | Notes |
|---|---|---|
| track padding | 3px | Surrounds the pill |
| button padding | 6px 14px | Click target ≥ 28px high |
| radius | 9999px | Pill, on both track and button |
| track bg | --surface-muted | Quiet enough to sit in a header |
| active bg | --surface | Lifts the pressed button |
| aria-pressed | "true" / "false" | One pressed at a time |
Do & don't
Use it in demos, dev banners, and the permission-gate recipe to simulate a role change client-side.
Use it in production UI where the role is set by the back end. A user shouldn't be able to elevate themselves.
Keep labels to one word — "Clerk", "Manager", "Owner". The control is meant to be glance-readable.
Ship four or more roles in this control. Switch to p-segmented-control or a dropdown.
Code
<!-- Two-role switcher --> <div class="p-role-switcher" role="group" aria-label="Switch role"> <button type="button" aria-pressed="true">Clerk</button> <button type="button" aria-pressed="false">Manager</button> </div> // React: flip aria-pressed and call onChange. function RoleSwitcher({ roles, value, onChange }) { return ( <div className="p-role-switcher" role="group"> {roles.map((r) => ( <button key={r.id} type="button" aria-pressed={value === r.id} onClick={() => onChange(r.id)} >{r.label}</button> ))} </div> ); }
Related
For the role model + gates that actually drive what the user can do, see the Role & permission gate recipe. For more than three options, use Segmented control.