Centrim Design System — a token-first, accessible React component system.
Data display
Tables, lists, cards and record metadata — one hierarchy, one density scale and one set of feedback states across every Centrim Life module.
Overview
How the data display family fits together.
What is this?
The data display family renders record sets and record detail: Table for column comparison, List for sentence-shaped rows, DataRow for the mobile form of a table, Card and InfoCard for grouped and read-only information, UserRow for people, SelectionCard for choices, and ActivityFeed for history.
When to use it
- Showing a set of records that share attributes.
- Summarising one record's facts.
- Letting people select, sort, page or act on records.
How to use it
- Keep the hierarchy: primary → secondary → metadata → action.
- Pick a density (compact / default / comfortable) per surface, not per row.
- Reuse Checkbox, Radio, Badge, Avatar, Button and Pagination — never re-skin them.
What to avoid
- Table- or card-specific empty, loading and error components.
- Grid-heavy borders where spacing and a divider will do.
- New status colours or spacing values outside the V2 scales.
Why it is designed this way
Legacy Centrim Life screens each solved rows their own way: bordered grids in admin views, shadowed cards in resident views, bespoke checkboxes in pickers. V2 collapses these into one row model with three densities so a resident row, an asset row and a recurring job row read identically.
Feedback is shared, not duplicated: skeletons while loading, EmptyState when nothing exists, NoResultsState when filters exclude everything, ErrorState when the request failed, and a Toast once an action completes.
Do
- Give every table a caption and real <th> headers.
- Communicate sorting with an arrow glyph plus aria-sort.
- Replace the table with stacked DataRows on mobile.
- Name the record in every icon-only action label.
Don't
- Don't shrink a desktop table to fit a phone.
- Don't build a second pagination or checkbox for tables.
- Don't combine Empty State and No Results into one message.
- Don't use colour alone for status, selection or disabled rows.
Table
Sorting, selection, density, states and the mobile strategy.
Table
The tabular view of a record set — residents, assets, recurring jobs. Rows are separated by spacing and hairline dividers rather than a grid of borders, so scanning stays fast at any density.
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "@/design-system";
When to use
- Comparing many records across the same set of attributes.
- Workflows that need sorting, selection and bulk actions.
- Administrative views where density matters more than imagery.
When not to use
- A single record's attributes — use DescriptionList or InfoCard.
- Content with rich media or long copy — use Card or List.
- Fewer than three attributes per record — a List reads better.
Sortable, selectable table
Select-all is indeterminate when only part of the page is selected. Sorted columns show an arrow plus an aria-sort value.
| Status | Actions | ||
|---|---|---|---|
AB Alan Brightwell Cedar 04 | |||
DS Derek Salisbury Cedar 11 | |||
MW Margaret Whitfield Willow 12 | |||
NO Nadia Osei Willow 07 |
Density
Compact for administrative views, default for standard Centrim Life screens, comfortable for primary workflows. All three come from the V2 spacing scale.
| compact | Property | Next run |
|---|---|---|
| Fire door inspection | Willow House | 02 Sep 2026 |
| Legionella flush | Cedar Court | 04 Sep 2026 |
| default | Property | Next run |
|---|---|---|
| Fire door inspection | Willow House | 02 Sep 2026 |
| Legionella flush | Cedar Court | 04 Sep 2026 |
| comfortable | Property | Next run |
|---|---|---|
| Fire door inspection | Willow House | 02 Sep 2026 |
| Legionella flush | Cedar Court | 04 Sep 2026 |
Mobile strategy — stacked data rows
Below sm the table is replaced by DataRow cards rather than shrunk: primary information first, then labelled metadata, then actions.
Margaret Whitfield
Willow 12
- Care plan
- Enhanced care
- Key worker
- Priya Raman
- Next review
- 12 Sep 2026
Alan Brightwell
Cedar 04
- Care plan
- Residential
- Key worker
- Tom Okafor
- Next review
- 28 Aug 2026
List & people
Record lists and the shared person treatment.
List
A vertical record list for content that reads as sentences rather than columns — assets, services, notifications. Same hierarchy rules as the table: primary, secondary, metadata, action.
import { List, ListItem, ListContent, ListActions } from "@/design-system";
When to use
- Two or three attributes per record.
- Rows that pair an avatar or icon with a short description.
- Selectable pickers inside drawers and dialogs.
When not to use
- Comparing many attributes across records — use Table.
- A single record's full detail — use DescriptionList.
List with icon, metadata, status and action
- Property assets
Passenger lift — Willow House
Serviced 14 Jul 2026
Nurse call system — Cedar Court
Serviced 02 Aug 2026
Boiler — Elm Lodge
Service overdue
Multi-select list
Selection reuses the V2 Checkbox — never a bespoke control.
Passenger lift — Willow House
Serviced 14 Jul 2026
Nurse call system — Cedar Court
Serviced 02 Aug 2026
Boiler — Elm Lodge
Service overdue
UserRow
One treatment for a person across every module: assignees, key workers, residents and contacts all render identically.
import { UserRow } from "@/design-system";
When to use
- Anywhere a person is listed, assigned or selected.
- Inside table cells, lists, cards and assignment drawers.
When not to use
- A person's full profile — use DescriptionList or a detail layout.
- A dense mention chip — use Chip.
Sizes and slots
Priya Raman
Key worker
Tom Okafor
Senior carer
tom.okafor@centrimlife.example
Hana Lindqvist
Registered nurse
hana.lindqvist@centrimlife.example
Cards
Grouped surfaces, choices and read-only information.
Card
A grouped surface for content that belongs together. Hierarchy comes from radius, padding and a hairline border — elevation is reserved for surfaces that actually float.
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/design-system";
When to use
- Grouping a summary with its own actions.
- Grid layouts of comparable records, e.g. service groups.
When not to use
- Wrapping every element on a page — nested cards flatten hierarchy.
- A choice the user must make — use SelectionCard.
Variants
Willow House
42 residents · 3 care plans
Cedar Court refurbishment
Programme update · 21 Aug 2026
Lounge and dining areas reopen to residents from 04 September.
Interactive card
Renders as a real anchor for navigation.
Archived service group
Read-only until reinstated.
SelectionCard
A card-sized choice for residents, services, service groups, plans and assets. The card is the control — it renders a real radio or checkbox.
import { SelectionCard, SelectionCardGroup } from "@/design-system";
When to use
- Choices that need a description or price to be made confidently.
- Two to six options shown side by side.
When not to use
- Long option lists — use Select or Combobox.
- Presentational grouping — use Card.
Plan selection
Applied from the next billing period.
InfoCard
A read-only information block: label + value, title + description, or icon + information, with metadata one step quieter than the value.
import { InfoCard } from "@/design-system";
When to use
- Summarising a record at the top of a detail screen.
- Grids of contract, property or compliance facts.
When not to use
- A tracked number with a trend — use Metric.
- Long lists of pairs — use DescriptionList or KeyValue.
Information cards
Occupancy
93%
Willow House · updated 09:15
Next CQC review
12 Sep 2026
Documentation pack due one week prior.
Contract
Local authority
Ref CL-2291Ends 31 Mar 2027
Record detail
Metadata, history and the shared action set.
Metadata & key-value
Label/value information for a single record. KeyValue is the loose pair; DescriptionList is the semantic <dl> for record summaries.
import { KeyValue, DescriptionList, DescriptionItem } from "@/design-system";
When to use
- Record summaries in a detail aside.
- Contract, asset or property attributes.
When not to use
- Comparing records — use Table.
- Editable values — use FormField.
Key-value metadata
- Service group
- Personal care
- Frequency
- Twice daily
- Funding
- Local authority
Activity & history
The chronological record of changes, assignments and status transitions on an entity — the same treatment for audit logs, care notes and job history.
import { ActivityFeed, ActivityItem } from "@/design-system";
When to use
- Audit trails and record history tabs.
- Assignment and status-change logs.
When not to use
- Future planned steps — use Stepper or Timeline.
- Unread system messages — use the notifications pattern.
Record history
- PR
Priya Raman changed the care plan to Enhanced care
- TO
Tom Okafor assigned the fire door inspection to Hana Lindqvist
- S
Centrim Life marked resident status as On leave
Hospital admission recorded by the night team.
Data actions & feedback
View, edit, delete, assign and more-actions all reuse the V2 Button and IconButton — tables and cards never get their own action styles. Completion is confirmed with a Toast.
import { Button, IconButton, useToast } from "@/design-system";
When to use
- Row-level and card-level actions.
- Confirming a completed data action.
When not to use
- Announcing a persistent condition — use Alert or Banner.
- Field validation — use InlineFeedback.
Standard action set
Skeletons
Structure-matching placeholders for table rows, list rows, user rows, cards and metadata. One gentle pulse, disabled under prefers-reduced-motion.
import { SkeletonTableRow, SkeletonListRow, SkeletonUserRow, SkeletonMetadata } from "@/design-system";
When to use
- First load of a known layout.
- Refreshing a list or table in place.
When not to use
- Unknown result shapes — use PageLoading.
- Short in-place actions — use the button's loading state.