# Empty State

> Standardized empty result UI with illustration slot, title, description, and action.

- Available in: `@sisyphos-ui/react`, `@sisyphos-ui/vue`, `@sisyphos-ui/angular`
- Docs: https://www.sisyphosui.com/docs/components/empty-state

## Installation

Pick the framework binding that matches your stack:

```bash
pnpm add @sisyphos-ui/react   # React 18+
pnpm add @sisyphos-ui/vue     # Vue 3+
pnpm add @sisyphos-ui/angular # Angular 17+
```

## Import

```tsx
import "@sisyphos-ui/react/styles.css";
import { EmptyState } from "@sisyphos-ui/react";
```

## Framework usage

### React 18+

```tsx
import { EmptyState, Button } from "@sisyphos-ui/react";

export const NoResults = () => (
  <EmptyState
    bordered
    title="Nothing here yet"
    description="Once you create an item it'll show up here."
    actions={<Button>New item</Button>}
  />
);
```

### Vue 3+

```vue
<script setup lang="ts">
import { EmptyState, Button } from "@sisyphos-ui/vue";
</script>

<template>
  <EmptyState
    :bordered="true"
    title="Nothing here yet"
    description="Once you create an item it'll show up here."
  >
    <template #actions><Button>New item</Button></template>
  </EmptyState>
</template>
```

### Angular 17+

```ts
import { Component } from "@angular/core";
import { EmptyState, Button } from "@sisyphos-ui/angular";

@Component({
  selector: "app-no-results",
  standalone: true,
  imports: [EmptyState, Button],
  template: `
    <sui-empty-state
      [bordered]="true"
      title="Nothing here yet"
      description="Once you create an item it'll show up here."
    >
      <sui-button empty-actions>New item</sui-button>
    </sui-empty-state>
  `,
})
export class NoResultsComponent {}
```

## Examples

### Default

```tsx
import { Button, EmptyState } from "@sisyphos-ui/react";

export function Example() {
  return (
    <EmptyState
      bordered
      title="No results found"
      description="Try changing the filters or search for a different term."
      actions={<Button variant="outlined">Reset filters</Button>}
    />
  );
}
```

### With custom icon

Pass any ReactNode as `icon` to reinforce the message.

```tsx
import { Button, EmptyState } from "@sisyphos-ui/react";

const InboxIcon = () => (
  <svg viewBox="0 0 24 24" width={28} height={28} aria-hidden="true">
    <path fill="currentColor" d="M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zm0 12h-4a3 3 0 11-6 0H5V5h14z" />
  </svg>
);

export function Example() {
  return (
    <EmptyState
      bordered
      icon={<InboxIcon />}
      title="Inbox zero"
      description="You're all caught up. New items will show up here."
      actions={
        <>
          <Button variant="outlined">Settings</Button>
          <Button>Compose</Button>
        </>
      }
    />
  );
}
```

### Sizes

`size` tunes the vertical density.

```tsx
import { EmptyState } from "@sisyphos-ui/react";

export function Example() {
  return (
    <>
      <EmptyState bordered size="sm" title='size="sm"' description="Same content, different density." />
      <EmptyState bordered size="md" title='size="md"' description="Same content, different density." />
      <EmptyState bordered size="lg" title='size="lg"' description="Same content, different density." />
    </>
  );
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| icon | `ReactNode` | — | Decorative icon or illustration rendered above (or beside) the text. |
| title | `ReactNode` | — | Heading rendered as an `<h3>`. |
| description | `ReactNode` | — | Supporting copy rendered below the title. |
| actions | `ReactNode` | — | Call-to-action slot — typically one or two `Button` elements. |
| size | `"sm" \| "md" \| "lg"` | `"md"` | Size/density scale. |
| bordered | `boolean` | `false` | Adds a dashed border and subtle background. |
| variant | `"block" \| "inline"` | `"block"` | `block` stacks icon above text; `inline` is a compact horizontal row for modals, cards, and filter rows. |

## Accessibility notes

- The root exposes `role="status"`, so the empty message is politely announced when it appears (e.g. after a filter returns no results).
- The icon slot is `aria-hidden="true"` — decorative artwork is never announced.
- The title renders as an `<h3>` heading, keeping the empty view reachable via screen-reader heading navigation.

<!-- exports: { "EmptyState": "@sisyphos-ui/react" } -->