Primitives
Fieldset
Headless grouping that gives a set of related fields a shared accessible name (a native <fieldset> / <legend>, or role="group" + aria-labelledby on any element) plus an optional shared disabled state that reaches custom-role controls.
Disable the group and every control inside it follows. The fieldset reflects data-disabled and reaches custom-role controls a native <fieldset disabled> cannot.
The styleless counterpart to a native <fieldset> + <legend>, and the grouping companion to Field. It renders nothing and imposes no layout. Use it on a real <fieldset> to lean on native grouping, or on any other element to get role="group" + aria-labelledby wired automatically.
Anatomy
<fieldset forFieldset [disabled]="locked()">
<legend forFieldsetLegend>Shipping address</legend>
<div forField>
<label forLabel>Street</label>
<input forFieldControl />
</div>
</fieldset>
How grouping connects
ForFieldset detects its host tag, exactly like ForLabel's <label> check:
- On a native
<fieldset>, the browser groups its controls and labels them with the<legend>implicitly, so the directive emits noroleand noaria-labelledby. - On any other element, it emits
role="group"andaria-labelledbypointing at the[forFieldsetLegend]'s id: your own staticidwhen you set one, else a generated one.
Examples
Disable a group
disabled emits the native disabled attribute, which disables every control inside in one move. The data-disabled hook flows to the fieldset and to each forField so the whole block can dim together.
Group on any element
On non-fieldset markup forFieldset synthesizes the grouping: it emits role="group" and points aria-labelledby at the [forFieldsetLegend]'s generated id, so a plain <div> + <span> reads to assistive tech exactly like a native fieldset / legend.
API
ForFieldset
| Property | Type | Description |
|---|---|---|
disabled | input | Disables the group. Emits the native disabled attribute on a <fieldset> (or aria-disabled="true" elsewhere) and propagates to every descendant control via context, reaching custom-role controls and [forButton].Default: false |
| Data attribute | Values | |
|---|---|---|
data-disabled | present / absent |
ForFieldsetLegend
Group label. Emits the fieldset's legendId so aria-labelledby resolves; usable standalone outside a fieldset as an inert marker. Reflects no data-* attributes: it carries only the id that the group's aria-labelledby resolves to.
A static id you write on the legend is preserved, not clobbered, and the group's aria-labelledby follows it. An external aria-labelledby / aria-describedby reference or a <label for> pointing at your own id therefore keeps resolving:
<div forFieldset>
<span forFieldsetLegend id="shipping-legend">Shipping</span>
<!-- … fields … -->
</div>
<!-- → <div role="group" aria-labelledby="shipping-legend"> -->
Only a plain id="…" attribute is adopted; a [id]="expr" property binding evaluates after the directive constructs, so it is not. With no id of your own the legend gets a generated for-fieldset-legend-* one. Keep one legend per group: a fieldset is labelled by a single id, so a second [forFieldsetLegend] shares it (duplicate DOM ids) and warns in dev mode.
Accessibility
- Native
<fieldset>grouping is preserved. On a<fieldset>host, no extra ARIA is added, and the browser's native grouping and<legend>labelling apply. - Custom hosts get
role="group"+aria-labelledbywired to the[forFieldsetLegend]'s id, which is a consumer-set staticidwhen present, else a generated one. - Disabled propagation reaches custom-role controls that a native
<fieldset disabled>cannot disable, via context injection.
Styling
forty-cdk ships no styles: put your own class on each piece and key your CSS off the data-* attributes listed under API, not off the for* selectors (Styling forty-cdk explains why).
.set[data-disabled] {
opacity: 0.5;
}
Wrapping in a design system
Subclass the root and re-provide FOR_FIELDSET_CONTEXT with useExisting pointing at the subclass, since Angular does not inherit a directive's providers; Wrapping non-form roots walks the pattern.