Gecko UIGecko UI

Radio

Radio button for mutually exclusive selections

You are reading the v1 docs. v2 renamed several props and replaced GeckoUIPortal with GeckoUIProvider. Read this page in v2.

Live examples are only rendered in the v2 docs.

Radio

A styled radio button component for creating mutually exclusive selection groups.

Installation

import { Radio } from '@geckoui/geckoui';

Basic Usage

import { useState } from 'react';

function Example() {
  const [selected, setSelected] = useState('option1');

  return (
    <div>
      <label>
        <Radio
          name="options"
          value="option1"
          checked={selected === 'option1'}
          onChange={(e) => setSelected(e.target.value)}
        />
        Option 1
      </label>
      <label>
        <Radio
          name="options"
          value="option2"
          checked={selected === 'option2'}
          onChange={(e) => setSelected(e.target.value)}
        />
        Option 2
      </label>
    </div>
  );
}

Props API

PropTypeDefaultDescription
namestring-Radio group name (required for grouping)
valuestring-Value of this radio option
checkedboolean-Whether this radio is selected
disabledbooleanfalseDisable the radio button
onChangeChangeEventHandler-Callback when selection changes
classNamestring-CSS class for styling
...restInputHTMLAttributes-All standard HTML input attributes

Examples

Radio Group with Descriptions

function PaymentMethod() {
  const [selected, setSelected] = useState("free");

  const options = [
    { value: "free", title: "Free Plan", desc: "Perfect for trying out" },
    { value: "pro", title: "Pro Plan", desc: "$9/month - Most popular" },
    { value: "enterprise", title: "Enterprise", desc: "Contact us for pricing" }
  ];

  return (
    <div className="flex flex-col gap-3">
      {options.map((option) => (
        <label
          key={option.value}
          className="flex items-start gap-3 p-3 border rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800">
          <Radio
            name="plan"
            className="mt-2"
            value={option.value}
            checked={selected === option.value}
            onChange={(e) => setSelected(e.target.value)}
          />
          <div>
            <div className="flex items-center font-medium">
              <span>{option.title}</span>
            </div>
            <div className="text-sm text-gray-500">{option.desc}</div>
          </div>
        </label>
      ))}
    </div>
  );
}

Disabled State

<div className="space-y-2">
  <label className="flex items-center gap-2">
    <Radio name="status" value="enabled" checked />
    <span>Enabled</span>
  </label>
  <label className="flex items-center gap-2 opacity-50">
    <Radio name="status" value="disabled" disabled />
    <span>Disabled</span>
  </label>
</div>

Horizontal Layout

function SizeSelector() {
  const [size, setSize] = useState('M');
  const sizes = ['XS', 'S', 'M', 'L', 'XL'];

  return (
    <div className="flex gap-4">
      {sizes.map(s => (
        <label key={s} className="flex items-center gap-2">
          <Radio
            name="size"
            value={s}
            checked={size === s}
            onChange={(e) => setSize(e.target.value)}
          />
          <span>{s}</span>
        </label>
      ))}
    </div>
  );
}

Grouping Radio Buttons

Radio buttons with the same name prop are automatically grouped. Only one radio button in a group can be selected at a time.

// All these radios are grouped by name="color"
<Radio name="color" value="red" />
<Radio name="color" value="blue" />
<Radio name="color" value="green" />

Accessibility

  • Fully keyboard navigable
  • Arrow keys navigate between radio buttons in the same group
  • Space key selects the focused radio
  • Works with screen readers
  • Disabled state properly communicated

Styling

The component uses the class name GeckoUIRadio. Override styles using the className prop:

.GeckoUIRadio {
  /* Your custom styles */
}