Skip to content

Radio

Single-choice picker with `RadioGroup` compound API and roving tabindex.

Forms & Inputs·Available inReactVueAngular·View as Markdown

Preview

tsx
Plan

Switch the framework picker (top-right of the panel) to render the same demo live in React, Vue, or Angular — same class names, ARIA, and visual output across all three.

Installation

Sisyphos UI ships unified packages for React, Vue, and Angular. Pick the one that matches your stack — every framework exports the same component classes, ARIA semantics, and CSS tokens.

$ pnpm add @sisyphos-ui/react

Then import the bundled stylesheet once at app entry: import "@sisyphos-ui/react/styles.css";

Usage

Idiomatic usage in each supported framework
import { useState } from "react";
import { RadioGroup, Radio } from "@sisyphos-ui/react";

export const Plan = () => {
  const [plan, setPlan] = useState<string | number>("pro");
  return (
    <RadioGroup label="Plan" value={plan} onChange={setPlan} variant="card">
      <Radio value="free" label="Free" />
      <Radio value="pro" label="Pro" />
    </RadioGroup>
  );
};

Card variant

Card variant turns each option into a large, clickable surface.

tsx
Billing

Sizes

`size` on `RadioGroup` cascades to every `Radio` inside.

tsx
Small
Medium (default)
Large

API

PropTypeDefaultDescription
valuestring | numberSelected value (controlled). Use `defaultValue` for uncontrolled.
defaultValuestring | numberInitial selected value (uncontrolled).
onChange(value: string | number) => voidCalled with the new value when the selection changes.
optionsRadioOption[]Flat option array (`value`, `label`, `description`, `icon`, `disabled`) — alternative to composing `<Radio>` children.
labelstringGroup label rendered above the options and used as the group's accessible name.
direction"horizontal" | "vertical""vertical"Layout direction for the options.
variant"standard" | "card" | "list""standard"Visual style applied to each option.
size"xs" | "sm" | "md" | "lg" | "xl""md"Control size shared by all options.
color"primary" | "success" | "error" | "warning" | "info""primary"Semantic color for the selected state.
errorbooleanfalseMarks the group as invalid for styling and ARIA.
errorMessagestringMessage shown below the group when `error` is true.
allowAddOptionbooleanfalseShows a trailing add-option button; pair with `onAddOption`.

The full API including refs, ARIA attributes, and HTML passthroughs lives in the package README on npm.

Accessibility

Adheres to the Radio Group WAI-ARIA design pattern.

  • Options are wrapped in a role="radiogroup" container labeled by the group label via aria-label.
  • aria-required and aria-invalid mirror required / error on the group; the error message is announced with role="alert".
  • Each option is a native <input type="radio"> sharing an auto-generated name, so browser and AT semantics come for free.
  • Each radio is nested inside its <label>, so clicking the label (or card/list row) activates the option.
  • The custom radio visual is aria-hidden; only the native input is exposed to assistive tech.

Keyboard interactions

KeyAction
TabMoves focus into the group (onto the checked option, or the first option when none is checked).
ArrowDownthenArrowRightMoves selection to the next option (native radio behavior).
ArrowUpthenArrowLeftMoves selection to the previous option (native radio behavior).
SpaceSelects the focused option.
Need more?View on npm →
Was this page helpful?