---
title: Radio Group
description: Radio buttons for mutually exclusive choices.
icon: circle-dot
---

import { ComponentPreview } from "/snippets/component-preview.mdx";

Radio buttons let users select exactly one option from a set of choices.

## Basic Usage

<ComponentPreview json={{"view":{"type":"RadioGroup","name":"size","children":[{"type":"Radio","value":"sm","label":"Small","checked":false,"disabled":false,"required":false},{"type":"Radio","value":"md","label":"Medium","checked":true,"disabled":false,"required":false},{"type":"Radio","value":"lg","label":"Large","checked":false,"disabled":false,"required":false}]}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import (
    Radio,
    RadioGroup,
)

with RadioGroup(name="size"):
    Radio(value="sm", label="Small")
    Radio(value="md", label="Medium", checked=True)
    Radio(value="lg", label="Large")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "type": "RadioGroup",
    "name": "size",
    "children": [
      {
        "type": "Radio",
        "value": "sm",
        "label": "Small",
        "checked": false,
        "disabled": false,
        "required": false
      },
      {
        "type": "Radio",
        "value": "md",
        "label": "Medium",
        "checked": true,
        "disabled": false,
        "required": false
      },
      {
        "type": "Radio",
        "value": "lg",
        "label": "Large",
        "checked": false,
        "disabled": false,
        "required": false
      }
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

## Without RadioGroup

Individual radio buttons can be used independently:

<ComponentPreview json={{"view":{"cssClass":"gap-3","type":"Column","children":[{"type":"Radio","value":"yes","label":"Yes","checked":false,"name":"answer","disabled":false,"required":false},{"type":"Radio","value":"no","label":"No","checked":true,"name":"answer","disabled":false,"required":false}]}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import (
    Column,
    Radio,
)

with Column(gap=3):
    Radio(value="yes", label="Yes", name="answer")
    Radio(value="no", label="No", name="answer", checked=True)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-3",
    "type": "Column",
    "children": [
      {
        "type": "Radio",
        "value": "yes",
        "label": "Yes",
        "checked": false,
        "name": "answer",
        "disabled": false,
        "required": false
      },
      {
        "type": "Radio",
        "value": "no",
        "label": "No",
        "checked": true,
        "name": "answer",
        "disabled": false,
        "required": false
      }
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

## With Actions

The `on_change` parameter on `RadioGroup` runs actions when the selection changes. `$event` is the `value` string of the selected radio:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Column","children":[{"type":"RadioGroup","name":"theme","onChange":{"action":"setState","key":"choice","value":"You picked: {{ $event }}"},"children":[{"type":"Radio","value":"light","label":"Light","checked":false,"disabled":false,"required":false},{"type":"Radio","value":"dark","label":"Dark","checked":false,"disabled":false,"required":false},{"type":"Radio","value":"system","label":"System","checked":true,"disabled":false,"required":false}]},{"cssClass":"text-muted-foreground","content":"{{ choice | 'Make a selection' }}","type":"Text"}]}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Column, Radio, RadioGroup, Text
from prefab_ui.actions import SetState

with Column(gap=4):
    with RadioGroup(
        name="theme",
        on_change=SetState("choice", "You picked: {{ $event }}"),
    ):
        Radio(value="light", label="Light")
        Radio(value="dark", label="Dark")
        Radio(value="system", label="System", checked=True)
    Text(
        "{{ choice | 'Make a selection' }}",
        css_class="text-muted-foreground",
    )
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Column",
    "children": [
      {
        "type": "RadioGroup",
        "name": "theme",
        "onChange": {
          "action": "setState",
          "key": "choice",
          "value": "You picked: {{ $event }}"
        },
        "children": [
          {
            "type": "Radio",
            "value": "light",
            "label": "Light",
            "checked": false,
            "disabled": false,
            "required": false
          },
          {
            "type": "Radio",
            "value": "dark",
            "label": "Dark",
            "checked": false,
            "disabled": false,
            "required": false
          },
          {
            "type": "Radio",
            "value": "system",
            "label": "System",
            "checked": true,
            "disabled": false,
            "required": false
          }
        ]
      },
      {
        "cssClass": "text-muted-foreground",
        "content": "{{ choice | 'Make a selection' }}",
        "type": "Text"
      }
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

## Disabled State

<ComponentPreview json={{"view":{"type":"RadioGroup","name":"plan","children":[{"type":"Radio","value":"free","label":"Free","checked":true,"disabled":false,"required":false},{"type":"Radio","value":"pro","label":"Pro","checked":false,"disabled":false,"required":false},{"type":"Radio","value":"enterprise","label":"Enterprise","checked":false,"disabled":true,"required":false}]}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import (
    Radio,
    RadioGroup,
)

with RadioGroup(name="plan"):
    Radio(value="free", label="Free", checked=True)
    Radio(value="pro", label="Pro")
    Radio(value="enterprise", label="Enterprise", disabled=True)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "type": "RadioGroup",
    "name": "plan",
    "children": [
      {
        "type": "Radio",
        "value": "free",
        "label": "Free",
        "checked": true,
        "disabled": false,
        "required": false
      },
      {
        "type": "Radio",
        "value": "pro",
        "label": "Pro",
        "checked": false,
        "disabled": false,
        "required": false
      },
      {
        "type": "Radio",
        "value": "enterprise",
        "label": "Enterprise",
        "checked": false,
        "disabled": true,
        "required": false
      }
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

## API Reference

<Card icon="code" title="RadioGroup Parameters">
<ParamField body="name" type="str | None" default="None">
  Form field name shared by all radio buttons in the group.
</ParamField>

<ParamField body="on_change" type="Action | list[Action] | None" default="None">
  Action(s) to execute when the selection changes. `$event` is the `value` string of the selected radio.
</ParamField>

<ParamField body="css_class" type="str | None" default="None">
  Additional Tailwind CSS classes appended to the component's built-in styles.
</ParamField>
</Card>

<Card icon="code" title="Radio Parameters">
<ParamField body="value" type="str" required>
  Form value for this option.
</ParamField>

<ParamField body="label" type="str | None" default="None">
  Label text displayed next to the radio button.
</ParamField>

<ParamField body="checked" type="bool" default="False">
  Whether this radio button is initially selected.
</ParamField>

<ParamField body="name" type="str | None" default="None">
  Form field name. Usually inherited from RadioGroup.
</ParamField>

<ParamField body="disabled" type="bool" default="False">
  Whether the radio button is non-interactive.
</ParamField>

<ParamField body="required" type="bool" default="False">
  Whether a selection is required for form submission.
</ParamField>

<ParamField body="css_class" type="str | None" default="None">
  Additional Tailwind CSS classes.
</ParamField>
</Card>

## Protocol Reference

```json RadioGroup
{
  "type": "RadioGroup",
  "children?": "[Component]",
  "let?": "object",
  "name?": "string",
  "onChange?": "Action | Action[]",
  "cssClass?": "string"
}
```

```json Radio
{
  "type": "RadioGroup",
  "children?": "[Component]",
  "let?": "object",
  "name?": "string",
  "onChange?": "Action | Action[]",
  "cssClass?": "string"
}
```

For the complete protocol schema, see [RadioGroup](/protocol/radio-group), [Radio](/protocol/radio-group).
