XDSEmptyState@xds/core · EmptyState
Usage
EmptyState shows a placeholder when a content area has no data. Use it for empty lists, zero search results, first-time setups, or cleared inboxes. Always include a title and a next step so the user is not stuck.Best practices
| Guidance | Practices |
|---|---|
| Do | Include a clear title and a call-to-action button so users know how to proceed. |
| Do | Use an illustration or icon that reinforces the context of the empty state. |
| Do | Use the compact variant inside cards or sidebars where space is limited. |
| Don't | Leave an empty state without guidance — always explain what happened and what the user can do next. |
| Don't | Use a generic message like "No data" — be specific about what is empty and why. |
| Don't | Use an EmptyState for error messages that require immediate action — use a Banner instead. |
Anatomy
| Element | Description | |
|---|---|---|
| Icon | A visual cue above the title that reinforces the context, like a search icon for no results. | |
| Title | required | Primary message explaining what is empty — "No projects yet" not "No data". |
| Description | Additional context explaining why it is empty or what the user can do. | |
| Actions | One or two buttons guiding the user to a next step, like "Create project" or "Clear filters". |
Import
tsimport {XDSEmptyState} from '@xds/core/EmptyState'
Props
| Prop | Type | Description |
|---|---|---|
titlerequired | string | Primary message rendered as an <h3> heading inside the empty state. |
description | string | Optional secondary text providing additional context below the title. |
icon | ReactNode | Optional icon or illustration displayed above the title; rendered as decorative (aria-hidden="true"). |
actions | ReactNode | Optional action buttons displayed below the description, laid out horizontally by default and stacked vertically when isCompact is true. |
headingLevel | 1 | 2 | 3 | 4 | 5 | 6 (default: 3) | Controls the rendered HTML heading tag (h1-h6) to fit the document outline. |
isCompact | boolean (default: false) | Enables the compact variant with reduced spacing for constrained content areas. |
xstyle | StyleXStyles | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value — not an inline style object like style={{}}. |
Examples
Common configurations, variations, and states.EmptyState — Actions
tsx'use client';import {XDSEmptyState} from '@xds/core/EmptyState';import {XDSButton} from '@xds/core/Button';import {XDSIcon} from '@xds/core/Icon';import {MagnifyingGlassIcon} from '@heroicons/react/24/outline';export default function EmptyStateActions() {return (<XDSEmptyStateicon={<XDSIcon icon={MagnifyingGlassIcon} size="lg" />}title="No results found"description="Try adjusting your search terms or clearing filters to see more results."actions={<><XDSButton label="Go back" variant="secondary" /><XDSButton label="Clear filters" variant="primary" /></>}/>);}
EmptyState — CompactSmaller empty state with reduced spacing for constrained areas. Use inside sidebar panels, card widgets, or notification drawers where a full-size empty state would overwhelm the layout.
tsx'use client';import {XDSEmptyState} from '@xds/core/EmptyState';import {XDSButton} from '@xds/core/Button';import {XDSHStack} from '@xds/core/Layout';import {XDSIcon} from '@xds/core/Icon';import {InboxIcon} from '@heroicons/react/24/outline';export default function EmptyStateCompact() {return (<XDSEmptyStateicon={<XDSIcon icon={InboxIcon} size="lg" />}title="No notifications"description="You're all caught up. New notifications will appear here."actions={<XDSHStack gap={2}><XDSButton label="Settings" variant="secondary" size="sm" /><XDSButton label="Refresh" variant="primary" size="sm" /></XDSHStack>}isCompact/>);}
EmptyState — Container
tsx'use client';import {XDSEmptyState} from '@xds/core/EmptyState';import {XDSButton} from '@xds/core/Button';import {XDSCard} from '@xds/core/Card';import {XDSIcon} from '@xds/core/Icon';import {FolderPlusIcon} from '@heroicons/react/24/outline';export default function EmptyStateContainer() {return (<XDSCard><XDSEmptyStateicon={<XDSIcon icon={FolderPlusIcon} size="lg" />}title="No projects yet"description="Create your first project to start organizing your work. You can invite team members after."actions={<><XDSButton label="Import" variant="secondary" /><XDSButton label="Create project" variant="primary" /></>}/></XDSCard>);}
Showcase source
tsx'use client';import {XDSEmptyState} from '@xds/core/EmptyState';import {XDSButton} from '@xds/core/Button';import {XDSIcon} from '@xds/core/Icon';import {MagnifyingGlassIcon} from '@heroicons/react/24/outline';export default function EmptyStateShowcase() {return (<XDSEmptyStateicon={<XDSIcon icon={MagnifyingGlassIcon} size="lg" />}title="No results found"description="Try adjusting your search or filters to find what you need."actions={<XDSButton label="Clear filters" variant="secondary" />}/>);}