codefast/ui

Command Palette

Search for a command to run...

Source
Form

Radio

Single native radio input. Use Radio Group for accessible keyboard-navigable groups.

Examples

Single radios

Standalone radios sharing a name; the selected value is echoed below.

Size: Medium

31 lines
import { Label } from "@codefast/ui/label";
import { Radio } from "@codefast/ui/radio";
import { useState } from "react";

const SIZES = ["Small", "Medium", "Large"];

export function RadioSizes() {
  const [selected, setSelected] = useState("Medium");

  return (
    <div className="space-y-3">
      <div className="flex flex-col gap-3">
        {SIZES.map((size) => (
          <div key={size} className="flex items-center gap-2">
            <Radio
              id={`size-${size}`}
              name="size"
              value={size}
              checked={selected === size}
              onValueChange={(value) => setSelected(value)}
            />
            <Label htmlFor={`size-${size}`}>{size}</Label>
          </div>
        ))}
      </div>
      <p className="text-xs text-ui-muted">
        Size: <span className="font-medium text-ui-fg">{selected}</span>
      </p>
    </div>
  );
}

Horizontal

Lay standalone radios out in a row.

26 lines
import { Label } from "@codefast/ui/label";
import { Radio } from "@codefast/ui/radio";
import { useState } from "react";

const OPTIONS = ["Yes", "No", "Maybe"];

export function RadioHorizontal() {
  const [value, setValue] = useState("Yes");

  return (
    <div className="flex flex-wrap items-center justify-center gap-4">
      {OPTIONS.map((option) => (
        <div key={option} className="flex items-center gap-2">
          <Radio
            id={`vote-${option}`}
            name="vote"
            value={option}
            checked={value === option}
            onValueChange={(next) => setValue(next)}
          />
          <Label htmlFor={`vote-${option}`}>{option}</Label>
        </div>
      ))}
    </div>
  );
}

Disabled option

Disable an individual choice while keeping it visible.

26 lines
import { Label } from "@codefast/ui/label";
import { Radio } from "@codefast/ui/radio";
import { useState } from "react";

export function RadioDisabled() {
  const [value, setValue] = useState("available");

  return (
    <div className="flex flex-col gap-3">
      <div className="flex items-center gap-2">
        <Radio
          id="ship-available"
          name="shipping"
          value="available"
          checked={value === "available"}
          onValueChange={(next) => setValue(next)}
        />
        <Label htmlFor="ship-available">Standard — in stock</Label>
      </div>
      <div className="flex items-center gap-2 opacity-50">
        <Radio id="ship-soldout" name="shipping" value="soldout" disabled checked={false} />
        <Label htmlFor="ship-soldout">Overnight — sold out</Label>
      </div>
    </div>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

17 lines
import { Label } from "@codefast/ui/label";
import { Radio } from "@codefast/ui/radio";

export function RadioUsage() {
  return (
    <div className="flex flex-col gap-3">
      <div className="flex items-center gap-2">
        <Radio defaultChecked id="plan-starter" name="plan" value="starter" />
        <Label htmlFor="plan-starter">Starter</Label>
      </div>
      <div className="flex items-center gap-2">
        <Radio id="plan-pro" name="plan" value="pro" />
        <Label htmlFor="plan-pro">Pro</Label>
      </div>
    </div>
  );
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

Radio

Features

  • Plain native <input type="radio"> — radios sharing the same name form one exclusive group with zero JS.
  • A convenience onValueChange(value) callback fires alongside the native onChange.
  • For a managed, keyboard-navigable single-selection widget, use Radio Group instead.

API reference

Props for each part of the component. All native element props are also forwarded.

Radio

A single native radio input. Use Radio Group for managed groups.

checkedboolean

The controlled selected state (native input prop).

onValueChange(value: string) => void

Called with this radio’s value when it becomes checked.

namestring

Radios sharing a name form one exclusive group.

valuestring

The value submitted when this radio is chosen.

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

KeyFunction
TabMoves focus to the radio group.
Arrow+DownSelects the next radio in the group.
  • Give every radio in a set the same name so only one can be selected.
  • Pair each radio with a Label via matching id / htmlFor.
  • For a managed, keyboard-navigable group, prefer Radio Group.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Use Radio Group for most cases; reach for Radio for bespoke layouts.
  • Always provide labels.

Don’t

  • Don’t use radios for multi-select.
  • Don’t forget the shared name attribute.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.