Radio Input

React Radio Input components are used when users need to select one option from a set. They are commonly used in forms for plan selection, preferences, settings, and configuration choices.

This Radio Input component is built with React and styled using Tailwind CSS. It uses native radio inputs for predictable behavior, supports labels, sizes, and works in both controlled and uncontrolled forms.

Controlled

Selected: option2

Select a plan

Sizes

Installation

Usage

Import the component and group radios using the same name.

import { RadioInput } from "@/registry/core/radio-input";

export default () => (
  <div>
    <RadioInput name="plan" label="Basic Plan" value="basic" />
    <RadioInput name="plan" label="Pro Plan" value="pro" />
    <RadioInput name="plan" label="Enterprise Plan" value="enterprise" />
  </div>
);

Examples

Sizes

<RadioInput size="sm" name="size" label="Small radio" value="sm" />
<RadioInput size="md" name="size" label="Medium radio" value="md" />

Without Label

Use this only when the label is provided through surrounding context.

<RadioInput name="option" value="1" />

Controlled

import { useState } from "react";

export default () => {
  const [selected, setSelected] = useState("option1");

  return (
    <div className="flex flex-col gap-3">
      <RadioInput
        name="controlled"
        label="Option 1"
        value="option1"
        checked={selected === "option1"}
        onChange={(e) => setSelected(e.target.value)}
      />
      <RadioInput
        name="controlled"
        label="Option 2"
        value="option2"
        checked={selected === "option2"}
        onChange={(e) => setSelected(e.target.value)}
      />
      <RadioInput
        name="controlled"
        label="Option 3"
        value="option3"
        checked={selected === "option3"}
        onChange={(e) => setSelected(e.target.value)}
      />
    </div>
  );
};

Disabled

<RadioInput name="plan" label="Disabled option" value="disabled" disabled />
<RadioInput name="plan" label="Disabled checked" value="checked" disabled checked />

Default Checked

<RadioInput name="plan" label="Basic Plan" value="basic" />
<RadioInput name="plan" label="Pro Plan" value="pro" defaultChecked />
<RadioInput name="plan" label="Enterprise Plan" value="enterprise" />

Radio Group

Use semantic grouping for related options.

<fieldset>
  <legend className="text-sm font-medium mb-3">Select a plan</legend>
  <div className="flex flex-col gap-3">
    <RadioInput name="plan" label="Basic - $9/month" value="basic" />
    <RadioInput name="plan" label="Pro - $29/month" value="pro" />
    <RadioInput name="plan" label="Enterprise - $99/month" value="enterprise" />
  </div>
</fieldset>

API Reference

RadioInput

Extends input element props (excluding size).

PropTypeDefaultDescription
size'sm', 'md''sm'Radio button size
labelstring-Label text next to radio
namestring-Radio group name (required for grouping)
valuestring-Radio button value
idstring-Custom input ID (auto-generated if not provided)
disabledbooleanfalseDisable radio interaction
checkedboolean-Controlled checked state
defaultCheckedboolean-Uncontrolled default checked state
onChange(e: ChangeEvent) => void-Change event handler
classNamestring-Additional CSS classes for the label wrapper

Accessibility

  • Uses native <input type="radio"> with screen reader support
  • Automatically generates unique IDs if not provided
  • Label is properly associated with input via htmlFor
  • Radio buttons with the same name are automatically grouped
  • Keyboard accessible with arrow key navigation within groups
  • Focus ring provides clear visual feedback
  • Disabled state is communicated via aria-disabled on the label
  • Hover states are disabled when radio is disabled

Notes

  • The radio input uses sr-only to hide it visually while keeping it accessible
  • The inner dot is shown only when checked
  • Focus ring appears on keyboard focus with ring-4 style
  • Hover effects apply to both the radio and label for better UX
  • All radio buttons in a group must share the same name attribute
  • Only one radio in a group can be selected at a time
  • All standard input HTML attributes are supported (except size which is used for visual sizing)