Skip to content

RadioGroup

A set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time.

Code
import { Label, RadioGroup, RadioGroupItem } from "@falcon/ui-kit";
export function Example() {
return (
<RadioGroup
aria-label="Order handling"
defaultValue="comfortable"
className="tw:w-fit"
>
<div className="tw:flex tw:items-center tw:gap-3">
<RadioGroupItem value="default" id="r1" />
<Label htmlFor="r1">Default</Label>
</div>
<div className="tw:flex tw:items-center tw:gap-3">
<RadioGroupItem value="comfortable" id="r2" />
<Label htmlFor="r2">Comfortable</Label>
</div>
<div className="tw:flex tw:items-center tw:gap-3">
<RadioGroupItem value="compact" id="r3" />
<Label htmlFor="r3">Compact</Label>
</div>
</RadioGroup>
);
}

Use the following composition to build a RadioGroup:

RadioGroup
├── RadioGroupItem
└── RadioGroupItem

Radio group items with a description using the Field component.

Code
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
RadioGroup,
RadioGroupItem,
} from "@falcon/ui-kit";
export function Example() {
return (
<RadioGroup
aria-label="Order handling"
defaultValue="comfortable"
className="tw:w-fit"
>
<Field orientation="horizontal">
<RadioGroupItem value="default" id="desc-r1" />
<FieldContent>
<FieldLabel htmlFor="desc-r1">Default</FieldLabel>
<FieldDescription>
Standard spacing for most use cases.
</FieldDescription>
</FieldContent>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="comfortable" id="desc-r2" />
<FieldContent>
<FieldLabel htmlFor="desc-r2">Comfortable</FieldLabel>
<FieldDescription>More space between elements.</FieldDescription>
</FieldContent>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="compact" id="desc-r3" />
<FieldContent>
<FieldLabel htmlFor="desc-r3">Compact</FieldLabel>
<FieldDescription>
Minimal spacing for dense layouts.
</FieldDescription>
</FieldContent>
</Field>
</RadioGroup>
);
}

Use FieldLabel to wrap the entire Field for a clickable card-style selection.

Code
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
FieldTitle,
RadioGroup,
RadioGroupItem,
} from "@falcon/ui-kit";
export function Example() {
return (
<RadioGroup
aria-label="Delivery method"
defaultValue="pickup"
className="tw:max-w-sm"
>
<FieldLabel htmlFor="pickup-method">
<Field orientation="horizontal">
<FieldContent>
<FieldTitle>Customer pickup</FieldTitle>
<FieldDescription>
Collect from the selected branch.
</FieldDescription>
</FieldContent>
<RadioGroupItem value="pickup" id="pickup-method" />
</Field>
</FieldLabel>
<FieldLabel htmlFor="standard-delivery-method">
<Field orientation="horizontal">
<FieldContent>
<FieldTitle>Standard delivery</FieldTitle>
<FieldDescription>
Deliver on the next available route.
</FieldDescription>
</FieldContent>
<RadioGroupItem value="standard" id="standard-delivery-method" />
</Field>
</FieldLabel>
<FieldLabel htmlFor="scheduled-delivery-method">
<Field orientation="horizontal">
<FieldContent>
<FieldTitle>Scheduled delivery</FieldTitle>
<FieldDescription>Deliver on the requested date.</FieldDescription>
</FieldContent>
<RadioGroupItem value="scheduled" id="scheduled-delivery-method" />
</Field>
</FieldLabel>
</RadioGroup>
);
}

Use FieldSet and FieldLegend to group radio items with a label and description.

Code
import {
Field,
FieldDescription,
FieldLabel,
FieldLegend,
FieldSet,
RadioGroup,
RadioGroupItem,
} from "@falcon/ui-kit";
export function Example() {
return (
<FieldSet className="tw:w-full tw:max-w-xs">
<FieldLegend id="payment-terms-legend" variant="label">
Payment terms
</FieldLegend>
<FieldDescription>Select the terms for this order.</FieldDescription>
<RadioGroup aria-labelledby="payment-terms-legend" defaultValue="net-30">
<Field orientation="horizontal">
<RadioGroupItem value="prepaid" id="terms-prepaid" />
<FieldLabel htmlFor="terms-prepaid" className="tw:font-normal">
Prepaid
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="net-30" id="terms-net-30" />
<FieldLabel htmlFor="terms-net-30" className="tw:font-normal">
Net 30
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="net-60" id="terms-net-60" />
<FieldLabel htmlFor="terms-net-60" className="tw:font-normal">
Net 60
</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>
);
}

Use the disabled prop on RadioGroupItem to disable an item.

Code
import { Field, FieldLabel, RadioGroup, RadioGroupItem } from "@falcon/ui-kit";
export function Example() {
return (
<RadioGroup
aria-label="Fulfillment speed"
defaultValue="priority"
className="tw:w-fit"
>
<Field orientation="horizontal" data-disabled>
<RadioGroupItem value="same-day" id="disabled-same-day" disabled />
<FieldLabel htmlFor="disabled-same-day" className="tw:font-normal">
Same-day (unavailable)
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="priority" id="disabled-priority" />
<FieldLabel htmlFor="disabled-priority" className="tw:font-normal">
Priority
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="standard" id="disabled-standard" />
<FieldLabel htmlFor="disabled-standard" className="tw:font-normal">
Standard
</FieldLabel>
</Field>
</RadioGroup>
);
}

Use aria-invalid on RadioGroupItem and data-invalid on Field to show validation errors.

Code
import {
Field,
FieldDescription,
FieldLabel,
FieldLegend,
FieldSet,
RadioGroup,
RadioGroupItem,
} from "@falcon/ui-kit";
export function Example() {
return (
<FieldSet className="tw:w-full tw:max-w-xs">
<FieldLegend id="notification-preferences-legend" variant="label">
Notification preferences
</FieldLegend>
<FieldDescription>
Choose how you want to receive order updates.
</FieldDescription>
<RadioGroup
aria-labelledby="notification-preferences-legend"
defaultValue="email"
>
<Field orientation="horizontal" data-invalid>
<RadioGroupItem value="email" id="invalid-email" aria-invalid />
<FieldLabel htmlFor="invalid-email" className="tw:font-normal">
Email only
</FieldLabel>
</Field>
<Field orientation="horizontal" data-invalid>
<RadioGroupItem value="sms" id="invalid-sms" aria-invalid />
<FieldLabel htmlFor="invalid-sms" className="tw:font-normal">
Text message only
</FieldLabel>
</Field>
<Field orientation="horizontal" data-invalid>
<RadioGroupItem value="both" id="invalid-both" aria-invalid />
<FieldLabel htmlFor="invalid-both" className="tw:font-normal">
Both email and text message
</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>
);
}

Groups related radio items. Renders a <div> element.

className?: string | ((state: RadioGroupState) => string | undefined)

CSS class applied to the group, or a function based on its state.

defaultValue?: TValue

The initially selected value. Use value for controlled state.

disabled?: boolean

Whether the group ignores user interaction. Defaults to false.

form?: string

Identifies the form that owns the radio inputs.

inputRef?: React.Ref<HTMLInputElement>

Ref to the hidden input element.

name?: string

Identifies the group when a form is submitted.

onValueChange?: ((value: TValue, eventDetails: RadioGroupPrimitive.ChangeEventDetails) => void)

Event handler called when the selected value changes.

readOnly?: boolean

Whether users can select a different radio item. Defaults to false.

render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, RadioGroupState>

Allows replacing the group element or composing it with another component.

required?: boolean

Whether users must choose a value before submitting the form. Defaults to false.

style?: React.CSSProperties | ((state: RadioGroupState) => React.CSSProperties | undefined)

Style applied to the group, or a function based on its state.

value?: TValue

The currently selected value. Use defaultValue for uncontrolled state.

Represents a radio item within a group. Renders a <span> element and hidden <input>.

className?: string | ((state: RadioRootState) => string | undefined)

CSS class applied to the radio, or a function based on its state.

disabled?: boolean

Whether the radio ignores user interaction.

inputRef?: React.Ref<HTMLInputElement>

Ref to the radio’s hidden input element.

nativeButton?: boolean

Whether render produces a native <button> element. Defaults to false.

readOnly?: boolean

Whether users can select the radio.

render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, RadioRootState>

Allows replacing the radio element or composing it with another component.

required?: boolean

Whether users must choose the radio before submitting the form.

style?: React.CSSProperties | ((state: RadioRootState) => React.CSSProperties | undefined)

Style applied to the radio, or a function based on its state.

value: TValue

The unique value that identifies the radio within its group.