Design 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.

Residents with room, care plan, key worker and status
StatusActions
AB

Alan Brightwell

Cedar 04

On leave
DS

Derek Salisbury

Cedar 11

Discharged
MW

Margaret Whitfield

Willow 12

Active
NO

Nadia Osei

Willow 07

Active

Density

Compact for administrative views, default for standard Centrim Life screens, comfortable for primary workflows. All three come from the V2 spacing scale.

Recurring jobs, compact density
compactPropertyNext run
Fire door inspectionWillow House02 Sep 2026
Legionella flushCedar Court04 Sep 2026
Recurring jobs, default density
defaultPropertyNext run
Fire door inspectionWillow House02 Sep 2026
Legionella flushCedar Court04 Sep 2026
Recurring jobs, comfortable density
comfortablePropertyNext run
Fire door inspectionWillow House02 Sep 2026
Legionella flushCedar Court04 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

Active
Care plan
Enhanced care
Key worker
Priya Raman
Next review
12 Sep 2026

Alan Brightwell

Cedar 04

On leave
Care plan
Residential
Key worker
Tom Okafor
Next review
28 Aug 2026

Accessibility

  • Every table has a caption; use Table's `caption` prop when it should be screen-reader only.
  • Header cells are real <th scope="col"> and carry aria-sort when sortable.
  • Sorting is announced by a hidden state word plus an arrow glyph, never colour alone.
  • Selection uses the V2 Checkbox with a per-row accessible name; select-all is tri-state.
  • Row actions are IconButtons with explicit labels naming the record.
  • Disabled rows set aria-disabled and keep readable contrast.

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 assets3 assets
  • Passenger lift — Willow House

    Serviced 14 Jul 2026

    Active
  • Nurse call system — Cedar Court

    Serviced 02 Aug 2026

    On leave
  • Boiler — Elm Lodge

    Service overdue

    Discharged

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

Accessibility

  • Lists are real <ul>/<li> so counts are announced.
  • Interactive rows are focusable and expose a visible focus ring.
  • Multi-select rows use the V2 Checkbox with the row title as its accessible name.

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

PR

Priya Raman

Key worker

TO

Tom Okafor

Senior carer

tom.okafor@centrimlife.example

On shift
HL

Hana Lindqvist

Registered nurse

hana.lindqvist@centrimlife.example

Accessibility

  • Avatar initials are decorative; the name is real text.
  • Selection controls and actions carry the person's name in their accessible name.
  • The row is a grid on mobile so long names truncate instead of clipping the status.

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

Occupancy is steady at 93% for the third consecutive month.
Communal lounge at Cedar Court

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.

Accessibility

  • Interactive cards use asChild with a real link or button, so keyboard and screen-reader behaviour is native.
  • Disabled cards set aria-disabled and remove pointer interaction.
  • Card media always carries alt text.

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

Care plan

Applied from the next billing period.

Accessibility

  • Single mode is a radiogroup, multiple mode renders checkboxes — no custom controls.
  • Selection is shown by the control glyph and a border/ring, never colour alone.
  • Errors are announced through the group's errorText, which also marks the cards invalid.

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

Renewing

Ref CL-2291Ends 31 Mar 2027

Accessibility

  • Icons are decorative and hidden from assistive tech; the label carries the meaning.
  • Metadata uses tertiary text, which still meets AA against every surface token.

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

RoomWillow 12
Key workerPriya Raman
Admitted04 Feb 2024
Next review
Service group
Personal care
Frequency
Twice daily
Funding
Local authority

Accessibility

  • DescriptionList renders a real <dl> with <dt>/<dd> pairs.
  • Loading pairs swap the value for a decorative skeleton, keeping the label readable.

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

    Plan change

  • 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.

Accessibility

  • Timestamps use <time> elements.
  • Actors are rendered as text next to the decorative avatar.
  • Status changes name the new status in the sentence, not only in a coloured badge.

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

Accessibility

  • Icon-only actions always pass a label naming the record.
  • Destructive actions use the destructive variant plus explicit wording.
  • Toasts announce politely and never carry the only copy of an outcome.

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.

Structure-matching placeholders