Alert
A box that says something about the whole: that a route was saved, that a sector is dark, that a maintenance window is approaching. If the message is about one field, it belongs under the field as an Error Text or a Help Text.
How to use it
Section titled “How to use it”Incident LAT-0412 has been logged
The duty crew reports back within the hour.
The console has been updated. You need to sign in again.
Relay 14 is back. Traffic for sector 9 runs through it again.
Someone is on the wire in sector 3.
Sector 9 is dark
Crews are on the way.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.40.0/src/tokens/tokens.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.40.0/src/components/css/alert/alert.css"><!-- Or everything in one file: https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.40.0/dist/lotek.css --><div class="lt-alert"><p class="lt-alert__title">Incident LAT-0412 has been logged</p><p>The duty crew reports back within the hour.</p></div>
<div class="lt-alert" data-color="info"><p>The console has been updated. You need to sign in again.</p></div>
<div class="lt-alert" data-color="success"><p>Relay 14 is back. Traffic for sector 9 runs through it again.</p></div>
<div class="lt-alert" data-color="warning"><p>Someone is on the wire in sector 3.</p></div>
<div class="lt-alert" data-color="danger"><p class="lt-alert__title">Sector 9 is dark</p><p>Crews are on the way.</p></div>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:
import { lt } from "@lo-tek/interfaces/react"
<div {...lt.alert({ color: "success" })}> <p>Relay 14 is back. Traffic for sector 9 runs through it again.</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:
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.
// Once for the whole app, in the page template: every stylesheet, from the WebJar.head { link(rel = "stylesheet", href = LotekWebJar.CSS) }On a Kotlin or Java server, the same with kotlinx.html and lo-tek-kotlinx-html. The builder functions are in Lt, with an enum for each list of values:
import kotlinx.html.*import no.lotek.*import no.lotek.html.lt
fun FlowContent.alerts() { div { lt(Lt.alert()) p { lt(Lt.alert.title); +"Incident LAT-0412 has been logged" } p { +"The duty crew reports back within the hour." } } div { lt(Lt.alert(color = AlertColor.INFO)); p { +"The console has been updated. You need to sign in again." } } div { lt(Lt.alert(color = AlertColor.SUCCESS)); p { +"Relay 14 is back. Traffic for sector 9 runs through it again." } } div { lt(Lt.alert(color = AlertColor.WARNING)); p { +"Someone is on the wire in sector 3." } } div { lt(Lt.alert(color = AlertColor.DANGER)) p { lt(Lt.alert.title); +"Sector 9 is dark" } p { +"Crews are on the way." } }}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
Section titled “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" |
<div class="lt-alert" data-color="danger" role="alert"> <p class="lt-alert__title">Your routes were not saved</p> <p>The wire 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
Section titled “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.
Accessibility
Section titled “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.