Tessina UI
Tessina UI
GitHubIntroduction
InstallationUsageTheming
Components
ButtonIconButtonLinkSpinnerBadgeAvatarStatusChipShortcutSkeletonSurfaceProgressMeterRating
LabelFieldFieldsetCheckboxRadioSwitchSliderSelectComboboxSearchTextareaNumberFieldDate PickerTime PickerOTP InputFile UploadCalendar
AlertBannerToastTooltip
TabsAccordionCollapsibleBreadcrumbPaginationStepperSegmentedControlButtonGroupToggleButtonToggleGroupToolbarNavigation MenuMenubarBottom NavSidebar
Split ButtonFABDropdown MenuContextMenuCommandPopoverHoverCard
ContainerStackFlexGridAspectRatioSpacerCardCarouselDividerScroll Area
Table
ChatBubblePromptInputCodeBlock
ModalAlertDialogDrawerAction SheetTop Header MobileTop Header DesktopEmptyStateForm
Contributing
ComponentsForm Blocks

Fieldset

Groups related form controls under a shared legend, description, and helper text — built on Base UI's Fieldset primitive with four variants, five sizes, intent accents, and full RTL support.

Playground

Installation

pnpm add @tessinaui/ui

Usage

import {
  FieldsetRoot,
  FieldsetLegend,
  FieldsetHeader,
  FieldsetDescription,
  FieldsetBody,
  FieldsetHelperText,
} from "@tessinaui/ui";
<FieldsetRoot variant="outline">
  <FieldsetHeader>
    <FieldsetLegend required>Notification preferences</FieldsetLegend>
    <FieldsetDescription>
      Choose how you want to be notified about updates.
    </FieldsetDescription>
  </FieldsetHeader>

  <FieldsetBody>
    <Switch label="Email" defaultChecked />
    <Switch label="SMS" />
    <Switch label="Mobile push" />
  </FieldsetBody>

  <FieldsetHelperText>
    You can change these later in account settings.
  </FieldsetHelperText>
</FieldsetRoot>

Showcase

When to use

Reach for Fieldset when you have a group of related form controls that share a single label, description, or validation message — notification preferences, permission lists, billing options, plan selection, etc. The browser-native <fieldset> it renders gives screen readers the right grouping, and the disabled prop cascades to every form control inside (a behaviour you can't replicate with a <div>).

For a single labeled input, use Field. For a row of toggleable choices, CheckboxGroup and RadioGroup compose naturally inside Fieldset.Body.

API Reference

FieldsetRoot props

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg" | "xl""md"Scales legend, description, helper text, gap, and padding
variant"ghost" | "outline" | "filled" | "elevated""ghost"Visual treatment — ghost is just structure, the others wrap everything in a card
rounded"none" | "sm" | "md" | "lg" | "full""md"Card corner radius (only applies to non-ghost variants)
intent"none" | "primary" | "error" | "warning" | "success" | "info""none"Drives the border accent on non-ghost variants and the default HelperText colour
dir"ltr" | "rtl""ltr"Text direction
orientation"vertical" | "horizontal""vertical"Default layout for FieldsetBody children
disabledbooleanfalseDisables the fieldset and cascades to every form control inside (browser behaviour of <fieldset disabled>)
invalidbooleanfalseForces error styling regardless of intent
renderBase UI render prop—Polymorphic — replace the rendered <fieldset> element

FieldsetLegend props

PropTypeDefaultDescription
requiredbooleanfalseShows a red * after the legend text
optionalbooleanfalseShows a muted "(optional)" label after the legend text. Ignored when required is true
leadingIconReactNode—Icon rendered before the legend text

Renders a Base UI Fieldset.Legend (a <div> automatically associated with the fieldset for accessibility).

FieldsetHeader props

A flex column wrapper grouping Legend + Description so they stack with consistent spacing above the body.

FieldsetDescription props

A muted paragraph below the legend. Use it to clarify the purpose of the group.

FieldsetBody props

PropTypeDefaultDescription
orientation"vertical" | "horizontal"inheritedOverride the orientation set on the Root for this body only

Lays out children with size-aware gap. Horizontal orientation wraps when content overflows.

FieldsetHelperText props

PropTypeDefaultDescription
intentFieldsetIntentinheritedOverride the colour for this helper text only (defaults to the Root's intent, or error when invalid)
leadingIconReactNode—Status icon rendered before the helper text

Notes

  • Built on @base-ui/react/fieldset — the disabled prop cascades to descendant form controls via the native <fieldset disabled> behaviour.
  • Fieldset.Header is optional. You can place a bare Fieldset.Legend directly in the root if you don't need a description.
  • Pair with CheckboxGroup, RadioGroup, or any Field instance for full form composition. Inside Fieldset.Body they inherit the disabled + invalid context naturally.
  • invalid={true} is convenience sugar — it sets intent="error" styling without changing the prop on the Root, which keeps the API ergonomic for form libraries that track validation separately.

Field

A text input field with a label, helper text, FieldDropdown prefix, Button suffix, leading/trailing icon buttons, a clearable button, and a character counter. Supports all intent states and full RTL layout.

Checkbox

A form control that lets users select one or more options. Supports checked, unchecked, and indeterminate states. Five sizes, five intents, label/description/error patterns, and a CheckboxGroup compound component with select-all support.

On this page

PlaygroundInstallationUsageShowcaseWhen to useAPI ReferenceFieldsetRoot propsFieldsetLegend propsFieldsetHeader propsFieldsetDescription propsFieldsetBody propsFieldsetHelperText propsNotes