Centrim Design System — a token-first, accessible React component system.
V2 audit — People
Identity across the product: one avatar, one stacking rule, one picker for assigning people.
Avatar
Represents a person or entity as image, initials or a neutral glyph.
AvataravatarToneFromNameAVATAR_TONESLive component
AORBSMDCPRUser
NPASWEI
Legacy mapping
Legacy screens rendered five avatar diameters and random initials colours. V2 fixes five size tokens and a deterministic tone per name.
| Attribute | Specification |
|---|---|
| Default | size="medium" (32px), tone="neutral" |
| Variants | image · initials · glyph fallback · tone=auto |
| Sizes | xs (20px) · small (24px) · medium (32px) · large (40px) · xl (48px) |
| States | loaded · fallback · in a group (ringed) |
| Icon behaviour | Fallback User glyph at half the avatar size. |
| Spacing | No internal padding; groups overlap by 8px. |
| Typography | Initials `text-caption` → `text-label-lg` by size, weight 500. |
| Border radius | `rounded-full`. |
| Colour usage | `*-subtle` pairs only; `tone="auto"` hashes the name so a person keeps one colour everywhere. |
| Responsive | Steps down one size token in dense mobile rows; never below 20px. |
When to use
- Identifying the author, owner or assignee
When not to use
- Decorating a list that has no person in it
Accessibility
- Image avatars carry the person's name as alt text; glyph fallback keeps an sr-only name.
- Colour is decorative — it never encodes role or status.
AvatarGroup
Stacks several people and collapses the remainder into a +N indicator.
AvatarGroupLive component
Legacy mapping
Legacy participant rows listed every avatar and overflowed the container.
| Attribute | Specification |
|---|---|
| Default | max=4, size="medium" |
| Variants | stacked · stacked with overflow |
| Sizes | xs · small · medium · large · xl |
| States | within max · overflowing |
| Icon behaviour | None; the overflow chip shows +N text. |
| Spacing | -8px overlap, 2px `ring-surface` separation. |
| Typography | Overflow chip matches the avatar size token. |
| Border radius | `rounded-full`. |
| Colour usage | Overflow chip `bg-background-muted` + `text-text-secondary`. |
| Responsive | Lower `max` on narrow widths rather than shrinking the avatars. |
When to use
- Attendees, watchers, shared-with lists
When not to use
- When names must be readable — use a list
Accessibility
- One `role="group"` with a summary label; individual avatars are hidden from the reading order to avoid a name wall.
UserSelect
Searchable people picker for single or multiple assignment.
UserSelectLive component
- AOAmara Okafor
- SMSofia Marchetti
Everyone selected receives the shift summary.
Legacy mapping
Each legacy module shipped its own assignee dropdown, some without search and some without avatars. V2 provides one picker.
| Attribute | Specification |
|---|---|
| Default | multiple=false, size="medium" |
| Variants | single · multiple |
| Sizes | small · medium · large |
| States | empty · searching · no results · selected · disabled · error |
| Icon behaviour | Search icon in the filter row, Check on selected rows, labelled X on removable pills. |
| Spacing | Trigger padding 8px, pill gap 6px, option row padding 6px/8px. |
| Typography | Name `text-body-sm`, detail line `text-caption`. |
| Border radius | `rounded-md` trigger, `rounded-full` pills. |
| Colour usage | Neutral chrome; avatars supply the only colour via `tone="auto"`. |
| Responsive | Popover matches the trigger width; pills wrap and grow the trigger. |
When to use
- Assigning owners, inviting participants, sharing
When not to use
- Non-person entities — use Combobox or MultiSelect
Accessibility
- Listbox with `aria-multiselectable`; search field is labelled; the secondary detail line disambiguates duplicate names.