sc1m/design
ComponentsRadio

Radio

Radio component built on Base UI, styled with sc1m tokens.

StableBase UI

Live preview

Installation

pnpm dlx shadcn@latest add @sc1m/radio

This also merges the token layer and installs src/lib/cn.ts plus @base-ui/react. For the manual route — prerequisites, components.json, and app-level setup — see Installation.

Usage

import { Radio } from "@/components/ui/radio";

Example

The preview above, with its source. This is the demo module verbatim, so the code and the thing it renders cannot drift apart.

<RadioGroup defaultValue="small" aria-label="Size">
  {['small', 'medium', 'large'].map((size) => (
    <label key={size} className="flex items-center gap-2 text-sm">
      <Radio value={size} />
      {size}
    </label>
  ))}
</RadioGroup>

API reference

Each part forwards every prop of its Base UI counterpart; the tables list the ones declared on the part itself. See Base UI's reference for the inherited element props.

Radio

PropTypeDefaultDescription
valueValueThe unique identifying value of the radio in a group.
disabledbooleanWhether the component should ignore user interaction.
requiredbooleanWhether the user must choose a value before submitting a form.
readOnlybooleanWhether the user should be unable to select the radio button.
inputRefReact.Ref<HTMLInputElement>A ref to access the hidden input element.

Accessibility

Behaviour, focus management, and ARIA wiring come from Base UI's Radio — see its reference for the full keyboard map.

  • Keyboard focus draws a 2px ring in --ring, never removed — only shown on :focus-visible, so a pointer press does not paint one.
  • Disabled parts mute their contents rather than the element, keeping the focus ring at full strength where the part stays focusable.

Design tokens

The component reads semantic tokens only — no raw colour, radius, or duration appears in its source. Override the token, not the component.

TokenApplied to
--accentRadio
--line-strongRadio
--ringRadio
--surface-raisedRadio

Source

src/components/ui/radio/radio.tsx — no next/* imports, so it drops into any React 19 + Tailwind v4 app.