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
- TypeScript
- JavaScript
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" />
</>
);
}
import { Radio } from "@libdev-ui/base";
import React from "react";
export default function BasicRadioDemo() {
return (
<>
<Radio name="basic" value="a" label="Option A" defaultChecked />
<Radio name="basic" value="b" label="Option B" />
</>
);
}
Controlled group
Selected: b
- TypeScript
- JavaScript
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>
);
}
import { Radio, RadioGroup, Text, Box } from "@libdev-ui/base";
import React from "react";
export default function ControlledGroupDemo() {
const [value, setValue] = React.useState("b");
return (
<Box sl={{ display: "flex", flexDirection: "column", gap: 8 }}>
<Text>Selected: <strong>{value}</strong></Text>
<RadioGroup name="letters" value={value} onChange={(_, v) => setValue(v)} orientation="horizontal">
<Radio value="a" label="A" />
<Radio value="b" label="B" />
<Radio value="c" label="C" />
</RadioGroup>
</Box>
);
}
Custom icons
- TypeScript
- JavaScript
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>
);
}
import { Radio, RadioGroup } from "@libdev-ui/base";
import React from "react";
const Hollow = () => <span style={{ display: "inline-block", width: 14, height: 14, border: "2px solid currentColor", borderRadius: "50%" }} />;
const Dot = () => <span style={{ display: "inline-block", width: 10, height: 10, background: "currentColor", borderRadius: "50%" }} />;
export default function CustomIconsDemo() {
const [value, setValue] = React.useState("dot");
return (
<RadioGroup name="icons" value={value} onChange={(_, v) => setValue(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
- TypeScript
- JavaScript
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>
);
}
import { Radio, RadioGroup, Grid } from "@libdev-ui/base";
import React from "react";
export default function RadioSizesDemo() {
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
- TypeScript
- JavaScript
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>
);
}
import { Radio, RadioGroup, Grid, Text } from "@libdev-ui/base";
import React from "react";
export default function RadioVariantsColorsDemo() {
const variants = ["outlined","plain","soft","solid"];
const colors = ["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
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | — | If true, the component is checked. |
defaultChecked | boolean | — | The default checked state (uncontrolled). |
value | any | — | The value of the component. |
label | ReactNode | — | Label element displayed next to the radio. |
name | string | — | Name 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. |
disabled | boolean | false | If true, the component is disabled. |
readOnly | boolean | false | If true, the component is read-only. |
required | boolean | false | If true, the input element is required. |
autoFocus | boolean | false | Autofocus on mount. |
overlay | boolean | false | Action area fills the nearest positioned parent. |
disableIcon | boolean | false | Removes the icon and applies selected variant on action. |
checkedIcon | ReactNode | — | Icon to display when checked. |
uncheckedIcon | ReactNode | — | Icon to display when not checked. |
onChange | (event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => void | — | Fired 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. |
sl | SystemStyle | — | System overrides / additional CSS. |
RadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
value | any | — | The selected value. |
defaultValue | any | — | The default value (uncontrolled). |
onChange | (event: React.ChangeEvent<HTMLInputElement>, value: any) => void | — | Fired when selection changes. |
name | string | — | Name applied to child radios. |
orientation | 'horizontal' | 'vertical' | 'vertical' | Layout direction. |
overlay | boolean | false | Passes overlay to children. |
disableIcon | boolean | false | Passes 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. |
disabled | boolean | false | Disables all child radios. |
readOnly | boolean | false | Makes all child radios read-only. |
slotProps | { root? } | {} | Props for root slot. |
slots | { root? } | {} | Components for root slot. |