Reference generated from the custom elements manifest — 24 properties, 4 slots, 1 events.
CODE — HTML / REACT
Guidance
The single-line text field, and the system's reference implementation of a form control. It owns the whole field — label, asterisk, optional marker, field note, error note and character counter — so the surrounding page never has to assemble those parts itself, and it is form-associated, so its value reaches the owning <form>'s FormData across the shadow boundary.
WHEN TO USE
- You need one line of typed input: text, email, number, password, url or tel.
typeselects the native input type, which is what gives mobile keyboards and browser autofill something to work with. - The field belongs to a form whose data you read with
FormData. Setnameand the value is carried through form-associated custom element internals. - The field needs helper text, an error, a required marker or a character counter — all four are built in and positioned for you.
WHEN NOT TO USE
- The user needs to write more than a line or two. A single-line field with a long value hides most of what has been typed.USE TEXTAREA →
- The value comes from a fixed set of options rather than free typing. A text field with a validation message is a worse version of a picker.USE SELECT →
- The user is filtering or querying a list rather than filling in a field — that pattern wants its own affordance and clear control.USE SEARCH →
- You want a number the user nudges up and down rather than types, such as a quantity.USE INPUT-STEPPER →
DO
- Set
isErrorwhenever you seterrorNote. The error block only renders whenisErroris true, so an error string on its own displays nothing at all. - Prefer
hideLabelover omittinglabelwhen the layout has no room for it. The<label for>is still rendered and still associated — it is only visually hidden, and the required asterisk is relocated so it stays visible. - Use
fieldNotefor the rule the user needs BEFORE typing ("At least 8 characters"), anderrorNotefor what went wrong after. - Set
maxLengthwhen there is a real limit; it renders both the nativemaxlengthand a liven/maxcounter, and drive the counter withmaxLengthValue.
DON’T
- Don't rely on the error note being announced. Only the FIELD note is given the
aria-describedbyid — the error block is rendered without it, so a screen-reader user reaches the error only by browsing the field, not on focus. - Don't expect
isErrorto setaria-invalid. The component renders noaria-invalidat all, so the invalid state is conveyed visually and through the note, not through the accessibility tree. - Don't use
placeholderas the label. It disappears on the first keystroke, is not associated with the field, and leaves the user with no way back to the question. - Don't set
autoCompleteon a password field expecting it to apply — the component forcesautocomplete="off"whenevertype="password". - Don't stack
isRequiredandisOptionalon the same field. They render two contradictory markers, an asterisk and an "(Optional)" note.
ACCESSIBILITY IN PRACTICE
fieldIdis generated when you do not supply one and wires the<label for>to the<input id>, so the field always has a programmatic label even withhideLabelset.isRequiredrenders the nativerequiredattribute as well as the visual asterisk, so browser constraint validation and assistive technology both see it.ariaDescribedByis generated when absent and is applied to the input and to the field note. If you pass your own id, you own keeping it pointed at something that exists.isDisabledrenders the nativedisabledattribute here — unlikeal-button— so a disabled input genuinely leaves the tab order.
CONTENT GUIDELINES
- Label the data, not the action: "Email address", not "Enter your email". The field already tells the user to enter something.
- Write field notes as the rule, not the failure: "Use 8 or more characters" reads better before typing than "Password too short" does after.
- Write error notes so they say what to do next, and keep them specific enough that the user does not have to guess which rule they broke.
- Mark the minority. If most fields in a form are required, mark the optional ones with
isOptional; if most are optional, mark the required ones.
WHERE THIS CAME FROM
libs/al-web-components/components/input/input.ts`static formAssociated` and the FormAssociatedController — why a value set inside shadow DOM still reaches the owning form.libs/al-web-components/components/input/input.tsThe required asterisk, including the relocated variant rendered when `hideLabel` would otherwise hide it.libs/al-web-components/components/input/input.tsThe describedby wiring: it reaches the input and the field note, and no equivalent id is put on the error block.libs/al-web-components/components/input/input.tsThe `<label for>` that survives `hideLabel`, and the asterisk / optional markers rendered inside it.
Each line above names a file and a literal string that must still appear in it.pnpm gate:guidance re-reads them from this built page, so guidance that has stopped being true fails a check rather than misleading you.
FIGMA PARITY
Code and Figma each changed since the last confirmed sync. Neither side should be overwritten blindly.
- DECIDED BY
- CONTRACT DIFF
- FIGMA SIDE
- OBSERVED
- LAST CONFIRMED SYNC
- 2026-08-28
- PUBLIC SURFACE
- 24 ATTR · 4 SLOT · 1 EVENT · 0 PART
The component’s public surface — attributes and their value sets, slots, events, CSS parts and custom properties, from the manifest — compared against the Figma set’s property definitions.
ACCESSIBILITY
The CI gate disables color-contrast globally (libs/al-web-components/story-fixture/src/main.ts), so its result never reaches a test run. It is enabled for this measurement, and reported here whichever way it comes out.
INSTALL
import '@southleft/al-web-components/components/input';
import { ALInput } from '@southleft/al-react';API — 24 PROPS
SLOTS
EVENTS
PUBLIC METHODS
SOURCE — components/input/input.ts · Atoms/Form/Input