Fieldset
import { Fieldset } from '@absoluteui/components/fieldset';import '@absoluteui/components/fieldset/style.css';Using Angular? See Fieldset for Angular.
What it does
Section titled “What it does”Enhances a native <fieldset> that groups related controls, such as an address, a date of birth, or contact preferences, with the AbsoluteUI legend, help text, required marker, and a group-level error. Fieldset.enhance keeps the fieldset’s own controls in place; the native element provides the group semantics and the disabled state.
When to use
Section titled “When to use”- Several fields answer one question: address, date of birth, contact preferences.
- A validation rule that spans fields: ‘Enter a street and a city’, ‘Choose at least one channel’.
When not to use
Section titled “When not to use”- One control: use Form Field or the control’s own label.
- A set of checkboxes or radios with one value: use Checkbox Group or Radio Group (they render their own fieldset).
- Visual grouping without a shared question: use Card or layout primitives.
Examples
Section titled “Examples”Address group with a group error
Section titled “Address group with a group error”import { Fieldset } from '@absoluteui/components/fieldset';import { TextInput } from '@absoluteui/components/text-input';import { Button } from '@absoluteui/components/button';
const element = document.createElement('fieldset');const streetHost = document.createElement('div');const cityHost = document.createElement('div');element.append(streetHost, cityHost);const check = document.createElement('button');check.type = 'button';check.textContent = 'Check address';Button.enhance(check);document.body.append(element, check);const street = TextInput.create(streetHost, { label: 'Street', autocomplete: 'address-line1' });const city = TextInput.create(cityHost, { label: 'City', autocomplete: 'address-level2' });const address = Fieldset.enhance(element, { legend: 'Delivery address', description: 'Where we send the order', required: true });check.addEventListener('click', () => { const missing = street.value.trim() === '' || city.value.trim() === ''; address.update({ error: missing ? 'Enter a street and a city' : null }); if (missing) address.focus();});import { Fieldset } from '@absoluteui/components/fieldset';import '@absoluteui/components/fieldset/style.css';
const element = document.querySelector<HTMLFieldSetElement>('#birth-date');if (element) Fieldset.enhance(element, { legend: 'Date of birth', description: 'For example, 27 3 2007' });More usage
Section titled “More usage”import { Fieldset } from '@absoluteui/components/fieldset';import { ErrorSummary } from '@absoluteui/components/error-summary';
const element = document.querySelector<HTMLFieldSetElement>('#contact');const summaryHost = document.querySelector<HTMLElement>('#summary');if (element && summaryHost) { const contact = Fieldset.enhance(element, { legend: 'How should we contact you?', required: true }); const summary = ErrorSummary.create(summaryHost); const message = 'Choose at least one way to contact you'; contact.update({ error: message }); summary.show([{ message, target: contact.legend, focus: () => { contact.focus(); } }]);}Anatomy
Section titled “Anatomy”<fieldset class="aui-fieldset [aui-fieldset--invalid]" aria-describedby="help error ..."> <legend class="aui-field__label">Legend<span class="aui-field__required" aria-hidden="true">*</span><span>(required) (visually hidden)</span></legend> <div class="aui-field__description">help</div> <div class="aui-field__error aui-validation-message">icon + group error</div> ... the fieldset's own controls ...</fieldset>API reference
Section titled “API reference”Factory
Section titled “Factory”Fieldset.enhance(element: HTMLFieldSetElement, options: FieldsetOptions): FieldsetGlobal configuration key: fieldset (see Configuration).
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
legend |
string |
Visible legend; the group’s accessible name. Required. | |
hideLegend |
boolean |
"false" |
Visually hide the legend (it stays the accessible name). |
description |
string |
Help text for the group, referenced by aria-describedby. | |
required |
boolean |
"false" |
Required marker; ‘(required)’ is added to the spoken legend. |
disabled |
boolean |
Sets the native disabled attribute; unset leaves it alone. | |
error |
string | null |
Group-level error message; empty or null hides it. | |
icons |
Partial<FieldsetIcons> |
Icon slot overrides. | |
locale |
string |
"en-US" |
Locale of the required text. Globally configurable. Inherited from common configuration. |
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
element |
HTMLFieldSetElement |
The enhanced fieldset. |
legend |
HTMLLegendElement |
The rendered legend. |
options |
Readonly<FieldsetOptions> |
Current options. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
focus(): void |
Focus the first enabled, visible control in the group (pass as an Error Summary item’s focus). |
update(options: Partial<FieldsetOptions>): void |
Merge and apply options. |
destroy(): void |
Remove the legend, help, and error; restore a page legend and aria-describedby. |
Content areas
Section titled “Content areas”| Area | Description |
|---|---|
controls |
The fieldset’s own children (any controls); they stay in place after the legend, help, and error. |
CSS classes
Section titled “CSS classes”All rules live in the aui.components cascade layer, so application styles override them without specificity battles.
| Class | Purpose |
|---|---|
aui-fieldset |
The enhanced fieldset. |
aui-fieldset--invalid |
A group error is shown. |
aui-field__label |
Legend (shared field chrome). |
aui-field__required |
Visual required marker. |
aui-field__description |
Help text. |
aui-field__error |
Group error message. |
Icon slots
Section titled “Icon slots”| Slot | Default icon |
|---|---|
error |
alert-circle |
Design tokens
Section titled “Design tokens”Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.
--aui-color-error-fg | --aui-color-text | --aui-color-text-disabled | --aui-color-text-muted | --aui-font-family-sans | --aui-font-size-md | --aui-font-size-sm | --aui-font-weight-medium | --aui-font-weight-semibold | --aui-icon-size-sm | --aui-line-height-tight | --aui-space-1 | --aui-space-3
TypeScript definitions
Section titled “TypeScript definitions”interface FieldsetIcons { error: IconRef }interface FieldsetOptions { legend: string; hideLegend?: boolean; description?: string; required?: boolean; disabled?: boolean; error?: string | null; locale?: string; icons?: Partial<FieldsetIcons>;}Accessibility
Section titled “Accessibility”Pattern: Native fieldset and legend (HTML grouping): the legend names the group; help and the group error are referenced by aria-describedby.
Keyboard
Section titled “Keyboard”| Key | Context | Action |
|---|---|---|
| Tab | Controls inside | Moves through the group’s controls in document order (the fieldset itself is not focusable). |
| Element | Role |
|---|---|
| fieldset | group (native) |
| legend | names the group (native) |
ARIA attributes
Section titled “ARIA attributes”| Attribute | Element | Value |
|---|---|---|
aria-describedby |
fieldset | help and error ids while shown, followed by the page’s own ids |
aria-hidden |
required asterisk | true; ‘(required)’ is spoken with the legend instead |
Never takes focus itself. focus() moves focus to the first enabled control, for Error Summary links.
WCAG 2.2 success criteria addressed
Section titled “WCAG 2.2 success criteria addressed”| Criterion | Level | Note |
|---|---|---|
| 1.3.1 Info and Relationships | A | |
| 2.4.6 Headings and Labels | AA | |
| 3.3.1 Error Identification | A | |
| 3.3.2 Labels or Instructions | A | |
| 4.1.2 Name, Role, Value | A |
Automated test results: Accessibility and compliance.
Notes and known caveats
Section titled “Notes and known caveats”- The group role cannot carry aria-required, so required state is spoken as part of the legend.
- Native disabled removes every native control inside from the tab order.
- Screen readers differ in how often they repeat the legend when moving between controls; keep legends short.
- Manual screen-reader verification (NVDA, JAWS, VoiceOver) is pending.
Behavior
Section titled “Behavior”States
Section titled “States”Default, required, invalid (group error shown), disabled (native), legend hidden.
State transitions
Section titled “State transitions”| From | Trigger | To |
|---|---|---|
| valid | update({ error: 'message' }) |
invalid; the message is added to aria-describedby |
| invalid | update({ error: null }) |
valid |
| any | update({ disabled }) |
native disabled on or off |
| any | destroy() |
the page’s fieldset as it was |
Accessibility notes
Section titled “Accessibility notes”- Keep legends short: screen readers may repeat them when moving between the controls.
- Show the group error next to the group and in the Error Summary; use
focus()as the summary item’sfocus. - The e2e axe run covers three themes; manual screen-reader verification is pending.
Responsive behavior
Section titled “Responsive behavior”A grid of the legend, help, error, and the page’s controls; the controls keep their own layout.
Right-to-left
Section titled “Right-to-left”Logical properties: the error bar sits at the inline start.
Theming
Section titled “Theming”The shared field chrome follows the theme; forced-colors mode uses system colors for text and the error bar.
Global configuration
Section titled “Global configuration”Only the inherited locale is configurable:
configureAbsoluteUI({ components: { fieldset: { locale: 'de-DE' } } });Component configuration
Section titled “Component configuration”The instance locale overrides configuration; configuration changes re-render existing fieldsets.
icons.error (default alert-circle), shown with the group error.
Security
Section titled “Security”Legend, help, and error text use textContent; they are never parsed as HTML.
Data handling
Section titled “Data handling”No persistence, network access, or telemetry. The fieldset holds no values; its controls do.
Performance
Section titled “Performance”Constant work per render.
Supported data scale
Section titled “Supported data scale”Not data-driven.
Edge cases
Section titled “Edge cases”- A legend already in the fieldset is removed while enhanced and restored by
destroy(). disabledleft unset never touches the native attribute, so[disabled]bindings of frameworks keep working.focus()skips disabled and hidden controls; it does nothing when none is focusable.
Errors
Section titled “Errors”| Code | Category | Cause |
|---|---|---|
FIELDSET_HOST |
configuration | The element is not a <fieldset>. |
FIELDSET_OPTIONS |
configuration | Missing or blank legend, or an option of the wrong type. |
ICON_UNKNOWN |
configuration | Unknown icon override. |
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION |
configuration | Invalid or unknown configuration. |
Invalid options throw before the fieldset is modified; an invalid update() leaves the previous state intact.
Known limitations
Section titled “Known limitations”- Fieldset does not validate its controls; the application sets the group error (for example from Form validation).
- Manual screen-reader verification is pending.
Unsupported scenarios
Section titled “Unsupported scenarios”- Collapsing the group: use Collapsible or Accordion.
- HTML in the legend.