Skip to main content

Radio

The Radio component allows users to select a single option from a group. It supports slots, RadioGroup context, motion animations, and custom icons.

Below are live previews of common patterns, followed by JavaScript and TypeScript code samples in tabs.

Basic usage

import * as React from "react";
import { Radio } from "@libdev-ui/base";

export default function BasicRadioDemo(): JSX.Element {
return (
<>
<Radio name="basic" value="a" label="Option A" defaultChecked />
<Radio name="basic" value="b" label="Option B" />
</>
);
}

Controlled group

Selected: b

import * as React from "react";
import { Radio, RadioGroup, Text, Box } from "@libdev-ui/base";

export default function ControlledGroupDemo(): JSX.Element {
const [value, setValue] = React.useState<string>("b");
return (
<Box sl={{ display: "flex", flexDirection: "column", gap: 8 }}>
<Text>Selected: <strong>{value}</strong></Text>
<RadioGroup name="letters" value={value} onChange={(_, v) => setValue(String(v))} orientation="horizontal">
<Radio value="a" label="A" />
<Radio value="b" label="B" />
<Radio value="c" label="C" />
</RadioGroup>
</Box>
);
}

Custom icons

import * as React from "react";
import { Radio, RadioGroup } from "@libdev-ui/base";

const Hollow: React.FC = () => <span style={{ display: "inline-block", width: 14, height: 14, border: "2px solid currentColor", borderRadius: "50%" }} />;
const Dot: React.FC = () => <span style={{ display: "inline-block", width: 10, height: 10, background: "currentColor", borderRadius: "50%" }} />;

export default function CustomIconsDemo(): JSX.Element {
const [value, setValue] = React.useState<string>("dot");
return (
<RadioGroup name="icons" value={value} onChange={(_, v) => setValue(String(v))} orientation="horizontal">
<Radio value="hollow" label="Hollow" uncheckedIcon={<Hollow />} checkedIcon={<Hollow />} />
<Radio value="dot" label="Dot" uncheckedIcon={<Hollow />} checkedIcon={<Dot />} />
<Radio value="dot-only" label="Dot (no unchecked)" checkedIcon={<Dot />} />
</RadioGroup>
);
}

Sizes

import * * as React from "react";
import { Radio, RadioGroup, Grid } from "@libdev-ui/base";

export default function RadioSizesDemo(): JSX.Element {
return (
<Grid columns={3} gap={12}>
<RadioGroup name="sizes-sm" orientation="horizontal">
<Radio size="sm" value="1" label="Small 1" defaultChecked />
<Radio size="sm" value="2" label="Small 2" />
</RadioGroup>
<RadioGroup name="sizes-md" orientation="horizontal">
<Radio size="md" value="1" label="Medium 1" defaultChecked />
<Radio size="md" value="2" label="Medium 2" />
</RadioGroup>
<RadioGroup name="sizes-lg" orientation="horizontal">
<Radio size="lg" value="1" label="Large 1" defaultChecked />
<Radio size="lg" value="2" label="Large 2" />
</RadioGroup>
</Grid>
);
}

Variants & Colors

Variant: outlined

Variant: plain

Variant: soft

Variant: solid

import * as React from "react";
import { Radio, RadioGroup, Grid, Text } from "@libdev-ui/base";

export default function RadioVariantsColorsDemo(): JSX.Element {
const variants: Array<"outlined" | "plain" | "soft" | "solid"> = ["outlined","plain","soft","solid"];
const colors: Array<"primary" | "secondary" | "success" | "danger" | "warning" | "info"> = ["primary","secondary","success","danger","warning","info"];
return (
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
{variants.map((variant) => (
<div key={variant} style={{ display: "flex", flexDirection: "column", gap: 8 }}>
<Text sl={{ fontWeight: 600 }}>Variant: {variant}</Text>
<Grid columns={3} gap={12}>
{colors.map((color) => (
<RadioGroup key={variant + "-" + color} name={variant + "-" + color} variant={variant} color={color} defaultValue="2" orientation="horizontal">
<Radio value="1" label={"1 (" + color + ")"} />
<Radio value="2" label="2" />
<Radio value="3" label="3" />
</RadioGroup>
))}
</Grid>
</div>
))}
</div>
);
}

Props

Radio

PropTypeDefaultDescription
checkedbooleanIf true, the component is checked.
defaultCheckedbooleanThe default checked state (uncontrolled).
valueanyThe value of the component.
labelReactNodeLabel element displayed next to the radio.
namestringName attribute of the input.
color'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | string'primary'Color token.
variant'outlined' | 'plain' | 'soft' | 'solid' | string'outlined'Visual variant.
size'sm' | 'md' | 'lg' | string'md'Size token.
disabledbooleanfalseIf true, the component is disabled.
readOnlybooleanfalseIf true, the component is read-only.
requiredbooleanfalseIf true, the input element is required.
autoFocusbooleanfalseAutofocus on mount.
overlaybooleanfalseAction area fills the nearest positioned parent.
disableIconbooleanfalseRemoves the icon and applies selected variant on action.
checkedIconReactNodeIcon to display when checked.
uncheckedIconReactNodeIcon to display when not checked.
onChange(event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => voidFired when state changes.
slotProps{ root?, action?, icon?, input?, label?, radio? }{}Props for each slot.
slots{ root?, action?, icon?, input?, label?, radio? }{}Components for each slot.
slSystemStyleSystem overrides / additional CSS.

RadioGroup

PropTypeDefaultDescription
valueanyThe selected value.
defaultValueanyThe default value (uncontrolled).
onChange(event: React.ChangeEvent<HTMLInputElement>, value: any) => voidFired when selection changes.
namestringName applied to child radios.
orientation'horizontal' | 'vertical''vertical'Layout direction.
overlaybooleanfalsePasses overlay to children.
disableIconbooleanfalsePasses disableIcon to children.
size'sm' | 'md' | 'lg' | string'md'Default size for children.
color'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | string'primary'Default color for children.
variant'outlined' | 'plain' | 'soft' | 'solid' | string'plain'Default variant for children.
disabledbooleanfalseDisables all child radios.
readOnlybooleanfalseMakes all child radios read-only.
slotProps{ root? }{}Props for root slot.
slots{ root? }{}Components for root slot.