Layout and text container for a single form control. Owns the vertical rhythm of label / control / hint / error and nothing else.
The qds-field component provides consistent layout for labelled form controls. It manages the visual arrangement of a label, the slotted control, helper text (hint), and an error message. It is convenience, not correctness – every control is fully accessible without it.
qds-field does NOT own the accessibility tree. It renders label text visually, but the slotted control renders its own real <label for> and wires aria-describedby / aria-invalid / aria-required inside its own shadow root. The required marker (*) is aria-hidden="true" because the required state reaches assistive technology through the control’s own aria-required.
When the slotted control declares static qdsFieldConsumer = true, qds-field automatically pushes its label, hint, error-text, required, invalid, disabled, and size attributes down to the control – only for attributes the field actually has. It also listens for qds-validity-change events from the control and mirrors validity into its own invalid and error-text when no explicit error-text was set.
<qds-field label="Email" hint="We will never share your email" required>
<qds-text-input></qds-text-input>
</qds-field>
For horizontal layout:
<qds-field label="Username" orientation="horizontal">
<qds-text-input></qds-text-input>
</qds-field>
label - string, default ''. Label text displayed above (or beside in horizontal) the control. Pushed to a slotted consumer.hint - string, default ''. Helper text displayed below the control. Pushed to a slotted consumer.error-text - string, default ''. Error message shown when invalid is true. Pushed to a slotted consumer. Presence does not itself mark invalid.required - boolean, default false. Renders the visual required marker and pushes to a slotted consumer.invalid - boolean, default false. Shows error-text and pushes to a slotted consumer.disabled - boolean, default false. Dims label and hint, pushes to a slotted consumer.orientation - 'vertical' | 'horizontal', default vertical. horizontal puts the label in a left column of --qds-field-label-width.reserve-message - boolean, default false. Reserves one line below the control so validation does not shift layout.size - 'sm' | 'md' | 'lg', default md. Sets label type size and pushes to a slotted consumer.container - The outer wrapper element.label - The label text element.required - The required marker span (aria-hidden="true").control - The slot wrapper for the slotted control.hint - The helper text element.error - The error message element.--qds-field-label-width - Width of the label column in horizontal orientation. Default 180px.--qds-field-gap - Gap between label, control, and message rows. Default var(--theme-space-1, 4px).--qds-field-label-color - Color of the label text. Default var(--theme-text-secondary).--qds-field-hint-color - Color of the hint text. Default var(--theme-text-tertiary).--qds-field-error-color - Color of the error text and required marker. Default var(--theme-error).None of its own. Control events bubble through qds-field untouched. The field listens for qds-validity-change (bubbles, composed) from the slotted control and mirrors detail.valid into invalid and detail.message into error-text when no explicit error-text is set.
<qds-field
label="Password"
hint="At least 8 characters with a number"
required
size="md"
>
<qds-text-input></qds-text-input>
</qds-field>
<qds-field label="Remember me" orientation="horizontal" size="sm">
<qds-checkbox></qds-checkbox>
</qds-field>
<qds-field
label="Email"
hint="We will never share your email"
error-text="Please enter a valid email address"
invalid
reserve-message
>
<qds-text-input></qds-text-input>
</qds-field>