Empty state

A useful next step when there is nothing to show yet.

dataguidance
Preview
Empty state preview

No projects yet

Create your first project to see deployments, domains and usage here.

When to use

  • Empty lists, zero search results, and first-run views.
  • A view that should morph between states, such as empty and success, by changing props.

When not to use

  • Use skeleton while data is still loading.
  • Use alert for errors inside a page that still has content.
  • Use onboarding-checklist when first-run needs several steps.

shadcn CLI

Also installs (1)

  • manicat-foundation
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "empty-state",
  "type": "registry:ui",
  "title": "Empty state",
  "description": "A useful next step when there is nothing to show yet.",
  "categories": [
    "data"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json"
  ],
  "files": [
    {
      "path": "registry/components/empty-state/empty-state.tsx",
      "type": "registry:component",
      "target": "@components/manicat/empty-state/empty-state.tsx"
    },
    {
      "path": "registry/components/empty-state/empty-state.module.css",
      "type": "registry:component",
      "target": "@components/manicat/empty-state/empty-state.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/empty-state",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/empty-state",
    "markdown": "https://uiarc.dev/components/empty-state/markdown",
    "tags": [
      "data",
      "guidance"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { Badge } from "@/components/manicat/badge/badge";
import { EmptyState } from "@/components/manicat/empty-state/empty-state";
import { Button } from "@/components/manicat/button/button";

export function EmptyStateExample() {
  return (
    <EmptyState
      title="No projects yet"
      description="Create your first project to see deployments, domains and usage here."
      icon={<Badge tone="info">New</Badge>}
      action={<Button>Create project</Button>}
    />
  );
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

First-run projects What a list shows before anything exists: an explanation and the one action that fixes it.

First-run projects What a list shows before anything exists: an explanation and the one action that fixes it. preview

No projects yet

Create your first project to see deployments, domains and usage here.

Accessibility

  • Renders a section with an h3 title; pass label to name the region.
  • The icon is aria-hidden.
  • Outgoing copy is hidden from assistive tech while it fades.

Motion

  • Changing title or description rolls the copy in place while the block height springs to fit.
  • A new icon pops in with a short blur.
  • Reduced motion swaps copy with a fade and snaps height; the icon's idle animation stops.

Responsive behavior

  • Padding scales with the viewport between fixed bounds, and the description caps at 18rem so lines stay short.
  • Actions wrap and center, so two buttons stack on narrow screens.

Performance

  • One ResizeObserver drives the height spring; the icon's idle animation is CSS and stops under reduced motion.

Notes for AI

  • Use for empty lists, zero search results, and first-run views. Use skeleton while data is loading.
  • Keep it mounted and change its props to morph between states such as empty and success.