Components
Radio
A Radio is an option the user can select. Use multiple radio to show a list of options. Users can switch between the options, but can only select one.
HTML
Unable to parse html
const Preview = () => { return <Radio label='Radio' value='value' name='name' />; }; render(<Preview />)
Usage
Use the class ds-input on <input> together with type="radio".
For a valid form element, we recommend using <ds-field> together with a <label>.
CSS variables and data attributes
Sizes are controlled with data-size and colors with data-color. The component will inherit from the closest parent where these are set.
Radio is ds-input with type="radio", so variables and data attributes that apply to input also apply to radio.
| Name | Value |
|---|---|
| --dsc-input-padding-block | var(--ds-size-2) |
| --dsc-input-padding-inline | var(--ds-size-3) |
| --dsc-input-padding | var(--dsc-input-padding-block) var(--dsc-input-padding-inline) |
| --dsc-input-size--toggle | var(--ds-size-6) |
| --dsc-input-size | var(--ds-size-12) |
| --dsc-input-background--readonly | var(--ds-color-neutral-surface-tinted) |
| --dsc-input-background | var(--ds-color-neutral-surface-default) |
| --dsc-input-border-color--readonly | var(--ds-color-neutral-border-subtle) |
| --dsc-input-border-color | var(--ds-color-neutral-border-default) |
| --dsc-input-border-style | solid |
| --dsc-input-border-width--toggle | max(var(--ds-border-width-default),calc(var(--ds-size-1)/2)) |
| --dsc-input-border-width | var(--ds-border-width-default) |
| --dsc-input-outline-color--hover | var(--ds-color-neutral-border-default) |
| --dsc-input-outline-color--toggle--hover | var(--dsc-input-accent-color) |
| --dsc-input-outline-width--hover | var(--ds-border-width-default) |
| --dsc-input-outline-style--hover | solid |
| --dsc-input-color--readonly | var(--ds-color-neutral-text-default) |
| --dsc-input-color | var(--ds-color-neutral-text-default) |
| --dsc-input-stroke-color | var(--ds-color-base-contrast-default) |
| --dsc-input-stroke-color--invalid | var(--ds-color-danger-base-contrast-default) |
| --dsc-input-stroke-width | 0.05em |
| --dsc-input-accent-color | var(--ds-color-base-default) |
| --dsc-input-accent-color--invalid | var(--ds-color-danger-text-subtle) |
| --dsc-input-line-height | var(--ds-line-height-md) |
| Name | Value |
|---|---|
| data-width | auto |
Examples
Grouping
Use fieldset for grouping multiple choices.
HTML
Unable to parse html
const GroupEn = () => { const { getRadioProps } = useRadioGroup({ name: 'contact', value: 'email', }); return ( <Fieldset> <Fieldset.Legend>How would you like us to contact you?</Fieldset.Legend> <Fieldset.Description> Choose the method that works best for you. We use this only to send important updates about your case. </Fieldset.Description> <Radio label='Email' description='We will use the email address you provided earlier (name@example.com)' {...getRadioProps('email')} /> <Radio label='SMS' description='We will use the phone number you provided earlier (99 99 99 99)' {...getRadioProps('sms')} /> <Radio label='Letter' description='Delivery may take 3-5 working days, depending on the postal service.' {...getRadioProps('letter')} /> </Fieldset> ); }; render(<GroupEn />)
Outline
data-variant="outline" adds extra padding and a border around the option to create a larger clickable area.
HTML
Unable to parse html
const OutlineEn = () => { const { getRadioProps } = useRadioGroup({ name: 'course-level', variant: 'outline', }); return ( <Fieldset> <Fieldset.Legend>Which course level fits you best?</Fieldset.Legend> <Fieldset.Description> Choose the level that best describes your experience with the topic. </Fieldset.Description> <Radio label='Beginner' description='Best for you if you are completely new and want a gentle introduction.' {...getRadioProps('beginner')} /> <Radio label='Intermediate' description='Best for you if you know the basics and want to go deeper.' {...getRadioProps('intermediate')} /> <Radio label='Expert' description='Best for you if you want advanced topics and hands-on cases.' {...getRadioProps('expert')} /> </Fieldset> ); }; render(<OutlineEn />)
Inline
Radio can be positioned horizontally with flex, but should generally be placed vertically.
HTML
Unable to parse html
const InlineEn = () => { return ( <Fieldset> <Fieldset.Legend>Contact by email?</Fieldset.Legend> <Fieldset.Description> Confirm whether you would like to be contacted by email. </Fieldset.Description> <div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--ds-size-6)' }} > <Radio name='my-inline' label='Yes' value='yes' /> <Radio name='my-inline' label='No' value='no' /> </div> </Fieldset> ); }; render(<InlineEn />)
ReadOnly
type="radio" is always :read-only and does not support this in the same way as input types you can type into.
If you set readonly on radio, we ensure that it behaves as if it has read-only access by stopping onClick and onChange.
The user will still be able to focus on the element.
HTML
Unable to parse html
const ReadOnly = () => ( <Radio label='Radio' value='value' name='name' readOnly /> ); render(<ReadOnly />)
React
In React, building a radio is easier, because we have a ready-made component that handles most of the logic and state management for us.
Radio is a composite component that uses field, label, validation message, and input to create a radio.
In addition, we have a dedicated useRadioGroup React hook to make it easier to manage a group of Radio components.
- disabled
- Description
Disables element @note Avoid using if possible for accessibility purposes
- Type
boolean
- readOnly
- Description
Toggle `readOnly`
- Type
boolean
- data-indeterminate
- Description
Indeterminate state for checkbox inputs Only works when used inside `Field` component
- Type
boolean- Default
false
- aria-label
- Description
Optional aria-label
- Type
string
- label
- Description
Radio label
- Type
ReactNode
- description
- Description
Description for field
- Type
ReactNode
- value
- Description
Value of the `input` element
- Type
string | number | readonly string[]
- error
- Description
Error message for field
- Type
ReactNode
- variant
- Description
If outline, the radio will have a border.
- Type
"outline"
- aria-labelledby
- Type
string
| Name | Type | Default | Description |
|---|---|---|---|
| disabled | boolean | - | Disables element @note Avoid using if possible for accessibility purposes |
| readOnly | boolean | - | Toggle `readOnly` |
| data-indeterminate | boolean | false | Indeterminate state for checkbox inputs Only works when used inside `Field` component |
| aria-label | string | - | Optional aria-label |
| label | ReactNode | - | Radio label |
| description | ReactNode | - | Description for field |
| value | string | number | readonly string[] | - | Value of the `input` element |
| error | ReactNode | - | Error message for field |
| variant | "outline" | - | If outline, the radio will have a border. |
| aria-labelledby | string | - | - |