C-22 · Components · Feedback
All elements · EmptyState on the Components page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve EmptyState
Approving as
| Axis | Values |
|---|---|
data-variant |
empty (default) · no-results · loading · error · no-access · offline · coming-soon |
data-compact · data-bordered |
inline size / dashed frame |
__icon · __title · __description · __actions
|
slots |
Guidance
When to use
- Fill a list, table or pane that has no items yet, and say how to add the first one.
-
Show that a search or filter returned nothing with
data-variant="no-results"and a Clear filters action. -
Replace a region that failed to load with
data-variant="error"and Retry and Report actions. -
Explain why a region is blank with
no-access,offlineorcoming-soon. -
Use
data-compactinside a card or side pane, anddata-borderedfor a dashed frame where content will appear.
When to consider something else
- When only part of a view has a problem and the rest still works, use Banner above the content. See Banner.
- When content is loading and its layout is known, use Skeleton rather than the loading variant. See Skeleton.
- When a component or page crashed, use Error boundary. See ErrorBoundary.
- When the user drops files to fill the area, use Dropzone. See Dropzone.
Usability
- Say what is missing in the title and what to do in the description, such as "Try fewer filters or a different search term".
- Give one clear next step in
__actions, such as Browse queue or Clear filters. - For no access, name the group or role the user needs.
- Match the variant to the cause, so users can tell no data from no results from no access.
- Don't show an empty state while data is still loading; use the loading variant or Skeleton until the request ends.
- Don't blame the user or use jokes in error and no-access messages.
- Don't add an action the user has no permission to take.
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab / Shift+Tab | Moves to the buttons in __actions; the empty state itself is not focusable. |
| Enter or Space | Activates the focused action. |
Roles and names
-
The empty state adds no role.
__titleis adiv; when the empty state fills a whole pane, the binding should render it as a heading at the right level. -
The
__iconis decorative and should bearia-hidden; the title carries the meaning. - When the empty state replaces results after a search or filter, announce the title in a polite live region (4.1.3).
-
The loading variant should sit in a region with
aria-busy="true", or userole="status"so the loading text is announced. - The error variant shown after a user action may use
role="alert".
Focus
- Do not move focus to the empty state when it appears after filtering; keep it on the filter or search field.
- When an action, such as Clear filters, brings the content back, keep focus on a sensible control rather than losing it with the removed button.
Other requirements
- Text needs 4.5:1, including the secondary description (1.4.3); the dashed border is decorative and needs no contrast.
- The variant must not rely on the icon color alone to tell error from empty; the title says it in words (1.4.1).
-
The loading variant's spinner stops under
prefers-reduced-motion(2.3.3); its title must still say it is loading. - The layout must fit at 320px width without horizontal scrolling (1.4.10).
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (2 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (5 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- empty --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
No recorded changes yet.