Design System / 07.8
Feedback
Show status beside the affected content, inside a running task, or in a short-lived toast. Every moving indicator has a still reduced-motion state.
Alert
A paper status block with a hairline frame and tinted left edge. The label and status dot repeat the state in words and shape; a muted companion tint is optional, never the only signal, and falls back to currentColor when a host omits tint tokens. Error uses an assertive alert role; the other states are polite status regions.
Live specimen
Rendered output
Notice
Success
Warning
Error
API reference
Inputs, types, and behavior
- Inputvariant
- Type"error" | "warning" | "success" | "info"
- BehaviorDefaults to info. Error maps to role="alert"; every other state maps to role="status".
- Inputlabel
- Typestring?
- BehaviorOverrides the visible state word. A blank value falls back to the variant label.
- Inputchildren
- TypeReactNode
- BehaviorMessage body. Keep urgent dynamic errors in Alert and non-urgent confirmations in Toast.
- InputclassName / classNames
- Typestring? / { root, label, body }?
- BehaviorclassName is an alias for classNames.root. Each slot merges last and wins over the recipe, so a host type ladder reaches the label. A font-size passed through a slot drops the recipe's leading — restate it. The block sits on --surface.
Empty state
A centered hairline frame for an empty result, with a concise label, optional context, and one useful next action. The component adds no live-region behavior, so a host controls when and how a newly empty result set is announced.
Live specimen
Rendered output
No proofs awaiting review
API reference
Inputs, types, and behavior
- Inputlabel
- Typestring
- BehaviorRequired visible uppercase headline; blank runtime input falls back to Nothing here.
- Inputchildren
- TypeReactNode?
- BehaviorShort context capped at a 38ch measure.
- Inputaction
- TypeReactNode?
- BehaviorOptional slot for one relevant Button or link with its own behavior.
- InputclassName / classNames
- Typestring? / { root, label, body, action }?
- BehaviorclassName is an alias for classNames.root. The label slot is how a host applies its own micro register; the root class alone never reached it. Restate leading alongside any font-size. The frame sits on --surface.
Progress bar
A two-pixel track with a transform-scaled determinate fill. Values clamp to zero through one; non-finite values become indeterminate instead of emitting broken styles or ARIA. Without a value, a band sweeps the track; reduced motion holds a static dim band.
Live specimen
Rendered output
API reference
Inputs, types, and behavior
- Inputvalue
- Typenumber?
- BehaviorZero through one, clamped. Omit or pass a non-finite value for indeterminate progress.
- InputshowValue
- Typeboolean = false
- BehaviorShows a rounded tabular percentage only for determinate progress.
- Inputlabel
- Typestring = "Progress"
- BehaviorAccessible name for the progressbar; blank input falls back to Progress.
- InputclassName
- Typestring?
- BehaviorMerged last on the full-width bar and optional value row.
Progress steps
An ordered workflow with numbered squares and hairline connectors. Completed, current, and upcoming states differ in fill, border, and text; assistive technology also receives completion text and aria-current. A non-finite or negative current index starts at zero, while an index at or beyond the list length marks every step done.
Live specimen
Rendered output
- Completed: Brief
- Completed: Draft
- Proof
- Release
Completed state
- Completed: Brief
- Completed: Draft
- Completed: Proof
- Completed: Release
API reference
Inputs, types, and behavior
- Inputsteps
- Typestring[]
- BehaviorOrdered labels. Empty strings receive a numbered fallback; an empty array renders an empty named list.
- Inputcurrent
- Typenumber
- BehaviorZero-based current index. Finite fractions truncate; invalid or negative values resolve to zero.
- Inputlabel
- Typestring = "Progress"
- BehaviorAccessible name for the ordered list; blank input falls back to Progress.
- InputclassName
- Typestring?
- BehaviorMerged last on the ordered list; add a minimum width when a long flow should scroll instead of compress.
Scenario runner
A user-started sequence for long tasks such as exports, deployments, and imports. Named stage buttons allow direct selection; Run, Pause, Replay, and Reset keep control with the reader. Output enters over 300ms using opacity and a four-pixel settle, while reduced motion switches states instantly. Nothing autoplays on mount, and a running sequence pauses when its browser tab becomes hidden.
Live specimen
Rendered output
Issue export
Source package
Gather the layout, linked images, fonts, and current captions.
API reference
Inputs, types, and behavior
- Inputsteps
- TypeScenarioStep[]
- BehaviorUp to forty named stages with ReactNode content, optional metadata, stable id, and 500–10,000ms dwell before the next stage.
- Inputlabel / description
- Typestring / ReactNode?
- BehaviorNames the section and output region; the current stage is announced politely only after user interaction.
- InputheadingAs
- Type"h2"–"h6" = "h3"
- BehaviorSets the visible runner-title level. Stage selection remains an ordinary ordered list of buttons linked to one output region.
- InputoutputClassName
- Typestring?
- BehaviorMerged last on the output viewport for host-owned sizing and layout.
- InputclassName
- Typestring?
- BehaviorMerged last on the squared outer frame.
Skeleton
Secondary-surface placeholders for a block, one line, or a short text stack. Their slow opacity breath is decorative and stops under reduced motion. Add one loading label per region; unlabeled skeletons remain hidden from assistive technology. The owning region, not the placeholder, should carry aria-busy.
Live specimen
Rendered output
API reference
Inputs, types, and behavior
- Inputvariant
- Type"block" | "line" | "text"
- BehaviorDefaults to a 120px block. Text stacks lines and shortens its last row.
- Inputlines
- Typenumber = 3
- BehaviorText row count, floored and bounded from 1–100. Non-finite input returns to three.
- Inputlabel
- Typestring?
- BehaviorAdds role="status" with hidden loading text; blank input keeps the visual decorative.
- InputclassName
- Typestring?
- BehaviorMerged last on the visual block, line, or text stack for sizing.
Spinner
A rotating square outline rather than a circular spinner. It can move continuously or tick through eight discrete steps, inherits currentColor in inverse contexts, and becomes a static square when reduced motion is requested.
Live specimen
Rendered output
API reference
Inputs, types, and behavior
- Inputlabel
- Typestring = "Loading"
- BehaviorHidden text inside role="status"; blank input falls back to Loading.
- Inputsize
- Typenumber = 14
- BehaviorSquare edge in pixels. Non-positive or non-finite input returns to 14.
- Inputstepped
- Typeboolean = false
- BehaviorUses eight discrete rotational steps instead of a continuous turn.
- InputclassName
- Typestring?
- BehaviorMerged last on the inline status wrapper.
Toast
The exported standalone notification block. Its label and message form one polite, atomic status; the optional 44px dismiss control is a sibling, so its button name is not repeated in the announcement. The block owns no placement or timer. Urgent errors belong in Alert.
Live specimen
Rendered output
Archive note
API reference
Inputs, types, and behavior
- Inputchildren
- TypeReactNode
- BehaviorNon-urgent notification body.
- Inputlabel
- Typestring = "Notice"
- BehaviorVisible mono label; blank input falls back to Notice and also names the dismiss action.
- InputonDismiss
- Type() => void?
- BehaviorAdds a self-dimming 44px × button. The parent still owns removal and any focus policy.
- InputclassName
- Typestring?
- BehaviorMerged last on the paper notification block.
Toast provider
The client-side delivery layer. useToast queues a fixed bottom-right stack, returns each ID, and can dismiss by ID. At most three active notices remain; adding a fourth retires the oldest. Hover or focus pauses every auto-dismiss clock, and exit timing collapses when the live reduced-motion preference is active.
Live specimen
Rendered output
API reference
Inputs, types, and behavior
- Inputchildren
- TypeReactNode
- BehaviorApplication subtree that can call useToast; mount one provider outside transform and filter ancestors.
- Inputtoast(input)
- Type({ message, label?, duration? }) => number
- BehaviorQueues a notice and returns its ID. Duration defaults to 4000ms; non-positive values persist; non-finite values use the default.
- Inputdismiss(id)
- Type(number) => void
- BehaviorStarts the same guarded exit as the built-in × button; stale IDs are safe no-ops.
"use client";
function SaveNotice() {
const { toast } = useToast();
return (
<Button
onClick={() =>
toast({ message: "The production proof was archived." })
}
>
Save proof
</Button>
);
}
<ToastProvider>
<SaveNotice />
</ToastProvider>