Skip to main content
On this pageOverview

Fieldset

Overview

A semantic form section that groups related controls with a legend and description. Fieldset is a view-only component that wraps the native <fieldset> element — when disabled, the browser propagates the disabled state to all child form controls automatically.

See it in an app

Check out how Fieldset is wired up in a real Foldkit app.

Examples

Basic

The toView callback receives three attribute groups: fieldset for the wrapper, legend for the group title, and description for help text. Nest other Foldkit UI components inside the fieldset body.

Personal InformationWe just need a few details.
As it appears on your government-issued ID.
A brief introduction about yourself.

You agree to our Terms of Service and Privacy Policy.

// Pseudocode — Fieldset is view-only. Nest other Foldkit UI components
// inside the fieldset body in your own view function.
import { Ui } from 'foldkit'

import { Class, div, fieldset, legend, span } from './html'

Ui.Fieldset.view({
  id: 'personal-info',
  toView: attributes =>
    fieldset(
      [...attributes.fieldset, Class('rounded-lg border p-6')],
      [
        legend(
          [...attributes.legend, Class('text-base font-semibold')],
          ['Personal Information'],
        ),
        span(
          [...attributes.description, Class('text-sm text-gray-500 mt-1')],
          ['We just need a few details.'],
        ),
        div(
          [Class('mt-4 flex flex-col gap-4')],
          [
            // Nest Input, Textarea, Checkbox, etc. here
          ],
        ),
      ],
    ),
})

Disabled

Set isDisabled: true to disable the entire group. The native <fieldset disabled> attribute propagates to all child inputs, textareas, buttons, and selects — you don’t need to disable each control individually.

Personal InformationThis fieldset is disabled.
// Pseudocode — Fieldset is view-only. Setting isDisabled on the fieldset
// propagates to all child form elements via the native <fieldset disabled>
// attribute.
import { Ui } from 'foldkit'

import { Class, fieldset, legend, span } from './html'

Ui.Fieldset.view({
  id: 'personal-info-disabled',
  isDisabled: true,
  toView: attributes =>
    fieldset(
      [...attributes.fieldset, Class('rounded-lg border p-6')],
      [
        legend(
          [...attributes.legend, Class('text-base font-semibold')],
          ['Personal Information'],
        ),
        span(
          [...attributes.description, Class('text-sm text-gray-500 mt-1')],
          ['This section is disabled.'],
        ),
        // All nested form controls inherit the disabled state
      ],
    ),
})

Styling

Fieldset is headless — your toView callback controls all markup and styling.

AttributeCondition
data-disabledPresent when isDisabled is true.

Accessibility

The legend attribute group includes an id (accessible via Fieldset.legendId(id)) and the description group includes an id (accessible via Fieldset.descriptionId(id)) that the fieldset references through aria-describedby.

API Reference

ViewConfig

Configuration object passed to Fieldset.view().

NameTypeDefaultDescription
idstring-Unique ID for the fieldset element. Used to generate linked IDs for legend and description.
toView(attributes: FieldsetAttributes) => Html-Callback that receives attribute groups for the fieldset, legend, and description elements.
isDisabledbooleanfalseWhether the fieldset is disabled. The native disabled attribute on <fieldset> propagates to all child form controls.

FieldsetAttributes

Attribute groups provided to the toView callback.

NameTypeDefaultDescription
fieldsetReadonlyArray<Attribute<Message>>-Spread onto the <fieldset> element. Includes id, aria-describedby, and the disabled attribute when applicable.
legendReadonlyArray<Attribute<Message>>-Spread onto the <legend> element. Includes an id for programmatic reference.
descriptionReadonlyArray<Attribute<Message>>-Spread onto a description element. Includes an id that the fieldset references via aria-describedby.

Stay in the update loop.

New releases, patterns, and the occasional deep dive.


Built with Foldkit.

© 2026 Devin Jameson