Radio Group

Single-select option group for mutually exclusive choices with form semantics and reduced-motion support.

Installation

npx shadcn@latest add @iconiq/r-radio-group

File Structure

Usage

"use client";

import { useState } from "react";
import RadioGroup from "@/components/ui/r-radio-group";

const options = [
  {
    value: "standard",
    label: "Standard delivery",
    description: "Tracked parcel in three to five business days.",
  },
  {
    value: "express",
    label: "Express",
    description: "Handoff next business day where available.",
  },
  {
    value: "pickup",
    label: "Pickup point",
    description: "Collect when convenient — no doorstep drop.",
  },
];

export function RadioGroupPreview() {
  const [value, setValue] = useState("standard");

  return (
    <div className="flex w-full justify-center px-4 py-6">
      <div className="flex w-full max-w-md flex-col gap-2">
        <RadioGroup
          aria-describedby="delivery-help"
          label="Delivery options"
          className="w-full"
          onChange={setValue}
          options={options}
          value={value}
        />
        <p className="text-muted-foreground text-sm" id="delivery-help">
          Pick the delivery speed that fits your timeline.
        </p>
      </div>
    </div>
  );
}

Props

Props
Description

Radio option shape

value

Unique identifier for the option and the selected value reported through onChange.

Type string

label

Primary line shown for the option.

Type string

description

Optional secondary line shown below the label with reduced emphasis.

Type string

disabled

Disables this option while keeping it visible in the list.

Type boolean

RadioGroup

options

Available choices in display order.

Type { value: string; label: string; description?: string; disabled?: boolean }[]

defaultValue

Initial uncontrolled selection. If omitted or invalid, the component falls back to the first option.

Type string

value

Controlled selected value. When provided, parent state owns selection and the component only reports changes.

Type string

onChange

Called whenever a user selects a row.

Type (value: string) => void

disabled

Disables the entire group and all rows.

Type boolean

invalid

Marks the group invalid for assistive tech and applies destructive focus styling.

Type boolean

label

Visible field label rendered above the group. When required is true, a destructive asterisk is appended.

Type string

labelClassName

Merged onto the visible field label.

Type string

required

Marks the native radio inputs as required for form validation and shows a destructive asterisk when label is set.

Type boolean

form

Associates the native radio inputs with a form element by id when the group is rendered outside that form.

Type string

orientation

Layout direction for the option rows. Defaults to vertical.

Type "horizontal" | "vertical"

name

Shared radio input name. If omitted, the component generates one per instance.

Type string

"aria-describedby"

ID of helper or error text associated with the radiogroup.

Type string

"aria-label"

Accessible name for the radiogroup when label is omitted. Prefer label when you need a visible field title.

Type string

"aria-labelledby"

ID of external text that labels the radiogroup. Use this instead of aria-label when visible copy already exists.

Type string

className

Merged onto the root wrapper for spacing or sizing adjustments.

Type string

Motion and accessibility

The component wraps native radio inputs in an animated row shell so keyboard, form, and screen-reader behavior stay intact.

Built on Radix RadioGroup.Root and RadioGroup.Item with roving focus, hidden native inputs, and the Iconiq staggered row entrance plus spring-loaded ring and dot animation.

The root keeps radiogroup semantics and each input supports Arrow keys plus Home and End navigation with a single tab stop inside the set.

Disabled rows skip hover and tap motion while remaining visible.

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: @radix-ui/react-radio-group, motion.

Installs a Radix radio group with the same API as the Base UI version.

Keeps the row entrance and ring-and-dot motion from the original radio group component.

The generated registry file is /r/r-radio-group.json.

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: @radix-ui/react-radio-group, motion.

Installs a Radix radio group with the same API as the Base UI version.

Keeps the row entrance and ring-and-dot motion from the original radio group component.

The generated registry file is /r/r-radio-group.json.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.

Delivery options

Pick the delivery speed that fits your timeline.