GitHub

/ radio-group

RadioGroup

@kumiki/components/radio-group

Compound <Root> + <Item> for mutually-exclusive option groups.

This component, layer by layer

Styled, copy-paste presets (preview). Run pnpm kumiki add to drop the source into your project, then edit freely.

Live preview

Live preview…

Install
pnpm add @kumiki/atelier
Plan picker
<script lang="ts">
  import { Tailwind as RadioGroup } from '@kumiki/atelier/radio-group';
  import type { RadioItem } from '@kumiki/components/radio-group';

  type Plan = 'free' | 'pro' | 'team';
  const plans: RadioItem<Plan>[] = [
    { id: 'free', value: 'free', label: 'Free' },
    { id: 'pro',  value: 'pro',  label: 'Pro'  },
    { id: 'team', value: 'team', label: 'Team' },
  ];
  let value = $state<Plan | null>('pro');
</script>

<RadioGroup.Root items={plans} bind:value aria-label="Plan">
  {#each plans as p (p.id)}
    <RadioGroup.Item value={p}>{p.label}</RadioGroup.Item>
  {/each}
</RadioGroup.Root>

/ accessibility

Accessibility

axe-core — run on every PR (LTR + RTL × every documented state).

Keyboard

KeyEffect
Arrow ↑/↓ ←/→Move focus and select adjacent item.
Home / EndFirst / last item.
TabMove focus into / out of the group.

Test discipline

  • axe-core — run on every PR (LTR + RTL × every documented state).
  • APG keyboard tests — Playwright, hand-written per pattern.
  • VoiceOver / NVDA — Guidepup nightly schedule.
  • Type-level required names — title / aria-label / aria-labelledby.
Read the W3C ARIA APG pattern ↗