abaabil

Input

3rd lightest of the eight, by js weight

A single <input>, themed through CSS custom properties. The interesting part isn't the input itself, it's the wiring teams get wrong by hand: a real associated <label>, a description and an error both joined into one aria-describedby, and aria-invalid.

Example (a11y tier)

We'll only use this to send your receipt.

This one field has a description and an error visible at the same time. Both are joined into a single aria-describedby (space-separated ids), so a screen reader announces the label, then the description, then the error, in that order, not just whichever one the markup happened to put closest to the input.

Import

import Input from 'abaabil/input'         // structure only
import Input from 'abaabil/input/styled'  // + CSS
import Input from 'abaabil/input/a11y'    // + label/description/error wiring

What the a11y tier adds

  • Renders a real <label> associated with the input via htmlFor/id, instead of a styled <div> that merely looks like a label.
  • Joins whichever of description and error are actually present into one aria-describedby, generated with useId so ids stay unique with several inputs on one page. A consumer-supplied aria-describedby is preserved and combined with the generated ids rather than replaced.
  • Sets aria-invalid whenever error is present, so assistive tech gets the invalid state even before any validation library's own attribute would land.
  • Warns in development if the input would have no accessible name: no label, no aria-label, no aria-labelledby.

Props

PropTypeDefaultTierDescription
typestring'text'allInput type.
classNamestringallMerged with the base class.
labelstringa11yRendered as a real <label>, associated with the input via htmlFor/id.
descriptionstringa11yRendered as help text and wired into aria-describedby.
errorstringa11yRendered as an error message, sets aria-invalid, and is wired into aria-describedby alongside the description.
requiredbooleanfalsea11ySets the native required attribute.
idstringa11yOverrides the generated input id.
...propsallEverything else (name, placeholder, onChange, aria-describedby, ...) lands on the <input>. A consumer-supplied aria-describedby composes with the generated description/error ids rather than being replaced.