Radio is an interactive control that can be turned on or off. Radios are most often used in groups, wherein only a single option may be selected.
Examples #
Import Syntax #
import Radio from 'mineral-ui/Radio';
Note
Mineral UI also provides a RadioGroup, which offers a simpler API for working with a group of Radios, and a FormField to provide an accessible label and other features. Examples here omit RadioGroups and FormFields for clarity and brevity.
Uncontrolled #
Uncontrolled Radios behave just like their HTML input
counterparts wherein the checked state is handled by the DOM. The only
difference is that defaultChecked
must be used to set the initial state
rather than checked
.
<DemoForm> <Radio name="mineral" label="Quartz" value="quartz" defaultChecked /> <Radio name="mineral" label="Magnetite" value="magnetite" /> </DemoForm>
Controlled #
In a controlled Radio, the checked state is handled by a React
component. Set the checked state with the checked
prop and provide an
onChange
handler.
() => { class MyForm extends Component { constructor(props) { super(props); this.state = { value: 'quartz' }; this.handleChange = this.handleChange.bind(this); } handleChange(event) { this.setState({ value: event.target.value }); } render() { return ( <DemoForm> <Radio name="mineral" label="Quartz" value="quartz" checked={this.state.value === 'quartz'} onChange={this.handleChange} /> <Radio name="mineral" label="Magnetite" value="magnetite" checked={this.state.value === 'magnetite'} onChange={this.handleChange} /> </DemoForm> ); } } return <MyForm />; }
Disabled #
Use the disabled prop to indicate that the Radio is not available for interaction.
<DemoForm> <Radio label="Quartz" value="quartz" disabled /> <Radio label="Magnetite" value="magnetite" defaultChecked disabled /> </DemoForm>
Required #
The required
prop on a Radio does nothing visually on its
own, but is important for accessibility.
<DemoForm> <Radio name="mineral" label="Quartz" value="quartz" required defaultChecked /> <Radio name="mineral" label="Magnetite" value="magnetite" required /> </DemoForm>
Invalid #
The invalid
prop on a Radio does nothing visually on its
own, but is important for accessibility.
<DemoForm> <Radio name="mineral" label="Quartz" value="quartz" defaultChecked invalid /> <Radio name="mineral" label="Magnetite" value="magnetite" invalid /> </DemoForm>
Sizes #
Radio is available in a few sizes.
<DemoForm> <Radio name="size" label="Small" value="small" size="small" /> <Radio name="size" label="Medium" value="medium" size="medium" /> <Radio name="size" label="Large" value="large" defaultChecked /> <Radio name="size" label="Jumbo" value="jumbo" size="jumbo" /> </DemoForm>
Label Position & Justification #
Use the labelPosition
prop to adjust the position of the
control relative to the label. Use the justify
prop to maximize the space
between the label and the control. These props are often useful when used in
tandem with one another.
<DemoForm> <Radio name="mineral" label="Quartz" value="quartz" /> <FormFieldDivider /> <Radio name="mineral" label="Magnetite" value="magnetite" labelPosition="start" /> <FormFieldDivider /> <Radio name="mineral" label="Azurite" value="azurite" justify /> <FormFieldDivider /> <Radio name="mineral" label="Hematite" value="hematite" labelPosition="start" justify /> </DemoForm>
Label Wrapping #
This example demonstrates how the text of a long label will wrap in relation to the position of the control.
<DemoForm> <Radio name="example" label={loremIpsum} defaultChecked /> </DemoForm>
Visually Hidden Label #
If the purpose of a Radio is obvious from context and adding
a label would negatively affect the design, you can use hideLabel
to
visually hide the label while retaining accessibility.
<DemoForm> <Radio label="Select All" hideLabel /> </DemoForm>
Input ref #
The following example demonstrates how to get a reference to the underlying input
element.
() => { class MyForm extends Component { constructor() { super(); this.focus = this.focus.bind(this); } focus() { this.input.focus(); } render() { return ( <DemoLayout> <Radio label="Option 1" value="1" inputRef={ref => { this.input = ref; }} /> <Button onClick={ this.focus }>Focus the input</Button> </DemoLayout> ) } } return <MyForm />; }
Bidirectionality #
Radios support right-to-left (RTL) languages.
<div dir="rtl"> <ThemeProvider theme={{ direction: 'rtl' }}> <DemoForm> <Radio name="example" label="مرحبا بالعالم" /> <Radio name="example" label="مرحبا بالعالم" labelPosition="start" /> <FormFieldDivider /> <Radio name="example" label="مرحبا بالعالم" justify /> <Radio name="example" label="مرحبا بالعالم" labelPosition="start" justify /> </DemoForm> </ThemeProvider> </div>
API & Theme #
Radio Props #
The Radio component takes the following React props.
Name | Type | Default | Description |
---|---|---|---|
checked | boolean | Checked state of the radio. Primarily for use with controlled components. If this prop is specified, an | |
defaultChecked | boolean | Initial checked state of the radio; primarily for use with uncontrolled components | |
disabled | boolean | Disables the radio button | |
hideLabel | boolean | Visually hide label, but keep available for assistive technologies | |
inputRef | Ref for the radio button | ||
invalid | boolean | Indicates that the value of the input is invalid | |
justify | boolean | Maximize the distance between the label and the control | |
label | string | React$Element<*> | required | Label associated with the input element |
labelPosition | 'start' | 'end' | 'end' | Determines the position of the label relative to the control |
name | string | Used to uniquely define a group of radio buttons | |
onChange | Called when a radio is selected | ||
required | boolean | Indicates that the user must select an option before submitting a form | |
rootProps | Object | Props to be applied directly to the root element rather than the input | |
size | 'small' | 'medium' | 'large' | 'jumbo' | 'large' | Available sizes |
value | string | The value of the radio button |
Radio Theme Variables #
These variables can be used as hooks to override this component's
style at either a
local
or global
level. The theme
referenced below is whatever theme is available
from props to the instance of this component.
Variable | Value |
---|---|
RadioControl_backgroundColor | theme.input_backgroundColor |
RadioControl_backgroundColor_checked | theme.borderColor_theme |
RadioControl_backgroundColor_checkedHover | theme.borderColor_theme_hover |
RadioControl_borderColor | theme.borderColor |
RadioControl_borderColor_hover | theme.borderColor_theme_hover |
RadioControl_borderColor_checked | theme.borderColor_theme |
RadioControl_borderColor_checkedHover | theme.borderColor_theme_hover |
RadioControl_borderRadius | 100% |
RadioControl_boxShadow_focus | 0 0 0 1px boxShadow_focusInner, 0 0 0 2px borderColor_theme_focus |
RadioControl_size | 1em |
RadioControl_size_jumbo | 1.5em |
RadioText_color | theme.color |
RadioText_fontSize | theme.fontSize_ui |
RadioText_fontSize_small | 0.75em |
RadioText_marginHorizontal | theme.space_inline_md |
Usage #
Best Practices #
Begin labels with a capital letter.
Don't use punctuation at the end of each line if the label is a single sentence, word, or fragment.