Skip to content

RadioGroup ​

A custom radio button group component with smooth animations and icon support. Built with Web Components and fully accessible.

Installation ​

bash
npx @capsuleui/core add RadioGroup

Usage ​

Basic RadioGroup ​

html
<capsule-radio-group value="option1">
  <label style="display: flex; align-items: center; gap: 0.5rem;">
    <capsule-radio-group-item value="option1"></capsule-radio-group-item>
    <span>Option 1</span>
  </label>
  <label style="display: flex; align-items: center; gap: 0.5rem;">
    <capsule-radio-group-item value="option2"></capsule-radio-group-item>
    <span>Option 2</span>
  </label>
  <label style="display: flex; align-items: center; gap: 0.5rem;">
    <capsule-radio-group-item value="option3"></capsule-radio-group-item>
    <span>Option 3</span>
  </label>
</capsule-radio-group>

With Custom Icons ​

html
<capsule-radio-group value="apple">
  <label style="display: flex; align-items: center; gap: 0.5rem;">
    <capsule-radio-group-item value="apple">
      <capsule-icon name="mdi:apple"></capsule-icon>
    </capsule-radio-group-item>
    <span>Apple</span>
  </label>
  <label style="display: flex; align-items: center; gap: 0.5rem;">
    <capsule-radio-group-item value="android">
      <capsule-icon name="mdi:android"></capsule-icon>
    </capsule-radio-group-item>
    <span>Android</span>
  </label>
</capsule-radio-group>

Note: Icons are only visible when the radio item is checked. If no icon is provided, a default circle indicator is shown.

Disabled State ​

html
<capsule-radio-group
  value="option1"
  disabled
>
  <label style="display: flex; align-items: center; gap: 0.5rem;">
    <capsule-radio-group-item value="option1"></capsule-radio-group-item>
    <span>Option 1</span>
  </label>
  <label style="display: flex; align-items: center; gap: 0.5rem;">
    <capsule-radio-group-item value="option2"></capsule-radio-group-item>
    <span>Option 2 (disabled)</span>
  </label>
</capsule-radio-group>

Invalid State ​

html
<capsule-radio-group value="option1">
  <label style="display: flex; align-items: center; gap: 0.5rem;">
    <capsule-radio-group-item
      value="option1"
      aria-invalid="true"
    ></capsule-radio-group-item>
    <span>Invalid option</span>
  </label>
</capsule-radio-group>

API Reference ​

Components ​

ComponentDescription
capsule-radio-groupRoot container for the radio group
capsule-radio-group-itemIndividual radio button item (supports slot for custom icons)

Attributes ​

RadioGroup ​

AttributeTypeDefaultDescription
valuestring-Selected value
disabledbooleanfalseDisables all radio items

RadioGroupItem ​

AttributeTypeDefaultDescription
valuestring-Value of this radio item
disabledbooleanfalseDisables this radio item
checkedbooleanfalseWhether this item is checked (read-only)
aria-invalidbooleanfalseMarks radio as invalid for accessibility

Features ​

  • ✅ Smooth animations - Scale animation for indicator
  • ✅ Custom icons - Support for custom icons via indicator slot
  • ✅ Keyboard navigation - Arrow keys and Space/Enter support
  • ✅ Form integration - Works with native HTML forms
  • ✅ Accessibility - Full ARIA support and keyboard navigation
  • ✅ Focus states - Clear focus indicators with ring
  • ✅ Invalid states - Visual feedback for invalid radios
  • ✅ Dark mode - Automatic dark mode support

Styling Details ​

The RadioGroup component applies the following styles:

  • Item size: 1rem x 1rem (size-4)
  • Border: 1px solid var(--input)
  • Border radius: var(--radius-full) (circular)
  • Indicator size: 0.5rem x 0.5rem (size-2)
  • Gap between items: 0.75rem (gap-3)
  • Focus ring: 3px ring with var(--ring) color
  • Invalid state: Red border with destructive color ring

Accessibility ​

  • ✅ role="radiogroup" on root container
  • ✅ role="radio" on each item
  • ✅ aria-checked for checked state
  • ✅ aria-disabled for disabled state
  • ✅ aria-invalid for validation states
  • ✅ Keyboard navigation (Arrow keys, Space, Enter)
  • ✅ Tabindex management for focus

Events ​

javascript
const radioGroup = document.querySelector('capsule-radio-group');
radioGroup.addEventListener('change', (event) => {
  console.log('Selected value:', event.detail.value);
});

Form Integration ​

html
<form>
  <capsule-radio-group
    name="choice"
    value="option1"
  >
    <label style="display: flex; align-items: center; gap: 0.5rem;">
      <capsule-radio-group-item value="option1"></capsule-radio-group-item>
      <span>Option 1</span>
    </label>
    <label style="display: flex; align-items: center; gap: 0.5rem;">
      <capsule-radio-group-item value="option2"></capsule-radio-group-item>
      <span>Option 2</span>
    </label>
  </capsule-radio-group>
</form>

Released under the MIT License.