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 it with npx shadcn@latest add @cruiseui/empty-state.
Install
Terminal
npx shadcn@latest add @cruiseui/empty-stateFirst time? Installation shows the one-off components.json setup (the @cruiseui registry) and how to turn the theme on.
Example
Corners
No orders yet
When you buy something, it shows up here.
No results for “agbada”
Check the spelling or try a shorter word.
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>
);
}
<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>Needs theme.css. Interactive parts (menus, tabs, drawers) also need the script in the spec for that component.
When to use it
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).
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.