Text Field
A label, a single-line input, and an optional hint, wired together from one field name so the label's `for` and the hint's `aria-describedby` cannot drift apart.
Examples
Label and input
The name is given once; the id and the label's `for` are derived from it.
With a hint
Help text below the input, announced with it rather than left as loose prose beside it.
Separated by commas, for example 0801, 080C. Leave empty to assign none.
Input types
Text and email. Arms are added when a screen needs one.
Autofill is refused here: this is not the address of whoever is filling the form in.
Suggestion list
`.list(id)` points the input at a `<datalist>` the caller renders once, so a list of hundreds of entries is not repeated per control. It suggests and never restricts, so the value still has to be validated where it is accepted — and with no JavaScript it stays an ordinary text field.
Start typing a name.
One-time code
One intent method sets autocomplete, inputmode, pattern and maxlength together — setting three of the four is a field that looks right and autofills nothing.
Dates and years
`InputType::Date` is the native date control — it holds a full `YYYY-MM-DD` and renders empty for anything else, so a lesser precision or a placeholder value has to be handled before it gets here. `year` bundles the three attributes a four-digit year needs; it is deliberately not `type="number"`, whose spinner changes the value on a stray scroll.
Leave empty while the project is ongoing.
Four digits.
Holding a rejected entry
A rejected form comes back showing what was typed, including the part that was wrong.
Rejected, with the reason
`error` sets `aria-invalid` and the description together, and the message keeps the hint rather than replacing it — the reader needs the rule as well as the complaint.
Separated by commas.
"nope!" is not a project shortcode. Shortcodes are letters and digits only.
Enter a valid email address.
Nothing wrong with this one.
The same name twice on one page
`with_id` moves the id, the label's `for` and the hint's `aria-describedby` together, so two forms collecting the same field do not collide.
Where the invitation goes.
Where replies go.