Misc
Empty
Fills the space of a list, table or page that has nothing to show yet, and says what to do next.
Import
import { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia } from "@booleanpress/ui/empty"Usage
Build the message from its parts: a header with an optional icon, a title and a description, then the content for the actions.
import { MailIcon } from "lucide-react"
import { Button } from "@booleanpress/ui/button"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@booleanpress/ui/empty"
export function NoEmails() {
return (
<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<MailIcon />
</EmptyMedia>
<EmptyTitle>No emails yet</EmptyTitle>
<EmptyDescription>Emails appear here as soon as your site sends one.</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button>Send a test email</Button>
</EmptyContent>
</Empty>
)
}Empty has no border or background of its own, only a dashed border style: add border for the dashed frame. EmptyMedia takes variant="icon" for an icon in a rounded tile, or the default for a bare icon or picture.
Say which kind of empty it is. A first run (nothing created yet) offers the action that creates; a search with no result offers to clear the search; an error is not an empty state, and belongs in an Alert.
Examples
Basic
An icon tile, a title, a description and one action.
Bordered
className="border" draws the dashed frame; two actions sit side by side.
No results
A bare icon and a way back out of a search that found nothing.
Accessibility
- Semantics
- Plain
divs, with no roles.EmptyTitleandEmptyDescriptionare not headings or paragraphs, so the page's heading levels are untouched. - Labels
- The text is the content. Wrap the title in the heading level your page needs if the empty state is the main content of a section.
- Focus
- Not focusable; the buttons inside it are in the tab order. Nothing moves focus when the empty state appears.
- Known limits
- An empty state that replaces a list after a search or filter is not announced. Announce the result count in a live region the page owns.
EmptyTitleandEmptyDescriptionaredivs (stock), so a screen reader's heading navigation skips them.
Keyboard
| Key | Behaviour |
|---|
API
Empty
Renders a div and passes it every other prop.
EmptyHeader
Renders a div and passes it every other prop.
EmptyTitle
Renders a div and passes it every other prop.
EmptyDescription
Renders a p and passes it every other prop.
EmptyContent
Renders a div and passes it every other prop.
EmptyMedia
Renders a div and passes it every other prop.
Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.
Data attributes: data-slot="empty" (Empty), data-slot="empty-header" (EmptyHeader), data-slot="empty-title" (EmptyTitle), data-slot="empty-description" (EmptyDescription), data-slot="empty-content" (EmptyContent), data-slot="empty-icon" (EmptyMedia), and data-variant.
Theming
The tile is --muted, the description --muted-foreground. The dashed border takes its colour from --border when you add border.
The tokens its classes read. Change their values in your theme, and it follows.
| Token | Used for |
|---|---|
--foreground | text |
--muted | background |
--muted-foreground | text |
--primary | text |