Glin UI
Primitive / Atom

Radio Group

Mutually exclusive selection control with variant-capable radio items.

Edit on GitHub

Choose a plan

Billed monthly. Change or cancel any time.

Installation

Install from
pnpm dlx @glinui/cli@latest add radio-group

Prefer the package?

Usage

Variants and sizes

import { RadioGroup, RadioGroupItem } from "@glinui/ui"
export function Demo() {
return (
<div className="space-y-3">
<RadioGroup defaultValue="glinr" orientation="horizontal" className="flex items-center gap-3">
<RadioGroupItem value="glinr" variant="glinr" aria-label="glinr" />
<RadioGroupItem value="solid" variant="solid" aria-label="solid" />
<RadioGroupItem value="plain" variant="plain" aria-label="plain" />
<RadioGroupItem value="soft" variant="soft" aria-label="soft" />
<RadioGroupItem value="outline" variant="outline" aria-label="outline" />
<RadioGroupItem value="ghost" variant="ghost" aria-label="ghost" />
</RadioGroup>
<RadioGroup defaultValue="md" orientation="horizontal" className="flex items-center gap-3">
<RadioGroupItem value="sm" size="sm" aria-label="Small" />
<RadioGroupItem value="md" size="md" aria-label="Medium" />
<RadioGroupItem value="lg" size="lg" aria-label="Large" />
</RadioGroup>
</div>
)
}

Glass (opt-in)

Glass is opt-in and needs a backdrop behind it: pick Photo or Vivid in the stage backdrop switcher.

import { RadioGroup, RadioGroupItem } from "@glinui/ui"
export function Demo() {
return (
<RadioGroup defaultValue="a" orientation="horizontal" className="flex items-center gap-3">
<RadioGroupItem value="a" variant="glass" aria-label="A" />
<RadioGroupItem value="b" variant="glass" aria-label="B" />
</RadioGroup>
)
}

Default Value

import { RadioGroup, RadioGroupItem } from "@glinui/ui"

export function RadioGroupDefaultValueDemo() {
  return (
    <RadioGroup defaultValue="monthly">
      <div className="flex items-center gap-2">
        <RadioGroupItem value="monthly" id="monthly" />
        <label htmlFor="monthly" className="text-sm">Monthly billing</label>
      </div>
      <div className="flex items-center gap-2">
        <RadioGroupItem value="annual" id="annual" />
        <label htmlFor="annual" className="text-sm">Annual billing</label>
      </div>
    </RadioGroup>
  )
}

Disabled Item

import { RadioGroup, RadioGroupItem } from "@glinui/ui"

export function RadioGroupDisabledItemDemo() {
  return (
    <RadioGroup defaultValue="light">
      <div className="flex items-center gap-2">
        <RadioGroupItem value="light" id="light" />
        <label htmlFor="light" className="text-sm">Light</label>
      </div>
      <div className="flex items-center gap-2">
        <RadioGroupItem value="dark" id="dark" />
        <label htmlFor="dark" className="text-sm">Dark</label>
      </div>
      <div className="flex items-center gap-2">
        <RadioGroupItem value="system" id="system" disabled />
        <label htmlFor="system" className="text-sm text-neutral-400">System (unavailable)</label>
      </div>
    </RadioGroup>
  )
}

Horizontal

import { RadioGroup, RadioGroupItem } from "@glinui/ui"

export function RadioGroupHorizontalDemo() {
  return (
    <RadioGroup defaultValue="xs" orientation="horizontal" className="flex gap-6">
      <div className="flex items-center gap-2">
        <RadioGroupItem value="xs" id="xs" />
        <label htmlFor="xs" className="text-sm">XS</label>
      </div>
      <div className="flex items-center gap-2">
        <RadioGroupItem value="sm" id="sm-size" />
        <label htmlFor="sm-size" className="text-sm">SM</label>
      </div>
      <div className="flex items-center gap-2">
        <RadioGroupItem value="md" id="md-size" />
        <label htmlFor="md-size" className="text-sm">MD</label>
      </div>
      <div className="flex items-center gap-2">
        <RadioGroupItem value="lg" id="lg-size" />
        <label htmlFor="lg-size" className="text-sm">LG</label>
      </div>
    </RadioGroup>
  )
}

Item Variants

import { RadioGroup, RadioGroupItem } from "@glinui/ui"

export function RadioGroupVariantDemo() {
  return (
    <RadioGroup defaultValue="glass" orientation="horizontal" className="flex items-center gap-4">
      <RadioGroupItem value="default" variant="default" aria-label="Default" />
      <RadioGroupItem value="glass" variant="glass" aria-label="Glass" />
      <RadioGroupItem value="liquid" variant="liquid" aria-label="Liquid" />
      <RadioGroupItem value="matte" variant="matte" aria-label="Matte" />
      <RadioGroupItem value="outline" variant="outline" aria-label="Outline" />
    </RadioGroup>
  )
}

Item Sizes

import { RadioGroup, RadioGroupItem } from "@glinui/ui"

export function RadioGroupSizeDemo() {
  return (
    <RadioGroup defaultValue="md" orientation="horizontal" className="flex items-center gap-4">
      <RadioGroupItem value="sm" size="sm" aria-label="Small" />
      <RadioGroupItem value="md" size="md" aria-label="Medium" />
      <RadioGroupItem value="lg" size="lg" aria-label="Large" />
    </RadioGroup>
  )
}

Accessibility

  • Built on Radix RadioGroup with full ARIA support.
  • Each item requires a unique `value`.
  • Built on `@radix-ui/react-radio-group`, which follows the [WAI-ARIA Radio Group pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/).
  • Arrow keys move focus and selection between items within the group.
  • Each `RadioGroupItem` must have a corresponding `<label>` linked via `id` / `htmlFor`.
  • The group can be given a label via `aria-label` or `aria-labelledby` on `RadioGroup`.

Keyboard Interactions

KeyAction
Arrow Up / Down / Left / RightNavigate between radio items.
SpaceSelect the focused radio item.

ARIA Attributes

  • `role="radiogroup"` on root
  • `role="radio"` on items
  • `aria-checked`

Reduced Motion

Indicator transitions respect `prefers-reduced-motion`.

The fill indicator animation on selection is removed when `prefers-reduced-motion: reduce` is detected.

Affected properties

transformopacity

API Reference

RadioGroupProps

PropTypeRequiredDefaultDescription
valuestringNo-Controlled selected value.
defaultValuestringNo-Initial selected value for uncontrolled usage.
onValueChange(value: string) => voidNo-Change handler.
orientation"horizontal" | "vertical"No"vertical"Layout direction.
disabledbooleanNofalseDisables all items.

RadioGroupItemProps

PropTypeRequiredDefaultDescription
valuestringYes-Value submitted by the item when selected.
variantControlVariantPropNoambient (glinr)Surface look for `RadioGroupItem`. Omit to follow the ambient design style. Glass is opt-in.
size"sm" | "md" | "lg"No"md"Control size for `RadioGroupItem`.
disabledbooleanNofalseDisables this radio item.

Source

Import directly from the package or browse the source on GitHub. Click any file to view it.

Import

import { RadioGroup } from "@glinui/ui"

Source Files

Dependencies

@glinui/ui

Generated API Snapshot

Beta

Auto-extracted from TypeScript source in packages/ui/src/components/radio-group.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.

Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata

Primary Props Type

RadioGroupProps

RadioGroupItemProps

PropTypeRequiredDefaultDescription
disabledbooleanNo-Disables this radio item.
size"sm" | "md" | "lg"No"md"Size of the radio control.
valuestringYes-Value submitted by this radio item when selected.
variantControlVariantPropNo-Surface treatment for the radio item shell. Omit to follow the ambient design style. Also: solid, plain, soft, outline, ghost, glass (opt-in), liquid, matte, frosted.

RadioGroupProps

PropTypeRequiredDefaultDescription
defaultValuestringNo-Initial selected value for uncontrolled usage.
disabledbooleanNo-Disables all radio items in the group.
onValueChange(value: string) => voidNo-Called when the selected value changes.
orientation"horizontal" | "vertical"No-Layout direction for radio items.
valuestringNo-Controlled selected value.