Back to Heroui

Radio

apps/docs/content/docs/react/migration/(components)/radio.mdx

3.0.57.5 KB
Original Source
<Callout type="info"> Refer to the [v3 Radio documentation](/docs/react/components/radio-group) for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2. </Callout>

Structure Changes

In v2, Radio used a simple structure with props:

tsx
import { RadioGroup, Radio } from "@heroui/react";

export default function App() {
  return (
    <RadioGroup label="Select city">
      <Radio value="london">London</Radio>
      <Radio value="tokyo" description="Capital of Japan">Tokyo</Radio>
    </RadioGroup>
  );
}

In v3, Radio requires compound components:

tsx
import { RadioGroup, Radio, Label, Description } from "@heroui/react";

export default function App() {
  return (
    <RadioGroup>
      <Label>Select city</Label>
      <Radio value="london">
        <Radio.Control>
          <Radio.Indicator />
        </Radio.Control>
        <Radio.Content>
          <Label>London</Label>
        </Radio.Content>
      </Radio>
      <Radio value="tokyo">
        <Radio.Control>
          <Radio.Indicator />
        </Radio.Control>
        <Radio.Content>
          <Label>Tokyo</Label>
          <Description>Capital of Japan</Description>
        </Radio.Content>
      </Radio>
    </RadioGroup>
  );
}

Key Changes

1. Component Structure

v2: Simple Radio with children as label
v3: Compound components: Radio.Control, Radio.Indicator, Radio.Content

2. Prop Changes

v2 Propv3 LocationNotes
onValueChangeonChangeRenamed event handler
label (on RadioGroup)Use Label component
description (on Radio)Use Description component inside Radio.Content
sizeRemoved (use Tailwind CSS)
colorRemoved (use Tailwind CSS)
classNamesUse className props on individual components
disableAnimationRemoved (animations handled differently)
variantNew prop on RadioGroup: "primary" (default) or "secondary" for lower emphasis styling
isReadOnlyNew prop on RadioGroup: prevents value changes while keeping the group focusable

Migration Examples

Form Validation

<Tabs items={["v2", "v3"]}> <Tab value="v2"> tsx <RadioGroup label="Select city"> <Radio value="london" description="Capital of England"> London </Radio> </RadioGroup> <RadioGroup isInvalid errorMessage="Please select an option" label="Select city" > <Radio value="london">London</Radio> </RadioGroup> </Tab> <Tab value="v3"> tsx import { Label, Description, FieldError } from "@heroui/react"; <RadioGroup> <Label>Select city</Label> <Radio value="london"> <Radio.Control> <Radio.Indicator /> </Radio.Control> <Radio.Content> <Label>London</Label> <Description>Capital of England</Description> </Radio.Content> </Radio> </RadioGroup> <RadioGroup isInvalid> <Label>Select city</Label> <Radio value="london"> <Radio.Control> <Radio.Indicator /> </Radio.Control> <Radio.Content> <Label>London</Label> </Radio.Content> </Radio> <FieldError>Please select an option</FieldError> </RadioGroup> </Tab> </Tabs>

Controlled

<Tabs items={["v2", "v3"]}> <Tab value="v2"> ```tsx import { useState } from "react";

const [selected, setSelected] = useState("london");

<RadioGroup
  value={selected}
  onValueChange={setSelected}
>
  <Radio value="london">London</Radio>
  <Radio value="tokyo">Tokyo</Radio>
</RadioGroup>
```
</Tab> <Tab value="v3"> ```tsx import { useState } from "react";
const [selected, setSelected] = useState("london");

<RadioGroup value={selected} onChange={setSelected}>
  <Label>Select city</Label>
  <Radio value="london">
    <Radio.Control>
      <Radio.Indicator />
    </Radio.Control>
    <Radio.Content>
      <Label>London</Label>
    </Radio.Content>
  </Radio>
  <Radio value="tokyo">
    <Radio.Control>
      <Radio.Indicator />
    </Radio.Control>
    <Radio.Content>
      <Label>Tokyo</Label>
    </Radio.Content>
  </Radio>
</RadioGroup>
```
</Tab> </Tabs>

Horizontal Orientation

<Tabs items={["v2", "v3"]}> <Tab value="v2"> tsx <RadioGroup orientation="horizontal" label="Select city"> <Radio value="london">London</Radio> <Radio value="tokyo">Tokyo</Radio> </RadioGroup> </Tab> <Tab value="v3"> tsx <RadioGroup orientation="horizontal"> <Label>Select city</Label> <Radio value="london"> <Radio.Control> <Radio.Indicator /> </Radio.Control> <Radio.Content> <Label>London</Label> </Radio.Content> </Radio> <Radio value="tokyo"> <Radio.Control> <Radio.Indicator /> </Radio.Control> <Radio.Content> <Label>Tokyo</Label> </Radio.Content> </Radio> </RadioGroup> </Tab> </Tabs>

Variants

v3 introduces a variant prop on RadioGroup with "primary" (default) and "secondary" options:

tsx
<RadioGroup variant="primary">
  <Label>Select city</Label>
  <Radio value="london">
    <Radio.Control>
      <Radio.Indicator />
    </Radio.Control>
    <Radio.Content>
      <Label>London</Label>
    </Radio.Content>
  </Radio>
</RadioGroup>
<RadioGroup variant="secondary">
  <Label>Select city</Label>
  <Radio value="london">
    <Radio.Control>
      <Radio.Indicator />
    </Radio.Control>
    <Radio.Content>
      <Label>London</Label>
    </Radio.Content>
  </Radio>
</RadioGroup>

Read Only

v3 supports isReadOnly on RadioGroup, which prevents value changes while keeping the group focusable:

tsx
<RadioGroup isReadOnly defaultValue="london">
  <Label>Select city</Label>
  <Radio value="london">
    <Radio.Control>
      <Radio.Indicator />
    </Radio.Control>
    <Radio.Content>
      <Label>London</Label>
    </Radio.Content>
  </Radio>
  <Radio value="tokyo">
    <Radio.Control>
      <Radio.Indicator />
    </Radio.Control>
    <Radio.Content>
      <Label>Tokyo</Label>
    </Radio.Content>
  </Radio>
</RadioGroup>

Component Anatomy

The v3 Radio follows this structure:

RadioGroup (Root)
  ├── Label (optional)
  ├── Radio
  │   ├── Radio.Control
  │   │   └── Radio.Indicator
  │   └── Radio.Content
  │       ├── Label
  │       └── Description (optional)
  └── FieldError (optional)

Summary

  1. Component Structure: Must use compound components (Radio.Control, Radio.Indicator, Radio.Content)
  2. Label Handling: label prop removed - use Label component
  3. Description Handling: description prop removed - use Description component inside Radio.Content
  4. Event Handler: onValueChangeonChange
  5. Styling Props Removed: size, color - use Tailwind CSS
  6. ClassNames Removed: Use className props on individual components
  7. Error Message: Use FieldError component instead of errorMessage prop
  8. New variant Prop: RadioGroup supports "primary" (default) and "secondary" for lower emphasis styling
  9. New isReadOnly Prop: RadioGroup supports isReadOnly to prevent value changes while keeping the group focusable