Empty State
FreeA placeholder component shown when a view has no content to display. Combines an illustration or icon, a heading, a descriptive message, and a call-to-action button. Guides users toward the next step instead of leaving them at a dead end.
6 variants
Variants
| Variant | Description | When to use |
|---|---|---|
| Default | Standard empty state with icon, heading, description, and action button. | Use when a list, table, or dashboard section has no data to show. |
| With Illustration | Empty state with a larger SVG illustration for more visual presence. | Use for full-page empty states like first-time onboarding or empty dashboards. |
| Compact | Minimal empty state with just an icon and text, no illustration. | Use for inline empty states within cards or sidebars where space is limited. |
Usage Guidelines
Do
Always include a clear call-to-action so users know what to do next.
Don't
Leave an empty area completely blank with no guidance.
Do
Use friendly, encouraging language — not technical jargon.
Don't
Use generic messages like "No data" — be specific about what is missing.
Do
Match the illustration style to the product brand.
Don't
Include more than one primary action — keep the path forward clear.
Do
Provide a meaningful heading that explains why the area is empty.
Don't
Code
HTML
<div class="lex-empty-state" role="status">
<div class="lex-empty-state__icon" aria-hidden="true">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="1.5">
<path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
</svg>
</div>
<h3 class="lex-empty-state__title">No projects yet</h3>
<p class="lex-empty-state__description">
Create your first project to start organising your work.
</p>
<button class="lex-button lex-button--primary lex-button--md">
Create project
</button>
</div>CSS Custom Properties
.lex-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: var(--lex-space-48) var(--lex-space-24);
max-width: 400px;
margin: 0 auto;
}
.lex-empty-state__icon {
color: var(--lex-text-muted);
margin-bottom: var(--lex-space-16);
}
.lex-empty-state__title {
font-size: var(--lex-font-size-lg);
font-weight: 600;
color: var(--lex-text-default);
margin: 0 0 var(--lex-space-8);
}
.lex-empty-state__description {
font-size: var(--lex-font-size-sm);
color: var(--lex-text-muted);
line-height: var(--lex-line-height-relaxed);
margin: 0 0 var(--lex-space-20);
}React
// Using Lexicon CSS classes with React
import { Folder } from 'lucide-react';
// Using Lexicon CSS classes with React
export function ProjectList() {
return (
<EmptyState
icon={<Folder size={48} />}
title="No projects yet"
description="Create your first project to start organising your work."
action={
<Button variant="primary" onClick={handleCreate}>
Create project
</Button>
}
/>
);
}Design Tokens
| Token | Value (dark) | Value (light) | CSS property |
|---|---|---|---|
| --lex-empty-state-icon-size | — | — | size |
| --lex-empty-state-icon-color | — | — | color |
| --lex-empty-state-text-color | — | — | color |
Accessibility
- Use role="status" so screen readers announce the empty state when it appears.
- The illustration or icon should be aria-hidden="true" since it is decorative.
- The heading and description provide the accessible content — do not rely solely on the illustration.
- The call-to-action button must clearly describe what it does — "Create project", not "Go".