# Help Text

> Explanatory text below a form field. A CSS component with one class and no JavaScript.

The small text below a field that explains what the system expects. If the text is an error message, use [Error Text](/components/error-text.md).

## How to use it

**Plain HTML**

```html
<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/help-text/help-text.css">
<!-- Or everything in one file: https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.40.0/dist/lotek.css -->
```

```html
<p class="lt-help-text">State the budget in EB. The crew sees the number.</p>
<p class="lt-help-text" data-variant="strong">The order is binding once a crew takes it.</p>
<p class="lt-help-text" data-variant="success">The floor plans have been uploaded.</p>
<p class="lt-help-text" data-variant="warning">The window closes in three days.</p>
```

**TypeScript**

```ts
import "@lo-tek/interfaces/tokens.css"
import "@lo-tek/interfaces/help-text.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,** spread the attributes in. That is the way in React, Astro and anything else that renders:

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


<p {...lt.helpText()}>State the budget in EB. The crew sees the number.</p>
```

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

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

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


const label = document.querySelector<HTMLLabelElement>("#budget-label")
const input = document.querySelector<HTMLInputElement>("#budget")
const helpText = document.querySelector<HTMLElement>("#budget-help")


const field = lt.field({ id: "budget", help: true })


lt.setAttributes(label, field.label)
lt.setAttributes(input, lt.input(), field.control)
lt.setAttributes(helpText, lt.helpText(), field.help)
```

[`lt.field`](/components/field.md) generates the `id` and sets `aria-describedby`, so the wiring cannot be forgotten.

If you only need the class:

```ts
lt.setAttributes(helpText, lt.helpText({ variant: "warning" }))
```

**kotlinx.html**

```kotlin
// 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:

```kotlin
import kotlinx.html.*
import no.lotek.*
import no.lotek.html.lt


fun FlowContent.hints() {
    p { lt(Lt.helpText()); +"State the budget in EB. The crew sees the number." }
    p { lt(Lt.helpText(variant = HelpTextVariant.STRONG)); +"The order is binding once a crew takes it." }
    p { lt(Lt.helpText(variant = HelpTextVariant.SUCCESS)); +"The floor plans have been uploaded." }
    p { lt(Lt.helpText(variant = HelpTextVariant.WARNING)); +"The window closes in three days." }
}
```

| `data-variant` | Used for |
| - | - |
| *(omitted)* | Muted. The default. |
| `strong` | Full text colour, when the text has to be read before the field is filled in |
| `success` | Confirmation that something went well |
| `warning` | Something the user should know, but that does not stop submission |

## Wired to the field

Without `aria-describedby` the help text is not read out when the field gets focus.

**Plain HTML**

```html
<label class="lt-label" for="budget">Budget</label>
<input class="lt-input" id="budget" inputmode="numeric" aria-describedby="budget-help" />
<p class="lt-help-text" id="budget-help">In EB, without the code. The crew sees it.</p>
```

[Field](/components/field.md) generates the `id` and sets `aria-describedby` for you.

## Classes you can style

| Class | What it is |
| - | - |
| `.lt-help-text` | The text. The colour comes from `data-variant`. |

See [Customising](/customising.md) for how the layer works.

## Accessibility

- Without `aria-describedby` the text is invisible to screen readers. The wiring is the whole point.
- Keep it short. It is read out right after the label every time the field gets focus.
- Colour should not carry the meaning. A `warning` has to say in its words what the problem is.
