Centrim Design System — a token-first, accessible React component system.
V2 audit — Navigation
Two controls that look similar and mean different things: Tabs switch panels of content, SegmentedControl switches the view of one content set.
Tabs
Switches between sibling panels of content within one page.
TabsTabListTabTabPanelLive component
Legacy mapping
Legacy modules used underlined tabs, pill tabs and button rows interchangeably. V2 keeps one underlined tab set.
| Attribute | Specification |
|---|---|
| Default | Underlined, size="medium" |
| Variants | underlined · with counts · with icons |
| Sizes | small · medium |
| States | default · hover · focus-visible · active · disabled |
| Icon behaviour | Optional leading icon at `--size-icon-sm`; counts render as a Badge, never a raw parenthesis. |
| Spacing | Tab padding 12/16px; list gap 4px; 1px bottom rule spans the row. |
| Typography | `text-label-md`; the active tab gains weight, not size. |
| Border radius | None on the tab; the indicator is a 2px underline. |
| Colour usage | Active `text-text-primary` + `bg-primary` indicator; rest `text-text-secondary`. |
| Responsive | Horizontally scrollable with edge fade below `md`; never wraps to two rows. |
When to use
- Peer sections of one record
- 3–7 panels
When not to use
- Navigating to another page
- Switching how the same data is displayed
Accessibility
- Radix Tabs roving focus, `aria-controls`/`aria-labelledby` wiring, Home/End support.
- Visible `ds-focus-ring` on `:focus-visible`; never focus-suppressed.
SegmentedControl
Switches the view, density or range of one content set. Always one option selected.
SegmentedControlSegmentLive component
Legacy mapping
Legacy screens used attached button rows with manual active styling and no keyboard semantics. V2 replaces them with a real single-select toggle group.
| Attribute | Specification |
|---|---|
| Default | size="medium", fullWidth=false |
| Variants | text · icon + text · icon only (labelled) |
| Sizes | small (24px) · medium (32px) · large (40px) |
| States | default · hover · focus-visible · selected · disabled |
| Icon behaviour | Icon at `--size-icon-xs|sm` matched to the segment size; icon-only segments need `aria-label`. |
| Spacing | Track padding 4px, segment gap 4px, segment padding 10/12/16px. |
| Typography | `text-label-sm|md|lg`, weight 500. |
| Border radius | `rounded-md` track, `rounded-sm` segments. |
| Colour usage | Track `bg-background-subtle`; selected segment lifts to `bg-surface` with `shadow-xs`. |
| Responsive | `fullWidth` splits the row evenly on mobile; falls back to a Select above ~4 options on narrow screens. |
When to use
- Day / week / month, list / board, chart type
When not to use
- Independent toggles — use ToggleGroup multiple
- Distinct content panels — use Tabs
Accessibility
- Radix ToggleGroup single-select; empty selection is rejected so a view is always active.
- Visible `ds-focus-ring` on `:focus-visible`; never focus-suppressed.
ToggleGroup
Formatting-style toggles, single or multiple, rendered as an attached button set.
ToggleGroupToggleGroupItemLive component
Legacy mapping
Legacy editors used ad-hoc active classes on buttons.
| Attribute | Specification |
|---|---|
| Default | variant="default", size="medium" |
| Variants | single · multiple · default · outline |
| Sizes | small · medium · large |
| States | off · on · hover · focus-visible · disabled |
| Icon behaviour | Icon size follows the group size; icon-only items require an accessible name. |
| Spacing | Items butt together with -1px overlap. |
| Typography | `text-label-sm|md|lg`. |
| Border radius | Outer corners `rounded-md`. |
| Colour usage | Selected `bg-primary` + `text-primary-foreground`. |
| Responsive | Wraps to a second row rather than shrinking targets. |
When to use
- Alignment, formatting, filter toggles
When not to use
- Primary view switching — use SegmentedControl
Accessibility
- Radix ToggleGroup semantics; group needs `aria-label`.
- Pointer target ≥24px (≥44px on coarse pointers) via `ds-target`.