Installation
npm install @kuzenbo/core @kuzenbo/theme
Usage
import { RadioGroup } from "@kuzenbo/core";
import { Label } from "@kuzenbo/core";
function App() {
return (
<RadioGroup defaultValue="monthly">
<Label className="flex items-center gap-2">
<RadioGroup.Item value="monthly" />
Monthly billing
</Label>
<Label className="flex items-center gap-2">
<RadioGroup.Item value="annual" />
Annual billing
</Label>
</RadioGroup>
);
}
Examples
Controlled RadioGroup
Manage selection state with React.
import { RadioGroup } from "@kuzenbo/core";
import { Label } from "@kuzenbo/core";
import { useState } from "react";
function ControlledExample() {
const [billingCycle, setBillingCycle] = useState("annual");
return (
<div className="grid gap-2">
<RadioGroup value={billingCycle} onValueChange={setBillingCycle}>
<Label className="flex items-center gap-2">
<RadioGroup.Item value="monthly" />
Monthly ($49 per seat)
</Label>
<Label className="flex items-center gap-2">
<RadioGroup.Item value="annual" />
Annual ($39 per seat - 20% savings)
</Label>
<Label className="flex items-center gap-2">
<RadioGroup.Item value="multi-year" />
24-month agreement ($34 per seat)
</Label>
</RadioGroup>
<p className="text-muted-foreground text-sm">
Selected: {billingCycle}
</p>
</div>
);
}
Sizes
Radio items are available in five size variants.
import { RadioGroup } from "@kuzenbo/core";
import { Label } from "@kuzenbo/core";
function SizesExample() {
return (
<div className="grid gap-4">
<RadioGroup defaultValue="xs-standard">
<Label className="flex items-center gap-2">
<RadioGroup.Item size="xs" value="xs-standard" />
XS standard review
</Label>
</RadioGroup>
<RadioGroup defaultValue="sm-standard">
<Label className="flex items-center gap-2">
<RadioGroup.Item size="sm" value="sm-standard" />
SM standard review
</Label>
</RadioGroup>
<RadioGroup defaultValue="md-standard">
<Label className="flex items-center gap-2">
<RadioGroup.Item size="md" value="md-standard" />
MD standard review
</Label>
</RadioGroup>
<RadioGroup defaultValue="lg-standard">
<Label className="flex items-center gap-2">
<RadioGroup.Item size="lg" value="lg-standard" />
LG standard review
</Label>
</RadioGroup>
<RadioGroup defaultValue="xl-standard">
<Label className="flex items-center gap-2">
<RadioGroup.Item size="xl" value="xl-standard" />
XL standard review
</Label>
</RadioGroup>
</div>
);
}
Disabled Option
Individual radio items can be disabled.
import { RadioGroup } from "@kuzenbo/core";
import { Label } from "@kuzenbo/core";
function DisabledOptionExample() {
return (
<RadioGroup defaultValue="monthly">
<Label className="flex items-center gap-2">
<RadioGroup.Item value="monthly" />
Monthly invoicing
</Label>
<Label className="flex items-center gap-2">
<RadioGroup.Item value="quarterly" />
Quarterly invoicing
</Label>
<Label className="flex items-center gap-2">
<RadioGroup.Item value="annual" disabled />
Annual invoicing (requires legal sign-off)
</Label>
</RadioGroup>
);
}
Horizontal Layout
Use flexbox or grid to arrange radio items horizontally.
import { RadioGroup } from "@kuzenbo/core";
import { Label } from "@kuzenbo/core";
function HorizontalLayoutExample() {
return (
<RadioGroup
className="grid grid-cols-3 gap-2"
defaultValue="us"
>
<Label className="border-border flex items-center gap-2 rounded-md border px-3 py-2">
<RadioGroup.Item value="us" />
US
</Label>
<Label className="border-border flex items-center gap-2 rounded-md border px-3 py-2">
<RadioGroup.Item value="eu" />
EU
</Label>
<Label className="border-border flex items-center gap-2 rounded-md border px-3 py-2">
<RadioGroup.Item value="apac" />
APAC
</Label>
</RadioGroup>
);
}
Custom Indicator
Customize the radio indicator appearance.
import { RadioGroup } from "@kuzenbo/core";
import { Label } from "@kuzenbo/core";
function CustomIndicatorExample() {
return (
<RadioGroup defaultValue="finance">
<div className="flex items-center gap-2">
<RadioGroup.Item value="finance">
<RadioGroup.Indicator>
<span className="bg-primary block size-2 rounded-full" />
</RadioGroup.Indicator>
</RadioGroup.Item>
<Label>Finance-led approval path</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroup.Item value="operations">
<RadioGroup.Indicator>
<span className="bg-primary block size-2 rounded-full" />
</RadioGroup.Indicator>
</RadioGroup.Item>
<Label>Operations-led approval path</Label>
</div>
</RadioGroup>
);
}
Props
RadioGroup
RadioGroup extends Base UI RadioGroup props.
Controlled value of the selected radio item.
Default selected value for uncontrolled usage.
Callback fired when the selected value changes.
Additional CSS classes to apply to the radio group container.
Radio items and other content.
RadioGroup.Item
RadioGroup.Item extends Base UI Radio props.
The value of this radio item.
Size variant of the radio item.Options: "xs" | "sm" | "md" | "lg" | "xl"
When true, disables this radio item.
Additional CSS classes to apply to the radio item.
Custom indicator content. Defaults to a filled circle indicator.
Subcomponents
RadioGroup.Indicator
The visual indicator shown when the radio item is selected.
<RadioGroup.Item value="option">
<RadioGroup.Indicator size="xs">
<CustomDotIcon />
</RadioGroup.Indicator>
</RadioGroup.Item>
TypeScript
import type {
RadioGroupProps,
RadioGroupItemProps,
RadioGroupIndicatorProps,
} from "@kuzenbo/core";
const CustomRadioGroup = <T,>(props: RadioGroupProps<T>) => {
return <RadioGroup {...props} />;
};
Accessibility
- RadioGroup uses semantic ARIA radiogroup role
- Radio items use ARIA radio role
- Supports keyboard navigation with arrow keys
- Only one item can be selected at a time
- Disabled items are skipped in keyboard navigation
- Proper focus management and visual focus indicators