Installation
pnpm dlx shadcn@latest add https://asciicn.dev/r/empty-state.jsonUsage
import { EmptyState } from "@/components/asciicn/empty-state";
import { Button } from "@/components/ui/button";
export function NoProjects() {
return (
<EmptyState
illustration="folder"
title="No projects yet"
description="Create a project to deploy your first site."
action={<Button>New project</Button>}
/>
);
}Each drawing is about 21 cells wide, set as text in --ascii-font: line art in the muted text colour, a few accent glyphs in color, and a ░ drop shadow down the right and along the bottom, like a dialog in a text-mode interface. The accent glyphs that mean "nothing yet" (the dots above the inbox, the ? in the lens, the dust in the folder, the gap in the cable) blink in turn.
To draw your own, pass illustration={{ art, mask }}: two arrays of strings the same size. In the mask, a space is line art, a is accent, s is shadow, and 1 to 3 are accent glyphs that blink in that order.
<EmptyState
illustration={{
art: ["┌───┐", "│ · │", "└───┘"],
mask: [" ", " 1 ", " "],
}}
title="Nothing queued"
/>Examples
Illustrations
All four drawings at a 12px cell, each with its own accent colour.
Inside a settings panel
The folder in green, under a panel header, with one action.
No search results
The magnifier under a search field, with an outline button to clear it.
Props
| Prop | Type | Default |
|---|---|---|
| title* What is empty, such as "No projects yet". | Type: ReactNode | Default – |
| description One or two sentences on why it is empty and what to do. | Type: ReactNode | Default – |
| action Buttons or links, laid out in a centred row. | Type: ReactNode | Default – |
| illustration Which drawing to show, or your own art and mask. | Type: "inbox" | "search" | "folder" | "cable" | EmptyStateArt | Default "inbox" |
| titleAs Heading level of the title, to fit the page outline. | Type: "h2" | "h3" | "h4" | "p" | Default "h3" |
| color Accent colour of the drawing, a palette name or any CSS colour. | Type: AsciiColor | Default "ink" |
| animate Blink the accent glyphs in turn. | Type: boolean | Default true |
| cell Glyph cell height in CSS pixels. | Type: number | Default 14 |
Notes
- The drawing is
aria-hidden; the title is a real heading and the description real text. PicktitleAsso the heading fits the page outline. - The art is plain DOM text, so it renders on the server, stays sharp at any zoom and can be selected and copied.
- The blink runs on the Web Animations API, which the browser runs off the main thread. Each glyph stays lit most of the cycle and dims briefly. With reduced motion, or
animate={false}, every glyph stays lit. - The four drawings are exported as
EMPTY_STATE_ARTif you want to reuse them elsewhere.