

<Preview name="BasicRadioGroupExample" />

## Overview [#overview]

Radio Group lets users choose one option from a mutually exclusive set. Items follow the same surface pattern as Checkbox: the radio item lands at parent +2, hover uses the contextual hover surface, and the checked state uses a brand border with a brand indicator dot.

## Usage [#usage]

```tsx
import { Label } from "@tilt-legal/cubitt-components/label";
import {
  RadioGroup,
  RadioGroupItem,
} from "@tilt-legal/cubitt-components/radio-group";
```

```tsx
<RadioGroup defaultValue="option-1">
  <Label orientation="horizontal">
    <RadioGroupItem value="option-1" />
    Option 1
  </Label>
  <Label orientation="horizontal">
    <RadioGroupItem value="option-2" />
    Option 2
  </Label>
</RadioGroup>
```

## Examples [#examples]

### Sizes [#sizes]

Use the `size` prop on the group to scale all child items.

<Tabs items="[&#x22;Preview&#x22;, &#x22;Code&#x22;]">
  <Tab value="Preview">
    <Preview name="RadioGroupSizesExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Label } from "@tilt-legal/cubitt-components/label";
    import {
      RadioGroup,
      RadioGroupItem,
    } from "@tilt-legal/cubitt-components/radio-group";

    export default function Example() {
      return (
        <div className="flex flex-col items-center gap-6">
          <RadioGroup className="flex flex-row gap-4" defaultValue="sm-1" size="sm">
            <Label orientation="horizontal">
              <RadioGroupItem value="sm-1" />
              Option 1
            </Label>
            <Label orientation="horizontal">
              <RadioGroupItem value="sm-2" />
              Option 2
            </Label>
            <Label orientation="horizontal">
              <RadioGroupItem value="sm-3" />
              Option 3
            </Label>
          </RadioGroup>
          <RadioGroup className="flex flex-row gap-6" defaultValue="md-1" size="md">
            <Label orientation="horizontal">
              <RadioGroupItem value="md-1" />
              Option 1
            </Label>
            <Label orientation="horizontal">
              <RadioGroupItem value="md-2" />
              Option 2
            </Label>
            <Label orientation="horizontal">
              <RadioGroupItem value="md-3" />
              Option 3
            </Label>
          </RadioGroup>
          <RadioGroup className="flex flex-row gap-6" defaultValue="lg-1" size="lg">
            <Label orientation="horizontal">
              <RadioGroupItem value="lg-1" />
              Option 1
            </Label>
            <Label orientation="horizontal">
              <RadioGroupItem value="lg-2" />
              Option 2
            </Label>
            <Label orientation="horizontal">
              <RadioGroupItem value="lg-3" />
              Option 3
            </Label>
          </RadioGroup>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

### Disabled [#disabled]

Individual radio items can be disabled.

<Tabs items="[&#x22;Preview&#x22;, &#x22;Code&#x22;]">
  <Tab value="Preview">
    <Preview name="DisabledRadioGroupExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Label } from "@tilt-legal/cubitt-components/label";
    import {
      RadioGroup,
      RadioGroupItem,
    } from "@tilt-legal/cubitt-components/radio-group";

    export default function Example() {
      return (
        <RadioGroup defaultValue="disabled-1">
          <Label orientation="horizontal">
            <RadioGroupItem value="disabled-1" />
            Enabled option
          </Label>
          <Label orientation="horizontal">
            <RadioGroupItem disabled value="disabled-2" />
            Disabled (unselected)
          </Label>
          <Label orientation="horizontal">
            <RadioGroupItem disabled value="disabled-3" />
            Disabled option
          </Label>
        </RadioGroup>
      );
    }
    ```
  </Tab>
</Tabs>

### With Description [#with-description]

Use a wrapped label when a radio option has title and description content.

<Tabs items="[&#x22;Preview&#x22;, &#x22;Code&#x22;]">
  <Tab value="Preview">
    <Preview name="RadioGroupWithDescriptionExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Label } from "@tilt-legal/cubitt-components/label";
    import {
      RadioGroup,
      RadioGroupItem,
    } from "@tilt-legal/cubitt-components/radio-group";

    export default function Example() {
      return (
        <RadioGroup className="gap-4" defaultValue="plan-1">
          <Label className="items-start" orientation="horizontal">
            <RadioGroupItem value="plan-1" />
            <div className="flex flex-col gap-1.5">
              <p>Free Plan</p>
              <p className="text-fg-2 text-sm">
                Perfect for personal projects and small teams.
              </p>
            </div>
          </Label>
          <Label className="items-start" orientation="horizontal">
            <RadioGroupItem value="plan-2" />
            <div className="flex flex-col gap-1.5">
              <p>Pro Plan</p>
              <p className="text-fg-2 text-sm">
                Advanced features for growing businesses.
              </p>
            </div>
          </Label>
          <Label className="items-start" orientation="horizontal">
            <RadioGroupItem value="plan-3" />
            <div className="flex flex-col gap-1.5">
              <p>Enterprise Plan</p>
              <p className="text-fg-2 text-sm">
                Custom solutions for large organizations.
              </p>
            </div>
          </Label>
        </RadioGroup>
      );
    }
    ```
  </Tab>
</Tabs>

### URL State [#url-state]

Provide `paramName` to sync selection with the current URL.

<Tabs items="[&#x22;Preview&#x22;, &#x22;Code&#x22;]">
  <Tab value="Preview">
    <Preview name="RadioGroupURLStateExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Label } from "@tilt-legal/cubitt-components/label";
    import {
      RadioGroup,
      RadioGroupItem,
    } from "@tilt-legal/cubitt-components/radio-group";

    export default function Example() {
      return (
        <RadioGroup
          defaultValue="standard"
          paramClearOnDefault={true}
          paramName="demo-shipping"
        >
          <Label orientation="horizontal">
            <RadioGroupItem value="standard" />
            Standard Shipping
          </Label>
          <Label orientation="horizontal">
            <RadioGroupItem value="express" />
            Express Shipping
          </Label>
          <Label orientation="horizontal">
            <RadioGroupItem value="overnight" />
            Overnight Shipping
          </Label>
        </RadioGroup>
      );
    }
    ```
  </Tab>
</Tabs>

## API Reference [#api-reference]

### RadioGroup [#radiogroup]

| Prop            | Type                      | Default | Description                                              |
| --------------- | ------------------------- | ------- | -------------------------------------------------------- |
| `value`         | `string`                  | -       | Controlled selected value.                               |
| `defaultValue`  | `string`                  | -       | Initial selected value when uncontrolled.                |
| `onValueChange` | `(value: string) => void` | -       | Callback fired when the selected value changes.          |
| `disabled`      | `boolean`                 | `false` | Disables all radio items in the group.                   |
| `name`          | `string`                  | -       | Form name shared by the radio items.                     |
| `required`      | `boolean`                 | `false` | Marks the group as required in forms.                    |
| `size`          | `"sm" \| "md" \| "lg"`    | `"md"`  | Size applied to child items unless an item overrides it. |
| `className`     | `string`                  | -       | Additional classes for the group container.              |

### URL State Props [#url-state-props]

| Prop                  | Type                              | Default | Description                                                  |
| --------------------- | --------------------------------- | ------- | ------------------------------------------------------------ |
| `paramName`           | `string`                          | -       | URL parameter name. Providing this enables URL state.        |
| `paramValue`          | `string`                          | -       | Controlled URL parameter value.                              |
| `onUrlValueChange`    | `(value: string \| null) => void` | -       | Callback fired when the URL-backed value changes.            |
| `paramClearOnDefault` | `boolean`                         | `true`  | Removes the URL parameter when the value equals the default. |
| `paramThrottle`       | `number`                          | -       | Throttles URL updates in milliseconds.                       |
| `paramDebounce`       | `number`                          | -       | Debounces URL updates in milliseconds.                       |

### RadioGroupItem [#radiogroupitem]

| Prop        | Type                   | Default | Description                                      |
| ----------- | ---------------------- | ------- | ------------------------------------------------ |
| `value`     | `string`               | -       | Unique value for the radio item.                 |
| `disabled`  | `boolean`              | `false` | Disables this radio item.                        |
| `size`      | `"sm" \| "md" \| "lg"` | -       | Item size. Inherits the group size when omitted. |
| `className` | `string`               | -       | Additional classes for the radio item.           |

### Notes [#notes]

* Use `RadioGroupItem` inside `RadioGroup`.
* Wrap `RadioGroupItem` in `Label` when the label text should toggle the item.
* Give each `RadioGroupItem` a unique `value` within its group.
