npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@spark-web/radio

v5.3.0

Published

--- title: Radio storybookPath: forms-radio--default isExperimentalPackage: true ---

Readme


title: Radio storybookPath: forms-radio--default isExperimentalPackage: true

Radios are used select a single value from several options — ususally in a form. If multiple choices are valid, consider using a Checkbox instead.

Examples

In order to toggle between options, all Radio components should have a matching name prop (unless you are using them inside of a RadioGroup).

<Fieldset legend="Shrek Characters" gap="large">
  <Radio name="character_radio" value="Shrek" defaultChecked>
    Shrek
  </Radio>
  <Radio name="character_radio" value="Fiona">
    Fiona
  </Radio>
  <Radio name="character_radio" value="Donkey">
    Donkey
  </Radio>
</Fieldset>

Size

Radio buttons are available in two sizes: small and medium.

<Stack gap="large" dividers>
  <Fieldset legend="Radio variations (small)" gap="large">
    <Radio size="small" checked={false}>
      Unchecked
    </Radio>
    <Radio size="small" checked>
      Checked
    </Radio>
    <Radio size="small" disabled>
      Disabled
    </Radio>
    <Radio size="small" checked disabled>
      Checked + disabled
    </Radio>
  </Fieldset>
  <Fieldset legend="Radio variations (small)" gap="large">
    <Radio size="medium" checked={false}>
      Unchecked
    </Radio>
    <Radio size="medium" checked>
      Checked
    </Radio>
    <Radio size="medium" disabled>
      Disabled
    </Radio>
    <Radio size="medium" checked disabled>
      Checked + disabled
    </Radio>
  </Fieldset>
</Stack>

RadioGroup

The RadioGroup can be used to control a group of Radio components. The RadioGroup handles the value, tone, message, and disabled state of it's children.

Controlled

To control a group of Radio components, wrap them with a RadioGroup and provide it with a value and onChange function.

All Radio children must be provided with a value.

const [selected, setSelected] = React.useState('Shrek');

return (
  <Fieldset legend="Shrek Characters" gap="large">
    <RadioGroup value={selected} onChange={setSelected} gap="large">
      <Radio value="Shrek">Shrek</Radio>
      <Radio value="Fiona">Fiona</Radio>
      <Radio value="Donkey">Donkey</Radio>
    </RadioGroup>
    {selected && (
      <Text>
        The selected character is <Strong>{selected}</Strong>
      </Text>
    )}
  </Fieldset>
);

Message and tone

The message is used to communicate the status of a field, such as an error message. This will be announced on focus and can be combined with a tone to illustrate intent. The supported tones are: critical, positive and neutral.

const [selected, setSelected] = React.useState('critical');
const statuses = {
  critical: {
    message: 'Critical message',
    tone: 'critical',
  },
  positive: {
    message: 'Positive message',
    tone: 'positive',
  },
  neutral: {
    message: 'Neutral message',
    tone: 'neutral',
  },
};

return (
  <Fieldset legend="Message and Tone" gap="large">
    <RadioGroup
      message={statuses[selected]?.message}
      tone={statuses[selected]?.tone}
      value={selected}
      onChange={setSelected}
    >
      <Radio value="critical">Critical</Radio>
      <Radio value="positive">Positive</Radio>
      <Radio value="neutral">Neutral</Radio>
    </RadioGroup>
  </Fieldset>
);

RadioCard

A RadioCard is an alternative to Radio. Use RadioCard where a user needs to make one selection out of several choices, and where each option requires some detailed information.

Controlled

const terms = [
  { label: '6 months', description: '$426.08/fortnight' },
  { label: '12 months', description: '$214.54/fortnight' },
  { label: '24 months', description: '$108.77/fortnight' },
  { label: '36 months', description: '73.52/fortnight' },
  { label: '48 months', description: '55.89/fortnight' },
];

const [selected, setSelected] = React.useState(terms[0].label);

return (
  <Stack gap="large">
    <Fieldset legend="Select a repayment term" gap="large">
      <RadioGroup value={selected} onChange={setSelected}>
        {terms.map(({ label, description }) => (
          <RadioCard key={label} value={label} description={description}>
            {label}
          </RadioCard>
        ))}
      </RadioGroup>
    </Fieldset>
    {selected && (
      <Text>
        You have selected <Strong>{selected}</Strong>
      </Text>
    )}
  </Stack>
);

Uncontrolled

<Fieldset legend="Select a repayment term" gap="large">
  <RadioCard
    description="$426.08/fortnight"
    name="repayment_terms"
    defaultChecked
  >
    6 months
  </RadioCard>
  <RadioCard description="$214.54/fortnight" name="repayment_terms">
    12 months
  </RadioCard>
  <RadioCard description="$108.77/fortnight" name="repayment_terms">
    24 months
  </RadioCard>
  <RadioCard description="73.52/fortnight" name="repayment_terms">
    36 months
  </RadioCard>
  <RadioCard description="55.89/fortnight" name="repayment_terms">
    48 months
  </RadioCard>
</Fieldset>

Without description

RadioCards without a description have a lower prominence label.

const [selected, setSelected] = React.useState('Shrek');

return (
  <Fieldset legend="Shrek Characters" gap="large">
    <RadioGroup value={selected} onChange={setSelected} gap="large">
      <RadioCard value="Shrek">Shrek</RadioCard>
      <RadioCard value="Fiona">Fiona</RadioCard>
      <RadioCard value="Donkey">Donkey</RadioCard>
    </RadioGroup>
    {selected && (
      <Text>
        The selected character is <Strong>{selected}</Strong>
      </Text>
    )}
  </Fieldset>
);

Props

Radio

The Radio component also extends InputHTMLAttributes props and are not listed here.

RadioPrimitive

The CheckboxPrimitive component also extends InputHTMLAttributes props and are not listed here.

RadioGroup

RadioCard

The RadioCard component also extends InputHTMLAttributes props and are not listed here.