Skip to content
Noksha UIv0.1
Colour theme

forms

Radio

Grouped single-choice inputs with arrow-key roving focus.

Examples

Group

Arrow keys move between options and select as they go — one Tab stop for the whole group, per the WAI-ARIA radio pattern.

Free forever, 1 project

$20/month, unlimited projects

$60/month, shared workspaces

Bold styles

Eleven looks built entirely from `className`, `containerClassName` and the `--rd-solid` variable — neon, a diamond, a gradient ring, glass, and more, with no fork of the component underneath any of them.

Sizes

Three sizes on the same control scale the rest of the library uses.

Tones

The six semantic tones, each repointing the same `--rd-solid` variable the ring and dot are built from.

Disabled

A disabled radio is still a real input — `:disabled` drives the dimmed ring and the cursor together, not just the colour.

With text

A label and a line of helper text per option, wired to the control through `Field.Description` rather than a hand-written `aria-describedby`.

Notify me the moment something happens.

One summary email every morning.

A roundup every Monday.

Don't send notification emails.

Selectable cards

The radio drives the whole card through `:has(:checked)` — no click handler on the card itself, and only one can ever be selected.

Orientation

`orientation` swaps `aria-orientation` and the flex direction together, so arrow-key navigation always matches the layout it drives.

Horizontal

Vertical

Inline

Compact, `sm`-sized radios sharing one horizontal group, for a size picker rather than a form.

Invalid

Field only marks the group invalid after a first submit attempt, and `Field.Error` mounts nothing until then — an always-present error paragraph gets announced as empty by some screen readers before the user has done anything wrong.

hobby
pro
team

Controlled

`value` and `onValueChange` are the entire contract — the buttons below prove it by driving the group from outside, with no internal state of their own to fight.

Nav list

A sidebar-style picker — one option checked at a time, a hidden radio behind each row, and a left accent bar driven by `has-[:checked]` rather than a click handler.

Pulse list

The dot itself is still a real `Radio` — only `className` and `dotClassName` change — highlighted inside a row whose border reacts to the same `:checked` state.

Icon tiles

The same hidden-radio pattern in two layouts — a grid of square tiles and a list of pills — both driven by `has-[:checked]` on the label, no click handler on the tile.

Segmented

Five sliding-glider segmented controls — pill tabs, dark blocks, glass tiers, a vertical edge-light, and a glass dial — each a real `RadioGroup` with the glider position computed from the selected index.

Pill tabs
Dark blocks
Glass tiers
Vertical glow
Glass ball

Flip badge

A 3D flip card next to each option, rotated by `group-has-[:checked]` rather than a click handler on the badge itself.

Rotary dial

Six radios arranged around a dial, each positioned with `rotate → translate → counter-rotate`; the pointer angle is computed from the selected index rather than hand-tuned per option.

Wheel picker

A vertical picker where the unselected rows fade, shrink and blur by their distance from the selected one — the distance is computed in React, not chained per-option CSS.

Own the source

Noksha ships as a package and as copy-paste source. Take the files and they are yours to change. These are read from the generated registry, so they are exactly what the library ships — never a paraphrase of it.

Take these files, and field, internal helpers along with them — the imports below point at them. Or let the CLI do it: npx @noksha-ui/cli add radio writes them, follows the same dependency graph, and fixes up the imports.

export { Radio, RadioGroup, radioVariants } from './radio.js';
export type { RadioGroupProps, RadioProps, RadioSize, RadioTone } from './radio.types.js';

API reference

Accepted values

RadioSize
smmdlg

RadioGroupProps

Also accepts everything from Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'>.

PropTypeDescription
namestringThe shared `name`. Generated when omitted, so the group still posts.
valuestring
defaultValuestring
onValueChange(value: string) => void
orientation'horizontal' | 'vertical'
sizeRadioSize
toneRadioTone
disabledboolean
requiredboolean
invalidboolean

RadioProps

Also accepts everything from Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>.

PropTypeDescription
value*string
sizeRadioSize
toneRadioTone
invalidboolean
containerClassNamestringClasses for the outer wrapper; `className` styles the visible circle.
dotClassNamestringClasses for the centre dot.