# Alert

> A message about the whole page or the whole form. CSS component with two classes and no JavaScript.

A box that says something about the whole: that the application was sent, that the service is down, that the deadline is approaching. If the message is about one field, it belongs under the field as an [Error Text](/components/error-text.md) or a [Help Text](/components/help-text.md).

## How to use it

**Plain HTML**

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/tokens/tokens.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/components/css/alert/alert.css">
<!-- Or everything in one file: https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/dist/lotek.css -->
```

```html
<div class="lt-alert">
<p class="lt-alert__title">Your case has been registered</p>
<p>You will get a reply within three weeks.</p>
</div>


<div class="lt-alert" data-color="info">
<p>We have updated the service. You need to sign in again.</p>
</div>


<div class="lt-alert" data-color="success">
<p>Your application has been sent. A receipt is on its way to your email.</p>
</div>


<div class="lt-alert" data-color="warning">
<p>The application deadline is in three days.</p>
</div>


<div class="lt-alert" data-color="danger">
<p class="lt-alert__title">Your application was not sent</p>
<p>The network did not respond. Try again in a moment.</p>
</div>
```

**TypeScript**

```ts
import "@lo-tek/interfaces/tokens.css"
import "@lo-tek/interfaces/alert.css"
```

`lt` is used in two ways, and which one depends on whether you create the element or find it.

**If you create the markup,** you spread the attributes in. That is the route in React, Astro and anything else that renders:

```tsx
import { lt } from "@lo-tek/interfaces/react"


<div {...lt.alert({ color: "success" })}>
  <p>Your application has been sent. A receipt is on its way to your email.</p>
</div>
```

The import goes to `/react` here, since the block is JSX. From there the keys are called `className` and `htmlFor`. In Astro and anything else without React you import `@lo-tek/interfaces` and get `class` and `for`.

**If the element is already there,** you set them on it. That is the route when you enhance HTML a server or a template has sent:

```ts
import { lt, type AlertColor } from "@lo-tek/interfaces"


const box = document.querySelector<HTMLElement>("#status")
if (!box) throw new Error("element not found")


// Arrow function, not `function`: a hoisted function declaration does not
// inherit the narrowing of `box` above, and then it is `null` again inside the body.
const show = (color: AlertColor, text: string) => {
  lt.setAttributes(box, lt.alert({ color }))
  box.textContent = text
}
```

If the colour comes from a response from outside, validate it with `lt.alert.isColor(x)`. `lt.alert.title` gives the class for the heading. See [Type-safe use](/type-safe-use.md).

| `data-color` | Used for |
| - | - |
| *(omitted)* | Neutral information |
| `info` | Something the user should know, but that needs no action |
| `success` | Something went well |
| `warning` | Something needs attention, but stops nothing |
| `danger` | Something went wrong, or stops the user |

## Role when the message appears later

The role is not part of `data-color`, because it depends on *when* the message appears, not on what it means.

| Situation | What you set |
| - | - |
| The message is in the markup when the page loads | No role |
| The message appears while the user is working | `role="status"` |
| The user has to stop and do something now | `role="alert"` |

```html
<div class="lt-alert" data-color="danger" role="alert">
  <p class="lt-alert__title">Your application was not sent</p>
  <p>The network did not respond. Try again in a moment.</p>
</div>
```

`role="alert"` interrupts what the screen reader is doing. Use it only when the interruption is justified. `role="status"` waits until the user has finished their sentence.

The element must be in the DOM before you fill it with text. If you insert the whole box already filled in, the screen reader does not notice the change.

## Classes you can style

| Class | What it is |
| - | - |
| `.lt-alert` | The box itself. The colour comes from `data-color`. |
| `.lt-alert__title` | The heading inside the box |

| Variable | Default |
| - | - |
| `--lt-alert-padding` | `var(--lt-spacing-3) var(--lt-spacing-4)` |
| `--lt-alert-radius` | `var(--lt-spacing-1)` |
| `--lt-alert-accent` | `var(--lt-spacing-1)`, the width of the stripe along the edge |

Each colour has a stripe on the edge and a faint surface behind the text, and the body text keeps its contrast against that surface in both themes. See [Customising](/customising.md).

## Accessibility

- The colour alone says nothing. The text must carry the message for someone who cannot tell green from red as well.
- One message at a time. Three boxes on top of each other read as noise, and the user cannot find the one that matters.
- Say what the user should do. “Try again in a moment” helps where “An error occurred” does not.
- If the message can be closed, give the close button a text that says what is being closed, not just a cross.
