# Radio Group

> One choice out of a few, always visible.

Component · Forms · Pro kit · [Live page](https://ui.twentyfirst.media/pro/components/RadioGroup/)

One choice out of a few, always visible. `RadioGroup` for 2–5 options with labels and hints, `Segmented` for 2–4 short options that switch a value inline.

RadioGroup props: `label`, `options` (strings or {value, label, hint, disabled}), `value`/`defaultValue`, `onChange(value)`, `cards` (bordered tiles in a grid), `hint`.
Segmented props: `options` (strings or {value, label, icon}), `value`/`defaultValue`, `onChange(value)`, `size` ("sm"), `block`, `label` (accessible name).

- Six or more options, or options that need search: use Combobox.
- Segmented sets a value (billing period, density); Tabs switch views of content. Don't mix them up.
- `cards` when each option needs a sentence to explain it (plans, themes).

## Example

```tsx
import * as React from "react";
import { RadioGroup, Segmented } from "@twentyfirstmedia/pro";

function App() {
  const a = React.useState("Team"),
    b = React.useState("Monthly");
  return (
    <div
      className="tf-panel"
      style={{
        gap: 24,
      }}
    >
      <RadioGroup
        label="Plan"
        cards
        value={a[0]}
        onChange={a[1]}
        options={[
          {
            value: "Starter",
            label: "Starter",
            hint: "€9 per seat · 3 projects",
          },
          {
            value: "Team",
            label: "Team",
            hint: "€24 per seat · unlimited",
          },
          {
            value: "Business",
            label: "Business",
            hint: "SSO, audit log, SLA",
          },
        ]}
      />
      <div
        style={{
          display: "flex",
          gap: 48,
          flexWrap: "wrap",
          alignItems: "flex-start",
        }}
      >
        <RadioGroup
          label="Invoice reminders"
          defaultValue="due"
          options={[
            {
              value: "never",
              label: "Never",
            },
            {
              value: "due",
              label: "On the due date",
            },
            {
              value: "weekly",
              label: "Weekly until paid",
              hint: "Stops when the bank feed matches it",
            },
          ]}
        />
        <div className="tf-field">
          <span className="tf-field-label">Billing</span>
          <Segmented label="Billing" value={b[0]} onChange={b[1]} options={["Monthly", "Yearly"]} />
        </div>
        <div className="tf-field">
          <span className="tf-field-label">View</span>
          <Segmented
            label="View"
            size="sm"
            defaultValue="grid"
            options={[
              {
                value: "grid",
                label: "Grid",
                icon: "grid",
              },
              {
                value: "list",
                label: "List",
                icon: "menu",
              },
            ]}
          />
        </div>
      </div>
    </div>
  );
}
export default App;
```

## Props

### RadioGroup

| Prop | Type | Notes |
| --- | --- | --- |
| `label?` | `string` |  |
| `options` | `(string \| Option)[]` | Required |
| `value?` | `string` |  |
| `defaultValue?` | `string` |  |
| `onChange?` | `(v: string) => void` |  |
| `cards?` | `boolean` |  |
| `hint?` | `string` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### Segmented

| Prop | Type | Notes |
| --- | --- | --- |
| `options` | `(string \| Option)[]` | Required |
| `value?` | `string` |  |
| `defaultValue?` | `string` |  |
| `onChange?` | `(v: string) => void` |  |
| `size?` | `"sm"` |  |
| `block?` | `boolean` |  |
| `label?` | `string` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |
