# EmptyState

> What an empty list means and what to do next: default, positive (all done) and filtered tones.

Category: Feedback. Docs page: https://rime.mjsons.net/components/empty-state

## Installation

```bash
npx shadcn@latest add KezLahd/rime/empty-state
```

EmptyState never says just "No data". It names why the space is empty and offers the next step as an action. compact fits inside a Table.

## Usage

```tsx
import { EmptyState } from "@/components/ui";

<EmptyState title="No projects yet" description="Create a project to start tracking work." action={<Button href="/projects/new">New project</Button>} />
```

## Props: EmptyState

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `title` (required) | `ReactNode` |  |  |
| `description` (required) | `ReactNode` |  | What to do next. Required: a bare "No data" is not an empty state. |
| `action` | `ReactNode` |  |  |
| `secondaryAction` | `ReactNode` |  |  |
| `icon` | `ReactNode` |  |  |
| `tone` | `"default" \| "positive" \| "filtered"` | `"default"` | default = nothing here yet. positive = nothing needs you ("All caught up"), a green tile. filtered = the filters exclude everything; offer to clear them. |
| `compact` | `boolean` |  | Tighter spacing for inside tables and dropdowns. |
| `className` | `string` |  |  |

## Examples

### Tones

```tsx
<EmptyState tone="positive" title="All caught up" description="Nothing is waiting for review." />
```

## Theme tokens

System tokens it reads: `--brand-gradient-soft`, `--ink-brand`, `--ink-heading`, `--ink-muted`, `--line-brand`, `--neutral-fill`, `--neutral-line`, `--r-md`, `--success-fill`, `--success-ink`, `--success-line`, `--text-body`, `--text-caption`, `--text-small`.

## Accessibility

- The icon is decorative; the title and description are plain text, so put the empty state under the heading of the list it belongs to.

## Do

- Use tone="filtered" with a clear-filters action when filters emptied the list.

## Don't

- Never ship a bare "No data".
