# Alert

> Quiet inline notice with a tone (info, success, warning, danger), optional title, description, action and dismiss.

Source: https://docs.nasaqui.com/components/alert

## Install

```bash
npx shadcn@latest add https://docs.nasaqui.com/r/alert.json
```

A quiet, inline notice about the content next to it: a draft invoice that was not sent, a failed sync, a plan
limit that is close. It sits in the page flow, stays until the situation changes or the user dismisses it, and
never interrupts. Each tone has its own glyph, so it reads without colour.

**Relationship to Attention.** [`Attention`](https://docs.nasaqui.com/components/attention) is a sorted list of things the user should act
on across the product ("What needs my attention?"), fed by the product. `Alert` is one message about the local
context, written by the developer at the spot where it applies. If you have several items to triage, use
`Attention`; if you have one sentence about this page or form, use `Alert`.

## When to use

- A persistent message tied to a page, card or form: warnings, limits, results, background information.
- Something the user may want to act on, with one action button beside it.

## When not to use

- A list of things to do: use [`Attention`](https://docs.nasaqui.com/components/attention).
- A transient confirmation of something the user just did ("Saved"): use [`toast`](https://docs.nasaqui.com/components/toast).
- A field-level validation message: use the [`Field`](https://docs.nasaqui.com/components/field) error slot.
- A decision the user must make before continuing: use [`AlertDialog`](https://docs.nasaqui.com/components/alert-dialog).
- A status next to a value in a table or header: use [`Status`](https://docs.nasaqui.com/components/status) or [`Badge`](https://docs.nasaqui.com/components/badge).

## Import

```tsx
import { Alert } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"
```

## Quick start

```tsx
import { Alert } from "@fadymondy/nasaq/web";

export function SyncFailed() {
  return (
    <Alert tone="danger" title="Sync failed">
      Could not reach the data source. Check the credentials.
    </Alert>
  );
}
```

## Anatomy

```
Alert                     role="alert" (warning, danger) or "status" (info, success)   data-slot="alert"
├─ icon                   tone glyph                                                   data-slot="alert-icon"
├─ body                                                                                data-slot="alert-body"
│  ├─ title               optional                                                     data-slot="alert-title"
│  └─ description         children                                                     data-slot="alert-description"
└─ actions                action and dismiss button                                    data-slot="alert-actions"
```

## API

### `Alert`

`AlertProps` extends `ComponentProps<"div">` (without `title`).

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `tone?` | `"info" \| "success" \| "warning" \| "danger"` | `"info"` | Meaning, glyph and colour. |
| `title?` | `ReactNode` | none | Short heading. Omit for a one-line notice. |
| `children?` | `ReactNode` | none | The description. |
| `icon?` | `LucideIcon` | tone glyph | Replaces the glyph. |
| `action?` | `ReactNode` | none | One action at the inline end, e.g. `<Button size="sm">`. |
| `onDismiss?` | `() => void` | none | Shows a dismiss button; the host hides the alert. |
| `dismissLabel?` | `string` | `"Dismiss"` / `"تجاهل"` by locale | `aria-label` of the dismiss button. |
| `role?` | `AriaRole` | `"alert"` for warning and danger, else `"status"` | Override the live-region role. |
| `className?` | `string` | none | Merged onto the root. |

`AlertTone` is the union of the four tone names.

## Examples

### With action and dismiss

```tsx
import { Alert, Button } from "@fadymondy/nasaq/web";
import { useState } from "react";

export function PaymentFailed() {
  const [open, setOpen] = useState(true);
  if (!open) return null;
  return (
    <Alert
      tone="danger"
      title="Payment failed"
      action={<Button size="sm">Update card</Button>}
      onDismiss={() => setOpen(false)}
    >
      The account is restricted in 3 days unless it is updated.
    </Alert>
  );
}
```

### Arabic, one line

```tsx
import { Alert } from "@fadymondy/nasaq/web";

export function DraftInvoice() {
  return <Alert tone="warning">هذه الفاتورة مسودة ولم تُرسل بعد.</Alert>;
}
```

## Accessibility

- `warning` and `danger` use `role="alert"`: assistive tech announces them immediately when they appear. `info` and `success` use `role="status"`: announced politely. Override with `role`.
- Tone is carried by a distinct glyph as well as colour. The glyph is `aria-hidden`; put the meaning in the text ("Sync failed", not just red).
- The dismiss button is a real `<button>` with an `aria-label`; localise `dismissLabel` when not using the Nasaq provider.

| Key | Action |
| --- | --- |
| `Tab` | Moves to the action and dismiss buttons. |
| `Enter` / `Space` | Activates the focused button. |

## RTL & i18n

- The grid is icon, body, actions in inline order, so it mirrors in RTL. Text uses `text-start`; the action gap uses `ms-3`.
- Built-in string: the dismiss label, "Dismiss" or "تجاهل" when the Nasaq locale starts with `ar`.

## Styling & tokens

- Surface: `bg-nq-{tone}-soft`, `border-nq-{tone}/30`, `rounded-card`; glyph `text-nq-{tone}-text`; text stays `text-foreground` / `text-muted-foreground`.
- Target `[data-slot=alert]`, `[data-tone=warning]`, `alert-title`, `alert-description`, `alert-actions`. Extend with `className`.

## Do / Don't

- **Do** say what happened and what to do, in the title or description.
- **Do** keep one action at most; put the primary next step there.
- **Don't** stack more than two alerts on a page; a list belongs in [`Attention`](https://docs.nasaqui.com/components/attention).
- **Don't** use `danger` for things that are merely unusual.

## Related

- [Attention](https://docs.nasaqui.com/components/attention) · [Toast](https://docs.nasaqui.com/components/toast) · [Status](https://docs.nasaqui.com/components/status) · [Badge](https://docs.nasaqui.com/components/badge)

## Lab

https://docs.nasaqui.com/?path=/docs/components-alerts-notifications-alert--docs

## Code

### React

```tsx
import { Alert } from "@fadymondy/nasaq/web";

export function SyncFailed() {
  return (
    <Alert tone="danger" title="Sync failed">
      Could not reach the data source. Check the credentials.
    </Alert>
  );
}
```

### shadcn

```tsx
import { Alert } from "@/components/ui/alert";

export function SyncFailed() {
  return (
    <Alert tone="danger" title="Sync failed">
      Could not reach the data source. Check the credentials.
    </Alert>
  );
}
```

### Vue

```vue
<script setup lang="ts">
import { NqAlert } from "@fadymondy/nasaq/vue";
</script>

<template>
  <NqAlert tone="danger" title="Sync failed">
    Could not reach the data source. Check the credentials.
  </NqAlert>
</template>
```

### Blade

```blade
<x-nq::alert tone="danger" title="Sync failed">
    Could not reach the data source. Check the credentials.
</x-nq::alert>
<x-nq::alert tone="info" title="Heads up" dismissible class="mt-3">
    A new version of the Riyadh Storefront is ready to deploy.
</x-nq::alert>
```

### HTML + Alpine

```html
<div data-slot="alert" data-tone="danger" role="alert"
        class="relative grid grid-cols-[auto_1fr_auto] items-start gap-x-3 rounded-card border p-3 text-start border-nq-danger/30 bg-nq-danger-soft">
    <svg aria-hidden="true" data-slot="alert-icon" class="mt-0.5 size-4 text-nq-danger-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <path d="m15 9-6 6"/>
  <path d="m9 9 6 6"/>
</svg>    <div data-slot="alert-body" class="flex min-w-0 flex-col gap-0.5">
                    <div data-slot="alert-title" class="text-label text-foreground">Sync failed</div>
                            <div data-slot="alert-description" class="text-body-sm text-muted-foreground">Could not reach the data source. Check the credentials.</div>
            </div>
    </div>
<div data-slot="alert" data-tone="info" role="status"
     x-data="nqAlert()" x-modelable="open" x-show="open"     class="relative grid grid-cols-[auto_1fr_auto] items-start gap-x-3 rounded-card border p-3 text-start border-nq-info/30 bg-nq-info-soft mt-3">
    <svg aria-hidden="true" data-slot="alert-icon" class="mt-0.5 size-4 text-nq-info-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="12" cy="12" r="10"/>
  <circle cx="12" cy="12" r="1"/>
</svg>    <div data-slot="alert-body" class="flex min-w-0 flex-col gap-0.5">
                    <div data-slot="alert-title" class="text-label text-foreground">Heads up</div>
                            <div data-slot="alert-description" class="text-body-sm text-muted-foreground">A new version of the Riyadh Storefront is ready to deploy.</div>
            </div>
            <div data-slot="alert-actions" class="ms-3 flex items-center gap-1">
                            <button data-slot="button"
     type="button"                         aria-label="Dismiss" x-on:click="dismiss()" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-nq-hover size-control-sm p-0 text-muted-foreground [&_svg]:size-3.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg></button>
                    </div>
    </div>
```
