# Alert

Alert is a neobrutalist React component from Cruise UI. Info, success, warning and danger messages with a square icon chip; a full-width banner variant.

Install (with the @cruiseui registry in components.json, see Installation):

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

Import: `import { CruiseAlert } from "@/components/cruise/alert";`

## When to use

A message about the page or an action that people should see without it disappearing.

## When not to

Short-lived feedback after an action (use a Toast). Field errors (use a FormField).

## Example (React)

```tsx
"use client";

import { useState } from "react";
import { CruiseAlert } from "@/components/cruise/alert";
import { CruiseButton } from "@/components/cruise/button";

export default function AlertExample() {
  const [shown, setShown] = useState(true);
  return (
    <div className="flex flex-col gap-4">
      <CruiseAlert tone="info" title="Delivery is free this week">
        Orders over ₦10,000 in Lagos ship free until Sunday.
      </CruiseAlert>
      <CruiseAlert tone="success" title="Payment received">
        We&apos;ve sent your receipt to your email.
      </CruiseAlert>
      {shown && (
        <CruiseAlert tone="warning" title="Your card expires soon" onDismiss={() => setShown(false)}>
          Update it before the 30th to keep your plan.
        </CruiseAlert>
      )}
      <CruiseAlert
        tone="danger"
        title="Payment failed"
        action={<CruiseButton variant="secondary">Try again</CruiseButton>}
      >
        Your bank declined the charge. No money was taken.
      </CruiseAlert>
    </div>
  );
}
```

## HTML

Needs theme.css (https://cruiseui.dev/theme.css).

```html
<div class="alert" role="alert" data-tone="danger">
  <span class="alert-icon" aria-hidden="true">
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>
  </span>
  <div class="alert-body">
    <p class="alert-title">Payment failed</p>
    <p class="alert-text">Your bank declined the charge. No money was taken.</p>
    <div class="alert-actions"><button type="button" class="brutal btn btn-secondary">Try again</button></div>
  </div>
  <button type="button" class="alert-dismiss" aria-label="Dismiss" onclick="this.closest('.alert').remove()">
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg>
  </button>
</div>
<!-- info / success / warning: role="status" and data-tone="info" | "success" | "warning". Banner: add class="alert-banner". -->
```

## Props: CruiseAlert

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `tone?` | `CruiseAlertTone` | `"info"` | — |
| `title` | `ReactNode` | — | — |
| `children?` | `ReactNode` | — | — |
| `action?` | `ReactNode` | — | A button or link, e.g. "Try again". |
| `onDismiss?` | `(() => void)` | — | Shows the dismiss "X" (aria-label="Dismiss"). |
| `banner?` | `boolean` | `false` | Full width, no corners or shadow: for the top of a page. |
| `className?` | `string` | — | — |

## Accessibility

- role="alert" only for danger (it interrupts); role="status" for the others.
- The tone has an icon and a title, not colour alone.
- The dismiss button has aria-label="Dismiss".
