Empty
The Empty component fills the space where content is missing and shows users the action that adds it.
When to Use
- when a list has no records yet, such as “No invoices yet”, with the Button that creates the first one
- for a record with nothing under it, such as “No projects for Luma Architects”
- for a page that can’t be shown, like “Page not found”, with a search field in place of a Button
- when content is on its way, like “Importing your clients”, with a Spinner as the media
When Not to Use
- for content whose layout is known while it loads (use a Skeleton)
- for a search that matches nothing in a Combobox or in Command (use
ComboboxEmptyorCommandEmpty) - for content that failed to load (use an Alert)
Anatomy
| Element | Usage |
|---|---|
| Media | Optional |
| Title* | Optional |
| Description* | Optional |
| Content | Optional |
| Container | Required |
* The Empty component has a title, a description, or both.
EmptyHeader stacks the media, the title, and the description. EmptyContent is placed under the header and stacks its content.
Provide the action that fills the space so that users don’t have to look for it elsewhere. The action is a Button, or a search field on “Page not found”.
Variants
Set the variant on EmptyMedia.
| Variant | Purpose |
|---|---|
default | Media with a shape of its own, such as an Avatar or a row of Avatars |
icon | An icon |
Behavior
The Empty component is as wide as its container, and its content is centered. As a flex item, it grows to fill the remaining space. The header and the content are at most 384px wide.
To show a dashed border around the Empty component, add the class border.
Content
| String | Rule | Example | Counterexample |
|---|---|---|---|
| Title | Say what is missing, with no period | “No invoices yet” | “Nothing here” |
| Description | Say in one sentence what the action leads to | “Create an invoice to bill a client for your work.” | “You have no invoices.” |
| Action | Start with the verb, and name what it adds | “Create invoice” | “Get started” |
Accessibility
The Empty component isn’t focusable and has no keys of its own. Users reach the controls in its content with Tab.
Set aria-hidden on the icon. See Iconography for the rule.
Installation
npx shadcn@latest add @summit/emptyUsage
import { Button } from '@/components/ui/button';
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty';
import { ReceiptIcon } from '@phosphor-icons/react';
<Empty className="border">
<EmptyHeader>
<EmptyMedia variant="icon">
<ReceiptIcon aria-hidden />
</EmptyMedia>
<EmptyTitle>No invoices yet</EmptyTitle>
<EmptyDescription>Create an invoice to bill a client for your work.</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button size="sm">Create invoice</Button>
</EmptyContent>
</Empty>;With an Avatar
If the media has a shape of its own, as an Avatar does, keep variant at default.
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
<EmptyMedia>
<Avatar size="lg">
<AvatarFallback>LA</AvatarFallback>
</Avatar>
</EmptyMedia>;With a Search Field and a Link
EmptyContent accepts any control. To add a link under the control, use a second EmptyDescription.
import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group';
import { MagnifyingGlassIcon } from '@phosphor-icons/react';
<EmptyContent>
<InputGroup>
<InputGroupInput aria-label="Search" placeholder="Search" />
<InputGroupAddon>
<MagnifyingGlassIcon />
</InputGroupAddon>
</InputGroup>
<EmptyDescription>
Need help? <a href="/support">Contact support</a>
</EmptyDescription>
</EmptyContent>;API Reference
The parts accept the props of a div.
EmptyMedia
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'icon' | 'default' | Whether the media is shown on a tile |