EmptyState
Centered placeholder block for 'no data yet' and 'no results' states. Pairs an icon with a heading, supporting text, and an optional CTA.
Playground
No items yet
Get started by adding the first item.
<EmptyState
description="Get started by adding the first item."
title="No items yet"
>
{#snippet cta()}
<Button intent="primary">
<PlusIcon />
Add item
</Button>
{/snippet}
</EmptyState>01 Examples
With icon and CTA
No apartments yet
Get started by adding the first apartment.
<EmptyState
icon={BuildingIcon}
title="No apartments yet"
description="Get started by adding the first apartment."
>
{#snippet cta()}
<Button intent="primary"><PlusIcon />Add apartment</Button>
{/snippet}
</EmptyState>Compact — for inline empty rows
No matches
Try adjusting your filter.
<EmptyState
density="compact"
icon={FunnelIcon}
title="No matches"
description="Try adjusting your filter."
/>Embedded inside a Card
Recent activity
Nothing here yet
New events will show up as they happen.
<Card variant="outlined" padding="md">
<h3 class="text-text-primary mb-3 text-sm font-semibold">Recent activity</h3>
<EmptyState
density="compact"
icon={SearchIcon}
title="Nothing here yet"
description="New events will show up as they happen."
/>
</Card>02 Customization
Pair with any icon from @urbicon-ui/blocks. The container picks up the semantic bg-primary-subtle / text-primary tokens, so the look adapts automatically to your theme override.
Use the cta snippet for the primary action; render arbitrary markup via children for richer empty states (e.g. tutorials, illustrations).
03 Accessibility
The icon is decorative
The decorative icon is hidden from screen readers via its built-in aria-hidden.
The title is an h3
The title renders as <h3> so it slots into existing page heading
hierarchy without competing with the page <h1>.
04 API Reference
Prop | Type | Default | Description | |
|---|---|---|---|---|
title required | string | — | Title property for the EmptyState component | |
children | Snippet | — | Optional richer content rendered below the description (and replacing it visually). | |
class | string | — | Extra classes merged onto the wrapper. | |
cta | Snippet | — | Action buttons rendered below the description. | |
density | compactdefault | 'default' | Visual density. compact is suitable for inline empty rows in tables
or cards; default for full-page empty states. | |
description | string | — | Supporting paragraph below the title. | |
icon | Component<IconProps> | — | Icon component rendered above the title. Pass any icon from
@urbicon-ui/blocks/icons (or a compatible stroke icon). | |
preset | string | — | Apply a named preset registered via <BlocksProvider presets={{ EmptyState: {...} }}>.
Prefer this over class overrides when the same look should be reused
across the project. | |
slotClasses | Partial<Record<EmptyStateSlots, string>> | — | Per-slot class overrides. Slots: base | iconWrapper | title | description | children | cta | |
unstyled | boolean | — | Remove all default tv classes. | |
...HTMLAttributes<HTMLDivElement> inherited | HTMLAttributes | — | HTML attributes (excluding: 'children' | 'title') |
05 Types
Local type definitions used by this component.
Name | Kind | Category | Used by | Description | |
|---|---|---|---|---|---|
EmptyStateProps | interface | props | 0 | — | |
IconProps | interface | props | 0 | — | |
EmptyStateSlots | type | variant | 0 | Slot names derived from the tv() config — single source of truth for slotClasses. | |
SlotNames | type | helper | 0 | Extracts the slot-name union from a slotted tv() config function — the
companion to VariantProps. The slot-mode overload returns
(props?) => { [K in keyof S]: SlotFn }, so keyof ReturnType<T> is exactly
the set of slot names a component declares in tv({ slots: … }).
Use it to type a component's slotClasses prop from the single source of
truth (its *.variants.ts) instead of hand-maintaining a parallel union
that silently drifts when a slot is added or renamed: |
06 Installation
Import
import { EmptyState, BuildingIcon } from '@urbicon-ui/blocks';