---
title: "RadioGroup"
description: "A radio group where only one option can be chosen. It supports per-option descriptions and vertical or horizontal orientation."
kind: component
id: C-012
registry: "radio-group"
docs: "https://koten.codehive.com.co/components/radio-group"
markdown: "https://koten.codehive.com.co/md/components/radio-group.md"
install: "npx shadcn@latest add https://koten.codehive.com.co/r/radio-group.json"
language: en
---

# RadioGroup · ラジオ

> Component C-012 in the Koten UI catalog.

A radio group where only one option can be chosen. It supports per-option descriptions and vertical or horizontal orientation.

> Japanese labels in this page are documentation metadata. Keep the consumer UI in the product's language and do not add Japanese decoration unless the user asks (R-031).

## Install

Install `koten-theme` first when the project does not have Koten tokens yet. Use the runner of your project.

```bash
# Node
npx shadcn@latest add https://koten.codehive.com.co/r/radio-group.json

# Bun
bunx shadcn@latest add https://koten.codehive.com.co/r/radio-group.json
```

## Files

- `@/components/ui/radio-group.tsx`
- `@/lib/koten/cn.ts`
- `@/lib/koten/format.ts`
- `@/lib/koten/intl.ts`
- `@/lib/koten/labels.ts`
- `@/lib/koten/provider.tsx`

## Reference

- Upstream primitive: https://base-ui.com/react/components/radio-group

## Examples

### Options and descriptions

Each option declares label, description and disabled; the group is named by label.

```tsx
<RadioGroup
  label="Shipping method"
  defaultValue="standard"
  options={[
    { value: "standard", label: "Standard", description: "3–5 business days." },
    { value: "express", label: "Express", description: "24–48 hours." },
    { value: "pickup", label: "Store pickup", description: "Ready in 2 hours." },
    { value: "sameday", label: "Same day", description: "Tokyo only.", disabled: true },
  ]}
/>
```

### Horizontal orientation

Horizontal orientation lays the options in a row that wraps when space runs out.

```tsx
<RadioGroup
  label="Billing period"
  orientation="horizontal"
  defaultValue="monthly"
  options={[
    { value: "monthly", label: "Monthly" },
    { value: "annual", label: "Annual" },
  ]}
/>
```

### Use inside a form

With no initial value, the group shows the error until a method is chosen; each option keeps its description visible.

```tsx
<form
  className="grid w-full max-w-sm gap-[var(--koten-gap)]"
  onSubmit={(event) => event.preventDefault()}
>
  <div className="grid gap-1">
    <RadioGroup label="Shipping method" options={shippingOptions} />
    <p role="alert" className="text-2xs leading-relaxed text-danger">
      Select a shipping method to see the delivery date.
    </p>
  </div>
  <div className="flex justify-end">
    <Button type="submit" variant="primary">Continue to payment</Button>
  </div>
</form>
```

## Props

| Prop | Type | Default | Notes |
| --- | --- | --- | --- |
| `label` | `string` | `—` | Group name provided through aria-labelledby; required. |
| `options` | `readonly RadioOption[]` | `—` | Each option declares value, label and optional description and disabled. |
| `value / defaultValue` | `string` | `—` | Controlled or uncontrolled. |
| `onValueChange` | `(value: string) => void` | `—` | Returns the value of the checked option. |
| `orientation` | `vertical \| horizontal` | `vertical` | vertical stacks; horizontal wraps in a row. |
| `disabled` | `boolean` | `false` | Disables the group and all of its options. |
| `name` | `string` | `—` | Group name in the form. |

## Accessibility

- The group is named through aria-labelledby, and each option is a real radio inside its label.
- Only one option can be checked; arrow keys move within the group without leaving it.
- Descriptions sit outside the label so the accessible name stays clean.

## Sources

- Catalog page: https://koten.codehive.com.co/components/radio-group
- Markdown: https://koten.codehive.com.co/md/components/radio-group.md
- Repository: https://github.com/codehive-colombia/koten
