# Alert

A message inside the page that tells the user about a state, a risk or a change they need to know about.

```tsx
import { InfoIcon } from "lucide-react"
import { Alert, AlertDescription, AlertTitle } from "@zenoxai/ui/components/alert"

function AlertDemo() {
  return (
    <Alert variant="info" className="max-w-md">
      <InfoIcon />
      <AlertTitle>Scheduled maintenance on Sunday</AlertTitle>
      <AlertDescription>
        Log ingestion pauses from 02:00 to 03:00 UTC. Events received during the
        window are queued and processed afterwards.
      </AlertDescription>
    </Alert>
  )
}
```

## Usage

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

import {
  Alert,
  AlertDescription,
  AlertTitle,
} from "@zenoxai/ui/components/alert"

export function MaintenanceNotice() {
  return (
    <Alert variant="info">
      <InfoIcon />
      <AlertTitle>Scheduled maintenance on Sunday</AlertTitle>
      <AlertDescription>
        Log ingestion pauses from 02:00 to 03:00 UTC.
      </AlertDescription>
    </Alert>
  )
}
```

Place an alert above the content it is about, at the width of that content. Put an icon first:
the alert switches to a two-column grid and aligns the title and description next to it. The
title states the fact in one line; the description, when needed, says what it means for the user
or what to do.

Use something else when:

- The message is a one-line note above a list or a form, with no title. Use
  [InfoBanner](/patterns/info-banner).
- The message confirms an action the user just took ("Rule saved"). Use a toast
  ([Sonner](/components/sonner)).
- The user must decide before continuing. Use an [Alert Dialog](/components/alert-dialog).
- A list or a table has no data or failed to load. Use
  [ListEmptyState](/patterns/list-empty-state) or [ListErrorState](/patterns/list-error-state).

## Variants

```tsx
import { ArchiveIcon, CircleCheckIcon, CircleXIcon, InfoIcon, KeyRoundIcon, TriangleAlertIcon } from "lucide-react"
import { Alert, AlertTitle } from "@zenoxai/ui/components/alert"

function AlertVariants() {
  return (
    <div className="grid w-full max-w-md gap-3">
      <Alert>
        <KeyRoundIcon />
        <AlertTitle>API keys expire after 90 days</AlertTitle>
      </Alert>
      <Alert variant="info">
        <InfoIcon />
        <AlertTitle>A new detection pack is available</AlertTitle>
      </Alert>
      <Alert variant="success">
        <CircleCheckIcon />
        <AlertTitle>Okta connector reconnected</AlertTitle>
      </Alert>
      <Alert variant="warning">
        <TriangleAlertIcon />
        <AlertTitle>The license expires in 7 days</AlertTitle>
      </Alert>
      <Alert variant="neutral">
        <ArchiveIcon />
        <AlertTitle>This report is archived and read-only</AlertTitle>
      </Alert>
      <Alert variant="destructive">
        <CircleXIcon />
        <AlertTitle>Ingestion stopped for 3 assets</AlertTitle>
      </Alert>
    </div>
  )
}
```

| Variant       | Use for                                                                       |
| ------------- | ----------------------------------------------------------------------------- |
| `default`     | Neutral context on the card surface: a rule, a limit, a reminder.             |
| `info`        | Information that changes how the user reads the page: maintenance, a preview. |
| `success`     | A state that recovered or completed: a connector back online, a scan done.    |
| `warning`     | A risk that needs attention soon: an expiring license, missing owners.        |
| `neutral`     | A muted, low-priority note: an archived or read-only record.                  |
| `destructive` | Something is broken or data is being lost: ingestion stopped, sync failed.    |

## With an action

`AlertAction` pins a control to the top-right corner, centered on the first line of text, and
reserves space for it, so the title never runs under it. Keep it to one small button that fixes the problem the alert describes.

```tsx
import { CircleXIcon } from "lucide-react"
import { Alert, AlertAction, AlertDescription, AlertTitle } from "@zenoxai/ui/components/alert"
import { Button } from "@zenoxai/ui/components/button"

function AlertWithAction() {
  return (
    <Alert variant="destructive" className="max-w-md">
      <CircleXIcon />
      <AlertTitle>Microsoft 365 connector disconnected</AlertTitle>
      <AlertDescription>
        The access token was revoked. No sign-in events since 09:42.
      </AlertDescription>
      <AlertAction>
        <Button variant="outline" size="xs">
          Reconnect
        </Button>
      </AlertAction>
    </Alert>
  )
}
```

## With a link

Links in the title and description are underlined. Use a link when the fix lives on another
page; use `AlertAction` when the user can fix it from here.

```tsx
import { TriangleAlertIcon } from "lucide-react"
import { Alert, AlertDescription, AlertTitle } from "@zenoxai/ui/components/alert"

function AlertWithLink() {
  return (
    <Alert variant="warning" className="max-w-md">
      <TriangleAlertIcon />
      <AlertTitle>12 assets have no owner</AlertTitle>
      <AlertDescription>
        Alerts on these assets are not routed to anyone.{" "}
        <a href="#accessibility">Assign owners</a> to start routing them.
      </AlertDescription>
    </Alert>
  )
}
```

## Accessibility

- `Alert` renders `role="alert"`, an assertive live region: screen readers interrupt the user to
  read it when it appears. That fits a failure or a risk that shows up while the user works. For
  a message that is not urgent, override the role: `role="status"` when it appears after an
  action, `role="note"` when it is part of the page from the first render.
- The icon is decorative. The title must carry the meaning on its own; never rely on the color
  to tell a warning from an error.

## API reference

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

### Alert

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| variant | `"default" \| "destructive" \| "info" \| "success" \| "warning" \| "neutral" \| null` |  | Tone of the message. `default` is a plain card; `info`, `success`, `warning` and `destructive` tint the border, fill and text; `neutral` is a muted gray box. |

### AlertTitle

No props of its own.

### AlertDescription

No props of its own.

### AlertAction

No props of its own.

