COMPONENTS / ATOMS / al-input← ALL COMPONENTS

Input

<al-input><ALInput> REACTbetaOPEN IN FIGMA ↗

Reference generated from the custom elements manifest — 24 properties, 4 slots, 1 events.

PLAYGROUND13 CONTROLS
PREVIEW / al-input / SOUTHLEFT
Loading preview
type
labelPosition
autoComplete
FLAGS
ICON SLOTS
CODE — HTML / REACT

Guidance

AUTHORED · CITED TO SOURCE

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. type selects 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. Set name and 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 isError whenever you set errorNote. The error block only renders when isError is true, so an error string on its own displays nothing at all.
  • Prefer hideLabel over omitting label when 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 fieldNote for the rule the user needs BEFORE typing ("At least 8 characters"), and errorNote for what went wrong after.
  • Set maxLength when there is a real limit; it renders both the native maxlength and a live n/max counter, and drive the counter with maxLengthValue.

DON’T

  • Don't rely on the error note being announced. Only the FIELD note is given the aria-describedby id — 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 isError to set aria-invalid. The component renders no aria-invalid at all, so the invalid state is conveyed visually and through the note, not through the accessibility tree.
  • Don't use placeholder as 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 autoComplete on a password field expecting it to apply — the component forces autocomplete="off" whenever type="password".
  • Don't stack isRequired and isOptional on the same field. They render two contradictory markers, an asterisk and an "(Optional)" note.

ACCESSIBILITY IN PRACTICE

  • fieldId is 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 with hideLabel set.
  • isRequired renders the native required attribute as well as the visual asterisk, so browser constraint validation and assistive technology both see it.
  • ariaDescribedBy is 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.
  • isDisabled renders the native disabled attribute here — unlike al-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.

BOTH CHANGEDSouthleft Design SystemFIGMA SET · Input

Code and Figma each changed since the last confirmed sync. Neither side should be overwritten blindly.

DECIDED BY
SOURCE HASH
FIGMA SIDE
OBSERVED
LAST CONFIRMED SYNC
2026-08-28
PUBLIC SURFACE
24 ATTR · 4 SLOT · 1 EVENT · 0 PART

A sha1 of every .ts/.scss byte in the component directory, compared against the hash stored at the last sync. It cannot say what changed, and a comment edit moves it. Re-stamping this component records a contract digest instead.

CHECKEVIDENCEDETAILRESULT
Default stateAXEinput--DefaultPASS
Advanced statesAXE16 further storiesPASS
Screen readerMANUALNo screen-reader pass has been recorded for this component.NOT RECORDED
Keyboard navigationINTERACTION TESTSNo interaction tests and no manual keyboard pass.NOT RECORDED

MEASURED 2026-09-08 · 17 STORIES · AXE WCAG2A + WCAG2AA + WCAG21A + WCAG21AA + WCAG22AA

COLOR CONTRAST1 RULE FAILING

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.

RULEWHEREELEMENTS
color-contrastElements must meet minimum color contrast ratio thresholdsinput--Disabled, input--WithIconBeforeAfterDisabled3
import '@southleft/al-web-components/components/input';
import { ALInput } from '@southleft/al-react';
PROPTYPEDEFAULT
type'text' | 'email' | 'number' | 'password' | 'url' | 'hidden' | 'tel'Type variants - Specifies the type input element to display - **text** renders a standar text input - **email** renders a text input specifically for an email format - **number** renders an input for number values only - **password** renders an input for a password input format - **url** renders an input for urls only - **tel** renders an input for telephone number values only'text'
isActivebooleanisActive - Dynamically sets to true if the input has a value
isReadonlybooleanReadonly attribute - Specifies that an input field is read-only
isErrorbooleanError state - Changes the component's treatment to represent an error state
isDisabledbooleanDisabled attribute - Changes the component's treatment to represent a disabled state
isRequiredbooleanRequired attribute - Specifies that an input field must be filled out before submitting the form
isOptionalbooleanOptional state - Specifies that a field is optional and adds the text 'optional' to the label
isFocusedbooleanAutofocus attribute - When present, it specifies that the text area should automatically get focus when the page loads
hideLabelbooleanHide label? - If true, hides the label VISUALLY. The label element stays in the DOM and keeps its `for` association, so screen readers still announce the field. Before v2 this also revealed the placeholder, because the floating label occupied the placeholder's position and the two could not both show. The label no longer sits inside the field, so that coupling is gone: a `placeholder` now renders whenever it is set, independently of this.
labelPosition'top' | 'inset'Label position - `top` (default) puts the label above the field. - `inset` puts it inside the field's top padding, above the value — the v2 replacement for the floating label. It is STATIC: unlike the old floating label it never moves between states, so there is no jump on focus and no background patch punched through the field's border.'top'
labelstringLabel attribute - Specifies what content to enter within the input element'Label'
placeholderstringPlaceholder attribute - Specifies a short hint that describes the expected value of an input element
namestringName attribute - Specifies the name of an input element
valuestringValue attribute - Specifies the value of an input element
errorNotestringError message - An error field note that displays below the input
fieldNotestringField note - The helper text that displays below the input
fieldIdstringId attribute - The ID used for A11y and to associate the label with the input
ariaDescribedBystringaria-describedby attribute - Applied to the field note or error note for A11y
minLengthnumberMin length - Specifies the minimum number of characters required in an input element
maxLengthnumberMax length - Specifies the maximum number of characters required in an input element
maxLengthValuenumberMaxlength value - Dynamically outputs the number of characters inside the input field
minnumberMinimum value - Specifies a minimum value for an input element
maxnumberMaximum value - Specifies a maximum value for an input element
autoComplete'on' | 'off'Autocomplete property - Specifies whether an input element should have autocomplete enabled
SLOTDESCRIPTION
beforeThe content that appears before the text in the input
afterThe content that appears after the text in the input
field-noteIf content is slotted, it will display in place of the fieldNote property
errorIf content is slotted, it will display in place of the errorNote property
EVENTDESCRIPTIONTYPE
onInputChangeFired when the input's value changes. Detail: `{ value }`.CustomEvent
METHODDESCRIPTION
handleOnChange()Handle on change events 1. Update the maxlengthValue as text is being inputted in the field 2. If the value is greater than zero, then set active to true to move the label above the input 3. If the value is less than zero, then set active to false and move the label back to its original position 4. Dispatch the custom event
setBeforePadding()Set the padding-left for the input field based on the before content width
setInputPadding()Set input padding 1. Set the padding-left for the input field based on the before slotted content 2. If the before slotted content has not loaded, wait 100ms and try again 3. Set the padding-right for the input field based on the after slotted content

SOURCE — components/input/input.ts · Atoms/Form/Input