field
#existingsourceA labelled form control with optional helper text or error message in a fixed canonical layout. Always wraps exactly one input control via the default slot.
When to use
- Every labelled form input — pair with `input`, `select`, or `textarea`
- Inline validation feedback (helper or error)
- Required-field indicator (`*` next to label)
- Form fields that need consistent label-above-input layout
When not to use
- Unlabelled controls (e.g. a search input with placeholder only — use SearchInput)
- Multi-input fields like address blocks — use Fieldset (when it lands)
- Toggle switches with adjacent label — use LabeledSwitch
Accessibility
Role: group
- Tab — Moves focus to the wrapped input
Screen reader: `label` is wired to the wrapped input via `for`/`id`. When `error` is set, the message gets `role=alert` so screen readers announce it immediately. Helper text is hidden when error is set.
Notes: Caller MUST pass the same `field_id` to the wrapped input via its `id` prop — the audit fails if these are mismatched.
Props
| Name | Type | Default | Description |
|---|---|---|---|
label* | string | — | Visible label text. Always rendered — placeholder text alone is not a label and fails accessibility. |
field_id* | string | — | Stable id used to bind label `for=` to the wrapped input's `id=`. Caller must pass the same id to the wrapped input via its `id` prop. v1: id strings; later may become opaque tokens. |
helper | string | — | Optional helper text below the input. Hidden when error is set. |
error | string | — | Error message below the input. When set, helper is hidden, the wrapped input shows its error visual, and the message gets `role=alert` so screen readers announce it. |
required | boolean | false | Renders a visual `*` next to the label. |
Examples
Username field with helper text.
YAML
type: field
props:
label: Username
field_id: login-username
helper: Or your email address.
slots:
default:
- type: input
props:
value: ${state.username}
on_input: ${actions.set_username}
auto_focus: truePassword field with error display (replaces ad-hoc error markup in PasswordLoginForm).
YAML
type: field
props:
label: Password
field_id: login-password
error: ${state.error_message}
slots:
default:
- type: input
props:
value: ${state.password}
on_input: ${actions.set_password}
input_type: password
error: ${state.has_error}Required field marker.
YAML
type: field
props:
label: Email
field_id: register-email
required: true
helper: We'll never share it.
slots:
default:
- type: input
props:
value: ${state.email}
on_input: ${actions.set_email}
input_type: email