Empty State

Pro

The zero-data, no-results and first-run placeholder. A neutral icon tile, a balanced title, a readable description and a single outline action, composed from named parts, with a density axis for in-panel use.

No projects yet

Create your first project to start organizing work, inviting teammates, and shipping.

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add empty-state

Usage#

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Anatomy#

import {  EmptyState,  EmptyStateMedia,  EmptyStateTitle,  EmptyStateDescription,  EmptyStateActions,} from "@/components/ui/empty-state"<EmptyState>  <EmptyStateMedia />  <EmptyStateTitle />  <EmptyStateDescription />  <EmptyStateActions /></EmptyState>

Variants#

The variant prop colors the icon from a single semantic token. The tile around it stays neutral, with no fill and the plain border, so a search, error, or success state reads as one family across all four themes. Set it on the root and every part picks it up through context.

No results

Nothing matched that search.

Couldn't load data

Something went wrong on our end.

All caught up

You've cleared your inbox.

Illustrated states#

Give each empty moment a small object that belongs to the job: an archive waiting for its first project, a mail sorter with no letters, or a search bench with an empty tray. Keep the machine quiet and let the title and description explain what happened.

No projects yet

Create a project to start organizing your work.

Your inbox is quiet

New messages delivered here will land in this tray.

No results found

Try changing the search or clearing a filter.

Density#

density retunes padding, the media and icon size, the title size, and the description measure, never color or the rounded brand corners. comfortable suits a full page or marketing surface; compact (the default) fits an in-panel placeholder. Without a prop it reads the nearest DensityProvider, so an app shell can set it once.

No notifications

You're all caught up. New alerts land here.

No notifications

You're all caught up. New alerts land here.

Without actions#

The action row is optional; drop EmptyStateActions for a purely informational placeholder.

No team members

Invitations you send will show up here until they're accepted.

Inline#

An empty list inside a record (no evidence, no linked vehicles) sits between sections that have content, and the stacked block would outweigh all of them. layout="inline" puts the same parts on one line: a small tile, the title as a muted message, and any action pushed to the end.

No evidence attached
No officers involved

API reference#

EmptyState

The root: a centered column that shares variant and density with every part through context. Forwards all native <div> props; every part accepts className, merged last.

PropTypeDefaultDescription
variant"default" | "primary" | "success" | "warning" | "info" | "destructive""default"Colors the media icon from one semantic token; the tile stays neutral in every variant.
density"comfortable" | "compact""compact"Retunes padding, the media and icon size, the title size and the description measure. Falls back to the nearest DensityProvider.
layout"stacked" | "inline""stacked"inline lays the parts on one left-aligned line (small tile, the title as a muted message, actions at the end) for an empty list inside a sheet or panel. Mirrored as data-layout.
asChildbooleanfalseMerge onto your own element via Radix Slot instead of rendering a <div>.

EmptyStateMedia

The neutral icon tile (hairline ring, no fill), sized by density; wrap a single icon. Rendered aria-hidden, and forwards all native <div> props.

PropTypeDefaultDescription
asChildbooleanfalseMerge onto your own element via Radix Slot instead of rendering a <div>.

EmptyStateTitle

The balanced, semibold title. Renders a <div> and forwards all native <div> props.

EmptyStateDescription

Muted supporting copy kept to a readable measure. Forwards all native <p> props.

EmptyStateActions

The optional action row; holds one outline Button, since an empty state points at a single next step. Forwards all native <div> props.

PropTypeDefaultDescription
size"sm" | "md" | "lg""sm"Control height imposed on the children, so the button needs no size; an explicit one still wins.
Data attributeDescription
data-control-sizeThe imposed control size.

FAQ#

Nest the named parts inside the root: `EmptyStateMedia` (wrap a single icon), `EmptyStateTitle`, `EmptyStateDescription`, and the optional `EmptyStateActions`. They are exported individually rather than as `EmptyState.Media`, because dot-notation statics do not survive the RSC server-to-client boundary.