Our Tailwind CSS radio button component will let your users choose only one of a predefined set of mutually exclusive options. Radio
buttons should be used instead of checkboxes if only one item can be selected from a list.
Use the following example to create simple Radio
buttons for your projects.
import { Radio } from "@material-tailwind/react";
export function RadioDefault() {
return (
<div className="flex gap-10">
<Radio name="type" label="HTML" />
<Radio name="type" label="React" defaultChecked />
</div>
);
}
The Radio
component comes with 19 different colors that you can change it using the color
prop.
import { Radio } from "@material-tailwind/react";
export function RadioColors() {
return (
<div className="flex w-max gap-4">
<Radio name="color" />
<Radio name="color" color="gray" defaultChecked />
<Radio name="color" color="blue" />
<Radio name="color" color="green" />
<Radio name="color" color="red" />
<Radio name="color" color="amber" />
<Radio name="color" disabled color="purple" />
</div>
);
}
You can add a custom icon for the Radio
button component when it's checked by passing the icon
prop to the Radio
button component.
You can turn on/off the ripple effect for the Radio
button component using the ripple
prop.
import { Radio } from "@material-tailwind/react";
export function RadioRippleEffect() {
return (
<div className="flex gap-10">
<Radio name="type" label="Ripple Effect On" ripple={true} />
<Radio name="type" label="Ripple Effect Off" ripple={false} />
</div>
);
}
You can make a radio button disable by passing the disabled
prop to the Radio
component.
import { Radio } from "@material-tailwind/react";
export function RadioDisabled() {
return (
<div className="flex gap-10">
<Radio name="type" label="HTML" disabled />
<Radio name="type" label="React" disabled defaultChecked />
</div>
);
}
The label
prop for the the radio button can accept dom elements and because of that you can put links or any other dom elements you like to have with your radio button label.
import { Radio, Typography } from "@material-tailwind/react";
export function RadioWithLink() {
return (
<div className="flex flex-col gap-2">
<Radio
name="terms"
label={
<Typography
color="blue-gray"
className="flex font-medium text-blue-gray-500"
>
I agree with HTML
<Typography
as="a"
href="#"
color="blue-gray"
className="hover:text-blueg-gray-900 font-medium transition-colors"
>
terms and conditions
</Typography>
.
</Typography>
}
/>
<Radio
name="terms"
label={
<Typography
color="blue-gray"
className="flex font-medium text-blue-gray-500"
>
I agree with HTML
<Typography
as="a"
href="#"
color="blue-gray"
className="hover:text-blueg-gray-900 font-medium transition-colors"
>
terms and conditions
</Typography>
.
</Typography>
}
/>
</div>
);
}
Use the example below for a more complex usage of radio button with label that contains some description.
import { Radio, Typography } from "@material-tailwind/react";
export function RadioWithDescription() {
return (
<div className="flex flex-col gap-8">
<Radio
name="description"
label={
<div>
<Typography color="blue-gray" className="font-medium">
HTML Version
</Typography>
<Typography variant="small" color="gray" className="font-normal">
@material-tailwind/html, packed with rich components and widgets.
</Typography>
</div>
}
containerProps={{
className: "-mt-5",
}}
/>
<Radio
name="description"
defaultChecked
label={
<div>
<Typography color="blue-gray" className="font-medium">
React Version
</Typography>
<Typography variant="small" color="gray" className="font-normal">
@material-tailwind/react, packed with rich components and widgets.
</Typography>
</div>
}
containerProps={{
className: "-mt-5",
}}
/>
<Radio
name="description"
color="blue"
label={
<div>
<Typography color="blue-gray" className="font-medium">
React Version
</Typography>
<Typography variant="small" color="gray" className="font-normal">
@material-tailwind/react, packed with rich components and widgets.
</Typography>
</div>
}
containerProps={{
className: "-mt-5",
}}
/>
<Radio
name="description"
color="green"
label={
<div>
<Typography color="blue-gray" className="font-medium">
React Version
</Typography>
<Typography variant="small" color="gray" className="font-normal">
@material-tailwind/react, packed with rich components and widgets.
</Typography>
</div>
}
containerProps={{
className: "-mt-5",
}}
/>
<Radio
name="description"
color="red"
label={
<div>
<Typography color="blue-gray" className="font-medium">
React Version
</Typography>
<Typography variant="small" color="gray" className="font-normal">
@material-tailwind/react, packed with rich components and widgets.
</Typography>
</div>
}
containerProps={{
className: "-mt-5",
}}
/>
<Radio
name="description"
color="amber"
label={
<div>
<Typography color="blue-gray" className="font-medium">
React Version
</Typography>
<Typography variant="small" color="gray" className="font-normal">
@material-tailwind/react, packed with rich components and widgets.
</Typography>
</div>
}
containerProps={{
className: "-mt-5",
}}
/>
<Radio
name="description"
disabled
label={
<div>
<Typography color="blue-gray" className="font-medium">
React Version
</Typography>
<Typography variant="small" color="gray" className="font-normal">
@material-tailwind/react, packed with rich components and widgets.
</Typography>
</div>
}
containerProps={{
className: "-mt-5",
}}
/>
</div>
);
}
Use the example below for a vertical list of radio buttons.
Vue.js
Svelte.js
import {
Radio,
Card,
List,
ListItem,
ListItemPrefix,
Typography,
} from "@material-tailwind/react";
export function RadioVerticalList() {
return (
<Card>
<List>
<ListItem className="p-0">
<label
htmlFor="vertical-list-react"
className="flex w-full cursor-pointer items-center px-3 py-2"
>
<ListItemPrefix className="mr-3">
<Radio
name="vertical-list"
id="vertical-list-react"
ripple={false}
className="hover:before:opacity-0"
containerProps={{
className: "p-0",
}}
/>
</ListItemPrefix>
<Typography
color="blue-gray"
className="font-medium text-blue-gray-400"
>
React.js
</Typography>
</label>
</ListItem>
<ListItem className="p-0">
<label
htmlFor="vertical-list-vue"
className="flex w-full cursor-pointer items-center px-3 py-2"
>
<ListItemPrefix className="mr-3">
<Radio
name="vertical-list"
id="vertical-list-vue"
ripple={false}
className="hover:before:opacity-0"
containerProps={{
className: "p-0",
}}
/>
</ListItemPrefix>
<Typography
color="blue-gray"
className="font-medium text-blue-gray-400"
>
Vue.js
</Typography>
</label>
</ListItem>
<ListItem className="p-0">
<label
htmlFor="vertical-list-svelte"
className="flex w-full cursor-pointer items-center px-3 py-2"
>
<ListItemPrefix className="mr-3">
<Radio
name="vertical-list"
id="vertical-list-svelte"
ripple={false}
className="hover:before:opacity-0"
containerProps={{
className: "p-0",
}}
/>
</ListItemPrefix>
<Typography
color="blue-gray"
className="font-medium text-blue-gray-400"
>
Svelte.js
</Typography>
</label>
</ListItem>
</List>
</Card>
);
}
Use the example below for a horizontal list of radio buttons.
React.js
Vue.js
Svelte.js
import {
Radio,
Card,
List,
ListItem,
ListItemPrefix,
Typography,
} from "@material-tailwind/react";
export function RadioHorizontalList() {
return (
<Card className="w-full max-w-[24rem]">
<List className="flex-row">
<ListItem className="p-0">
<label
htmlFor="horizontal-list-react"
className="flex w-full cursor-pointer items-center px-3 py-2"
>
<ListItemPrefix className="mr-3">
<Radio
name="horizontal-list"
id="horizontal-list-react"
ripple={false}
className="hover:before:opacity-0"
containerProps={{
className: "p-0",
}}
/>
</ListItemPrefix>
<Typography
color="blue-gray"
className="font-medium text-blue-gray-400"
>
React.js
</Typography>
</label>
</ListItem>
<ListItem className="p-0">
<label
htmlFor="horizontal-list-vue"
className="flex w-full cursor-pointer items-center px-3 py-2"
>
<ListItemPrefix className="mr-3">
<Radio
name="horizontal-list"
id="horizontal-list-vue"
ripple={false}
className="hover:before:opacity-0"
containerProps={{
className: "p-0",
}}
/>
</ListItemPrefix>
<Typography
color="blue-gray"
className="font-medium text-blue-gray-400"
>
Vue.js
</Typography>
</label>
</ListItem>
<ListItem className="p-0">
<label
htmlFor="horizontal-list-svelte"
className="flex w-full cursor-pointer items-center px-3 py-2"
>
<ListItemPrefix className="mr-3">
<Radio
name="horizontal-list"
id="horizontal-list-svelte"
ripple={false}
className="hover:before:opacity-0"
containerProps={{
className: "p-0",
}}
/>
</ListItemPrefix>
<Typography
color="blue-gray"
className="font-medium text-blue-gray-400"
>
Svelte.js
</Typography>
</label>
</ListItem>
</List>
</Card>
);
}
You can use the className
prop to add custom styles to the Radio
component.
React
React
import { Radio, Typography } from "@material-tailwind/react";
function Icon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
className="h-full w-full scale-105"
>
<path
fillRule="evenodd"
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm13.36-1.814a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z"
clipRule="evenodd"
/>
</svg>
);
}
export function RadioCustomStyles() {
return (
<div className="flex gap-10">
<Radio
name="type"
ripple={false}
icon={<Icon />}
className="border-gray-900/10 bg-gray-900/5 p-0 transition-all hover:before:opacity-0"
label={
<Typography
color="blue-gray"
className="font-normal text-blue-gray-400"
>
React
</Typography>
}
/>
<Radio
name="type"
defaultChecked
ripple={false}
icon={<Icon />}
className="border-gray-900/10 bg-gray-900/5 p-0 transition-all hover:before:opacity-0"
label={
<Typography
color="blue-gray"
className="font-normal text-blue-gray-400"
>
React
</Typography>
}
/>
</div>
);
}
The following props are available for radio button component. These are the custom props that we've added for the radio button component and you can use all the other native input props as well.
Attribute | Type | Description | Default |
---|---|---|---|
color | Color | Change radio button color | gray |
label | node | Add label for radio button | undefined |
icon | node | Change checked icon for radio button | undefined |
ripple | boolean | Add ripple effect for radio button | true |
className | string | Add custom className for radio button | '' |
disabled | boolean | Makes the radio button disabled | false |
containerProps | object | Add custom props for radio button container | undefined |
labelProps | object | Add custom props for radio button label | undefined |
iconProps | object | Add custom props for radio button icon | undefined |
inputRef | ref | Add reference for input element. | undefined |
import type { RadioProps } from "@material-tailwind/react";
type color =
| "blue-gray"
| "gray"
| "brown"
| "deep-orange"
| "orange"
| "amber"
| "yellow"
| "lime"
| "light-green"
| "green"
| "teal"
| "cyan"
| "light-blue"
| "blue"
| "indigo"
| "deep-purple"
| "purple"
| "pink"
| "red";
Learn how to customize the theme and styles for radio button component, the theme object for radio button component has three main objects:
A. The defaultProps
object for setting up the default value for props of radio button component.
B. The valid
object for customizing the valid values for radio button component props.
C. The styles
object for customizing the theme and styles of radio button component.
You can customize the theme and styles of radio button component by adding Tailwind CSS classes as key paired values for objects.
interface RadioStylesType {
defaultProps: {
color: string;
label: string;
icon: node;
ripple: boolean;
className: string;
disabled: boolean;
containerProps: object;
labelProps: object;
iconProps: object;
};
valid: {
colors: string[];
};
styles: {
base: {
root: object;
container: object;
input: object;
label: object;
icon: object;
disabled: object;
};
colors: object;
};
}
import type { RadioStylesType } from "@material-tailwind/react";
const theme = {
radio: {
defaultProps: {
color: "blue",
label: undefined,
icon: undefined,
ripple: true,
className: "",
disabled: false,
containerProps: undefined,
labelProps: undefined,
iconProps: undefined,
},
valid: {
colors: [
"blue-gray",
"gray",
"brown",
"deep-orange",
"orange",
"amber",
"yellow",
"lime",
"light-green",
"green",
"teal",
"cyan",
"light-blue",
"blue",
"indigo",
"deep-purple",
"purple",
"pink",
"red",
],
},
styles: {
base: {
root: {
display: "inline-flex",
alignItems: "items-center",
},
container: {
position: "relative",
display: "flex",
alignItems: "items-center",
cursor: "cursor-pointer",
p: "p-3",
borderRadius: "rounded-full",
},
input: {
peer: "peer",
position: "relative",
appearance: "appearance-none",
width: "w-5",
height: "h-5",
borderWidth: "border",
borderRadius: "rounded-full",
borderColor: "border-blue-gray-200",
cursor: "cursor-pointer",
transition: "transition-all",
before: {
content: "before:content['']",
display: "before:block",
bg: "before:bg-blue-gray-500",
width: "before:w-12",
height: "before:h-12",
borderRadius: "before:rounded-full",
position: "before:absolute",
top: "before:top-2/4",
left: "before:left-2/4",
transform: "before:-translate-y-2/4 before:-translate-x-2/4",
opacity: "before:opacity-0 hover:before:opacity-10",
transition: "before:transition-opacity",
},
},
label: {
color: "text-gray-700",
fontWeight: "font-light",
userSelect: "select-none",
cursor: "cursor-pointer",
mt: "mt-px",
},
icon: {
position: "absolute",
top: "top-2/4",
left: "left-2/4",
translate: "-translate-y-2/4 -translate-x-2/4",
pointerEvents: "pointer-events-none",
opacity: "opacity-0 peer-checked:opacity-100",
transition: "transition-opacity",
},
disabled: {
opacity: "opacity-50",
pointerEvents: "pointer-events-none",
},
},
colors: {
"blue-gray": {
color: "text-blue-gray-500",
border: "checked:border-blue-gray-500",
before: "checked:before:bg-blue-gray-500",
},
gray: {
color: "text-gray-500",
border: "checked:border-gray-500",
before: "checked:before:bg-gray-500",
},
brown: {
color: "text-brown-500",
border: "checked:border-brown-500",
before: "checked:before:bg-brown-500",
},
"deep-orange": {
color: "text-deep-orange-500",
border: "checked:border-deep-orange-500",
before: "checked:before:bg-deep-orange-500",
},
orange: {
color: "text-orange-500",
border: "checked:border-orange-500",
before: "checked:before:bg-orange-500",
},
amber: {
color: "text-amber-500",
border: "checked:border-amber-500",
before: "checked:before:bg-amber-500",
},
yellow: {
color: "text-yellow-500",
border: "checked:border-yellow-500",
before: "checked:before:bg-yellow-500",
},
lime: {
color: "text-lime-500",
border: "checked:border-lime-500",
before: "checked:before:bg-lime-500",
},
"light-green": {
color: "text-light-green-500",
border: "checked:border-light-green-500",
before: "checked:before:bg-light-green-500",
},
green: {
color: "text-green-500",
border: "checked:border-green-500",
before: "checked:before:bg-green-500",
},
teal: {
color: "text-teal-500",
border: "checked:border-teal-500",
before: "checked:before:bg-teal-500",
},
cyan: {
color: "text-cyan-500",
border: "checked:border-cyan-500",
before: "checked:before:bg-cyan-500",
},
"light-blue": {
color: "text-light-blue-500",
border: "checked:border-light-blue-500",
before: "checked:before:bg-light-blue-500",
},
blue: {
color: "text-blue-500",
border: "checked:border-blue-500",
before: "checked:before:bg-blue-500",
},
indigo: {
color: "text-indigo-500",
border: "checked:border-indigo-500",
before: "checked:before:bg-indigo-500",
},
"deep-purple": {
color: "text-deep-purple-500",
border: "checked:border-deep-purple-500",
before: "checked:before:bg-deep-purple-500",
},
purple: {
color: "text-purple-500",
border: "checked:border-purple-500",
before: "checked:before:bg-purple-500",
},
pink: {
color: "text-pink-500",
border: "checked:border-pink-500",
before: "checked:before:bg-pink-500",
},
red: {
color: "text-red-500",
border: "checked:border-red-500",
before: "checked:before:bg-red-500",
},
},
},
},
};