# Empty state

Empty state is a neobrutalist React component from Cruise UI. What a list or page shows with nothing in it: an icon, a heading, one line and the next step.

Install (with the @cruiseui registry in components.json, see Installation):

```bash
npx shadcn@latest add @cruiseui/empty-state
```

Import: `import { CruiseEmptyState } from "@/components/cruise/empty-state";`

## When to use

Empty lists, searches with no results, offline screens, first-time pages.

## When not to

Errors that need fixing (use an Alert). Loading (use a Skeleton).

## Example (React)

```tsx
import { SearchX, ShoppingBag, WifiOff } from "lucide-react";
import { CruiseButton } from "@/components/cruise/button";
import { CruiseEmptyState } from "@/components/cruise/empty-state";

export default function EmptyStateExample() {
  return (
    <div className="grid gap-6 md:grid-cols-3">
      <div className="brutal brutal-static">
        <CruiseEmptyState
          icon={<ShoppingBag strokeWidth={2.5} />}
          title="No orders yet"
          description="When you buy something, it shows up here."
          action={<CruiseButton>Start shopping</CruiseButton>}
          headingLevel={3}
        />
      </div>
      <div className="brutal brutal-static">
        <CruiseEmptyState
          icon={<SearchX strokeWidth={2.5} />}
          title="No results for “agbada”"
          description="Check the spelling or try a shorter word."
          action={<CruiseButton variant="secondary">Clear search</CruiseButton>}
          headingLevel={3}
        />
      </div>
      <div className="brutal brutal-static">
        <CruiseEmptyState
          icon={<WifiOff strokeWidth={2.5} />}
          title="You're offline"
          description="We'll load your orders when you're back online."
          action={<CruiseButton variant="secondary">Try again</CruiseButton>}
          secondary={<a href="#help">Get help</a>}
          headingLevel={3}
        />
      </div>
    </div>
  );
}
```

## HTML

Needs theme.css (https://cruiseui.dev/theme.css).

```html
<div class="empty">
  <span class="empty-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18M16 10a4 4 0 0 1-8 0"/></svg></span>
  <h3 class="empty-title">No orders yet</h3>
  <p class="empty-text">When you buy something, it shows up here.</p>
  <div class="empty-actions"><a class="brutal btn on-primary" href="/shop">Start shopping</a></div>
</div>
```

## Props: CruiseEmptyState

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `icon?` | `ReactNode` | — | Default: Lucide inbox. |
| `title` | `ReactNode` | — | — |
| `description?` | `ReactNode` | — | — |
| `action?` | `ReactNode` | — | The main action, e.g. a CruiseButton. |
| `secondary?` | `ReactNode` | — | A secondary link. |
| `size?` | `"inline" \| "page"` | `"inline"` | — |
| `headingLevel?` | `4 \| 3 \| 2` | `2` | Heading level for the title (2 for a page, 3 inside a card). |
| `className?` | `string` | — | — |

## Accessibility

- The heading is a real heading (choose its level).
- The icon is decorative; the heading and line say what happened.
- The action is a real button or link.
