EmptyState
Placeholder layout shown when a view has no data, with guidance and next actions.
Compound parts compose into a labelled heading + description. EmptyStateIcon is decorative (aria-hidden="true"); EmptyStateTitle defaults to a <h3> and should be the primary label inside the empty region.
Preview
tsx
import {
EmptyState,
EmptyStateDescription,
EmptyStateIcon,
EmptyStateTitle,
} from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<EmptyState>
<EmptyStateIcon>
<svg
width="32"
height="32"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
>
<rect x="3" y="3" width="18" height="18" rx="2" />
<path d="M3 9h18" />
</svg>
</EmptyStateIcon>
<EmptyStateTitle>No items yet</EmptyStateTitle>
<EmptyStateDescription>Create your first item to get started.</EmptyStateDescription>
</EmptyState>
);
}
EmptyState ships four sizes — sm, md (default), lg, and xl. Bigger sizes are intended for first-run, full-page empty views; smaller sizes fit inline panels.
Preview
tsx
import { EmptyState, EmptyStateDescription, EmptyStateTitle } from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<EmptyState size="sm">
<EmptyStateTitle>Inline empty (sm)</EmptyStateTitle>
<EmptyStateDescription>Compact size for narrow panels.</EmptyStateDescription>
</EmptyState>
<EmptyState size="md">
<EmptyStateTitle>Default empty (md)</EmptyStateTitle>
<EmptyStateDescription>Use this size inside most page layouts.</EmptyStateDescription>
</EmptyState>
<EmptyState size="lg">
<EmptyStateTitle>Large empty (lg)</EmptyStateTitle>
<EmptyStateDescription>Bigger headline for prominent regions.</EmptyStateDescription>
</EmptyState>
</div>
);
}
Variants
Section titled “Variants”The subtle variant softens the surface for inline empty regions inside cards and panels. The default default variant stands on its own.
Preview
tsx
import {
EmptyState,
EmptyStateDescription,
EmptyStateIcon,
EmptyStateTitle,
} from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<EmptyState variant="subtle">
<EmptyStateIcon>
<svg
width="28"
height="28"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
>
<circle cx="11" cy="11" r="7" />
<line x1="21" y1="21" x2="16" y2="16" />
</svg>
</EmptyStateIcon>
<EmptyStateTitle>No results</EmptyStateTitle>
<EmptyStateDescription>Try a different keyword or clear your filters.</EmptyStateDescription>
</EmptyState>
);
}
With actions
Section titled “With actions”Compose primary and secondary actions inside EmptyStateActions to direct the user toward the next step.
Preview
tsx
import {
Button,
EmptyState,
EmptyStateActions,
EmptyStateDescription,
EmptyStateIcon,
EmptyStateTitle,
} from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<EmptyState>
<EmptyStateIcon>
<svg
width="32"
height="32"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
>
<path d="M3 7h18" />
<path d="M6 7v13a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V7" />
<path d="M9 7V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3" />
</svg>
</EmptyStateIcon>
<EmptyStateTitle>Your inbox is empty</EmptyStateTitle>
<EmptyStateDescription>
New messages will appear here. Invite a teammate to start a conversation.
</EmptyStateDescription>
<EmptyStateActions>
<Button>Invite teammate</Button>
<Button variant="ghost">Learn more</Button>
</EmptyStateActions>
</EmptyState>
);
}
PropTypeDefaultDescription
size
"sm"|"md"|"lg"|"xl"
md
Vertical and typographic scale. One of `sm`, `md`, `lg`, `xl`.
variant
"default"|"subtle"
default
Surface treatment. `default` adds a bordered card; `subtle` blends with
the surrounding container.
Accessibility
Section titled “Accessibility”EmptyStateTitlerenders as<h3>by default — override withas="h2"oras="h4"so the heading level matches the surrounding outline.EmptyStateIconis wrapped in a span witharia-hidden="true"— illustrations should not be announced.- Use
EmptyStateDescriptionto give an action-oriented next step, not just a restatement of the empty status. EmptyStateActionsis a<div>— wrap focusable controls so they remain in document tab order.- Keep the entire region focusable in scroll order so keyboard users encounter it the same way as sighted users.
Recipes
Section titled “Recipes”- Show an empty state on first sign-up to explain the feature without data.
- Pair a primary
Buttonwith a secondary link insideEmptyStateActions. - Reserve the
xlsize for full-page zero-data screens; usesminside compact panels. - Use the
subtlevariant inside cards to avoid stacking heavy surfaces.