Form Field
Wrapper composite que junta label, controle (Input/Select/Textarea), required indicator, helper text e error message. É onde a acessibilidade de form se materializa: associação correta de label↔controle, aria-describedby pra helper, aria-invalid em estado de erro.Composite wrapper that pairs label, control (Input/Select/Textarea), required indicator, helper text, and error message. This is where form accessibility lives: correct label↔control association, aria-describedby for helpers, aria-invalid on error.
Quando usarWhen to use
aria-label direto no controle). Mesmo assim, considere usar Form Field com --no-label pra manter consistência de espaçamento.The control doesn't need a visible label (e.g., search input in header with icon, using aria-label directly). Even so, consider Form Field with --no-label to keep spacing consistent.
AnatomiaAnatomy
.ds-field__label) — texto descritivo, com for= apontando pro id do controle.2 Required indicator (
.ds-field__required) — asterisco visual, aria-hidden="true" (a obrigatoriedade vem do aria-required no controle).3 Controle — Input/Select/Textarea/Checkbox group, com
id matching o label e aria-describedby apontando pro helper.4 Helper text (
.ds-field__helper) — orientação ou contexto adicional, com id referenciado pelo aria-describedby do controle.5 Error message (
.ds-field__error) — mensagem de validação, aparece apenas em .ds-field--error com role="alert".
1 Label (.ds-field__label) — descriptive text with for= pointing to the control's id.2 Required indicator (
.ds-field__required) — visual asterisk, aria-hidden="true" (required state comes from aria-required on the control).3 Control — Input/Select/Textarea/Checkbox group, with matching
id and aria-describedby pointing to the helper.4 Helper text (
.ds-field__helper) — guidance or additional context, with id referenced by control's aria-describedby.5 Error message (
.ds-field__error) — validation message, shown only in .ds-field--error with role="alert".
Encapsulando controlesWrapping form controls
Form Field é agnóstico ao tipo de controle. Funciona com Input, Textarea e Select via label[for]. Pra grupos (Checkbox/Radio), use <fieldset> + <legend> em vez de label/for individual — semantica de grupo é diferente da semantica de controle único.Form Field is control-agnostic. Works with Input, Textarea, and Select via label[for]. For groups (Checkbox/Radio), use <fieldset> + <legend> instead of individual label/for — group semantics differ from single-control semantics.
Note: para grupos, aria-describedby vai no container do grupo; <legend> substitui <label>. O wrapper <fieldset class="ds-field"> herda o gap vertical igual ao Input.Note: for groups, aria-describedby goes on the group container; <legend> replaces <label>. The <fieldset class="ds-field"> wrapper inherits the same vertical gap as Input.
Error stateError state
Adicione .ds-field--error no wrapper, aria-invalid="true" + aria-describedby no controle apontando pro id do error. role="alert" no error garante anúncio imediato pra screen readers.Add .ds-field--error on the wrapper, aria-invalid="true" + aria-describedby on the control pointing to the error's id. role="alert" on the error ensures immediate screen reader announcement.
<div class="ds-field ds-field--error">
<div class="ds-field__label-row">
<label class="ds-field__label" for="email">Email address</label>
<span class="ds-field__required" aria-hidden="true">*</span>
</div>
<div class="ds-input ds-input--error">
<input type="email" id="email" class="ds-input__field"
value="not-an-email"
aria-required="true"
aria-invalid="true"
aria-describedby="email-error">
</div>
<span class="ds-field__error" id="email-error" role="alert">
Please enter a valid email address.
</span>
</div>
Checklist de acessibilidadeAccessibility checklist
labelcomfor=matching oiddo controle (WCAG 1.3.1, 3.3.2).labelwithfor=matching the control'sid(WCAG 1.3.1, 3.3.2).- Required:
aria-required="true"no controle. Asterisco visual comaria-hidden="true".Required:aria-required="true"on the control. Visual asterisk witharia-hidden="true". - Helper text:
aria-describedbyno controle apontando proiddo helper.Helper text:aria-describedbyon the control pointing to helper'sid. - Error:
aria-invalid="true"no controle,aria-describedbyapontando proiddo error, erole="alert"no error pra anúncio imediato.Error:aria-invalid="true"on the control,aria-describedbypointing to error'sid, androle="alert"on the error for immediate announcement. - Sem label visível: use
aria-labeldireto no controle E aplique.ds-field--no-labelpra esconder a row.No visible label: usearia-labelon the control directly AND apply.ds-field--no-labelto hide the row. - Grupos (Checkbox/Radio): use
<fieldset>+<legend>em vez de label/for individual.Groups (Checkbox/Radio): use<fieldset>+<legend>instead of individual label/for.
ClassesClasses
| Class | UsoUsage |
|---|---|
ds-field | Wrapper. Stack vertical com gap consistente.Wrapper. Vertical stack with consistent gap. |
ds-field__label-row | Linha do label + required (horizontal).Label + required row (horizontal). |
ds-field__label | Texto do label (14px medium).Label text (14px medium). |
ds-field__required | Asterisco visual (decorativo, aria-hidden).Visual asterisk (decorative, aria-hidden). |
ds-field__helper | Helper text (12px secundário).Helper text (12px secondary). |
ds-field__error | Mensagem de erro. Visível apenas em --error.Error message. Visible only with --error. |
ds-field--error | Modificador: estado de erro. Mostra error message, tinge label.Modifier: error state. Shows error message, tints label. |
ds-field--no-label | Modificador: esconde label-row. Usar com aria-label no controle.Modifier: hides label-row. Pair with aria-label on control. |
ds-field--no-helper | Modificador: esconde helper.Modifier: hides helper. |