Fieldset creates a fieldset and legend for a group of related form items, like RadioButtons or CheckBoxes, in order to clearly indicate related form items."

also known as Form group, Input Group, Choice Group, Form Block

Figma:

Responsive:

Adaptive:

Props

Component props
Name
Type
Default
children
Required
React.Node
-

The content of Fieldset, typically RadioButtons, Checkboxes or TextFields.

legend
Required
string
-

Caption that clearly and concisely describes the form elements grouped in the fieldset.

errorMessage
string
-

When needed, pass a string with a helpful error message (be sure to localize!).

id
string
""

A unique identifier for this Fieldset. id must be specified when an errorMessage is added.

legendDisplay
"visible" | "hidden"
"visible"

Whether the legend should be visible or not. If hidden, the legend is still available for screen reader users, but does not appear visually. See the legend visibility variant for more info.

Usage guidelines

When to use
  • When inputs within a broader form are closely related and would benefit from a shared legend, such as TextFields for a billing address or a group of Checkboxes.
When not to use
  • When the fields are unrelated. Use TextFields and other input components within a <form/>.

Accessibility

Wrapping form fields in Fieldset creates an accessible grouping that signals to users when certain form items are related. The legend should clearly describe what information is needed from the group of items, whether they're RadioGroup, Checkboxes or TextFields.

In the example below, the pet RadioButtons are surrounded by a fieldset and include a legend of "Favorite pet". Learn more about the use of fieldset and legend.

import { useState } from 'react';
import { Fieldset, Flex, RadioButton, TextField } from 'gestalt';

export default function Example() {
  const [favorite, setFavorite] = useState('');
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <form>
        <Flex direction="column" gap={4}>
          <TextField
            id="name"
            label="Name"
            onChange={({ value }) => setName(value)}
            placeholder="First and last name"
            value={name}
          />
          <TextField
            id="email"
            label="Email"
            onChange={({ value }) => setEmail(value)}
            placeholder="example@test.com"
            type="email"
            value={email}
          />
          <Fieldset legend="Favorite pet">
            <Flex direction="column" gap={2}>
              <RadioButton
                checked={favorite === 'dogs'}
                id="favoriteDogA11y"
                label="Dogs"
                name="favorite"
                onChange={() => setFavorite('dogs')}
                value="dogs"
              />
              <RadioButton
                checked={favorite === 'cats'}
                id="favoriteCatA11y"
                label="Cats"
                name="favorite"
                onChange={() => setFavorite('cats')}
                value="cats"
              />
              <RadioButton
                checked={favorite === 'plants'}
                id="favoritePlantsA11y"
                label="Plants"
                name="favorite"
                onChange={() => setFavorite('plants')}
                value="plants"
              />
            </Flex>
          </Fieldset>
        </Flex>
      </form>
    </Flex>
  );
}

Localization

Be sure to localize all text strings. Note that localization can lengthen text by 20 to 30 percent.

Variants

Legend visibility

By default, the legend is visible above the items in the Fieldset. However, if the form items are labeled by content elsewhere on the page, or a more complex legend is needed, the legendDisplay prop can be used to visually hide the legend. In this case, it is still available to screen reader users, but will not appear visually on the screen.

In the example below, the "Company Account Goals" text is acting as a heading and a legend for the checkboxes, so instead of repeating another legend, we visually hide the Fieldset legend. When a user focuses on the first checkbox, a screen reader will announce "Sell more products, unchecked, checkbox, Choose up to 3 company account goals, group".

import { useState } from 'react';
import { Checkbox, Fieldset, Flex, Heading, Link, Text } from 'gestalt';

export default function Example() {
  const [checkedSell, setCheckedSell] = useState(false);
  const [checkedLeads, setCheckedLeads] = useState(false);
  const [checkedAudience, setCheckedAudience] = useState(false);
  const [checkedBrand, setCheckedBrand] = useState(false);
  const [checkedNotSure, setCheckedNotSure] = useState(false);

  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Flex direction="column" gap={4}>
        <Flex direction="column" gap={2}>
          <Heading size="400">Company Account Goals</Heading>
          <Text size="200">
            Choose up to 3.{' '}
            <Text inline size="200" weight="bold">
              <Link display="inline" href="#" target="blank">
                Learn more
              </Link>
            </Text>
          </Text>
        </Flex>
        <Fieldset
          legend="Choose up to 3 company account goals"
          legendDisplay="hidden"
        >
          <Flex direction="column" gap={{ column: 4, row: 0 }}>
            <Checkbox
              checked={checkedSell}
              id="sell"
              label="Sell more products"
              name="account goals"
              onChange={({ checked }) => {
                setCheckedSell(checked);
              }}
            />
            <Checkbox
              checked={checkedLeads}
              id="leads"
              label="Generate more leads"
              name="account goals"
              onChange={({ checked }) => {
                setCheckedLeads(checked);
              }}
            />
            <Checkbox
              checked={checkedAudience}
              id="audience"
              label="Attract an audience"
              name="account goals"
              onChange={({ checked }) => {
                setCheckedAudience(checked);
              }}
            />
            <Checkbox
              checked={checkedBrand}
              id="brand"
              label="Increase brand awareness"
              name="account goals"
              onChange={({ checked }) => {
                setCheckedBrand(checked);
              }}
            />
            <Checkbox
              checked={checkedNotSure}
              id="notSure"
              label="Not sure yet"
              name="account goals"
              onChange={({ checked }) => {
                setCheckedNotSure(checked);
              }}
            />
          </Flex>
        </Fieldset>
      </Flex>
    </Flex>
  );
}

Error message

import { useState } from 'react';
import { Box, Checkbox, Fieldset, Flex } from 'gestalt';

export default function Example() {
  const [checkedEn, setCheckedEn] = useState(false);
  const [checkedSp, setCheckedSp] = useState(false);
  const [checkedPo, setCheckedPo] = useState(false);

  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box padding={4}>
        <Fieldset
          errorMessage="At least 1 item must be selected"
          id="fieldset-error-message"
          legend="What languages would you like to learn?"
        >
          <Flex direction="column" gap={2}>
            <Checkbox
              checked={checkedEn}
              helperText="USA, India, and Pakistan have the top number of English speakers "
              id="english-info"
              label="English"
              name="languages"
              onChange={({ checked }) => {
                setCheckedEn(checked);
              }}
            />
            <Checkbox
              checked={checkedSp}
              helperText="Mexico, Columbia, and Spain are the top three Spanish-speaking countries"
              id="spanish-info"
              label="Spanish"
              name="languages"
              onChange={({ checked }) => {
                setCheckedSp(checked);
              }}
            />
            <Checkbox
              checked={checkedPo}
              helperText="Brazil, Angola, and Mozambique are the top three Portuguese-speaking countries"
              id="portuguese-info"
              label="Portuguese"
              name="languages"
              onChange={({ checked }) => {
                setCheckedPo(checked);
              }}
            />
          </Flex>
        </Fieldset>
      </Box>
    </Flex>
  );
}

Component quality checklist

Component quality checklist
Quality item
Status
Status description
Figma Library
Component is not currently available in Figma.
Responsive Web
Ready
Component responds to changing viewport sizes in web and mobile web.

Label
If a label is needed for a single form item (instead of a group of items), use Label.