A ready-to-use empty screen with guidance and primary and secondary action slots.
Your workspace is ready
Create a project to keep tasks, files, and updates together.
import { EmptyState } from "@/components/ballmac/empty-state"
export default function EmptyStateDemo() {
return (
<EmptyState
className="w-full max-w-md"
title="Your workspace is ready"
description="Create a project to keep tasks, files, and updates together."
action={
<a
href="#new-project"
className="bg-primary text-primary-foreground inline-flex h-9 items-center rounded-md px-4 text-sm font-medium outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50"
>
Create project
</a>
}
secondaryAction={
<a
href="#guide"
className="text-muted-foreground hover:text-foreground rounded-sm text-sm underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50"
>
Read the guide
</a>
}
/>
)
}Installation
$ pnpm dlx shadcn@latest add @ballmac/empty-stateInstall the dependencies.
$ pnpm add lucide-reactAdd the Ballmac items it builds on.
$ pnpm dlx shadcn@latest add @ballmac/emptyCopy the source into your project.
components/ballmac/empty-state.tsx// Ballmac UI: Empty State. https://ui.ballmac.com/components/empty-state import * as React from "react" import { Inbox } from "lucide-react" import { cn } from "@/lib/utils" import { Empty, EmptyAction, EmptyDescription, EmptyMedia, EmptyTitle, } from "@/components/ballmac/empty" type EmptyStateProps = Omit<React.ComponentProps<typeof Empty>, "children"> & { /** Plain-language explanation of what is missing. */ title: string /** Next-step guidance. */ description: string /** Decorative icon; defaults to an inbox. */ icon?: React.ReactNode /** Primary action, usually a link or button. */ action?: React.ReactNode /** Optional secondary action. */ secondaryAction?: React.ReactNode } function EmptyState({ className, title, description, icon, action, secondaryAction, ...props }: EmptyStateProps) { return ( <Empty data-slot="empty-state" className={cn("bg-card/70", className)} {...props} > <EmptyMedia>{icon ?? <Inbox aria-hidden="true" />}</EmptyMedia> <EmptyTitle>{title}</EmptyTitle> <EmptyDescription>{description}</EmptyDescription> {(action || secondaryAction) && ( <EmptyAction> {action} {secondaryAction} </EmptyAction> )} </Empty> ) } export { EmptyState, type EmptyStateProps }Update the import paths to match your project setup.
Usage
import { EmptyState } from "@/components/ballmac/empty-state"The full example is in the Code tab above.
Examples
States and variants
No results found
Try a different search term or remove a filter.
import { EmptyState } from "@/components/ballmac/empty-state"
export default function EmptyStateStates() {
return (
<EmptyState
compact
className="w-full max-w-sm"
title="No results found"
description="Try a different search term or remove a filter."
/>
)
}API reference
| Prop | Type | Default |
|---|---|---|
title*Plain-language explanation of what is missing. | string | — |
description*Next-step guidance. | string | — |
iconDecorative icon; defaults to an inbox. | React.ReactNode | — |
actionPrimary action, usually a link or button. | React.ReactNode | — |
secondaryActionOptional secondary action. | React.ReactNode | — |
Also accepts the standard attributes of its root element.
Accessibility
| Key | Action |
|---|---|
| Tab / Enter | Focus and activate supplied actions |
Use with AI
A ready-to-use empty screen with guidance and primary and secondary action slots. With the shadcn MCP server set up (guide), ask your agent:
Add the Ballmac UI Empty State (@ballmac/empty-state) to this project with the shadcn MCP, then use it where it fits.
Use it for
- Explain an empty collection
- Offer a clear first action
Not for
- Use empty for a custom composition
Registry JSON: https://ui.ballmac.com/r/empty-state.json
Credits
Free to use in personal and commercial projects.
- npm
- lucide-react
- Registry
- @ballmac/emptyshadcn/utils
Pairs well with
Empty
A responsive empty-state surface with media, concise guidance, and a dedicated action area.
Button
A button with six variants, three sizes, a pill shape and a built-in loading state. buttonVariants() styles links the same way.
Alert Dialog
Focus-managed confirmation for consequential actions, with a clear cancel path, optional media, and a token-based destructive action.
Alert
A semantic callout with five theme-aware tones, clear icon placement, an action row, and opt-in urgent announcements.