EmptyState
A generic empty-state surface for empty lists, filtered-out results, “not yet started” placeholders, and loading states. The loading prop swaps the icon for a Spinner and adds role="status" to the root so screen readers announce the loading state.
For chat-specific empty states (with quick-start suggestion chips) use ChatEmptyState instead.
Live Preview
Import
import { EmptyState } from 'entangle-ui';Usage
Default
<EmptyState icon={<InboxIcon />} title="Inbox zero" description="You're all caught up — no unread messages."/>With Action
With action
<EmptyState icon={<SearchIcon size="lg" />} title="No results" description="Try adjusting your search or filters." action={ <> <Button>Reset filters</Button> <Button variant="filled">New search</Button> </> }/>Variants
Default (centered column)
The default variant lays out icon, title, description, and action vertically centered — good for a whole panel or page.
Compact (inline row)
The compact variant switches to a single horizontal row with reduced padding, for empty list cells where a full vertical layout would feel oversized.
Compact
<EmptyState variant="compact" icon={<TagIcon />} title="No tags" description="Tags appear here once you add them."/>Loading State
Set loading to render a Spinner in place of the icon. The root receives role="status" and aria-live="polite".
Loading
<EmptyState loading title="Loading conversation..." />Loading ↔ empty swap
A common pattern: the same container shows either the loading state or the real empty state, based on a boolean. Because the outer layout is identical, the swap is visually stable.
Loading ↔ empty swap
Click Retry to toggle between the empty state and the loading state.
{ loading ? ( <EmptyState loading title="Searching..." /> ) : ( <EmptyState icon={<SearchIcon />} title="No results" description="Try adjusting your filters." action={<Button onClick={retry}>Retry</Button>} /> );}In a PanelSurface
Combine with PanelSurface to give the empty state a contained look:
<PanelSurface> <PanelSurface.Body scroll> {items.length === 0 ? ( <EmptyState icon={<TagIcon />} title="No tags" description="Press N to create one." /> ) : ( <TagList items={items} /> )} </PanelSurface.Body></PanelSurface>Props
| Prop | Type | Default | Description |
|---|---|---|---|
icon | ReactNode | — | Icon or illustration (typically 48–64px). |
title | ReactNode | — | Main heading. |
description | ReactNode | — | Supporting description — one short paragraph. |
action | ReactNode | — | CTA buttons rendered below the description. |
variant | 'default' | 'compact' | 'default' | Layout — centered column ("default") or single horizontal row ("compact"). |
loading | boolean | false | Render a Spinner in place of the icon and mark the root as role="status". |
className | string | — | Additional CSS class names. |
style | CSSProperties | — | Inline styles. |
testId | string | — | Test identifier for automated testing. |
ref | Ref<HTMLDivElement> | — | Ref to the underlying div element. |
Accessibility
- When
loading, the root is marked withrole="status"andaria-live="polite"so screen readers announce the loading state without requiring focus - Title is rendered as
<h3>inside the text column for proper document outline - Description is rendered as
<p>and constrained to roughly 48 characters for comfortable reading