# Empty

The parts of an empty state, for a page or a region that has nothing to show yet.

```tsx
import { ServerIcon, UploadIcon } from "lucide-react"
import { Button } from "@zenoxai/ui/components/button"
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@zenoxai/ui/components/empty"

function EmptyDemo() {
  return (
    <Empty>
      <EmptyHeader>
        <EmptyMedia variant="icon">
          <ServerIcon />
        </EmptyMedia>
        <EmptyTitle>No assets yet</EmptyTitle>
        <EmptyDescription>
          Connect a cloud account or import a CSV to build the asset inventory.
        </EmptyDescription>
      </EmptyHeader>
      <EmptyContent>
        <div className="flex gap-2">
          <Button variant="outline">Connect account</Button>
          <Button variant="outline">
            <UploadIcon data-icon="inline-start" />
            Import CSV
          </Button>
        </div>
      </EmptyContent>
    </Empty>
  )
}
```

## Usage

```tsx
import { ServerIcon } from "lucide-react"

import { Button } from "@zenoxai/ui/components/button"
import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from "@zenoxai/ui/components/empty"

export function NoAssets() {
  return (
    <Empty>
      <EmptyHeader>
        <EmptyMedia variant="icon">
          <ServerIcon />
        </EmptyMedia>
        <EmptyTitle>No assets yet</EmptyTitle>
        <EmptyDescription>
          Connect a cloud account to build the inventory.
        </EmptyDescription>
      </EmptyHeader>
      <EmptyContent>
        <Button>Connect account</Button>
      </EmptyContent>
    </Empty>
  )
}
```

Use `Empty` for a whole page or a large region that is empty because the user has not set
anything up: no assets, no integrations, no reports. Say what is missing in the title, why it
matters or what fills it in the description, and offer the first step in `EmptyContent`.

`EmptyMedia variant="icon"` draws the icon on a muted square. The `default` variant renders the
media as is, for an illustration.

For lists, tables and cards, use the patterns built on these parts. They fix the spacing and the
copy rules, and keep an empty result apart from a failed request:

- [ListEmptyState](/patterns/list-empty-state) when the request succeeded and returned nothing.
- [ListErrorState](/patterns/list-error-state) when the request failed.

## Outlined

Add a dashed border when the empty state sits among other content and needs an edge, such as a
region of a dashboard. Links in `EmptyDescription` are underlined.

```tsx
import { RadarIcon } from "lucide-react"
import { Button } from "@zenoxai/ui/components/button"
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@zenoxai/ui/components/empty"

function EmptyOutlined() {
  return (
    <Empty className="border border-dashed border-border">
      <EmptyHeader>
        <EmptyMedia variant="icon">
          <RadarIcon />
        </EmptyMedia>
        <EmptyTitle>No scans scheduled</EmptyTitle>
        <EmptyDescription>
          Schedule a scan to check external domains for exposed services. Read
          about <a href="#accessibility">scan scopes</a> first.
        </EmptyDescription>
      </EmptyHeader>
      <EmptyContent>
        <Button variant="outline" size="sm">
          Schedule scan
        </Button>
      </EmptyContent>
    </Empty>
  )
}
```

## Accessibility

- `EmptyTitle` renders a `<div>`, not a heading. When the empty state replaces the main content
  of a page, put a heading inside it, `<EmptyTitle><h2>No assets yet</h2></EmptyTitle>`, so the
  page keeps its outline.
- The icon is decorative. The title must say on its own what is empty.

## API reference

`import { ... } from "@zenoxai/ui/components/empty"`

### Empty

No props of its own.

### EmptyHeader

No props of its own.

### EmptyTitle

No props of its own.

### EmptyDescription

No props of its own.

### EmptyContent

No props of its own.

### EmptyMedia

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| variant | `"default" \| "icon" \| null` | `default` | `default` shows the media as it is, for an illustration; `icon` sets an icon in a 32px muted tile. |

