RadioButton
RadioButton is an extension to standard radio button element with theming.
Usage#
import { RadioButtonGroup } from '@primereact/ui/radiobuttongroup';
import { RadioButton } from '@primereact/ui/radiobutton';<RadioButtonGroup>
<RadioButton.Root>
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
</RadioButtonGroup>Examples#
Group#
Use the RadioButton.Group component with value and onValueChange props to control the selected state of radio buttons.
'use client';
import type { RadioButtonGroupChangeEvent } from '@primereact/types/shared/radiobuttongroup';
import { Label } from '@primereact/ui/label';
import { RadioButton } from '@primereact/ui/radiobutton';
import { RadioButtonGroup } from '@primereact/ui/radiobuttongroup';
import * as React from 'react';
export default function GroupDemo() {
const [ingredient, setIngredient] = React.useState<string | undefined>();
return (
<div className="flex items-center justify-center">
<RadioButtonGroup
className="flex flex-wrap gap-4"
value={ingredient}
onValueChange={(e: RadioButtonGroupChangeEvent) => setIngredient(e.value as string)}
>
<div className="flex items-center gap-2">
<RadioButton.Root inputId="ingredient1" name="pizza" value="cheese">
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<Label htmlFor="ingredient1">Cheese</Label>
</div>
<div className="flex items-center gap-2">
<RadioButton.Root inputId="ingredient2" name="pizza" value="mushroom">
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<Label htmlFor="ingredient2">Mushroom</Label>
</div>
<div className="flex items-center gap-2">
<RadioButton.Root inputId="ingredient3" name="pizza" value="pepper">
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<Label htmlFor="ingredient3">Pepper</Label>
</div>
<div className="flex items-center gap-2">
<RadioButton.Root inputId="ingredient4" name="pizza" value="onion">
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<Label htmlFor="ingredient4">Onion</Label>
</div>
</RadioButtonGroup>
</div>
);
}
Dynamic#
RadioButtons can be generated using a list of values.
'use client';
import type { RadioButtonGroupChangeEvent } from '@primereact/types/shared/radiobuttongroup';
import { Label } from '@primereact/ui/label';
import { RadioButton } from '@primereact/ui/radiobutton';
import { RadioButtonGroup } from '@primereact/ui/radiobuttongroup';
import * as React from 'react';
export default function DynamicDemo() {
const [ingredient, setIngredient] = React.useState<string | undefined>();
const categories = [
{ name: 'Accounting', key: 'A' },
{ name: 'Marketing', key: 'M' },
{ name: 'Production', key: 'P' },
{ name: 'Research', key: 'R' }
];
return (
<div className="flex items-center justify-center">
<RadioButtonGroup
className="flex flex-wrap gap-4"
value={ingredient}
onValueChange={(e: RadioButtonGroupChangeEvent) => setIngredient(e.value as string)}
>
{categories.map((item) => (
<div key={item.key} className="flex items-center gap-2">
<RadioButton.Root inputId={item.key} name="category" value={item.key}>
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<Label htmlFor={item.key}>{item.name}</Label>
</div>
))}
</RadioButtonGroup>
</div>
);
}
Card#
RadioButtons can be displayed in a card style.
Select a payment method:
'use client';
import type { RadioButtonGroupChangeEvent } from '@primereact/types/shared/radiobuttongroup';
import { RadioButton } from '@primereact/ui/radiobutton';
import { RadioButtonGroup } from '@primereact/ui/radiobuttongroup';
import React from 'react';
const CardDemo = () => {
const [selectedCard, setSelectedCard] = React.useState<string | undefined>();
const cards = [
{ id: 'card1', name: '💳 Credit Card', description: 'Pay with Visa, Mastercard, or AMEX.' },
{ id: 'card2', name: '💸 PayPal', description: 'Connect your PayPal account' },
{ id: 'card3', name: '🪙 Crypto', description: 'Pay with Bitcoin or Ethereum.' }
];
return (
<div className="max-w-xs mx-auto">
<h5 className="font-medium">Select a payment method:</h5>
<RadioButtonGroup
value={selectedCard}
onValueChange={(e: RadioButtonGroupChangeEvent) => setSelectedCard(e.value as string)}
className="mt-4 flex flex-col gap-3"
>
{cards.map((card) => (
<label
key={card.id}
htmlFor={card.id}
className={`flex-1 flex items-start gap-2 p-4 rounded-lg border hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors cursor-pointer ${selectedCard === card.id ? 'border-primary' : 'border-surface'}`}
>
<div className="flex-1 flex flex-col gap-2">
<h5 className="font-medium leading-none">{card.name}</h5>
<p className="text-sm text-surface-500">{card.description}</p>
</div>
<RadioButton.Root inputId={card.id} name="card" value={card.id}>
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
</label>
))}
</RadioButtonGroup>
</div>
);
};
export default CardDemo;
Sizes#
Use the size property to change the size of a radio button.
import { Label } from '@primereact/ui/label';
import { RadioButton } from '@primereact/ui/radiobutton';
export default function SizesDemo() {
return (
<div className="flex justify-center">
<div className="flex flex-wrap gap-4">
<div className="flex items-center gap-2">
<RadioButton.Root inputId="size_small" name="size" size="small">
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<Label htmlFor="size_small" className="text-sm">
Small
</Label>
</div>
<div className="flex items-center gap-2">
<RadioButton.Root inputId="size_normal" name="size">
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<Label htmlFor="size_normal" className="">
Normal
</Label>
</div>
<div className="flex items-center gap-2">
<RadioButton.Root inputId="size_large" name="size" size="large">
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<Label htmlFor="size_large" className="text-lg">
Large
</Label>
</div>
</div>
</div>
);
}
Filled#
Specify the filled property to display the component with a higher visual emphasis than the default outlined style.
import { RadioButton } from '@primereact/ui/radiobutton';
export default function FilledDemo() {
return (
<div className="flex items-center justify-center">
<RadioButton.Root variant="filled">
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
</div>
);
}
Disabled#
When the disabled property is present, the element cannot be edited and focused.
import { RadioButtonGroup } from '@primereact/ui/radiobuttongroup';
import { RadioButton } from '@primereact/ui/radiobutton';
export default function DisabledDemo() {
return (
<div className="flex justify-center">
<RadioButtonGroup className="flex items-center gap-2" value="2">
<RadioButton.Root disabled>
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
<RadioButton.Root value="2" disabled>
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
</RadioButtonGroup>
</div>
);
}
Invalid#
Invalid state is displayed using the invalid property to indicate a failed validation. This style is useful when integrating with form validation libraries.
import { RadioButton } from '@primereact/ui/radiobutton';
export default function InvalidDemo() {
return (
<div className="flex justify-center">
<RadioButton.Root invalid>
<RadioButton.Box>
<RadioButton.Indicator />
</RadioButton.Box>
</RadioButton.Root>
</div>
);
}
Accessibility#
Screen Reader#
RadioButton component uses a hidden native radio button element internally that is only visible to screen readers. Value to describe the component can either be provided via label tag combined with id prop or using aria-labelledby, aria-label props.
<label for="rb1">One</label>
<RadioButton inputId="rb1" />
<span id="rb2">Two</span>
<RadioButton aria-labelledby="rb2" />
<RadioButton aria-label="Three" />