EmptyState

A placeholder component displayed when a list or data area has no content. Includes an icon, title, optional description, and optional call-to-action button. Renders inside a dashed border container.

Anatomy

A centered flex column inside a dashed rounded border. Top to bottom: icon in a muted circle, bold title, muted description text, and an optional primary button.

No projects yet

Create your first project to get started.

Variants

With action

No projects yet

Create your first project to get started.

Without action

Inbox zero

You're all caught up. No new notifications.

Search empty

No results found

Try adjusting your search or filter criteria.

With CTA

No team members

Invite your colleagues to start collaborating.

Common Contexts

EmptyState adapts to many data-list scenarios by swapping the icon and copy.

All caught up

No unread notifications.

No documents

Upload your first document.

No results

Try a different search term.

Design Guidelines

Do

  • Provide a clear CTA when possible. Empty states are prime opportunities to guide users to the next action.
  • Use context-specific icons and copy. "No projects yet" is more helpful than a generic "Nothing here" message.
  • Use for truly empty states. Show this only when a list or view has zero items — not for loading or error states.

Don't

  • Don't use for error states. Network or permission errors need different messaging — use an Alert or dedicated error component.
  • Don't stack multiple EmptyStates. One empty state per view; if multiple sections are empty, show a single top-level message.
  • Don't write long descriptions. One sentence is enough — the user should understand the situation and what to do next immediately.

Developer Reference

Props

  • icon (optional, default: Inbox) — a LucideIcon displayed in the muted circle.
  • title (required) — bold heading shown below the icon.
  • description (optional) — muted supporting text below the title.
  • actionLabel (optional) — label for the primary CTA button. Button only renders if this prop is provided.
  • onAction (optional) — click handler for the CTA button.
  • className — applied to the outer container for sizing overrides.

Usage

import { OriginUiEmptyState } from "@/components/branding/origin-ui-empty-state"
import { FolderOpen, Inbox } from "lucide-react"

// With action button
<OriginUiEmptyState
  icon={FolderOpen}
  title="No projects yet"
  description="Create your first project to get started."
  actionLabel="New Project"
  onAction={() => router.push("/projects/new")}
/>

// Without action
<OriginUiEmptyState
  icon={Inbox}
  title="Inbox zero"
  description="You're all caught up. No new notifications."
/>