# Fieldset

Groups related controls under a shared legend.

```tsx
import * as stylex from "@stylexjs/stylex"
import { Fieldset, FieldsetLegend } from "@/components/ui/fieldset"
import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"

const styles = stylex.create({ fieldset: { width: "20rem" } })

export default function FieldsetDemo() {
  return (
    <Fieldset xstyle={styles.fieldset}>
      <FieldsetLegend>Personal information</FieldsetLegend>
      <Field>
        <FieldLabel>First name</FieldLabel>
        <Input placeholder="Jane" />
      </Field>
      <Field>
        <FieldLabel>Last name</FieldLabel>
        <Input placeholder="Doe" />
      </Field>
    </Fieldset>
  )
}
```

## Installation

1. Install the following dependencies:

   ```bash
   npm install @base-ui/react @stylexjs/stylex
   ```

2. Set up the token layer and the StyleX compiler from [Installation](https://carbon.style/docs/installation), including `state-styles.ts`.
   Install [Stack](https://carbon.style/docs/components/stack) for fieldset layout.

3. Copy and paste the following code into your project.

   ```tsx title="components/ui/fieldset.tsx"
   "use client"

   import type { CSSProperties } from "react"
   import { Fieldset as FieldsetPrimitive } from "@base-ui/react/fieldset"
   import * as stylex from "@stylexjs/stylex"
   import type { StyleXStyles } from "@stylexjs/stylex"
   import { VStack, type SpacingStep } from "@/components/ui/stack"
   import { stateStyles } from "@/lib/state-styles"
   import { leading, space, text } from "@/theme/tokens.stylex"

   const styles = stylex.create({
     root: { minWidth: 0 },
     legend: { marginBlockEnd: space.s1_5, fontWeight: 500 },
   })
   const variants = stylex.create({
     legend: { fontSize: text.base, lineHeight: leading.base },
     label: { fontSize: text.sm, lineHeight: leading.sm },
   })
   type FieldLegendVariant = keyof typeof variants
   type Overrides = { xstyle?: StyleXStyles; className?: string; style?: CSSProperties }
   function Fieldset({
     gap = 4,
     xstyle,
     className,
     style,
     render,
     ...props
   }: Omit<FieldsetPrimitive.Root.Props, "className" | "style"> & Overrides & { gap?: SpacingStep }) {
     return (
       <FieldsetPrimitive.Root
         data-slot="fieldset"
         {...props}
         render={(rootProps, state) => (
           <VStack
             {...rootProps}
             xstyle={[styles.root, xstyle]}
             render={typeof render === "function" ? (p) => render(p, state) : (render ?? <fieldset />)}
             gap={gap}
           />
         )}
         className={className}
         style={style}
       />
     )
   }
   function FieldsetLegend({
     variant = "legend",
     xstyle,
     className,
     style,
     ...props
   }: Omit<FieldsetPrimitive.Legend.Props, "className" | "style"> &
     Overrides & { variant?: FieldLegendVariant }) {
     return (
       <FieldsetPrimitive.Legend
         data-slot="fieldset-legend"
         data-variant={variant}
         {...props}
         {...stateStyles(() => [styles.legend, variants[variant], xstyle], { className, style })}
       />
     )
   }
   const fieldsetStyles = { ...styles, variants }
   export { Fieldset, FieldsetLegend, fieldsetStyles, type FieldLegendVariant }
   ```

4. Update the import paths to match your project setup.

## Usage

```tsx
import { Fieldset, FieldsetLegend } from "@/components/ui/fieldset"
import { Field, FieldLabel } from "@/components/ui/field"

import { Input } from "@/components/ui/input"

;<Fieldset>
  <FieldsetLegend>Personal information</FieldsetLegend>
  <Field>
    <FieldLabel>First name</FieldLabel>
    <Input />
  </Field>
</Fieldset>
```

## Anatomy

`Fieldset` contains a `FieldsetLegend` followed by related `Field` controls.

## API reference

Accepts [Base UI Fieldset props](https://base-ui.com/react/components/fieldset), including `render`, plus `xstyle`, `className` and inline `style`.

### Fieldset

| Prop  | Type          | Default |
| ----- | ------------- | ------- |
| `gap` | `SpacingStep` | `4`     |

### FieldsetLegend

| Prop      | Type                  | Default    |
| --------- | --------------------- | ---------- |
| `variant` | `"legend" \| "label"` | `"legend"` |

### fieldsetStyles

| Key        | What it is                     |
| ---------- | ------------------------------ |
| `root`     | Shrinkable fieldset            |
| `legend`   | Legend weight and bottom space |
| `variants` | Legend and label type sizes    |

### Data attributes

| Attribute                     | On              | Effect                 |
| ----------------------------- | --------------- | ---------------------- |
| `data-slot="fieldset"`        | root            | Fieldset anatomy       |
| `data-slot="fieldset-legend"` | legend          | Legend anatomy         |
| `data-variant`                | legend          | Type size              |
| `data-disabled`               | root and legend | Base UI disabled state |
