Empty

Centered placeholder for regions with no data, no results, or a failed load.

Your inbox is empty

New project requests will show up here as they come in. Invite your team to start collaborating.

Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/empty.json
Usage
Import from the master file and compose. Pass `variant="outline"` for a dashed bordered panel.
TSImport
import { Empty } from "@/components/ui/empty";
TSExample
import { Button } from "@/components/ui/button";
import { Empty } from "@/components/ui/empty";
import { FoldersIcon } from "@/components/ui/folders";

export function Example() {
  return (
    <Empty
      icon={FoldersIcon}
      title="No projects yet"
      description="Create your first project to start collecting assets and briefs."
      action={<Button>New project</Button>}
    />
  );
}
Composition
Anatomy of the Empty primitive.
Empty                       (single component — pass content as props)
├── variant="default | outline"
├── size="sm | lg"                   (sm = default, compact chip + tighter spacing; lg = full-page hero)
├── icon={LucideAnimatedIcon}        (renders FeaturedIconAnimated above the title)
├── inky | inky="lost | celebrate | fine | …"  (draws Inky instead of the icon; plain, or with that face)
├── illustration={OpenDoorsIcon}     (draws a static scene, e.g. from squad-icons, instead of the icon)
├── illustrationSize={120}           (illustration width; defaults 160 sm / 208 lg)
├── iconColor="brand | success | destructive | muted | …"
├── iconVariant="flat | gradient"       (default "flat"; "gradient" = brand-tinted card chip)
├── iconSize="sm | md | lg | xl | 2xl"   (default "xl"; "2xl" for hero states)
├── iconAutoPlay                    (play stroke-draw on mount + replay on hover)
├── title=""                        (renders as SectionHeader)
├── description=""
├── titleSize="xs | sm | md | lg | xl"  (default "lg" — text-xl/2xl)
├── titleFont="sans | heading"    (default "sans" Inter; "heading" = Albra display)
└── action={<>buttons</>}           (action row beneath the description)

Need a custom layout (non-animated icon, multi-region body)? The slot
exports — EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription,
EmptyContent — are still exported as the escape hatch.
Default
Centered icon, title, description, and action buttons — drop into any panel that has nothing to show yet. Uses the `FoldersIcon` lucide-animated icon by default; hover the chip to replay the stroke draw.

Your inbox is empty

New project requests will show up here as they come in. Invite your team to start collaborating.

Large
`size="lg"` is the hero empty state — a bigger icon chip, roomier spacing, and a larger title. Use it for full-page empties; the default `size="sm"` is the compact state for cards, lists, and panels.

No projects yet

You haven't created any projects yet. Get started by creating your first project.

Outline
`variant="outline"` adds a dashed border + card background so the empty state reads as a self-contained panel.

No projects yet

Create your first project to start collecting assets and briefs.

Success
Mirrors the form submit success page. Uses the lucide-animated `CheckIcon` with `iconColor="success"`, `iconSize="2xl"`, and `iconAutoPlay` so the stroke draws once on mount.

Request submitted

Your request has been received

Title font
Toggle the title font via `titleFont`. `sans` (default) is Inter; `heading` switches to the Albra display face — handy for hero error/success states.

Sans (default)

Title rendered in Inter — matches body copy weighting.

Heading (Albra)

Title rendered in the Albra display face.

Error
Mirrors the form error boundary. Uses the lucide-animated `XIcon` with `iconColor="destructive"`, `iconSize="2xl"`, and `iconAutoPlay` plus retry / reload actions.

Something went wrong

An unexpected error occurred, please try again later. Support has been notified

Inky
`inky` on its own draws plain Inky in place of the icon chip: he idles, and reacts to hover and click. For an empty state with nothing wrong.

Nothing here yet

New project requests will show up here as they come in.

Inky — lost
`inky="lost"` swaps the icon chip for Inky, looking lost. For no results, an empty search, a 404.

No results found

Nothing matches that search. Try a different word or clear the filters.

Inky — success
`inky="celebrate"` throws the confetti. For a milestone: approved, launched, finished.

Project approved!

Final files are on their way to your church.

Inky — error
`inky="fine"` is Inky calm among the flames. For a failed load or an error boundary.

Something went wrong

An unexpected error occurred, please try again later. Support has been notified

SVG Library illustration
Swap the icon chip for a full-colour scene from the SVG Library (`squad-icons`). Pass the scene to `illustration`; it's sized per `size` (160px `sm`, 208px `lg`) unless `illustrationSize` sets a width — 120px here. Shown with `OpenDoorsIcon`, `SmallGroupCouchIcon` and `CoffeeBarIcon`.

No visitors yet

First-time guests show up here after they fill out a connect card.

No small groups

Start a group and it'll appear here for people to join.

Nothing scheduled

Events you add to the calendar will line up here.

API Reference
Props exposed by the Empty component.
PropTypeDefaultDescription
variant"default" | "outline""default"`outline` adds a dashed border and card background so the empty state reads as a self-contained panel.
size"sm" | "lg""sm"`sm` (default) is the compact state — smaller icon chip (`lg`), tighter padding/gap, and a base-size title, for card/section empties. `lg` is the full-page hero.
iconAnimatedIconComponent—lucide-animated icon component (e.g. `CheckIcon`, `XIcon`, `FoldersIcon`). Rendered through FeaturedIconAnimated above the title.
inkyInkyEmotion | true | InkyProps—Draw Inky instead of the icon chip: `true` for plain Inky (idles, reacts to hover), a face to pin — `lost` for no results, `celebrate` for success, `fine` for an error — or any of Inky's props (`{ costume, preset, shape, emotion, … }`) to dress him up. Wins over `icon`; 96px at `size="sm"`, 128px at `lg` unless the props set `size`.
illustrationComponentType<{ size?: number | string }>—Draw a static illustration instead of the icon chip — any component with a `size` (width) prop, e.g. a scene from the SVG Library (`OpenDoorsIcon` from `squad-icons`). 160px at `size="sm"`, 208px at `lg`. `inky` wins over it; it wins over `icon`.
illustrationSizenumber | string160 / 208 (per size)Illustration width in px (or any CSS length). Height follows the artwork's aspect ratio.
iconColorFeaturedIconColor—Chip color — `brand`, `success`, `destructive`, etc. Mirrors the FeaturedIcon palette.
iconVariant"flat" | "gradient""flat"Featured-icon chip style. `flat` (default) is a soft borderless tint; `gradient` is the brand-tinted bordered chip.
iconSize"sm" | "md" | "lg" | "xl" | "2xl""lg" / "xl" (per size)Chip size. Defaults from `size` (`lg` for `sm`, `xl` for `lg`). Use `2xl` for hero states.
iconAutoPlaybooleanfalsePlay the lucide-animated stroke draw on mount and replay on hover.
titlestring—Heading rendered through SectionHeader.
descriptionstring—Subtext rendered through SectionHeader.
titleSize"xs" | "sm" | "md" | "lg" | "xl""lg" / "sm" (per size)SectionHeader size. Defaults from `size` (`lg` default — text-xl/2xl; `sm` for the compact state).
titleFont"sans" | "heading""sans"Title font family. `sans` (default) is Inter; `heading` switches to the Albra display face.
actionReactNode—Action row beneath the description — wrap multiple buttons in a fragment.
classNamestring—Override or extend the resolved root classes.