Radio group
Single-select list with a sliding highlight, spring radio control, and optional descriptions. Built with Framer Motion and your theme tokens.
Live preview
One choice per group · Motion follows selection · Copy-paste friendly
Install
v0
Ship the registry bundle to v0 and iterate on motion or layout with prompts.
Usage
Default export — import RadioGroup from @/components/ui/radiogroup. See tile 05 for the full API and registry install URL.
import RadioGroup from "@/components/ui/radiogroup";
import { useState } from "react";
const options = [
{
value: "monthly",
label: "Monthly",
description: "Cancel anytime",
},
{
value: "yearly",
label: "Yearly",
description: "Two months free",
},
];
export function BillingCycle() {
const [value, setValue] = useState("monthly");
return (
<RadioGroup onChange={setValue} options={options} value={value} />
);
}Dependencies
Registry peers and props — file name radiogroup.tsx, default export RadioGroup.
options (required)
Array of objects with value (stable id), label (primary line), and optional description (muted subline). The first option’s value is used as the initial selection when uncontrolled.
value (optional)
Controlled selected value as a string matching one option.value. Pair with onChange for full control; when omitted, internal state starts from the first option.
onChange (optional)
Called with the chosen option value when the user selects a row. Use with value for controlled mode.
className (optional)
Forwarded to the root radiogroup wrapper for max-width, spacing, or layout in forms.
Framer Motion
Staggered row entrance, hover nudge and tap scale, shared layoutId sliding background for the active row, and spring-driven ring/dot on the radio control. The highlight uses layoutId "radio-active-bg" — if you render multiple RadioGroup instances on the same page, duplicate that id can cross-animate; fork the file and give each group a unique layoutId when needed.
Accessibility
Root has role="radiogroup"; each row is a button with role="radio" and aria-checked. For production forms, pair with a visible legend or label and consider roving tabindex if you extend keyboard behavior.
shadcn registry
Install adds radiogroup.tsx under components/ui; the registry item declares framer-motion as the peer dependency.