Empty State

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# Add this component (its dependencies come along)npx koalaui-cli@latest add empty-state

Usage#

usage.tsxTSX
import {  EmptyState,  EmptyStateMedia,  EmptyStateTitle,  EmptyStateDescription,  EmptyStateActions,} from "@/components/ui/empty-state"import { Button } from "@/components/ui/button"import { MagnifyingGlass } from "@phosphor-icons/react/ssr"export function Example() {  return (    <EmptyState>      <EmptyStateMedia>        <MagnifyingGlass />      </EmptyStateMedia>      <EmptyStateTitle>No results found</EmptyStateTitle>      <EmptyStateDescription>        Try adjusting your search or filters to find what you&apos;re looking for.      </EmptyStateDescription>      <EmptyStateActions>        <Button variant="outline">Clear filters</Button>      </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.

Density#

density retunes padding, the media and icon size, the title size, and the description measure, never color or the rounded brand corners. comfortable (the default) suits a full page or marketing surface; compact fits an in-panel placeholder. It also reads from a 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.

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.