# Empty _(no submodules)_ - empty.variants — `emptyVariants` is the cva config…… - [empty.variants](./empty.variants.md) — `emptyVariants` is the cva config that powers the `` chassis component (with `emptyHeaderVariants`, `emptyMediaV… - empty.variants — `emptyVariants` is the cva config…… - [empty.variants](./empty.variants.md) — `emptyVariants` is the cva config that powers the `` chassis component (with `emptyHeaderVariants`, `emptyMediaV… - empty.variants — `emptyVariants` is the cva config…… - [empty.variants](./empty.variants.md) — `emptyVariants` is the cva config that powers the `` chassis component (with `emptyHeaderVariants`, `emptyMediaV… - empty.variants — `emptyVariants` is the cva config… - [empty.variants](./empty.variants.md) — `emptyVariants` is the cva config that powers the `` chassis component (with `emptyHeaderVariants`, `emptyMediaV… - [empty.variants](./empty.variants.md) — `emptyVariants` is the cva config that powers the `` chassis component (with `emptyHeaderVariants`, `emptyMediaV… ## Purpose `` is the chassis empty-state primitive for `@suaveplan/react-ui`. It mirrors the upstream shadcn `empty` registry item (per Wave 3a's reconciliation finding #6) and ships as a family of six components — `` (root), ``, ``, ``, ``, `` — that compose into the conventional empty-state layout. Per the shadcn skill rule, ALWAYS use `` for empty states rather than building custom empty-state markup — hand-rolled empty states diverge across teams in spacing, iconography, and CTA layout. The root `` exposes a `size` axis with three rungs (`sm` / `default` / `lg`) that control vertical breathing room. The component renders `role="status"` with `aria-live="polite"` so assistive tech announces the empty state when it appears (e.g. when a search returns no results) without interrupting the user. ## Features - Six composition primitives — `Empty`, `EmptyHeader`, `EmptyMedia`, `EmptyTitle`, `EmptyDescription`, `EmptyContent`. - Three sizes via the `size` axis (`sm` / `default` / `lg`) on the root. - `role="status"` + `aria-live="polite"` so AT announces the empty state when it appears. - `` is `aria-hidden="true"` because the title / description carries the accessible name. - `` renders as `

`, `` renders as `

` so the document outline stays clean. - All sub-components forward refs. ## Usage: Basic Example ```tsx import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, } from "@suaveplan/react-ui"; import { FolderIcon } from "lucide-react"; export function NoProjects() { return ( No projects yet Get started by creating a new project. ); } ``` ## Usage: Advanced Example ```tsx import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, } from "@suaveplan/react-ui"; import { useTranslation } from "@suaveplan/react-i18n"; import { InboxIcon } from "lucide-react"; export function EmptyInbox() { const { t } = useTranslation(); return ( {t("react-ui.empty.defaultTitle")} {t("react-ui.empty.defaultDescription")} ); } ``` ## API Reference ### `` `forwardRef` — root container. Renders `role="status"` and `aria-live="polite"`. | Prop | Type | Default | Description | |---|---|---|---| | `size` | `"sm" \| "default" \| "lg"` | `"default"` | Vertical breathing room. | | _all_ `HTMLAttributes` | _native_ | _native_ | Forwarded as-is. | ### `` `forwardRef` — flex column wrapping ``, ``, ``. ### `` `forwardRef` — wrapper for the icon / illustration. Always `aria-hidden="true"`. ### `` `forwardRef` — heading rendered as `

`. ### `` `forwardRef` — supplementary description rendered as `

`. ### `` `forwardRef` — flex row for action affordances. #### Errors The Empty components do NOT call `useTranslation()` so they do not interact with the i18n provider directly. The chassis ships translation keys (`react-ui.empty.defaultTitle`, `react-ui.empty.defaultDescription`, `react-ui.empty.noResults`) that consumers can use as fallbacks via `t('react-ui.empty.defaultTitle')` at the call site. ## Implementation Notes - `role="status"` + `aria-live="polite"` is set unconditionally on the root so AT announces the empty state when it appears (e.g. when a search returns no results) without interrupting the user. Consumers needing a more aggressive announcement should wrap in their own `aria-live="assertive"` container; consumers wanting silence should pass `role="presentation"` to override. - `` is `aria-hidden="true"` because the icon is decorative — the accessible name comes from the title and description text. - The chassis intentionally does NOT inject a default fallback title / description — the bundled translation keys (`react-ui.empty.defaultTitle`, `react-ui.empty.defaultDescription`) are convenience fallbacks consumers opt into via `t()`. Hardcoding fallback text would force every consumer to translate it even when their own copy already exists. - The `size` axis affects only the root's `gap` and `p` — sub-component spacing remains constant. This keeps the visual rhythm consistent across all empty-state sizes and means consumers can swap `size` without rewriting their composition. - `` uses `flex-wrap` so action buttons stack vertically on narrow viewports rather than overflow horizontally.