.agents/skills/accessibility/references/components/form_layout.md
EuiFormRow and invalid stateApplies to: EuiFormRow, EuiFieldText, EuiFieldNumber, EuiFilePicker, EuiComboBox, EuiTextArea, EuiSelect
EuiFormRow wires the label, hints, and error to its child control. Assistive technology and visual error styling stay consistent only when the child control’s isInvalid matches the row’s isInvalid.
EuiFormRow has isInvalid={…}, the direct child uses the same expression for isInvalid.isInvalid → child does not need it either.EuiFieldText, EuiFieldNumber, EuiFilePicker, EuiComboBox, EuiTextArea, EuiSelect, EuiFormControlLayoutDelimited, SingleFieldSelect.EuiFormRow, sync the innermost parent–child pair first.{...fieldProps}, confirm isInvalid is not already in the spread before adding another.isInvalid is a boolean — no i18n on it. Visible label / error text uses i18n.translate when added or changed.<EuiFormRow label="Name" isInvalid={!!errors.name} error={errors.name}>
<EuiFieldText value={name} onChange={setName} isInvalid={!!errors.name} />
</EuiFormRow>
// WRONG — row marks invalid, child does not
<EuiFormRow label="Name" isInvalid={!!errors.name} error={errors.name}>
<EuiFieldText value={name} onChange={setName} />
</EuiFormRow>
// RIGHT — same expression on both
<EuiFormRow label="Name" isInvalid={!!errors.name} error={errors.name}>
<EuiFieldText value={name} onChange={setName} isInvalid={!!errors.name} />
</EuiFormRow>