Components
Empty state
View in FigmaThe centered "nothing here yet" placeholder — an empty table, a cleared filter, a fresh workspace. title/description are data (read-only copy); icon/action are composition slots so the glyph and CTA keep their own APIs.
Install
npx shadcn@latest add @alix/emptyStatePreview
No projects yet
Create your first project to get started.
Usage
<EmptyState
icon={<InboxIcon />}
title="No projects yet"
description="Create your first project to get started."
action={<Button>New project</Button>}
/>Examples
Copy-only placeholder
Leave icon and action empty when the surrounding panel already explains the next step.
No saved insights
Saved perspectives appear here once a partner adds them to the workspace.
<div className="border border-border">
<EmptyState
title="No saved insights"
description="Saved perspectives appear here once a partner adds them to the workspace."
/>
</div>Action slot with choices
Pass a small action group when a fresh workspace has one primary path and one setup alternative.
No engagement brief
Create the working brief or import the latest client pack.
<EmptyState
icon={<FileText />}
title="No engagement brief"
description="Create the working brief or import the latest client pack."
action={
<div className="flex flex-wrap justify-center gap-2">
<Button>Create brief</Button>
<Button variant="outline">Import pack</Button>
</div>
}
/>Filtered panel state
Panel, Badge, Button, and EmptyState show an empty data view without changing the panel chrome.
Active engagements
Filtered by capability and office
No matching engagements
Try clearing the office filter or widening the capability set.
<Panel
title="Active engagements"
description="Filtered by capability and office"
actions={<Badge variant="outline">0 shown</Badge>}
>
<EmptyState
className="py-10"
icon={<Search />}
title="No matching engagements"
description="Try clearing the office filter or widening the capability set."
action={<Button variant="outline" size="sm">Clear filters</Button>}
/>
</Panel>When to use it
Use it for
- Empty tables, cleared filters, and fresh workspaces where the user needs a calm next step.
- Panel bodies where the surrounding chrome should remain visible even when the data set is empty.
- Slots that need a real Button, link, or icon without EmptyState mirroring those APIs.
Reach for something else
- Loading or unknown-duration work — use Progress or Button loading instead.
- Blocking decisions, confirmations, or destructive choices — use Dialog instead.
- Success, failure, or background task feedback — use Toast instead.
- Editorial page introductions — use SectionTitle inside SectionWrapper instead.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | ReactNode | — | The headline. Data — a string drops straight in. |
| description | ReactNode | — | Supporting line under the title. Data. |
| icon | ReactNode | — | Leading glyph — a slot, usually a lucide icon. Composition, so the icon's API (size, stroke) stays its own. |
| action | ReactNode | — | Primary call to action — a slot, usually a Button, so its full API (variant, loading, onClick) stays the button's. |