Radio
Terminal-styled radio button and radio group for single-selection.
Installation
dgadd is not public on npm yet. Until the first release, pack @diffgazer/add from the repository and install that tarball into this app, which is what puts dgadd on pnpm exec.
The hosted registry is not public yet because r.b4r7.dev does not resolve. Use this source checkout or a local registry preview until the endpoint returns 200.
Diffgazer packages are not yet published to npm. Until the first release, pack @diffgazer/ui and @diffgazer/keys from the repository and install those tarballs.
UI components require Tailwind CSS v4. Local copy mode imports src/styles/styles.css; package mode uses @diffgazer/ui CSS once packages are available.
Usage
Examples
Variants
Highlight, Invalid, and Disabled
API Reference
Radio
RadioGroup
RadioGroupItem
Data attributes
Accessibility
Keyboard Navigation
All four arrow keys, plus the vim aliases j/k, move focus and select items in automatic activation mode (per WAI-ARIA APG). Manual activation mode moves focus and emits onNavigate without changing value. Space selects the focused item. Enter commit via onEnter is a Diffgazer extension for preview/commit flows. Home/End jump to first/last item. Composite UIs can opt into initial focus with autoFocus, suspend RadioGroup-managed key handling with keyboardNavigation, and listen for onNavigationBoundaryReached(direction, event, key).
| Key | Action |
|---|---|
| ArrowUp / ArrowLeft / k | Moves focus to the previous enabled radio; automatic mode also selects it. |
| ArrowDown / ArrowRight / j | Moves focus to the next enabled radio; automatic mode also selects it. |
| Home / End | Moves focus to the first or last enabled radio and selects it in automatic mode. |
| Space | Selects the focused radio. |
| Enter | Calls onEnter for preview/commit flows, or selects when wired. |
Arrow navigation in both orientations
Notes
Requires @diffgazer/keys (package mode)
RadioGroup's roving keyboard navigation imports from the required @diffgazer/keys peer. Package consumers must install @diffgazer/keys with @diffgazer/ui; packages are not yet published to npm, so until the first release install both from locally packed tarballs. Importing @diffgazer/ui/components/radio without keys fails at module load with an error naming the missing @diffgazer/keys package. Copy/dgadd consumers do not need the package — copy mode rewrites the keyboard hooks to local source.
Composition Contract
Prefer importing RadioGroup and RadioGroupItem for shadcn-like code. RadioGroup.Item is the same item component exposed for Radix-like namespacing. Use either form inside RadioGroup, directly or through your own wrapper components. Every item value must be unique within a group because selection, highlighting, and form output are value-based.
Standalone vs RadioGroup
Standalone same-name Radio components stay mutually exclusive via a document-level event, but they are form-submission-only: there is no arrow-key navigation and each radio is its own tab stop. For a keyboard-complete group (roving focus, arrow navigation, a single tab stop), use RadioGroup.
Keyboard Navigation
RadioGroup delegates roving focus to @diffgazer/keys navigation. All four arrow keys move focus and select items by default regardless of orientation (per WAI-ARIA APG radio group pattern). Home/End jump to first/last item. Space selects the focused item. Enter commit is a Diffgazer extension for preview/commit flows, not the APG baseline. Use activationMode="manual" with onNavigate/onChange when arrows should move focus and highlight without changing value, and onEnter when Enter should commit the focused item. Use autoFocus to focus the highlighted, selected, or first enabled item when the group becomes active. Use keyboardNavigation to suspend RadioGroup-managed key handling; when suspended, enabled items remain tabbable. Use onNavigationBoundaryReached(direction, event, key) to hand focus to adjacent controls and filter vertical-only handoffs by key when needed.
Glyph Hierarchy
The brackets are chrome and render muted; the inner mark keeps the control's tone at bold weight, so a selected row is the only place full-contrast ink appears in the glyph column. The visible text is unchanged and the whole cell stays aria-hidden.
Indicator Variants
variant='bullet' (default) marks the selected state with [●]; variant='x' marks it with [x]. Both glyphs are three characters, the same width Checkbox reserves, so a form mixing radios and checkboxes keeps one label left edge at every size.
Orientation
Set orientation='horizontal' for inline layouts. Layout direction changes but all four arrow keys always navigate (per APG spec).
Required validation
A required RadioGroup participates in native validation only while it has an enabled item. If every item is disabled, the group follows native radio behavior: it is valid, omits aria-required and derived invalid state, contributes no value, and has no validation focus target.
Source
Install via CLI: pnpm exec dgadd add ui/radio. Keyboard hooks are included as standalone copies. For the full experience, use --integration keys.
Highlighted source loads after this disclosure opens. Browse the source repository.