1. Components
  2. Forms and inputs
  3. Radio Group

Radio Group

A radio group allows a user to select a single item from a list of mutually exclusive options.

Size
<RadioGroup defaultValue="sm" label="Size">
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>

Installation

npx dotui-cli@latest add radio-group

Usage

Use radio group to allow users to select a single option from a short list of related options.

import { RadioGroup, Radio } from "@/components/core/radio-group";
 
<RadioGroup defaultValue="sm" label="Size" description="Select a product size.">
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>;
import { Label, Description } from "@/components/core/field";
import {
  RadioGroupRoot,
  RadioRoot,
  RadioIndicator,
} from "@/components/core/radio-group";
 
<RadioGroupRoot defaultValue="sm">
  <Label>Size</Label>
  <RadioRoot value="sm">
    <span>Next.js</span>
    <RadioIndicator />
  </RadioRoot>
  <RadioRoot value="md">
    <span>Next.js</span>
    <RadioIndicator />
  </RadioRoot>
  <RadioRoot value="lg">
    <span>..</span>
    <RadioIndicator />
  </RadioRoot>
  <Description>Select a product size.</Description>
</RadioGroupRoot>;

Options

Orientation

RadioGroups are vertically oriented by default. The orientation prop can be used to change the orientation to 'horizontal'.

Size
<RadioGroup defaultValue="sm" label="Size" orientation="horizontal">
  <Radio value="sm" title="Small" description="Dimension: 128 x 128" />
  <Radio value="md" title="Medium" description="Dimension: 256 x 256" />
  <Radio value="lg" title="Large" description="Dimension: 512 x 512" />
</RadioGroup>

Variant

Use the variant prop to control the visual style of the radio buttons.

Size
<RadioGroup defaultValue="sm" label="Size" orientation="horizontal" variant="card">
  <Radio value="sm">
    <div className="flex flex-col gap-1">
      <span className="font-bold">Small</span>
      <span className="text-xs text-fg-muted">Dimension: 128 x 128</span>
    </div>
  </Radio>
  <Radio value="md">
    <div className="flex flex-col gap-1">
      <span className="font-bold">Medium</span>
      <span className="text-xs text-fg-muted">Dimension: 256 x 256</span>
    </div>
  </Radio>
  <Radio value="lg">
    <div className="flex flex-col gap-1">
      <span className="font-bold">Large</span>
      <span className="text-xs text-fg-muted">Dimension: 512 x 512</span>
    </div>
  </Radio>
</RadioGroup>

label

A visual label can be provided for the radio group using the label prop or a hidden label using aria-label prop.

Size
<RadioGroup defaultValue="sm" label="Size">
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>
<RadioGroup defaultValue="sm" aria-label="Size">
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>

Description

A description can be supplied to a radio group via the description prop. The description is always visible unless the isInvalid prop is true and an error message is provided.

Size
Select a product size.
<RadioGroup defaultValue="sm" label="Size" description="Select a product size.">
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>

Error message

An errorMessage can be supplied to a RadioGroup, which will be displayed when the isInvalid prop is set to true.

Size
Please select a product size.
<RadioGroup
  defaultValue={null}
  label="Size"
  isInvalid
  errorMessage="Please select a product size."
>
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>

Disabled

Use the isDisabled prop to disable the RadioGroup or a single Radio.

Size
Size
<RadioGroup label="Size" defaultValue="sm" isDisabled>
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>
<RadioGroup label="Size" defaultValue="sm">
  <Radio value="sm">Small</Radio>
  <Radio value="md" isDisabled>Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>

Read only

The isReadOnly prop makes the selection immutable. Unlike isDisabled, the RadioGroup remains focusable.

Size
<RadioGroup defaultValue="sm" label="Size" isReadOnly>
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>

Required

Use the isRequired prop to mark the radio group as required. Use the necessityIndicator prop to control the visual style of the required state.

Size
<RadioGroup defaultValue="sm" label="Size" isRequired>
  <Radio value="sm">Small</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>
<RadioGroup defaultValue="sm" label="Size" isRequired necessityIndicator="icon">
  <Radio value="sm">Small</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>
<RadioGroup defaultValue="sm" label="Size" isRequired necessityIndicator="label">
  <Radio value="sm">Small</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>
<RadioGroup defaultValue="sm" label="Size" necessityIndicator="label">
  <Radio value="sm">Small</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>

Uncontrolled

The defaultValue prop can be used to set the default state.

Size
<RadioGroup defaultValue="sm" label="Size">
  <Radio value="sm">Small</Radio>
  <Radio value="md">Medium</Radio>
  <Radio value="lg">Large</Radio>
</RadioGroup>

Controlled

Use the value and onChange props to control the value of the radio group.

Size

You selected: sm

const [size, setSize] = React.useState("sm");
return (
  <RadioGroup label="Size" value={size} onChange={(value) => setSize(value)}>
    <Radio value="sm">Small</Radio>
    <Radio value="md">Medium</Radio>
    <Radio value="lg">Large</Radio>
  </RadioGroup>
);

Composition

If you need to customize things further, you can drop down to the composition level.

SizePlease select a size.
<RadioGroupRoot defaultValue="sm">
  <Label>Size</Label>
  <Description>Please select a size.</Description>
  <div className="flex gap-2">
    <Radio value="sm">Small</Radio>
    <Radio value="md">Medium</Radio>
    <Radio value="lg">Large</Radio>
  </div>
  <FieldError />
</RadioGroupRoot>

API Reference

RadioGroup

PropTypeDefaultDescription
variant"default" | "card""default"The visual style of the radio group.
orientation'horizontal' | 'vertical''vertical'The axis the Radio Button(s) should align with.
valuestring | null-The current value (controlled).
defaultValuestring | null-The default value (uncontrolled).
isDisabledboolean-Whether the input is disabled.
isReadOnlyboolean-Whether the input can be selected but not changed by the user.
namestring-The name of the input element, used when submitting an HTML form.
isRequiredboolean-Whether user input is required on the input before form submission.
isInvalidboolean-Whether the input value is invalid.
validate(value: string | null) => ValidationError| true| null| undefined-A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if validationBehavior="native". For realtime validation, use the isInvalid prop instead.
validationBehavior'native' | 'aria''native'Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA.
childrenReactNode | (values: RadioGroupRenderProps & {defaultChildren: ReactNode | undefined}) => ReactNode-The children of the component. A function may be provided to alter the children based on component state.
EventTypeDescription
onChange(isSelected: boolean) => voidHandler that is called when the element's selection state changes.
onFocus(e: FocusEvent<Target>) => voidHandler that is called when the element receives focus.
onBlur(e: FocusEvent<Target>) => voidHandler that is called when the element loses focus.
onFocusChange(isFocused: boolean) => voidHandler that is called when the element's focus status changes.
Data attributeDescription
[data-orientation="horizontal | vertical"]The orientation of the radio group.
[data-disabled]Whether the radio group is disabled.
[data-readonly]Whether the radio group is read only.
[data-invalid]Whether the radio group invalid.
[data-required]Whether the radio group is required.

Radio

PropTypeDefaultDescription
variant"default" | "card""default"The visual style of the radio.
value*string-The value of the radio button, used when submitting an HTML form.
inputRefMutableRefObject<HTMLInputElement>-A ref for the HTML input element.
isDisabledboolean-Whether the radio button is disabled or not. Shows that a selection exists, but is not available in that circumstance.
autoFocusboolean-Whether the element should receive focus on render.
childrenReactNode | (values: RadioRenderProps & {defaultChildren: ReactNode | undefined}) => ReactNode-The children of the component. A function may be provided to alter the children based on component state.
EventTypeDescription
onFocus(e: FocusEvent<Target>) => voidHandler that is called when the element receives focus.
onBlur(e: FocusEvent<Target>) => voidHandler that is called when the element loses focus.
onFocusChange(isFocused: boolean) => voidHandler that is called when the element's focus status changes.
onKeyDown(e: KeyboardEvent) => voidHandler that is called when a key is pressed.
onKeyUp(e: KeyboardEvent) => voidHandler that is called when a key is released.
onHoverStart(e: HoverEvent) => voidHandler that is called when a hover interaction starts.
onHoverEnd(e: HoverEvent) => voidHandler that is called when a hover interaction ends.
onHoverChange(isHovering: boolean) => voidHandler that is called when the hover state changes.
Data attributeDescription
[data-selected]Whether the radio is selected.
[data-hovered]Whether the radio is currently hovered with a mouse.
[data-pressed]Whether the radio is currently in a pressed state.
[data-focused]Whether the radio is focused, either via a mouse or keyboard.
[data-focus-visible]Whether the radio is keyboard focused.
[data-disabled]Whether the radio is disabled.
[data-readonly]Whether the radio is read only.
[data-invalid]Whether the radio invalid.
[data-required]Whether the radio is required.

Accessibility

Keyboard interactions

KeyDescription
TabMoves focus to either the checked radio item or the first radio item in the group.
SpaceWhen focus is on an unchecked radio item, checks it.
ArrowDownMoves focus and checks the next radio item in the group.
ArrowUpMoves focus to the previous radio item in the group.
ArrowRightMoves focus and checks the next radio item in the group.
ArrowLeftMoves focus to the previous radio item in the group.
dotUI

Bringing singularity to the web.

Built by mehdibha. The source code is available on GitHub.