Radio Group
A set of checkable buttons where only one can be checked at a time.
import * as stylex from '@stylexjs/stylex';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { space, fontSize } from '@/lib/constants.stylex';
import { colors, font } from '@/lib/tokens.stylex';
const options = ['Default', 'Comfortable', 'Compact'];
export default function RadioGroupDemo() {
return (
<RadioGroup defaultValue="Comfortable">
{options.map((option) => (
<label key={option} {...stylex.props(styles.label)}>
<RadioGroupItem value={option} /> {option}
</label>
))}
</RadioGroup>
);
}
const styles = stylex.create({
label: {
alignItems: 'center',
color: colors.foreground,
display: 'flex',
fontFamily: font.sans,
fontSize: fontSize.sm,
gap: space.s2,
},
});
Install
npx shadcn@latest add @madeui/radio-group
Usage
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
Composition
<RadioGroup>
<RadioGroupItem />
<RadioGroupItem />
</RadioGroup>
Description
Pair each item with Field, FieldContent, and FieldDescription to add helper text.
Up to 5 projects and community support.
Unlimited projects and priority support.
import * as stylex from '@stylexjs/stylex';
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
} from '@/components/ui/field';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { space } from '@/lib/constants.stylex';
const plans = [
{
value: 'starter',
label: 'Starter',
description: 'Up to 5 projects and community support.',
},
{
value: 'pro',
label: 'Pro',
description: 'Unlimited projects and priority support.',
},
];
export default function RadioGroupDescription() {
return (
<RadioGroup defaultValue="starter" style={styles.group}>
{plans.map((plan) => (
<Field key={plan.value} orientation="horizontal">
<RadioGroupItem
value={plan.value}
id={`radio-group-description-${plan.value}`}
/>
<FieldContent>
<FieldLabel htmlFor={`radio-group-description-${plan.value}`}>
{plan.label}
</FieldLabel>
<FieldDescription>{plan.description}</FieldDescription>
</FieldContent>
</Field>
))}
</RadioGroup>
);
}
const styles = stylex.create({
group: {
gap: space.s4,
},
});
Choice card
Wrap each Field in FieldLabel for a clickable, card-style selection.
import * as stylex from '@stylexjs/stylex';
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
FieldTitle,
} from '@/components/ui/field';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { space, stroke } from '@/lib/constants.stylex';
import { colors, radius } from '@/lib/tokens.stylex';
const plans = [
{
value: 'starter',
label: 'Starter',
description: 'Up to 5 projects and community support.',
},
{
value: 'pro',
label: 'Pro',
description: 'Unlimited projects and priority support.',
},
];
export default function RadioGroupChoiceCard() {
return (
<RadioGroup defaultValue="pro" style={styles.group}>
{plans.map((plan) => (
<Field key={plan.value} orientation="horizontal">
{/* The label is the card, so the whole surface toggles the radio. */}
<FieldLabel style={styles.card}>
<RadioGroupItem value={plan.value} />
<FieldContent>
<FieldTitle>{plan.label}</FieldTitle>
<FieldDescription>{plan.description}</FieldDescription>
</FieldContent>
</FieldLabel>
</Field>
))}
</RadioGroup>
);
}
const styles = stylex.create({
group: {
gap: space.s3,
},
card: {
alignItems: 'flex-start',
borderColor: {
default: colors.border,
':has([data-checked])': colors.primary,
},
borderRadius: radius.lg,
borderStyle: 'solid',
borderWidth: stroke.border,
cursor: 'pointer',
display: 'flex',
gap: space.s3,
padding: space.s4,
},
});
Disabled
Set disabled on the group to disable every item, or on a single RadioGroupItem.
import * as stylex from '@stylexjs/stylex';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { space, fontSize } from '@/lib/constants.stylex';
import { colors, font } from '@/lib/tokens.stylex';
export default function RadioGroupDisabled() {
return (
<RadioGroup defaultValue="a" disabled>
<label {...stylex.props(styles.label, styles.disabled)}>
<RadioGroupItem value="a" /> Option A
</label>
<label {...stylex.props(styles.label, styles.disabled)}>
<RadioGroupItem value="b" /> Option B
</label>
</RadioGroup>
);
}
const styles = stylex.create({
label: {
alignItems: 'center',
color: colors.foreground,
display: 'flex',
fontFamily: font.sans,
fontSize: fontSize.sm,
gap: space.s2,
},
disabled: {
opacity: 0.5,
},
});
API reference
Built on Base UI Radio. The tables below cover the props this library adds or changes — every other prop is forwarded to the underlying Base UI part; see the Base UI Radio API reference for the full list.
RadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
value |
any |
— | Controlled selected value. |
defaultValue |
any |
— | |
onValueChange |
(value: any) => void |
— | |
disabled |
boolean |
false |
|
style |
StyleXStyles |
— | StyleX styles merged last — always win over the component’s own styles. |
RadioGroupItem
| Prop | Type | Default | Description |
|---|---|---|---|
value (required) |
any |
— | |
disabled |
boolean |
false |
|
style |
StyleXStyles |
— | StyleX styles merged last — always win over the component’s own styles. |