Radio
sl-radio
Shoelace’s Radio component, more commonly called Radio Button, allows the user to select a single option from a group. Radios should always be nested within a Radio Group.
Examples
Basic Radio
Radios are designed to be used with radio groups.
<sl-radio-group label="What would you like to do?" name="a" value="issue_shares" required> <sl-radio value="issue_shares">Issue shares</sl-radio> <sl-radio value="employee_buyback">Employee buyback</sl-radio> <sl-radio value="cancel_certificate">Cancel a certificate</sl-radio> </sl-radio-group>
sl-radio-group[ label="What would you like to do?" name="a" value="issue_shares" required ] sl-radio value="issue_shares" Issue shares sl-radio value="employee_buyback" Employee buyback sl-radio value="cancel_certificate" Cancel a certificate
/* — NOTE: To set default value for initial page load, ensure a value is set in the controller's #new action: e.g. if using `ts_form_for @cap_table_event`, set @cap_table_event = CapTableEvent.new(a: "issue_shares") */ = ts_form_for ... do |f| = f.input :a, as: :radio_buttons, label: "What would you like to do?", collection: [ ["Issue shares", "issue_shares"], ["Employee buyback", "employee_buyback"], ["Cancel a certificate", "cancel_certificate"], ], wrapper_html: { required: true }
import SlRadio from '@teamshares/shoelace/dist/react/radio'; import SlRadioGroup from '@teamshares/shoelace/dist/react/radio-group'; const App = () => ( <SlRadioGroup label="Select an option" name="a" value="1"> <SlRadio value="1">Option 1</SlRadio> <SlRadio value="2">Option 2</SlRadio> <SlRadio value="3">Option 3</SlRadio> </SlRadioGroup> );
This component works with standard <form>
elements. Please refer to the section on
form controls to learn more about form submission and
client-side validation.
Description
Add descriptive help text to individual radio items with the description
attribute. For
descriptions that contain HTML, use the description
slot instead.
<sl-radio-group label="What would you like to do?" name="a" value="issue_shares"> <sl-radio value="issue_shares" description="Awards company shares to an employee">Issue shares</sl-radio> <sl-radio value="employee_buyback" description="Buys back vested shares from departing employee owners">Employee buyback</sl-radio> <sl-radio value="cancel_certificate">Cancel a certificate <div slot="description">Declares certificate to be <em>null and void</em></div> </sl-radio> </sl-radio-group>
sl-radio-group[ label="What would you like to do?" name="a" value="issue_shares" ] sl-radio[ value="issue_shares" description="Awards company shares to an employee" ] | Issue shares sl-radio[ value="employee_buyback" description="Buys back vested shares from departing employee owners" ] | Employee buyback sl-radio[ value="cancel_certificate" ] | Cancel a certificate div slot="description" Declares certificate to be em null and void
/* — NOTE: To set default value for initial page load, ensure a value is set in the controller's #new action: e.g. if using `ts_form_for @cap_table_event`, set @cap_table_event = CapTableEvent.new(a: "issue_shares") — NOTE: Slots are not supported with ts_form_for — — Example below shows usage of "description" as attribute — When rendering `sl-radio-group` with ts_form_for, pass additional attributes such as `disabled` and `description` as extra items in the collection array after the label and value. By default Simple Form will use the first item as the label and the second item as the value, then pass any additional array items as attributes on the `sl-radio`. */ = ts_form_for ... do |f| = f.input :a, as: :radio_buttons, label: "What would you like to do?", collection: [ [ "Issue shares", "issue_shares", description: "Awards company shares to an employee", ], [ "Employee buyback", "employee_buyback", description: "Buys back vested shares from departing employee owners", ], [ "Cancel a certificate", "cancel_certificate", description: "Declares certificate to be null and void", ], ], wrapper_html: { required: true }
import SlRadio from '@teamshares/shoelace/dist/react/radio'; import SlRadioGroup from '@teamshares/shoelace/dist/react/radio-group'; const App = () => ( <SlRadioGroup label="Select an option" name="a" value="1"> <SlRadio value="1">Option 1</SlRadio> <SlRadio value="2">Option 2</SlRadio> <SlRadio value="3">Option 3</SlRadio> </SlRadioGroup> );
Contained
Add the contained
attribute to the Radio Group to draw a
card-like container around each radio item in the radio group. This style is useful for giving more emphasis
to the list of options.
<sl-radio-group label="What would you like to do?" name="a" value="issue_shares" contained> <sl-radio value="issue_shares" description="Awards company shares to an employee">Issue shares</sl-radio> <sl-radio value="employee_buyback" description="Buys back vested shares from departing employee owners">Employee buyback</sl-radio> <sl-radio value="cancel_certificate" disabled>Cancel a certificate <div slot="description">Declares certificate to be <em>null and void</em></div> </sl-radio> </sl-radio-group>
sl-radio-group[ label="What would you like to do?" name="a" value="issue_shares" contained=true ] sl-radio[ value="issue_shares" description="Awards company shares to an employee" ] | Issue shares sl-radio[ value="employee_buyback" description="Buys back vested shares from departing employee owners" ] | Employee buyback sl-radio[ value="cancel_certificate" disabled=true ] | Cancel a certificate div slot="description" Declares certificate to be em null and void
/* — NOTE: To set default value for initial page load, ensure a value is set in the controller's #new action: e.g. if using `ts_form_for @cap_table_event`, set @cap_table_event = CapTableEvent.new(a: "issue_shares") — NOTE: Slots are not supported with ts_form_for — — Example below shows usage of "description" as attribute — When rendering `sl-radio-group` with ts_form_for, pass additional attributes such as `disabled` and `description` as extra items in the collection array after the label and value. By default Simple Form will use the first item as the label and the second item as the value, then pass any additional array items as attributes on the `sl-radio`. */ = ts_form_for ... do |f| = f.input :a, as: :radio_buttons, label: "What would you like to do?", collection: [ [ "Issue shares", "issue_shares", description: "Awards company shares to an employee", ], [ "Employee buyback", "employee_buyback", description: "Buys back vested shares from departing employee owners", ], [ "Cancel a certificate", "cancel_certificate", description: "Declares certificate to be null and void", disabled: true, ] ], wrapper_html: { contained: true }
import { SlRadio } from '@teamshares/shoelace/dist/react'; const App = () => ( <> <SlRadioGroup label="Select an option" name="a" value="3"> <SlRadio contained value="1"> Option 1 </SlRadio> <SlRadio contained value="2" disabled> Option 2 </SlRadio> <SlRadio contained value="3"> Option 3<div slot="description">A short description about this option</div> </SlRadio> </SlRadioGroup> </> );
Adding the contained
attribute to the parent
Radio Group or to any radio in the group will
create contained
radios for the entire group.
Selected Content
Use the selected-content
slot to display additional content (such as an input field) inside a
contained
radio when the radio is selected (checked). The slot is unstyled by default. Use
::part(selected-content)
to style the content as needed.
Note: ts_form_for
doesn’t support slots. The
selected-content
slot cannot be used for radio groups rendered with ts_form_for
.
<sl-radio-group label="Select your payment amount" name="a" value="statement-balance" contained> <sl-radio value="statement-balance" description="$10.00">Last statement balance <div slot="selected-content">This is the amount you owe as of your Feb 21 statement</div> </sl-radio> <sl-radio value="current-balance" description="$150.00">Current balance <div slot="selected-content">This is the amount you owe as of today</div> </sl-radio> <sl-radio value="custom"> Custom amount <sl-input style="width: 240px;" slot="selected-content" label="Amount" type="currency"> </sl-radio> </sl-radio-group> <style> sl-radio::part(selected-content) { font-size: 14px; font-weight: normal; color: #6D7176; } </style>
sl-radio-group[ label="Select your payment amount" name="a" value="statement-balance" contained=true ] sl-radio[ value="statement-balance" description="$10.00" ] | Last statement balance div slot="selected-content" This is the amount you owe as of your Feb 21 statement sl-radio[ value="current-balance" description="$150.00" ] | Current balance div slot="selected-content" This is the amount you owe as of today sl-radio[ value="custom" ] | Custom amount sl-input[ style="width: 240px;" slot="selected-content" label="Amount" type="currency" ] css: sl-radio::part(selected-content) { font-size: 14px; font-weight: normal; color: #6D7176; }
/* NOTE: `ts_form_for` doesn't support slots. The `selected-content` slot cannot be used for radio groups rendered with `ts_form_for`. */
import { SlRadio } from '@teamshares/shoelace/dist/react'; const App = () => ( <> <SlRadioGroup label="Select an option" name="a" value="3"> <SlRadio contained value="1"> Option 1 </SlRadio> <SlRadio contained value="2" disabled> Option 2 </SlRadio> <SlRadio contained value="3"> Option 3<div slot="description">A short description about this option</div> </SlRadio> </SlRadioGroup> </> );
Initial Value
To set the initial value and checked state, use the value
attribute on the containing radio
group. Generally a radio group should have one item selected by default.
Note: When rendering with ts_form_for
, set the initial value in the
controller’s #new action: e.g. if using ts_form_for @cap_table_event
,
@cap_table_event = CapTableEvent.new(a: "issue_shares")
<sl-radio-group label="What would you like to do?" name="a" value="issue_shares"> <sl-radio value="issue_shares">Issue shares</sl-radio> <sl-radio value="employee_buyback">Employee buyback</sl-radio> <sl-radio value="cancel_certificate">Cancel a certificate</sl-radio> </sl-radio-group>
sl-radio-group[ label="What would you like to do?" name="a" value="issue_shares" ] sl-radio value="issue_shares" Issue shares sl-radio value="employee_buyback" Employee buyback sl-radio value="cancel_certificate" Cancel a certificate
/* — NOTE: To set default value for initial page load, ensure a value is set in the controller's #new action: e.g. if using `ts_form_for @cap_table_event`, set @cap_table_event = CapTableEvent.new(a: "issue_shares") */ = ts_form_for ... do |f| = f.input :a, as: :radio_buttons, label: "What would you like to do?", collection: [ ["Issue shares", "issue_shares"], ["Employee buyback", "employee_buyback"], ["Cancel a certificate", "cancel_certificate"], ]
import SlRadio from '@teamshares/shoelace/dist/react/radio'; import SlRadioGroup from '@teamshares/shoelace/dist/react/radio-group'; const App = () => ( <SlRadioGroup label="Select an option" name="a" value="3"> <SlRadio value="1">Option 1</SlRadio> <SlRadio value="2">Option 2</SlRadio> <SlRadio value="3">Option 3</SlRadio> </SlRadioGroup> );
Disabled
Use the disabled
attribute to disable a radio.
<sl-radio-group label="What would you like to do?" name="a" value="issue_shares"> <sl-radio value="issue_shares">Issue shares</sl-radio> <sl-radio value="employee_buyback">Employee buyback</sl-radio> <sl-radio value="cancel_certificate" disabled>Cancel a certificate</sl-radio> </sl-radio-group>
sl-radio-group[ label="What would you like to do?" name="a" value="issue_shares" ] sl-radio value="issue_shares" Issue shares sl-radio value="employee_buyback" Employee buyback sl-radio value="cancel_certificate" disabled=true Cancel a certificate
/* — NOTE: To set default value for initial page load, ensure a value is set in the controller's #new action: e.g. if using `ts_form_for @cap_table_event`, set @cap_table_event = CapTableEvent.new(a: "issue_shares") When rendering `sl-radio-group` with ts_form_for, pass additional attributes such as `disabled` and `description` as extra items in the collection array after the label and value. By default Simple Form will use the first item as the label and the second item as the value, then pass any additional array items as attributes on the `sl-radio`. */ = ts_form_for ... do |f| = f.input :a, as: :radio_buttons, label: "What would you like to do?", collection: [ [ "Issue shares", "issue_shares", ], [ "Employee buyback", "employee_buyback", ], [ "Cancel a certificate", "cancel_certificate", disabled: true, ], ]
import SlRadio from '@teamshares/shoelace/dist/react/radio'; import SlRadioGroup from '@teamshares/shoelace/dist/react/radio-group'; const App = () => ( <SlRadioGroup label="Select an option" name="a" value="1"> <SlRadio value="1">Option 1</SlRadio> <SlRadio value="2" disabled> Option 2 </SlRadio> <SlRadio value="3">Option 3</SlRadio> </SlRadioGroup> );
Usage
- Refer to the Radio Group component general guidelines
Testing
With Cypress
- Radios can be tested through their parent radio group. See Radio Group Testing for details.
Component Props
Note: The following appear as options in the Properties table but are currently not part of the Teamshares Design System. Please check with the design team before using these options:
- Sizes
small
,large
Property | Default | Details |
---|---|---|
value
|
— |
The radio’s value. When selected, the radio group will receive this value. |
size
|
'medium'
|
The radio’s size. When used inside a radio group, the size will be determined by the radio group’s size so this attribute can typically be omitted. |
description
|
''
|
A description of the radio’s label. Serves as help text for individual radio items. If you need to
display HTML, use the |
disabled
|
false
|
Disables the radio. |
contained
|
false
|
Draws a container around the radio. |
horizontal
|
false
|
Applies styles relevant to radios in a horizontal layout. |
updateComplete
|
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Slots
Name | Details |
---|---|
(default) | The radio’s label. |
description
|
A description of the radio’s label. Serves as help text for individual radio items. Alternatively,
you can use the description attribute.
|
selected-content
|
Use to nest rich content (like an input) inside a selected radio item. Use only with the contained style. |
Learn more about using slots.
Events
Name | Name | Name | React Event | Details | |
---|---|---|---|---|---|
sl-blur
|
sl-blur
|
sl-blur
|
onSlBlur
|
Emitted when the control loses focus. |
|
sl-focus
|
sl-focus
|
sl-focus
|
onSlFocus
|
Emitted when the control gains focus. |
Learn more about events.
CSS Parts
Name | Description |
---|---|
base
|
The component’s base wrapper. |
control
|
The circular container that wraps the radio’s checked state. |
control--checked
|
The radio control when the radio is checked. |
checked-icon
|
The checked icon, an <sl-icon> element. |
label
|
The container that wraps the radio’s label. |
description
|
The container that wraps the radio’s description. |
selected-content
|
The container that wraps optional content that appears when a radio is selected (checked). |
Learn more about customizing CSS parts.
Dependencies
This component automatically imports the following dependencies.
-
<sl-icon>