# List Empty State

The state of a list, table or card whose request succeeded and returned nothing.

```tsx
import { ListEmptyState } from "@zenoxai/ui/patterns/list-empty-state"

function ListEmptyStateDemo() {
  return (
    <ListEmptyState
      title="No alerts yet"
      description="Alerts appear here as soon as a connector reports a detection."
    />
  )
}
```

## Usage

```tsx
import { ListEmptyState } from "@zenoxai/ui/patterns/list-empty-state"
import { ListErrorState } from "@zenoxai/ui/patterns/list-error-state"

export function AlertList({ query }: { query: AlertsQuery }) {
  if (query.isError) return <ListErrorState onRetry={query.refetch} />
  if (query.data.length === 0) {
    return (
      <ListEmptyState
        title="No alerts yet"
        description="Alerts appear here as soon as a connector reports a detection."
      />
    )
  }
  return <AlertsTable alerts={query.data} />
}
```

Render `ListEmptyState` only when the request succeeded and came back empty. When the request
failed, render [ListErrorState](/patterns/list-error-state): an empty list tells the user there
is nothing to act on, and showing it for a failure hides a problem. While the request is in
flight, show a skeleton, not the empty state.

`title` and `description` arrive already translated. Write the title as a fact ("No alerts
yet"), and the description as what fills the list or what to do next. Pass an `action` only
when the user can change the outcome from here.

For a whole page that has nothing set up yet, such as an onboarding screen, compose the
[Empty](/components/empty) parts directly.

## No data or no match

"Nothing exists yet" and "nothing matches these filters" are different states. A list narrowed
to nothing by the user's filters or search should say so, and offer to clear them.

```tsx
import { FilterXIcon, SearchXIcon } from "lucide-react"
import { Button } from "@zenoxai/ui/components/button"
import { ListEmptyState } from "@zenoxai/ui/patterns/list-empty-state"

function ListEmptyStateFiltered() {
  return (
    <ListEmptyState
      icon={SearchXIcon}
      title="No alerts match these filters"
      description="Try a wider time range or remove a filter."
      action={
        <Button variant="outline" size="sm">
          <FilterXIcon data-icon="inline-start" />
          Clear filters
        </Button>
      }
    />
  )
}
```

## In a card

In a chart or summary card, keep the card header and put the empty state in `CardContent`. A
one-line title is usually enough there. In a table, render it in a single row that spans every
column, as in the [Table](/components/table) example.

```tsx
import { ChartNoAxesColumnIcon } from "lucide-react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@zenoxai/ui/components/card"
import { ListEmptyState } from "@zenoxai/ui/patterns/list-empty-state"

function ListEmptyStateInCard() {
  return (
    <Card className="w-full max-w-sm">
      <CardHeader>
        <CardTitle>Most targeted assets</CardTitle>
        <CardDescription>Last 7 days</CardDescription>
      </CardHeader>
      <CardContent>
        <ListEmptyState
          icon={ChartNoAxesColumnIcon}
          title="No attacks in this period"
        />
      </CardContent>
    </Card>
  )
}
```

## Accessibility

- The title is text, not a heading, so the page outline does not change when the list empties.
- The icon is decorative. Replace the default inbox glyph through `icon` when another one fits
  the content better, but never rely on it to carry the message.

## API reference

`import { ... } from "@zenoxai/ui/patterns/list-empty-state"`

### ListEmptyState

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| action | `ReactNode` |  | The one thing the user can do from here: clear the filters, create the first item. Omit when there is nothing to do but wait for data. |
| description | `string` |  | Already-translated second line. Omit for a one-line state. |
| icon | `LucideIcon` |  | Replaces the default inbox glyph. |
| title (required) | `string` |  | Already-translated title, for example "No alerts yet". |

