Patterns
Settings Section
When to use:
- a settings screen contains several related toggles
- the group should read as one preference area
Composition notes:
- keep
FieldsetLegendshort and stable - use
FieldsetHeaderfor extra guidance - render the actual toggles directly after the header
Trade-offs:
- improves semantic grouping and scanability
- adds more vertical structure than a loose list of controls
import {
Checkbox,
CheckboxCheckedIcon,
CheckboxIndicator,
CheckboxInput,
Fieldset,
FieldsetHeader,
FieldsetLegend,
Text,
} from '@vega-ui/react';
import { useId } from 'react';
Transparent Group In Existing Panel
When to use:
- the parent layout already provides the visible container
- only the grouping semantics are missing
Composition notes:
- switch to
appearance='transparent' - keep the legend even when border and padding are removed
Trade-offs:
- preserves semantics without duplicating containers
- makes the group boundary depend on surrounding layout
import type { CSSProperties } from 'react';
import {
Button,
Dialog,
DialogClose,
DialogContent,
DialogTrigger,
Fieldset,
FieldsetLegend,
Heading,
Icon,
IconButton,Grouped Validation Copy
When to use:
- several related controls fail one business rule
- the error belongs to the group rather than a single input
Composition notes:
- keep the legend as the stable group name
- place the message right after the legend and reference it from the fieldset with
aria-describedby - let child controls still render their own local state if needed
Trade-offs:
- clarifies group-level validation
- can become noisy if every child control also repeats the same message
import {
Button,
Checkbox,
CheckboxCheckedIcon,
CheckboxIndicator,
CheckboxInput,
Fieldset,
FieldsetLegend,
HelperText,
} from '@vega-ui/react';
import { FormEvent, useId, useState } from 'react';
Header With Action
When to use:
- the group has an action that affects all of its fields, such as autofill or reset
Composition notes:
- keep
FieldsetLegendthe first child, so it names the group - put the helper copy and the
ButtoninFieldsetHeader, withtype='button'so it does not submit the form
Trade-offs:
- the action sits next to the fields it changes
- a disabled fieldset disables the action too
import {
Button,
Fieldset,
FieldsetHeader,
FieldsetLegend,
Label,
Text,
TextField,
TextFieldInput,
} from '@vega-ui/react';
import { useId, useState } from 'react';
Comparison
Quick Decision Rule
Use Fieldset when multiple related controls need one semantic group label. Use a plain div or Card only when the grouping is purely visual.
Fieldset vs Card
Use Fieldset when:
- the grouping is semantic form structure
Use Card when:
- the container is only layout or presentation
Fieldset vs Separator
Use Fieldset when:
- inputs belong to one named control group
Use Separator when:
- you only need visual division
Fieldset vs Heading
Use FieldsetLegend when:
- the text labels one control group
Use Heading when:
- the text is document or section structure rather than native group semantics
Choose This Component When
- several form controls belong to one named concept
- the group needs native
<fieldset>and<legend>behavior - you need optional descriptive copy before the controls
- assistive technology should perceive the controls as one grouped question or setting area
Do Not Choose This Component When
- the grouping is only decorative
- one standalone input just needs a nearby label
- a plain layout container is enough
Troubleshooting
The Group Looks Correct But Screen Readers Do Not Announce A Group Label
Symptom
The controls appear grouped visually, but assistive technology does not announce a meaningful group name.
Likely Cause
FieldsetLegend is missing or a plain text element was used instead.
How To Verify
- inspect the markup
- confirm a real
<legend>is rendered inside the<fieldset>
Fix
Render FieldsetLegend as the first meaningful child of the root.
The Group Border Feels Duplicated Inside A Dialog Or Card
Symptom
The section looks visually heavy because both the parent container and the fieldset draw boundaries.
Likely Cause
appearance='outlined' is used inside another strongly framed surface.
How To Verify
- compare the section with
outlinedandtransparent - check whether the parent already provides enough boundary
Fix
Use appearance='transparent' when only semantic grouping is needed.
Group-Level Validation Copy Replaces The Legend
Symptom
The error message is visible, but the stable group label is missing or constantly changing.
Likely Cause
Validation text was used as the legend itself.
How To Verify
- inspect the rendered legend text
- confirm whether it contains transient validation copy
Fix
Keep the legend as the durable group label and place validation copy in FieldsetHeader or nearby supporting text.
Nested Groups Are Hard To Understand
Symptom
Nested sections render, but users cannot tell which controls belong to which scope.
Likely Cause
The outer and inner legends do not establish a clear hierarchy.
How To Verify
- read the legends in order without the surrounding layout
- confirm whether each group still makes sense on its own
Fix
Reduce nesting or rewrite the legends so each level names a distinct scope.