A named group of related controls, such as the modes shown on the map or the fields of a report form: the group's name above, the caller's controls below it, and one switch that disables them all.
When to use
Use Fieldset to name a group of related controls, such as the modes shown on the map or the fields of a report form, so they are heard as one group and can be disabled together.
| Use instead | When |
|---|---|
| CheckboxGroup | The group is a set of checkboxes that answer one question, such as which modes the map shows |
| RadioGroup | The group is a set of choices of which exactly one holds |
| Field | One control stands alone, named by its own label |
| Section | A titled block of content in a panel holds no controls |
Kongens Nytorv
Metro M1, M2 and M3.
Variants and states
| Rest | Disabled | |
|---|---|---|
| Default |
- Rest
- Disabled
Props
| Name | Type | Default | Description |
|---|---|---|---|
legend* | ReactNode | — | Required. The group's name, in sentence case, a few words or a short question, such as "Show on the map": shown above the controls, and the group's accessible name. |
hiddenLegend | boolean | false | Whether the legend is heard but not seen. Use it where a heading right above already names the group for the eye, so the group keeps its name for the ear. |
disabled | boolean | false | Whether every control in the group ignores the pointer and the keys. Native controls leave the tab order; Base UI's fields and groups inside take the disabled look; a fieldset round this one disables it too. |
children | ReactNode | — | The group's controls, in reading order, below the legend: checkboxes, radios, or fields. |
ref | Ref<HTMLElement> | — | Reaches the root: the <fieldset>, or the element render gives. |
slotProps | { legend?: FieldsetLegendProps | undefined; } | — | Props for each part: legend. |
legend (required)ReactNode, default —- Required. The group's name, in sentence case, a few words or a short question, such as "Show on the map": shown above the controls, and the group's accessible name.
hiddenLegendboolean, defaultfalse- Whether the legend is heard but not seen. Use it where a heading right above already names the group for the eye, so the group keeps its name for the ear.
disabledboolean, defaultfalse- Whether every control in the group ignores the pointer and the keys. Native controls leave the tab order; Base UI's fields and groups inside take the disabled look; a fieldset round this one disables it too.
childrenReactNode, default —- The group's controls, in reading order, below the legend: checkboxes, radios, or fields.
refRef<HTMLElement>, default —- Reaches the root: the
<fieldset>, or the elementrendergives. slotProps{ legend?: FieldsetLegendProps | undefined; }, default —- Props for each part:
legend.
Use it
import { Fieldset } from '@mylder/perron'Ask your agent
get_reference({ library: "base-ui", component: "Fieldset" })Keyboard and ARIA
Fieldset has no keys of its own and is never focusable. Its controls are reached in reading order, and keep their own keys.
| Key | Does | From |
|---|---|---|
Tab | Moves to the first focusable control in the group, then on through the rest; skips them all while disabled | The browser |
Shift+Tab | Moves back through the controls, out to what came before the group | The browser |
| Element | Role | Accessible name from | States announced |
|---|---|---|---|
root | group, native to <fieldset>; the rendered element's own role with render, such as radiogroup from Base UI's RadioGroup | aria-labelledby, the legend's id, from Base UI: its text | None on the group itself; the native disabled attribute disables each native control in it, and each control announces its own disabled state |
legend | None (generic div, or a span when hidden) | None: its text names the root | None |
What axe won't catch, from the contract, each with how this component meets it:
- Everything the eye is told, the ear is told, for every shape each prop accepts: the legend the eye reads above the controls is the group's name for the ear, through
aria-labelledby; a hidden legend is still the name; the disabled look of the legend matches the disabled state the browser announces on each control in the group, since the nativedisabledattribute disables them all. - Every landmark and named region has an accessible name: the root is a
group, not a landmark, and is always named by its legend, sincelegendis required (CR-3). - Every default label can be overridden: none here; Fieldset owns no string.
- Every shape the type accepts renders, in every variant:
legendrenders a string, an element and an array; it sits in a<div>, or a<span>when hidden, so it takes phrasing content, and a long Danish compound wraps inside the root's width (CR-1). - A hidden copy kept for animation is
aria-hidden, and a collapsed region isinert: none here; nothing animates or collapses. - Native semantics first: a native
<fieldset>and itsgrouprole, its nativedisabledattribute, and Base UI'saria-labelledby; Perron adds no ARIA. - Focus moves in reading order and returns on close: the legend comes first in the DOM and on screen, then the controls in the caller's order; Fieldset never moves focus, and nothing in it closes.
- Every target is at least
size.target-minsquare: Fieldset has no target of its own; its controls are the caller's components, which keep their own sizes. - Loops stop when the system asks for less motion: none here; nothing moves.
Owned strings
No owned strings: every word Fieldset shows or announces comes from the caller, through legend and children, and the group's name is the legend.
Do and don't
For a caller using the component, with the reason. Each row is a rule: a must row's Don't is never right, a should row's needs a reason, and Checked by says what catches the Don't in a caller's code.
| Rule | Level | Do | Don't | Checked by |
|---|---|---|---|---|
| DD-1 | should | Group controls that answer one question, such as which modes to show, or fields that belong together, such as a report's place and time | Wrap a single control in a Fieldset: one control is named by its own label, through Field | review |
| DD-2 | must | Write the legend in sentence case, a few words or a short question: "Show on the map" | Put a heading element inside legend, or type it in capitals: the legend is already the group's name, a heading inside it adds one to the page's outline that no section follows, and capitals come only from the overline style | review |
| DD-3 | should | Use CheckboxGroup or RadioGroup for a set of checkboxes or radios, once they ship: they compose Fieldset with the group's behaviour | Render Fieldset as a Base UI group yourself in a screen: the groups hold the value, the keys and the form name for you | review |
| DD-4 | should | Disable the whole group with disabled, so every control in it goes together | Disable each control by hand inside a Fieldset that stays enabled: the legend then looks live over dead controls | review |
| DD-5 | must | Use hiddenLegend where a heading right above already names the group for the eye | Leave out the legend, or replace it with an aria-label on the root: the legend is the group's one name, seen and heard alike | review |
| DD-6 | must | Use Section for a titled block of content in a panel | Use Fieldset to title content that holds no controls: a group with nothing to fill in tells a screen reader there is something to fill in | review |
| DD-7 | must | Give the group's description and error through a Base UI Field.Root, as CheckboxGroup and RadioGroup do | Put a hint or an error as plain text among the controls: nothing ties it to the group for the ear | review |