A centered message that replaces a region when there is nothing to show, with an optional decorative icon and a useful next step. It owns the content composition, not the surrounding card, table, or page surface; loading belongs to Skeleton or Spinner, and failure belongs to Alert.
First-use copy explains what will live here and offers the direct creation step. The parent canvas is the region boundary; EmptyState adds no nested panel or dashed drop-zone frame.
Invite someone to start sharing projects and updates.
A decorative canonical icon, one title/body group, and one primary next step. The canvas supplies the only boundary; the EmptyState remains portable across page, Card, and Table regions.
No-results copy describes the current query rather than pretending the product has no data. Clearing the filter is a reversible secondary action; the host results region, not this component, owns any polite live announcement.
Try another search or clear the current filters.
The same anatomy handles a different content pattern without a modifier. No role="alert" and no focus movement are built into EmptyState.
Only content parts belong to EmptyState. The root supplies alignment and inset; actions keep the behavior and states of the existing Button or Link components.
| Part | Class | Requirement | Rule |
|---|---|---|---|
| Visual | ds-empty__visual + ds-icon | Optional | Neutral field around a canonical, decorative, aria-hidden icon |
| Content | ds-empty__content | Required | Constrains and groups the title/body pair |
| Title | ds-empty__title | Required | Names the absence; heading level follows context |
| Body | ds-empty__body | Required | One concise explanation or next step |
| Actions | ds-empty__actions | Optional | Zero to two ordinary Links or Buttons; at most one primary |
Absence should clarify the current state and shorten the route out of it.
| Verdict | Rule |
|---|---|
| Do | Use EmptyState for a settled first-use, zero-data, or no-results region, exactly where its content would otherwise appear. |
| Do | Name what is absent in the title and use the body for one explanation or useful next step without blame. |
| Do | Keep the icon optional, canonical, decorative, and aria-hidden; the title carries the meaning. |
| Do | Use ordinary Link or Button components for actions, with at most one primary and one optional secondary. |
| Don’t | Add a background, border, radius, or shadow. The parent owns the region surface; a dashed border reads as a drop zone. |
| Don’t | Use EmptyState while content is loading or when loading failed — use Skeleton or Spinner for waiting and Alert for failure. |
| Don’t | Add role="alert" or move focus when results become empty; the host results region announces a concise status politely. |
| Don’t | Fill the absence with competing actions or explanatory copy longer than the content it replaces. |