# 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.