# 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.36.0/src/tokens/tokens.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/src/components/css/help-text/help-text.css">
<!-- Or everything in one file: https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.36.0/dist/lotek.css -->
```

```html
<p class="lt-help-text">You will find the number at the top right of the invoice.</p>
<p class="lt-help-text" data-variant="strong">The change applies from the start of next month.</p>
<p class="lt-help-text" data-variant="success">The attachment has been uploaded.</p>
<p class="lt-help-text" data-variant="warning">The application deadline is 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()}>You will find the number at the top right of the invoice.</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>("#reference-label")
const input = document.querySelector<HTMLInputElement>("#reference")
const helpText = document.querySelector<HTMLElement>("#reference-help")


const field = lt.field({ id: "reference", 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" }))
```

| `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="reference">Payment reference</label>
<input class="lt-input" id="reference" inputmode="numeric" aria-describedby="reference-help" />
<p class="lt-help-text" id="reference-help">You will find the number at the top of the invoice.</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.
