# RadioButtonGroup
**Category**: react
**URL**: https://ui.darkcode.dev/en/docs/react/components/radio-button-group
**Source**: https://raw.githubusercontent.com/DarkCode-Developers/darkcode-ui/refs/heads/main/apps/docs/content/docs/en/react/components/(forms)/radio-button-group.mdx
> A single-selection button group with card-style radio options, icons, and custom indicators
***
## Import
```tsx
import { RadioButtonGroup } from '@darkcode-ui/react';
```
### Usage
```tsx
import {Description, Label, RadioButtonGroup} from "@darkcode-ui/react";
const plans = [
{description: "For side projects and small teams", title: "Starter", value: "starter"},
{description: "Advanced reporting and analytics", title: "Pro", value: "pro"},
{description: "Share access with up to 10 teammates", title: "Teams", value: "teams"},
];
export function Default() {
return (
{plans.map((plan) => (
{plan.description}
))}
);
}
```
### Anatomy
Import the RadioButtonGroup component and access all parts using dot notation.
```tsx
import {RadioButtonGroup, Label, Description} from '@darkcode-ui/react';
export default () => (
)
```
### Delivery & Payment
### Subscription Plans
```tsx
import {Chip, Label, RadioButtonGroup} from "@darkcode-ui/react";
import {Icon} from "@iconify/react";
const subscriptions = [
{features: ["10 projects", "Community support"], price: "$0", title: "Free", value: "free"},
{
badge: "Most popular",
features: ["Unlimited projects", "Priority support", "Advanced analytics"],
price: "$12",
title: "Pro",
value: "pro",
},
{
features: ["Everything in Pro", "SSO & SAML", "Dedicated manager"],
price: "$49",
title: "Enterprise",
value: "enterprise",
},
];
export function SubscriptionPlans() {
return (
{subscriptions.map((plan) => (
{plan.badge ? (
{plan.badge}
) : null}
{plan.price}/month
{plan.features.map((feature) => (
{feature}
))}
))}
);
}
```
### Controlled
```tsx
"use client";
import {Description, Label, RadioButtonGroup} from "@darkcode-ui/react";
import React from "react";
const plans = [
{description: "For side projects and small teams", title: "Starter", value: "starter"},
{description: "Advanced reporting and analytics", title: "Pro", value: "pro"},
{description: "Share access with up to 10 teammates", title: "Teams", value: "teams"},
];
export function Controlled() {
const [value, setValue] = React.useState("pro");
return (
{plans.map((plan) => (
{plan.description}
))}
Selected plan: {value}
);
}
```
### Custom Indicator
Pass children to `RadioButtonGroup.Indicator` to render a custom icon that appears only when the item is selected.
```tsx
import {Description, Label, RadioButtonGroup} from "@darkcode-ui/react";
import {Icon} from "@iconify/react";
const plans = [
{description: "For side projects and small teams", title: "Starter", value: "starter"},
{description: "Advanced reporting and analytics", title: "Pro", value: "pro"},
{description: "Share access with up to 10 teammates", title: "Teams", value: "teams"},
];
export function CustomIndicator() {
return (
{plans.map((plan) => (
{plan.description}
))}
);
}
```
### Disabled Group
```tsx
import {Description, Label, RadioButtonGroup} from "@darkcode-ui/react";
const plans = [
{description: "For side projects and small teams", title: "Starter", value: "starter"},
{description: "Advanced reporting and analytics", title: "Pro", value: "pro"},
{description: "Share access with up to 10 teammates", title: "Teams", value: "teams"},
];
export function DisabledGroup() {
return (
Plan changes are paused while we roll out updates.
{plans.map((plan) => (
{plan.description}
))}
);
}
```
### Grid Layout
Set `layout="grid"` to arrange items in a responsive grid. Override the columns with a Tailwind class on the root.
### Icon Cards
### No Indicator
Omit `RadioButtonGroup.Indicator` to rely on the selection ring alone.
```tsx
import {Description, Label, RadioButtonGroup} from "@darkcode-ui/react";
const plans = [
{description: "For side projects and small teams", title: "Starter", value: "starter"},
{description: "Advanced reporting and analytics", title: "Pro", value: "pro"},
{description: "Share access with up to 10 teammates", title: "Teams", value: "teams"},
];
export function NoIndicator() {
return (
{plans.map((plan) => (
{plan.description}
))}
);
}
```
### Render Prop Children
`RadioButtonGroup.Item` accepts a render function that receives the radio's selection state.
```tsx
"use client";
import {Description, Label, RadioButtonGroup} from "@darkcode-ui/react";
import {Icon} from "@iconify/react";
const plans = [
{description: "For side projects and small teams", title: "Starter", value: "starter"},
{description: "Advanced reporting and analytics", title: "Pro", value: "pro"},
{description: "Share access with up to 10 teammates", title: "Teams", value: "teams"},
];
export function RenderPropChildren() {
return (
{plans.map((plan) => (
{({isSelected}) => (
<>
{isSelected ? "Selected plan" : plan.description}
>
)}
))}
);
}
```
### With Icons
```tsx
import {Description, Label, RadioButtonGroup} from "@darkcode-ui/react";
import {Icon} from "@iconify/react";
const options = [
{
description: "Best for individuals",
icon: "gravity-ui:person",
title: "Personal",
value: "personal",
},
{description: "Best for small teams", icon: "gravity-ui:persons", title: "Team", value: "team"},
{description: "Advanced controls", icon: "gravity-ui:gear", title: "Custom", value: "custom"},
];
export function WithIcons() {
return (
{options.map((option) => (
{option.description}
))}
);
}
```
### With Ripple
Add the `ripple` prop to `RadioButtonGroup.Item` for a press ripple effect.
```tsx
import {Description, Label, RadioButtonGroup} from "@darkcode-ui/react";
const plans = [
{description: "For side projects and small teams", title: "Starter", value: "starter"},
{description: "Advanced reporting and analytics", title: "Pro", value: "pro"},
{description: "Share access with up to 10 teammates", title: "Teams", value: "teams"},
];
export function WithRipple() {
return (
{plans.map((plan) => (
{plan.description}
))}
);
}
```
## Related Components
- **RadioGroup**: Single selection from multiple options
- **Fieldset**: Group related form controls with legends
- **Surface**: Base container surface
## Styling
RadioButtonGroup builds on top of the [RadioGroup](/docs/components/radio-group) and Radio
primitives, adding card-style layout, a positioned indicator, and a leading icon slot.
### CSS Classes
The RadioButtonGroup component uses these CSS classes ([View source styles](https://github.com/DarkCode-Developers/darkcode-ui/blob/main/packages/styles/components/radio-button-group.css)):
#### Base Classes
- `.radio-button-group` - Base RadioGroup container with flex layout
#### Layout Classes
- `.radio-button-group--grid` - Grid layout mode
#### Element Classes
- `.radio-button-group__item` - Card-like radio button with border and selection ring
- `.radio-button-group__indicator` - Positioned top-right indicator (radio dot or custom icon)
- `.radio-button-group__item-content` - Text/content area wrapping Radio.Content
- `.radio-button-group__item-icon` - Leading icon container
### Interactive States
- **Selected**: `[data-selected="true"]` on `.radio-button-group__item` (accent ring)
- **Focus visible**: `:focus-visible` or `[data-focus-visible="true"]` on `.radio-button-group__item` (focus ring)
- **Disabled**: `:disabled` or `[aria-disabled="true"]` on `.radio-button-group__item` (reduced opacity)
### CSS Variables
- `--radio-button-group-item-radius` - Border radius of items (default: `var(--radius-2xl)`)
## API Reference
### RadioButtonGroup
The root component. Wraps DarkCode UI [RadioGroup](/docs/components/radio-group) with card-style layout.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `layout` | `'flex' \| 'grid'` | `'flex'` | Layout mode for items |
Also supports all [DarkCode UI RadioGroup](/docs/components/radio-group) props (`value`, `defaultValue`, `onChange`, `isDisabled`, `isRequired`, `name`, `orientation`, `variant`, …).
### RadioButtonGroup.Item
A selectable card wrapping DarkCode UI Radio. Supports render prop children for accessing selection state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `ripple` | `boolean` | `false` | Whether a ripple animation is shown on press |
Also supports all DarkCode UI Radio props (`value`, `isDisabled`, `children`, …).
### RadioButtonGroup.Indicator
Selection indicator positioned at the top-right of the item.
- **No children**: renders the default DarkCode UI radio dot (Control + Indicator)
- **With children**: renders a custom icon that appears only when selected
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `ReactNode` | - | Custom indicator icon (shown when selected) |
Also supports all native `span` HTML attributes.
### RadioButtonGroup.ItemContent
Content area for title and description text. Wraps DarkCode UI `Radio.Content`.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `ReactNode` | - | Content elements |
Also supports all native `div` HTML attributes.
### RadioButtonGroup.ItemIcon
Leading icon container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `ReactNode` | - | Icon element |
Also supports all native `div` HTML attributes.