A short list of facts about one thing, each a name and what it is, such as "Operator: Movia" and "Last report: 08:14" about a vehicle, set as a description list in a detail panel or a report.
When to use
Use FactList for several facts about one thing, each a name and what it is, such as a vehicle's operator and last report in its detail panel.
| Use instead | When |
|---|---|
| Stat | The fact is one key figure, set large to read at a glance |
| VehicleTable | People compare the same facts across many vehicles, one row each |
| EmptyState | There are no facts to show |
Kongens Nytorv
Metro M1, M2 and M3.
- Operator
- Movia
- Vehicle
- 8412
- Speed
- 32 km/h
- Last report
- 08:14
Props
| Name | Type | Default | Description |
|---|---|---|---|
items* | readonly FactListItem[] | — | The facts, in reading order, each { label, value, key }: label names the fact, value says what it is, and key is its React key when the facts change order. Required |
unknownLabel | string | The locale's | Overrides "Unknown", heard in place of "—" for a fact with no value |
className | string | — | Joined after pn-FactList on the root |
style | CSSProperties | — | Reaches the root |
ref | Ref<HTMLDListElement> | — | Reaches the root element |
slotProps | { item?: ComponentProps<"div", {}, HTMLProps> | undefined; label?: ComponentProps<"dt", {}, HTMLProps> | undefined; value?: ComponentProps<"dd", {}, HTMLProps> | undefined; } | — | Props for each part: item, label, value. |
items (required)readonly FactListItem[], default —- The facts, in reading order, each
{ label, value, key }:labelnames the fact,valuesays what it is, andkeyis its React key when the facts change order. Required unknownLabelstring, default The locale's- Overrides "Unknown", heard in place of "—" for a fact with no value
classNamestring, default —- Joined after
pn-FactListon the root styleCSSProperties, default —- Reaches the root
refRef<HTMLDListElement>, default —- Reaches the root element
slotProps{ item?: ComponentProps<"div", {}, HTMLProps> | undefined; label?: ComponentProps<"dt", {}, HTMLProps> | undefined; value?: ComponentProps<"dd", {}, HTMLProps> | undefined; }, default —- Props for each part:
item,label,value.
Use it
import { FactList } from '@mylder/perron'Ask your agent
search_docs({ query: "FactList" })Keyboard and ARIA
FactList has no keys of its own and is never focusable. A value the caller makes a link or button brings that element's own keys, in reading order.
| Key | Does | From |
|---|---|---|
| None | FactList is not focusable or operable | Perron |
| Element | Role | Accessible name from | States announced |
|---|---|---|---|
root | None in ARIA: the browser exposes a description list | Not named, or the caller's aria-label or aria-labelledby | None; most screen readers say how many facts it holds |
item | None (generic div) | Not named; its name and value are read in place, name first | None |
label | term, from the dt | Its text, from the item's label | None |
value | definition, from the dd | Its text, from the item's value | None |
The "—" in value, when unknown | Hidden: aria-hidden="true" | Not read | None |
The words in value, when unknown | Text, in VisuallyHidden | The owned string "Unknown", or unknownLabel | None |
What axe won't catch, from the contract, each with how this component meets it:
- Everything the eye is told, the ear is told, for every shape each prop accepts: each name and value is read as shown, name first; "—" is
aria-hiddenand the ear hears "Unknown" in its place (CR-5). No colour carries meaning: values arecolor.text.primary, and tertiary only for the "—" the words speak for. - Every landmark and named region has an accessible name: none here; the
dlis a list, not a landmark or region, and a caller who names it givesaria-labeloraria-labelledbyon the root. - Every default label can be overridden:
unknownLabel. - Every shape the type accepts renders, in every variant:
labelandvalueareReactNodes; a string, a number, an element and a list each render,0is a value and not unknown (CR-4), an emptyitemsrenders an emptydl(CR-8), andFactList.test.tsxrenders each shape. TheDefaultstory gives string names and values. - A hidden copy kept for animation is
aria-hidden, and a collapsed region isinert: none here; nothing animates or collapses. The "—" isaria-hiddenbecause the words speak for it, not for animation. - Native semantics first:
dl,div,dtanddd, HTML's description list, with no role and no ARIA beyondaria-hiddenon the "—". - Focus moves in reading order and returns on close: FactList takes no focus and opens nothing; focusable values, such as links, come in the order of
items. - Every target is at least
size.target-minsquare: no target of its own; a link a caller puts in a value is the caller's to size. - Loops stop when the system asks for less motion: none here; FactList has no motion.
Owned strings
Every word FactList shows comes from the caller, through each item's label and value, but for the one it announces for a fact with no value.
| Key | English | Override | Seen or heard where |
|---|---|---|---|
unknown | "Unknown" | unknownLabel | value, heard in place of the aria-hidden "—" when an item has no value (CR-5) |
A fact with no value shows "—" and says "Unknown", reusing Stat's unknown key. Content design writes "—" for unknown and the brand never shows a guess, while a screen reader skips or spells a bare "—", so the ear would hear a name with nothing after it; Stat and Delay do the same, and one word across the Display family keeps every screen agreeing. unknown, "Unknown", is the key Stat added to packages/perron/src/locale/en.ts, with Danish "Ukendt", Swedish "Okänd" and Norwegian Bokmål "Ukjent"; its JSDoc, which names Stat alone, widens to name any figure or value no data gives.
Do and don't
For a caller using the component, with the reason. Each row is a rule: a must row's Don't is never right, a should row's needs a reason, and Checked by says what catches the Don't in a caller's code.
| Rule | Level | Do | Don't | Checked by |
|---|---|---|---|---|
| DD-1 | must | Leave out an item's value when no data gives it, so FactList shows "—" and says "Unknown" | Write "0", "n/a" or a guess for a value nobody knows: the brand never claims more than the data knows | review |
| DD-2 | must | Name each fact in a word or two, "Operator", "Last report", and write its value as content design does, "32 km/h" | Put the name inside the value, such as "Speed 32 km/h": the name and value then read as one term with no definition | review |
| DD-3 | should | Use FactList for several facts about one thing, such as a vehicle in its detail panel | Use it for one key figure, which is a Stat, or for rows people compare across many things, which is a table | review |
| DD-4 | must | Name the list with aria-labelledby pointing at the panel's heading when the panel holds more than one list | Give the list a heading inside items: every entry is a fact, a name and its value | review |
| DD-5 | must | Say a status in words in the value, or show it with a SeverityLabel or a Delay | Colour a value through className to say it is good or bad: colour alone tells no screen reader and no colour-blind person | review |
| DD-6 | should | Show EmptyState in place of FactList when there are no facts to show | Render FactList with an empty items and nothing beside it: an empty list tells the person nothing | review |
| DD-7 | must | Keep render on the root to another dl, or a component that renders one | Swap the root for a ul or div through render: its dt and dd would sit outside a dl, which HTML and axe both fail | review |
| DD-8 | must | Announce a changed fact in the screen's own polite live region, when it changes state | Make FactList a live region: a speed or report time that updates every few seconds floods the screen reader | review |