Components
Radio
A parts-based radio component with an options-driven group — arrow-key navigation comes native via the shared name
Installation
- $npx litefy@latest add radio
- $pnpm dlx litefy@latest add radio
- $yarn dlx litefy@latest add radio
- $bun --bun litefy@latest add radio
Usage
Basic radio buttons with individual and group modes.
import { Radio } from "@/ui";export default function RadioBasicDemo() { return ( <Radio.Group name="group-example" options={[ { label: "Option 1", value: "group1" }, { label: "Option 2", value: "group2" }, { label: "Option 3", value: "group3" }, ]} /> );}Disabled
Shows a disabled radio.
"use client";
import { Radio } from "@/ui";
export default function RadioDisabledDemo() {
return (
<Radio name="radio-disabled" disabled>
Disabled
</Radio>
);
}
Custom
Assemble the parts directly — RadioRoot must be nested inside RadioIndicator, and a shared name turns separately assembled roots into a native radio group.
"use client";
import { useState } from "react";
import { RadioLabel, RadioIndicator, RadioRoot } from "@/ui";
import { Check } from "lucide-react";
const SIZES = ["Small", "Medium", "Large"];
export default function Demo() {
const [size, setSize] = useState("Medium");
return (
<div className="flex flex-col gap-2">
{SIZES.map((val) => (
<RadioLabel key={val}>
<RadioIndicator className="has-checked:bg-primary">
<RadioRoot
name="size"
checked={size === val}
onChange={() => setSize(val)}
/>
<Check className="size-3 text-primary-foreground opacity-0 transition-opacity peer-checked:opacity-100" />
</RadioIndicator>
<span>{val}</span>
</RadioLabel>
))}
</div>
);
}
API Reference
Radio
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - | The radio content |
checked | boolean | false | Controlled checked state |
defaultChecked | boolean | false | Default checked state (uncontrolled) |
onCheckedChange | (checked: boolean) => void | - | Callback when the radio is checked |
indicator | React.ReactNode | - | Custom indicator content, replacing the default dot |
classNames | { indicator?; label? } | - | Custom classes for the indicator and label |
styles | { indicator?; label? } | - | Inline styles for the indicator and label |
className | ClassNameValue | - | Custom classes, applied to the label |
...props | React.ComponentProps<"input"> | - | Supports all native input props (except type, className), such as name, value, disabled |
Composable Components
RadioRoot
The bare radio input (sr-only peer) — selection state is read from it via has-checked: / peer-checked: variants.
RadioIndicator
The circular indicator. Focus ring (has-focus-visible:) and checked border (has-checked:) are built in.
RadioLabel
The label wrapper (clicking it toggles the radio).
RadioOptionConfig
| Field | Type | Default | Description |
|---|---|---|---|
label | string | - | Option display text |
value | string | - | Unique identifier value |
disabled | boolean | false | Disable the option |
indicator | React.ReactNode | - | Custom indicator, overrides common.indicator |
classNames / styles | - | - | Per-option part styles, override common |
Radio.Group
| Prop | Type | Default | Description |
|---|---|---|---|
options | RadioOptionConfig[] | - | Options data array |
value | string | - | Controlled selected value |
defaultValue | string | - | Default selected value (uncontrolled) |
onValueChange | (value: string) => void | - | Callback when the selected value changes |
disabled | boolean | false | Disable all options |
name | string | - | Group name — also enables the native arrow-key navigation between options |
className | ClassNameValue | - | Custom class names, applied to the container |
aria-label | string | - | Accessible group label |
common | { classNames?, styles?, indicator? } | - | Common config applied to all options |