# Alert

> A message box for important information, with tones, emphasis levels, and optional icon, title, description, and actions.

- Name: `alert`
- Status: beta
- Categories: feedback
- File: the install writes `alert.tsx` to your `ui` alias, `@/components/ui` by default.
- npm packages: `class-variance-authority`. The install adds them.
- Gallery: https://arbokui.com/components/alert
- Registry item: https://arbokui.com/r/alert.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/alert
   ```

## Use it for

- Telling people something important about the page or their task: a failed payment, planned downtime, a finished import.
- Use tone to say what kind of message it is: danger for errors, warning for risks, success for done, brand or neutral for news.
- Soft, the default, or outline fits most messages. Solid is the loudest, so save it for the one message that must not be missed.
- Add role='alert' only for an urgent message that appears after the page loads, like a failed save.
- Add role='status' to an alert that stays on the page while its text changes, like 'Saving…' then 'Saved'.

## Avoid it for

- role='alert' on a message that is there when the page loads. Screen readers would interrupt people for news that is not new.
- Buttons or links inside a solid alert. Button colors and focus rings are not checked on solid fills. Use soft or outline when the alert has actions.
- A problem with one field, row, or card. Say it under the thing with Notice.
- A choice people must make before they go on. Use a dialog.
- Short confirmations that should go away on their own. Use Toast.

## Props

- `tone`: `"neutral" | "brand" | "danger" | "success" | "warning"`. Default `"neutral"`. Color role.
- `emphasis`: `"solid" | "soft" | "outline" | "ghost"`. Default `"soft"`. How loud the alert is. Soft by default, unlike Badge and Button, because most alerts carry plain information.
- `role`: `"alert" | "status"`. Unset by default. Set it only for messages that appear or change after load. TypeScript rejects other roles.
- `className`: `string`. Extra classes. Later classes win, so className='rounded-none' replaces the radius.
- `AlertIcon`: `ComponentProps<"div">`. Part. Holds one icon beside the first line of text. aria-hidden by default.
- `AlertTitle`: `ComponentProps<"div">`. Part. A short summary in medium weight. A div, so it never breaks your heading order.
- `AlertDescription`: `ComponentProps<"div">`. Part. The details. Links inside it are underlined.
- `AlertActions`: `ComponentProps<"div">`. Part. A row of buttons or links under the text. It wraps on small screens.

## Accessibility

- Renders a \<div> with no role, so an alert that is there at load is read in order, like the rest of the page.
- role="alert" makes screen readers read the message at once, even mid-sentence. Use it only for urgent messages added after load.
- role="status" waits until the screen reader is quiet. Keep that alert on the page and change its text. Some screen readers miss a status region that arrives together with its text.
- AlertIcon is aria-hidden, and color is not read out. The title must say what kind of message it is, like "Payment failed".
- AlertTitle is a \<div>, not a heading. Put an \<h2> or \<h3> inside it if the alert needs to be in the page outline.
- The theme tests hold alert text to 4.5:1: solid and soft text on their own fills, and outline and ghost text on the page background.

## Examples

### Information that is on the page at load

```tsx
import { Info } from "lucide-react";

<Alert tone="brand" emphasis="soft">
  <AlertIcon>
    <Info />
  </AlertIcon>
  <AlertTitle>Planned maintenance</AlertTitle>
  <AlertDescription>The dashboard is read-only on Sunday from 02:00 to 04:00 UTC.</AlertDescription>
</Alert>
```

### An error after a failed save

```tsx
import { CircleAlert } from "lucide-react";

function SaveError({ error }: { error: string | null }) {
  if (!error) return null;
  return (
    <Alert role="alert" tone="danger" emphasis="soft">
      <AlertIcon>
        <CircleAlert />
      </AlertIcon>
      <AlertTitle>Your changes were not saved</AlertTitle>
      <AlertDescription>{error}</AlertDescription>
    </Alert>
  );
}
```

### A status that changes while it stays on the page

```tsx
function SaveStatus({ saving }: { saving: boolean }) {
  return (
    <Alert role="status" emphasis="outline">
      <AlertDescription>{saving ? "Saving…" : "All changes saved"}</AlertDescription>
    </Alert>
  );
}
```

### With actions (needs @arbokui/button)

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

<Alert tone="warning" emphasis="soft">
  <AlertTitle>Your trial ends in 3 days</AlertTitle>
  <AlertDescription>
    Add a payment method to keep your projects. <a href="/pricing">Compare plans</a>
  </AlertDescription>
  <AlertActions>
    <Button size="sm" tone="warning">
      Add payment method
    </Button>
    <Button size="sm" tone="warning" emphasis="soft">
      Remind me later
    </Button>
  </AlertActions>
</Alert>
```
