A labelled group of mutually exclusive radio options bound to a single value. Built on Base UI's RadioGroup and Radio.Root; renders a label, the options (each an inner Radio), and optional helper/error text.
Use @uxf/ui/radio-group for a controlled radio group outside a form, where you own value and onChange.
Use @uxf/form/radio-group inside a @uxf/form form — that twin wires react-hook-form (useController), consumes the form context (disabled/read-only, required validation), and derives its value from the field.
import { RadioGroup } from "@uxf/ui/radio-group";
import { useState } from "react";
const options = [
{ id: "1", label: "Radio one" },
{ id: "2", label: "Radio two" },
{ id: "3", label: "Radio three" },
];
function Example() {
const [value, setValue] = useState<string | number | null>("1");
return (
<RadioGroup
id="radiogroup"
label="Choose one"
name="choice"
onChange={setValue}
options={options}
value={value}
/>
);
}
Extends FormControlProps<ValueId | null> (from @uxf/ui/types). ValueId is RadioGroupOptionValueId (string | number).
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — (required) | Group label. |
name | string | — (required) | Field name. |
options | RadioGroupOption[] | — (required) | Options to render. |
value | ValueId | null | — (required) | Id of the selected option. |
onChange | (value: ValueId | null) => void | — (required) | Called with the selected option id. |
variant | RadioGroupVariant | "list" | Layout variant. |
radioSize | RadioSize | "default" | Size of the radio indicators. |
helperText | ReactNode | — | Text shown below the options; styled as an error when isInvalid. |
hiddenLabel | boolean | false | Visually hide the label (kept for accessibility). |
id | string | — | Root id; also used to build the error-message id. |
forceColumn | boolean | false | Declared on the props type but not applied by the current UI implementation. |
className | string | — | Extra class on the root element. |
style | CSSProperties | — | Inline style on the root element. |
isDisabled | boolean | false | Disables the group and all options. |
isInvalid | boolean | false | Error styling on the group and helper text. |
isReadOnly | boolean | false | Adds the read-only state class. |
isRequired | boolean | false | Marks the label as required. |
The inherited isFocused, onFocus, and onBlur are part of the shared FormControlProps shape but are not wired by this UI component; they are consumed by the @uxf/form twin.
RadioGroupOption — one entry of options:
| Field | Type | Description |
|---|---|---|
id | string | number | Option value. |
label | ReactNode | Option label. |
disabled | boolean | Disable this single option. |
From theme.ts:
| Group | Values |
|---|---|
variant | list, column, row, radioButton |
RadioGroupVariants is an open interface, so a project can add values via module augmentation:
declare module "@uxf/ui/radio-group/theme" {
interface RadioGroupVariants {
grid: true;
}
}
radioSize accepts the Radio sizes (default, lg). Individual options can be disabled via option.disabled; the whole group via isDisabled.
Import the stylesheets once in your global CSS:
@import url("@uxf/ui/css/radio.css");
@import url("@uxf/ui/css/radio-group.css");
form-component.css provides the helper/error text styling (.uxf-helper-text); import it if you use helperText or validation:
@import url("@uxf/ui/css/form-component.css");
Also requires the global @uxf/ui token layer, set up once per app — see @uxf/ui setup.