Empty
Successful no-content placeholder with optional description and action (Ant Empty class).
Empty is the successful no-content placeholder for pages and regions — title, optional description, visual, and action. It follows Ant Design Empty semantics. Prefer Empty when the request succeeded and there is simply nothing to show; use Result for failures and outcomes, and keep list/chat chrome empties (Data List, Message Scroller) inside those hosts. See Page Region Status for when Empty sits in the Loading / Empty / Error triad.
When To Use
- Show a successful empty list, panel, or page when the fetch succeeded and the collection has no items.
- Pair a short description and optional action (Create, Upload, Clear filters) so the user knows the next step.
- Use
size="region"(default) inside cards and panels; usesize="page"for a full-page empty band. - Do not use Empty for errors, 404s, or failed requests — use Result (and Skeleton for pending); host-branch the triad per Page Region Status.
- Do not replace DataListEmpty or MessageScrollerEmpty — those stay owned by their list/chat hosts.
Features
| Area | Behavior |
|---|---|
| Size | region (default) — compact card/panel; page — taller min-height and larger icon |
| Placement | Centered chrome; do not grow (flex-1) by default. List / Related List containers opt in. See Page And Region Status |
| Copy | Default title No data; host-supplied description and optional action |
| Visual | Default Inbox icon; override with image or icon |
| Children | When children is set, replaces the default title / description / action layout |
| A11y | Root exposes role="status" with data-slot="empty" |
| Slots | classNames for root · image · title · description · action |
Installing
pnpm dlx shadcn@latest add https://ui.isaacfei.com/r/empty.jsonnpx shadcn@latest add https://ui.isaacfei.com/r/empty.jsonyarn dlx shadcn@latest add https://ui.isaacfei.com/r/empty.jsonbun x shadcn@latest add https://ui.isaacfei.com/r/empty.jsonWith a namespace: npx shadcn@latest add @f-ui/empty.
registryDependencies: utils. Runtime: lucide-react.
Usage
import { Empty } from "@/components/f-ui/empty/empty";
<Empty description="When this list has items, they will show up here." />Examples
Region Empty
Default size="region" inside a card — title defaults to “No data” with a short description for an empty list.
No data
When this list has items, they will show up here.
"use client";
import { Empty } from "@/components/f-ui/empty/empty";
export function EmptyDemo() {
return (
<div className="rounded-xl border bg-card">
<Empty description="When this list has items, they will show up here." />
</div>
);
}With Action
Add a primary next step in action so the empty state points the user forward (Upload, Create, Clear filters).
No files yet
Upload a file to see it here.
"use client";
import { Empty } from "@/components/f-ui/empty/empty";
import { Button } from "@/components/ui/button";
export function EmptyWithActionDemo() {
return (
<div className="rounded-xl border bg-card">
<Empty
title="No files yet"
description="Upload a file to see it here."
action={
<Button type="button">
Upload
</Button>
}
/>
</div>
);
}Page Empty
size="page" uses a taller band and larger icon for full-page no-content — for example a projects index with nothing yet.
No projects yet
Create a project to start collaborating.
"use client";
import { Empty } from "@/components/f-ui/empty/empty";
import { Button } from "@/components/ui/button";
export function EmptyPageDemo() {
return (
<Empty
size="page"
title="No projects yet"
description="Create a project to start collaborating."
action={
<Button type="button">Create project</Button>
}
/>
);
}Composition
Empty
├── image / icon (default Inbox, or `image` / `icon`)
├── title (h2, default "No data")
├── description? (optional)
└── action? (optional action row)When children is passed, Empty renders only the children inside the sized root (no default title / description / action).
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | "No data" | Primary heading |
description | ReactNode | — | Supporting copy under the title |
image | ReactNode | — | Custom visual; wins over icon and the default Inbox |
icon | ReactNode | Inbox | Icon when image is omitted |
action | ReactNode | — | Inline next-step actions |
size | "page" | "region" | "region" | Page band vs compact in-panel layout |
children | ReactNode | — | When set, replaces the default composition |
className | string | — | Extra classes on the root |
classNames | EmptyClassNames | — | Per-slot class overrides |
Slots
| Slot | Element |
|---|---|
root | Outer data-slot="empty" container |
image | Visual wrapper (icon or custom image) |
title | Heading |
description | Description paragraph |
action | Actions row |