Status and feedback
Which component to use for telling someone what happened, what state a thing is in, or that it is loading. Find the job, take the component, and read the “not when” before you commit: it names the thing people reach for by mistake, and what to use instead.
At a glance
| Job | Use | Not when | Instead | Because |
|---|---|---|---|---|
| Say something about the page that stays until it is no longer true | Alert | A figure or list is built from only some of its sources | State | State kind="partial" sits right above the figures and says how many arrived; a banner is read past and the figure still looks like the total. |
| Confirming an action the person just took, which needs no further attention | Toast | A toast reports an event and leaves; an alert reports a condition and stays. | ||
| The region has nothing to show, failed to load, or is not allowed | State | A state replaces the content it stands for; an alert sits above content that is still there. | ||
| A note inside prose that qualifies what is around it | Callout | A callout is a rule beside text at reading scale; a tinted banner would make it an alert it is not. | ||
| The person must answer before anything else can happen | Dialog | A dialog takes focus and must be dismissed; an alert can be read past. | ||
| A form step has fields that failed validation | ErrorSummary | The error summary links each problem to its field and takes focus on submit. | ||
| Set a quiet aside inside prose | Callout | The message is about the page or a region, not the paragraph | Alert | An alert is a banner with a tone and an action; a callout is a rule beside text. |
| The region has nothing to show | State | A state says why the content is absent and what to do; a callout assumes there is prose around it. | ||
| A hint that belongs to one form field | Field | A field hint is tied to its control by aria-describedby; a callout is not. | ||
| A short status word | Tag | A status is one or two words in a tag, never a sentence. | ||
| Keep one broken region from blanking the app, and say plainly that it could not be shown | ErrorBoundary | A fetch failed or a source did not answer | State | A failed fetch is a state the screen expected and renders itself, with a retry; a boundary is for a render that threw. |
| The content is there and something about it is wrong or stale | Alert | An alert sits above content that still shows; a boundary replaces content that could not be drawn. | ||
| Show one file on its way — how far, and cancel or retry | FileProgress | The file has been attached and nothing is moving | FileUpload | FileItem lists what is attached; a transfer row exists only while bytes move or after they failed. |
| One task that is not a file — an import, an export | Progress | A labelled bar carries the same layout without the file's size and actions. | ||
| A batch of many files where only the totals matter | SegmentedProgress | Forty rows is a wall; a segmented bar says how many arrived, failed and wait. | ||
| Show an integration and the state it is in, with the way to fix it | Connection | The status is not about an integration | Tag | A tag is the general status word; ConnectionStatus has only the integration states. |
| The problem needs the reader to act before carrying on with the page | Alert | An alert is an inline banner with a title, body and action for one problem. | ||
| The thing on the row is an API key or a secret | KeyList | Keys have a fingerprint, scopes, last use and expiry; a connection has none of those. | ||
| Show how far one task has got toward done | Progress | A level that is simply true — usage, capacity, a score against a target | Meter | role="meter" reports a level; a progress bar says a task is advancing, and swapping them misreports what is happening. |
| Many items, each finished one way or another — 6 done, 1 failed, 3 to go | SegmentedProgress | One fill cannot say how things finished; a segmented bar splits the track by state and says each count. | ||
| The reader needs to see WHICH tasks are done, not just how many | ProgressList | A bar is a quantity; a checklist names each task and its state. | ||
| One row's live work in a list or table, with where it is and a count | LiveProgress | Live progress carries the pulse, the place being worked and the count, and turns into a tag when done or failed. | ||
| A file being uploaded or downloaded | FileProgress | A transfer row carries the name, the size, cancel and retry around the same bar. | ||
| The person is moving through named steps | Stepper | A stepper names each step and its state; a bar only says how much. | ||
| A short wait inside a control with nothing to measure | Spinner | A spinner is the smallest "still working" and takes no room. | ||
| Mark one item's state with the progress family's disc or glyph | ProgressMark | A whole list of tasks with their states and a count | ProgressList | The checklist already lays out the marks, the labels and the count, and announces failures. |
| A status word with a tint, standing alone | Tag | A tag is the status; a mark is decoration beside words and is hidden from assistive tech. | ||
| Show how a set of items is going, split by how each one finished | SegmentedProgress | One task with one fraction done | Progress | A single fill is clearer when there is only one way to finish. |
| The reader needs each item by name | ProgressList | A segmented bar counts; a checklist names. | ||
| The items move between states while the reader watches, by name | Lanes | Lanes show each agent as a pill sliding between states; a segmented bar is the summary. | ||
| Parts of a whole that are not progress — a budget by category, a share of votes | BarChart | A stacked bar chart is a composition; this is work advancing, coloured by state. | ||
| Show a list of tasks the system is working through, each with its state, and how many are done | ProgressList | The reader ticks the items off themselves | Checklist | A checklist is checkboxes the reader owns; a progress list reports work the system does. |
| Steps of a form the reader moves through, one current, with back and next | Stepper | A stepper is a position in an order the reader walks; a progress list is work being done for them. | ||
| Many items, where only the counts matter | SegmentedProgress | Naming a hundred items is a wall; a segmented bar says how many in each state. | ||
| Several agents running at once | Lanes | Lanes show concurrency — who is waiting, working and done; a list is one sequence. | ||
| Hold the shape of content that is still being read | Skeleton | There is nothing to show | State | A skeleton means "still reading" and never "nothing here"; an empty state names the cause and the way out. |
| The read failed, or a failed read is being retried | State | A skeleton never tells you it has finished; an error state says what went wrong, and the retry button shows its own wait. | ||
| A figure is shown from only some of its sources | State | The read finished; a skeleton would claim it is still loading. State kind="partial" says what is missing. | ||
| The wait is short and the layout is not known | Spinner | A spinner marks a brief wait without promising a shape. | ||
| A section is being written by a run right now | Live | LiveSection and LiveMark say the section is being written, in words. | ||
| Show that a short wait is under way, where its result will appear | Spinner | The shape of the content that is loading is known | Skeleton | A skeleton holds the layout so nothing jumps when the content lands. |
| The work has a known amount done and to do | Progress | A progress bar says how far along it is; a spinner only says "busy". | ||
| An agent or a run is working on something the reader is watching | Live | Live work is drawn where the work is, with a word beside the pulse. | ||
| A circular indicator with a known amount done | Progress | ProgressRing is the same ring with a value; the spinner is that ring when nothing can be measured. | ||
| A button is submitting | Button | The button has its own loading state (.is-loading) and keeps its label and width. | ||
| Stand in for content that is loading, empty, partial, failed, denied or done | State | The content is there and something about it needs saying | Alert | An alert sits above content that is still shown; a state replaces it. |
| The region is still loading and its shape is known | Skeleton | A skeleton holds the layout while it reads; State kind="loading" is for when the shape is not known. | ||
| A sign-in or access page that stands before the product | Entry | A way in is not an empty state; read as one it looks like a dead end. | ||
| Confirming a quick action that worked | Toast | A success state replaces a whole region; most successes only need a toast. | ||
| Show where someone is in a named sequence of steps | Stepper | Building the whole multi-step form, with back and forward | Flow | The flow shell already holds a vertical stepper, one content region and the footer. |
| How much of one task is done, with no named steps | Progress | A bar says how much; a stepper says which. | ||
| Many agents or items moving through waiting, working and done at once | Lanes | Lanes show many items by state; a stepper is one sequence. | ||
| A list of tasks the system works through for the reader — setup, an agent's run | ProgressList | A stepper is a position the reader walks; a progress list reports work done for them, with a spinner on the running task. | ||
| Events that already happened, in order | Timeline | A timeline is history; a stepper is position in a plan. | ||
| Say in one or two words what state a thing is in | Tag | The word is something the reader can press to do something | Button | A status is a tag and an action is a button; where both sit on one row they must differ in shape, not only in colour. |
| The value is a neutral attribute — an owner, a standard, a type — that may narrow the list | Facet | A tag carries no status here and is decoration; a facet is a name and a value, and narrows when pressed. | ||
| The state is an integration being connected, degraded or off | Connection | ConnectionStatus carries the integration states with a decorative dot and the word. | ||
| The status needs a sentence to explain it | Alert | A tag is one or two words; prose belongs in an alert, a hint or a state body. | ||
| Confirm that something just happened, briefly, without taking focus | Toast | You want to raise a toast from anywhere in the app with timers handled | ToastProvider | The provider owns the queue, the timeout and the pause on hover; Toast is only the surface. |
| The condition is still true after the moment passes — a failed source, a stale figure | Alert | A toast leaves; a condition that leaves with it is a condition nobody can find again. | ||
| The person has to decide something before going on | Dialog | An action in a toast is right for undo, not for a decision: a toast is polite and can be missed, and a decision needs a modal that holds focus. | ||
| An agent proposes a change and the person has to confirm or approve it | ConfirmCard | An action in a toast is right for undo, not for a decision; the confirm card holds the values and waits in the conversation until it is answered. | ||
| The region the action was meant to fill is empty or failed | State | The result belongs where the content would be, not in a corner. | ||
| Raise toasts from anywhere in an app, with the queue and timers handled | ToastProvider | You render the toast markup yourself, or in static HTML | Toast | The provider renders Toast for you; use the parts directly only when you own the queue. |
| The person has to decide something — confirm a delete, choose between two outcomes | Dialog | An action in a toast is right for undo, not for a decision; a decision needs a modal that holds focus until it is answered. | ||
| An agent asks the person to confirm or approve a change | ConfirmCard | An action in a toast is right for undo, not for a decision; the confirm card shows what will change and waits for an answer. | ||
| The message describes a condition rather than an event | Alert | A queued toast times out; a condition has to stay on the page. |
Alert
Say something about the page that stays until it is no longer true.
Use when
- A condition that holds for the whole page or region — a source is stale, eleven items are unanswered, the run failed.
- A message with a way out of it: put the action in
AlertActions, beside the problem it fixes. - Set
livewhen the banner appears after load; danger and warning announce assertively, the rest politely.
Not when
- A figure or list is built from only some of its sources →
State.State kind="partial"sits right above the figures and says how many arrived; a banner is read past and the figure still looks like the total. - Confirming an action the person just took, which needs no further attention →
Toast. A toast reports an event and leaves; an alert reports a condition and stays. - The region has nothing to show, failed to load, or is not allowed →
State. A state replaces the content it stands for; an alert sits above content that is still there. - A note inside prose that qualifies what is around it →
Callout. A callout is a rule beside text at reading scale; a tinted banner would make it an alert it is not. - The person must answer before anything else can happen →
Dialog. A dialog takes focus and must be dismissed; an alert can be read past. - A form step has fields that failed validation →
ErrorSummary. The error summary links each problem to its field and takes focus on submit.
Callout
Set a quiet aside inside prose.
Use when
- A note, caveat or rule that qualifies the text around it — "Figures exclude the March import."
- A short absence or warning at reading scale:
tone="warning"tints the rule, nothing else.
Not when
- The message is about the page or a region, not the paragraph →
Alert. An alert is a banner with a tone and an action; a callout is a rule beside text. - The region has nothing to show →
State. A state says why the content is absent and what to do; a callout assumes there is prose around it. - A hint that belongs to one form field →
Field. A field hint is tied to its control byaria-describedby; a callout is not. - A short status word →
Tag. A status is one or two words in a tag, never a sentence.
ErrorBoundary
Keep one broken region from blanking the app, and say plainly that it could not be shown.
Use when
- Around a routed page, inside the frame, so the header and navigation stay when the page throws:
<ErrorBoundary resetKey={path}>, and leaving the page recovers it. - Around a panel that renders data it does not control — a detail pane, a chart, an embedded preview — with the record id as
resetKey. - Hand the error to
onErrorfor the log. The person seesState kind="error", never the error text.
Not when
- A fetch failed or a source did not answer →
State. A failed fetch is a state the screen expected and renders itself, with a retry; a boundary is for a render that threw. - The content is there and something about it is wrong or stale →
Alert. An alert sits above content that still shows; a boundary replaces content that could not be drawn.
FileProgress
Show one file on its way — how far, and cancel or retry.
Use when
- An upload or download in a
FileList: name and percent above a 4px bar, the size or the reason below, cancel while it moves and retry when it fails. - Arriving and failing are announced once; the percentage is never read aloud.
Not when
- The file has been attached and nothing is moving →
FileUpload.FileItemlists what is attached; a transfer row exists only while bytes move or after they failed. - One task that is not a file — an import, an export →
Progress. A labelled bar carries the same layout without the file's size and actions. - A batch of many files where only the totals matter →
SegmentedProgress. Forty rows is a wall; a segmented bar says how many arrived, failed and wait.
Connection
Show an integration and the state it is in, with the way to fix it.
Use when
- A list of connected systems, each with its mark, name, a note and its state — connected, degraded, error, pending or off.
- The state is a word in
ConnectionStatus; the dot is decorative, so colour is never the only signal. - Actions to connect, reconnect or configure sit on the row in
ConnectionActions.
Not when
- The status is not about an integration →
Tag. A tag is the general status word;ConnectionStatushas only the integration states. - The problem needs the reader to act before carrying on with the page →
Alert. An alert is an inline banner with a title, body and action for one problem. - The thing on the row is an API key or a secret →
KeyList. Keys have a fingerprint, scopes, last use and expiry; a connection has none of those.
Progress
Show how far one task has got toward done.
Use when
- An upload, an import or an export with a known fraction —
valueofmax;label,helperand the value lay out by the family rule: label start, value end, helper under. - Under way with no known fraction: omit
valuefor the indeterminate bar;toneonly once it has ended (success, warning, danger). ProgressRingwhere a bar does not fit — 16 to 64px, the value inside from 48px, an icon or nothing in the centre.
Not when
- A level that is simply true — usage, capacity, a score against a target →
Meter.role="meter"reports a level; a progress bar says a task is advancing, and swapping them misreports what is happening. - Many items, each finished one way or another — 6 done, 1 failed, 3 to go →
SegmentedProgress. One fill cannot say how things finished; a segmented bar splits the track by state and says each count. - The reader needs to see WHICH tasks are done, not just how many →
ProgressList. A bar is a quantity; a checklist names each task and its state. - One row's live work in a list or table, with where it is and a count →
LiveProgress. Live progress carries the pulse, the place being worked and the count, and turns into a tag when done or failed. - A file being uploaded or downloaded →
FileProgress. A transfer row carries the name, the size, cancel and retry around the same bar. - The person is moving through named steps →
Stepper. A stepper names each step and its state; a bar only says how much. - A short wait inside a control with nothing to measure →
Spinner. A spinner is the smallest "still working" and takes no room.
ProgressMark
Mark one item's state with the progress family's disc or glyph.
Use when
ProgressMark— a 24px (or 16px) disc in one of the six states: queued, current (a spinner), complete, failed, stopped, skipped. The same disc a stepper marker draws.ProgressGlyph— the tick, cross, dash or!inline at 1em, beside a word that says the same thing.
Not when
- A whole list of tasks with their states and a count →
ProgressList. The checklist already lays out the marks, the labels and the count, and announces failures. - A status word with a tint, standing alone →
Tag. A tag is the status; a mark is decoration beside words and is hidden from assistive tech.
SegmentedProgress
Show how a set of items is going, split by how each one finished.
Use when
- A batch, a run or a set of checks: one track split into done, failed, stopped, skipped, running and to go, with a legend that says every count in words.
- The value is how many have finished however they finished, and assistive tech hears the whole breakdown — "6 done, 1 failed, 3 to go".
Not when
- One task with one fraction done →
Progress. A single fill is clearer when there is only one way to finish. - The reader needs each item by name →
ProgressList. A segmented bar counts; a checklist names. - The items move between states while the reader watches, by name →
Lanes. Lanes show each agent as a pill sliding between states; a segmented bar is the summary. - Parts of a whole that are not progress — a budget by category, a share of votes →
BarChart. A stacked bar chart is a composition; this is work advancing, coloured by state.
ProgressList
Show a list of tasks the system is working through, each with its state, and how many are done.
Use when
- Setup, onboarding or an agent's run: each task with its mark, an optional description, and
3 of 7with a 4px bar. - The running task's mark is the spinner and the list is
aria-busy; a failure and the end of the list are announced, nothing else.
Not when
- The reader ticks the items off themselves →
Checklist. A checklist is checkboxes the reader owns; a progress list reports work the system does. - Steps of a form the reader moves through, one current, with back and next →
Stepper. A stepper is a position in an order the reader walks; a progress list is work being done for them. - Many items, where only the counts matter →
SegmentedProgress. Naming a hundred items is a wall; a segmented bar says how many in each state. - Several agents running at once →
Lanes. Lanes show concurrency — who is waiting, working and done; a list is one sequence.
Skeleton
Hold the shape of content that is still being read.
Use when
- A page or a list is loading and its layout is known — lines of text, a title, a block, an avatar circle.
- Inside a region that announces its own loading (
aria-busy); each bar is alwaysaria-hidden.
Not when
- There is nothing to show →
State. A skeleton means "still reading" and never "nothing here"; an empty state names the cause and the way out. - The read failed, or a failed read is being retried →
State. A skeleton never tells you it has finished; an error state says what went wrong, and the retry button shows its own wait. - A figure is shown from only some of its sources →
State. The read finished; a skeleton would claim it is still loading.State kind="partial"says what is missing. - The wait is short and the layout is not known →
Spinner. A spinner marks a brief wait without promising a shape. - A section is being written by a run right now →
Live.LiveSectionandLiveMarksay the section is being written, in words.
Spinner
Show that a short wait is under way, where its result will appear.
Use when
- A brief wait inside a control or a small region — a button submitting, a panel refreshing.
- Decorative by default: the surrounding region carries
aria-busy; passlabelonly when it stands alone. - It is the indeterminate ring of the progress family at 16, 24 and 32px — the same track, arc colour and stroke as
ProgressRing.
Not when
- The shape of the content that is loading is known →
Skeleton. A skeleton holds the layout so nothing jumps when the content lands. - The work has a known amount done and to do →
Progress. A progress bar says how far along it is; a spinner only says "busy". - An agent or a run is working on something the reader is watching →
Live. Live work is drawn where the work is, with a word beside the pulse. - A circular indicator with a known amount done →
Progress.ProgressRingis the same ring with a value; the spinner is that ring when nothing can be measured. - A button is submitting →
Button. The button has its own loading state (.is-loading) and keeps its label and width.
State
Stand in for content that is loading, empty, partial, failed, denied or done.
Use when
- A region has no content to show and needs to say why:
kindis loading, empty, partial, error, denied or success. - A figure or list built from some sources but not all:
kind="partial"directly above the figures that did arrive, saying which are missing and offering a retry. Use it instead of anAlertso the figure cannot be read as the full total. - An empty list or a failed read that names its cause and offers the way out in
StateActions(Create…, Retry);artgives an empty place a line drawing. A retry shows its wait on the button, not by swapping in aSkeleton.
Not when
- The content is there and something about it needs saying →
Alert. An alert sits above content that is still shown; a state replaces it. - The region is still loading and its shape is known →
Skeleton. A skeleton holds the layout while it reads;State kind="loading"is for when the shape is not known. - A sign-in or access page that stands before the product →
Entry. A way in is not an empty state; read as one it looks like a dead end. - Confirming a quick action that worked →
Toast. A success state replaces a whole region; most successes only need a toast.
Stepper
Show where someone is in a named sequence of steps.
Use when
- A multi-step task where each step is an act the person performs — markers, one per step.
- A sequence that is a position the work is somewhere in —
rail, which fills what is behind. - A step that was refused (
failed), interrupted (stopped) or passed over (skipped) — never left at current or marked complete.size="sm"anddescriptionfor dense or explained steps.
Not when
- Building the whole multi-step form, with back and forward →
Flow. The flow shell already holds a vertical stepper, one content region and the footer. - How much of one task is done, with no named steps →
Progress. A bar says how much; a stepper says which. - Many agents or items moving through waiting, working and done at once →
Lanes. Lanes show many items by state; a stepper is one sequence. - A list of tasks the system works through for the reader — setup, an agent's run →
ProgressList. A stepper is a position the reader walks; a progress list reports work done for them, with a spinner on the running task. - Events that already happened, in order →
Timeline. A timeline is history; a stepper is position in a plan.
Tag
Say in one or two words what state a thing is in.
Use when
- A row, card or heading reports a status — Draft, Approved, At risk, Failed — and the variant maps to its meaning.
- A quiet marker on a dense row:
dotputs a filled dot before the word instead of a tint.
Not when
- The word is something the reader can press to do something →
Button. A status is a tag and an action is a button; where both sit on one row they must differ in shape, not only in colour. - The value is a neutral attribute — an owner, a standard, a type — that may narrow the list →
Facet. A tag carries no status here and is decoration; a facet is a name and a value, and narrows when pressed. - The state is an integration being connected, degraded or off →
Connection.ConnectionStatuscarries the integration states with a decorative dot and the word. - The status needs a sentence to explain it →
Alert. A tag is one or two words; prose belongs in an alert, a hint or a state body.
Toast
Confirm that something just happened, briefly, without taking focus.
Use when
- The result of an action the person took — "Saved", "Invite sent", "Export ready" — with at most one way to take it back:
ToastActionfor Undo, beforeToastClose. - An event that happened elsewhere while they work, worth a glance and no more.
- Rendering the surface yourself; mount
ToastRegiononce, near the root, before any toast is added.
Not when
- You want to raise a toast from anywhere in the app with timers handled →
ToastProvider. The provider owns the queue, the timeout and the pause on hover;Toastis only the surface. - The condition is still true after the moment passes — a failed source, a stale figure →
Alert. A toast leaves; a condition that leaves with it is a condition nobody can find again. - The person has to decide something before going on →
Dialog. An action in a toast is right for undo, not for a decision: a toast is polite and can be missed, and a decision needs a modal that holds focus. - An agent proposes a change and the person has to confirm or approve it →
ConfirmCard. An action in a toast is right for undo, not for a decision; the confirm card holds the values and waits in the conversation until it is answered. - The region the action was meant to fill is empty or failed →
State. The result belongs where the content would be, not in a corner.
ToastProvider
Raise toasts from anywhere in an app, with the queue and timers handled.
Use when
- Wrap the app once and call
useToast().toast({ title, tone })from any component. - Toasts should time out, pause while the pointer is over them, and cap at a few on screen.
- Undo after the fact:
toast({ title, action: { label: 'Undo', onAction } }). A toast with an action stays until dismissed (it defaults toduration: 0), and its button is announced with it and reached by Tab.
Not when
- You render the toast markup yourself, or in static HTML →
Toast. The provider rendersToastfor you; use the parts directly only when you own the queue. - The person has to decide something — confirm a delete, choose between two outcomes →
Dialog. An action in a toast is right for undo, not for a decision; a decision needs a modal that holds focus until it is answered. - An agent asks the person to confirm or approve a change →
ConfirmCard. An action in a toast is right for undo, not for a decision; the confirm card shows what will change and waits for an answer. - The message describes a condition rather than an event →
Alert. A queued toast times out; a condition has to stay on the page.
Other guides: Screens · Overlays · Navigation · Data · Input · Reading · Agents and live work
Generated from the when.ts beside each component — the same data the Claude Code plugin reads.