StatusDot
$ npx shadcn@latest add https://lacodda.github.io/dowel/r/status-dot.jsonEvery product drew its own coloured circle, and every one of them drew it the
same way — a <span> with a background — which means the condition existed
for exactly the readers who could see it.
The rule this pair is built on:
Colour is emphasis. The word is the message.
That is not a preference. About one man in twelve does not separate red from
green, --good and --bad are the two hues most screens rest on, and a
printed or projected screen loses the distinction for everybody. So label is
required, and a label that is not printed is still in the accessibility tree.
<StatusDot status={run.ok ? 'good' : 'bad'} label={t(`run.state.${run.state}`)} />The word is announced once. The dot and its text are one role="img" with
one aria-label, and the printed copy is aria-hidden — otherwise a reader
hears the state twice, once from the image and once from the text beside it.
StatusBadge is the same fact with room to write it. It is separate
rather than a variant because the choice between them is about the space on
the screen, not about the state — and a product that has the room should be
nudged towards the words. The badge is not named as an image: the word is on
the screen, and labelling it would replace the text a reader can already hear.
A shape is the second channel. icon replaces the dot with a tick, a cross
or an exclamation, which differ by shape rather than by hue. A badge given an
icon drops its dot — two marks for one condition is noise.
neutral is not a fifth colour. It is the absence of a judgement, for the
states that are neither good nor bad: queued, archived, unknown. Drawing those
in one of the four would be a claim the product did not make.
No words of its own. “Online” is the product’s vocabulary in the product’s language. See Badge for a label of any other kind, and Timeline, which takes the same vocabulary.
Props
Read from the types in ui/status-dot.tsx, the file a product copies - so the description of each prop is also what an editor shows over it there.
StatusDot
A dot, and the word it stands for.
| Prop | Type | Default | |
|---|---|---|---|
status | good | warn | bad | info | neutral | 'neutral' | |
size | sm | md | lg | 'md' | |
labelrequired | string | What this condition is called, in the product's words. Required, and not for decoration: it is what the dot means to anyone who does not see the colour. | |
showLabel | boolean | false | Whether to print the label beside the dot. |
icon | ReactNode | A shape drawn inside the dot's place instead of the circle - a tick, a cross, an exclamation. The second channel for a reader who sees the dot but not its hue, and the reason pulse is not the only way to differ. |
And every prop of React's HTMLAttributes<HTMLSpanElement> except children, passed on.
StatusBadge
The state, written out, on a tinted ground.
| Prop | Type | Default | |
|---|---|---|---|
status | good | warn | bad | info | neutral | 'neutral' | |
icon | ReactNode | A shape before the word - the second channel, where there is one. | |
dot | boolean | true | Draw the dot before the word. Off when an icon is given: two marks for one state is noise. |
And every prop of React's HTMLAttributes<HTMLSpanElement>, passed on.
Accessibility
The examples on the stand, through axe 4.14.0 in a browser, in both themes, against WCAG 2.2 A and AA and axe's best practices: 16 rules applied and passed, and none failed. The accessibility report has every item.
History
Each release that changed ui/status-dot.tsx - the file a product copies - newest first.