# RadioGroup

> Choose a single option from a set of mutually exclusive options.

**URL:** https://inference.sh/docs/agents/widgets/radio-group
**Last updated:** 2026-09-18

---

Choose a single option from a set of mutually exclusive options.

## Preview

```
○ Small
● Medium
○ Large
```

## Usage

```go
node := models.WidgetNode{
    Type: models.WidgetNodeTypeRadioGroup,
    Name: "size",
    Options: []models.WidgetSelectOption{
        {Label: "Small", Value: "sm"},
        {Label: "Medium", Value: "md"},
        {Label: "Large", Value: "lg"},
    },
    DefaultValue: "md",
}
```

## Props

| Name | Type | Description | Default |
|------|------|-------------|---------|
| `type` | `"radio-group"` | Node type | required |
| `name` | `string` | Form field name | required |
| `options` | `WidgetSelectOption[]` | Array of options to render | required |
| `defaultValue` | `string` | Initial selected value | - |
| `direction` | `"row" \| "col"` | Layout direction of radio items | `"row"` |
| `disabled` | `boolean` | Disable all options | `false` |
| `required` | `boolean` | Mark as required for form submission | `false` |
| `onChangeAction` | `ActionConfig` | Action dispatched when selection changes | - |
| `ariaLabel` | `string` | Accessible label (falls back to name) | - |

## Examples

### Horizontal Layout (default)

```go
{
    Type: models.WidgetNodeTypeRadioGroup,
    Name: "plan",
    Options: []models.WidgetSelectOption{
        {Label: "Free", Value: "free"},
        {Label: "Pro", Value: "pro"},
        {Label: "Enterprise", Value: "enterprise"},
    },
}
```

### Vertical Layout

```go
{
    Type:      models.WidgetNodeTypeRadioGroup,
    Name:      "priority",
    Direction: "col",
    Options: []models.WidgetSelectOption{
        {Label: "Low - Not time sensitive", Value: "low"},
        {Label: "Medium - Standard priority", Value: "medium"},
        {Label: "High - Urgent attention needed", Value: "high"},
    },
}
```

### With Label

```go
{
    Type: models.WidgetNodeTypeCol,
    Gap:  2,
    Children: []models.WidgetNode{
        {Type: models.WidgetNodeTypeLabel, Value: "Notification Preference", FieldName: "notifications"},
        {
            Type:      models.WidgetNodeTypeRadioGroup,
            Name:      "notifications",
            Direction: "col",
            Options: []models.WidgetSelectOption{
                {Label: "All notifications", Value: "all"},
                {Label: "Important only", Value: "important"},
                {Label: "None", Value: "none"},
            },
            DefaultValue: "all",
        },
    },
}
```

### With Change Action

```go
{
    Type: models.WidgetNodeTypeRadioGroup,
    Name: "theme",
    Options: []models.WidgetSelectOption{
        {Label: "Light", Value: "light"},
        {Label: "Dark", Value: "dark"},
        {Label: "System", Value: "system"},
    },
    OnChangeAction: &models.WidgetAction{
        Type:    "theme_changed",
        Payload: map[string]interface{}{},
    },
}
```

## Form Data

When submitted, the selected value is included:

```json
{
  "size": "md",
  "notifications": "all"
}
```

## TypeScript

```typescript
const node: WidgetNode = {
  type: "radio-group",
  name: "size",
  direction: "col",
  options: [
    { label: "Small", value: "sm" },
    { label: "Medium", value: "md" },
    { label: "Large", value: "lg" },
  ],
  defaultValue: "md",
}
```

## When to Use

| Use RadioGroup | Use Select |
|----------------|------------|
| 2-5 options | 5+ options |
| All options visible | Save space |
| Comparing options | Quick selection |
| Important choice | Less important |

## Best Practices

1. **Use for few options** - 2-5 items; use Select for more
2. **Always have a default** - Unless intentionally unselected
3. **Clear labels** - Make each option distinct
4. **Vertical for long labels** - Use `direction: "col"` when labels are descriptive
