# Field: Button Radio (category: selection)

URL: https://docs.forms.saastro.io/docs/button-radio

<FieldPreview name="button-radio" description="Interactive demo of button radio field" />

## Overview

The button radio field presents radio options as a segmented button group. It's ideal when you have 2-5 options and want a more compact, visually prominent selection UI.

## Usage

### Basic Button Radio

```tsx

const config = FormBuilder.create('form')
  .addField('size', (f) =>
    f
      .type('button-radio')
      .label('Size')
      .options([
        { label: 'S', value: 'small' },
        { label: 'M', value: 'medium' },
        { label: 'L', value: 'large' },
        { label: 'XL', value: 'xlarge' },
      ])
      .value('medium')
      .required(),
  )
  .addStep('main', ['size'])
  .build();
```

### Binary Choice

```tsx
.addField('billingCycle', (f) =>
  f.type('button-radio')
    .label('Billing')
    .options([
      { label: 'Monthly', value: 'monthly' },
      { label: 'Yearly', value: 'yearly' },
    ])
    .value('monthly')
    .required()
)
```

### With Icons (via label)

```tsx
.addField('view', (f) =>
  f.type('button-radio')
    .label('View')
    .options([
      { label: '📋 List', value: 'list' },
      { label: '📊 Grid', value: 'grid' },
      { label: '📈 Chart', value: 'chart' },
    ])
    .value('list')
    .required()
)
```

### JSON Configuration

```json
{
  "type": "button-radio",
  "label": "Size",
  "options": [
    { "label": "S", "value": "small" },
    { "label": "M", "value": "medium" },
    { "label": "L", "value": "large" }
  ],
  "value": "medium",
  "schema": { "required": true }
}
```

## Props

| Prop               | Type                                                  | Default | Description                       |
| ------------------ | ----------------------------------------------------- | ------- | --------------------------------- |
| `type`             | `'button-radio'`                                      | -       | Field type (required)             |
| `label`            | `string`                                              | -       | Group label                       |
| `helperText`       | `string`                                              | -       | Help text below field             |
| `options`          | `Option[]`                                            | -       | Array of button options           |
| `value`            | `string`                                              | -       | Default selected value            |
| `optionsClassName` | `string`                                              | -       | CSS classes for buttons container |
| `columns`          | `Partial<Record<Breakpoint, number>>`                 | -       | Grid columns by breakpoint        |
| `disabled`         | `boolean \| function \| ConditionGroup`               | `false` | Disable all buttons               |
| `hidden`           | `boolean \| function \| ConditionGroup \| Responsive` | `false` | Hide the field                    |

## Button Radio vs Radio

| Use Button Radio  | Use Radio          |
| ----------------- | ------------------ |
| 2-5 options       | Any number         |
| Compact UI        | Detailed options   |
| Visual selection  | Description needed |
| Horizontal layout | Vertical layout    |

## Validation

### Required Selection

```tsx
.addField('priority', (f) =>
  f.type('button-radio')
    .label('Priority')
    .options([
      { label: 'Low', value: 'low' },
      { label: 'Medium', value: 'medium' },
      { label: 'High', value: 'high' },
    ])
    .required('Please select a priority')
)
```

## Styling

### Custom Classes

```tsx
.addField('size', (f) =>
  f.type('button-radio')
    .label('Size')
    .options([...])
    .required()
    .classNames({
      wrapper: 'bg-muted/30 p-4 rounded-lg',
      label: 'text-lg font-semibold mb-3',
      error: 'text-destructive text-sm',
    })
)
```

### Options Layout with `optionsClassName`

Control button arrangement:

```json
{
  "type": "button-radio",
  "label": "Size",
  "optionsClassName": "flex flex-wrap gap-2",
  "options": [...]
}
```

### Responsive Layout

```tsx
.addField('billing', (f) =>
  f.type('button-radio')
    .label('Billing')
    .options([...])
    .columns({ default: 12, md: 6 })
)
```

### JSON Styling

```json
{
  "type": "button-radio",
  "label": "Size",
  "wrapper_className": "bg-muted/30 p-4 rounded-lg",
  "label_className": "text-lg font-semibold",
  "optionsClassName": "inline-flex gap-1",
  "columns": { "default": 12, "md": 6 }
}
```

## Related Fields

- [Radio](/docs/radio) - Traditional radio group
- [Button Checkbox](/docs/button-checkbox) - Multi-select buttons
- [Select](/docs/select) - Dropdown selection

## Accessibility

- Uses Radix UI ToggleGroup (single mode)
- Keyboard navigation (Arrow keys)
- Proper ARIA roles
- Focus visible states
