@spark-web/radio
Version:
--- title: Radio storybookPath: forms-radio--default isExperimentalPackage: true ---
255 lines (211 loc) • 6.34 kB
Markdown
---
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`).
```jsx live
<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`.
```jsx live
<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`.
```jsx live
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`.
```jsx live
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
```jsx live
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
```jsx live
<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.
```jsx live
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
<PropsTable displayName="Radio" />
The `Radio` component also extends `InputHTMLAttributes` props and are not
listed here.
### RadioPrimitive
<PropsTable displayName="RadioPrimitive" />
[data-attribute-map]:
https://github.com/brighte-labs/spark-web/blob/e7f6f4285b4cfd876312cc89fbdd094039aa239a/packages/utils/src/internal/buildDataAttributes.ts#L1
The `CheckboxPrimitive` component also extends `InputHTMLAttributes` props and
are not listed here.
### RadioGroup
<PropsTable displayName="RadioGroup" />
### RadioCard
<PropsTable displayName="RadioCard" />
The `RadioCard` component also extends `InputHTMLAttributes` props and are not
listed here.