@highlight-ui/radio-button
A control that allows the user to toggle between checked and unchecked states. Used to pick one option from a set of multiple available options. If you require a multi-selection input, please use the Checkbox.
Features
- RadioButton
- Controlled component
- Optional label to display next to the RadioButton input
- Optional sub-label to display under the main label
- Optional tooltip placed next to the main input label
- RadioButtonGroup
- Renders multiple RadioButtons given array of options
- Controlled component
- Vertical or horizontal display
- Optional name to apply to all RadioButtons within the group
Installation
Using npm:
npm install @highlight-ui/radio-button
Using yarn:
yarn add @highlight-ui/radio-button
Using pnpm:
pnpm install @highlight-ui/radio-button
In your (S)CSS file:
@import url('@highlight-ui/radio-button');
Once the package is installed, you can import the library:
import { RadioButton, RadioButtonGroup } from '@highlight-ui/radio-button';
Usage
RadioButton
import React, { useState } from 'react';
import { RadioButton } from '@highlight-ui/radio-button';
export default function RadioButtonExample() {
const [checkedStatus, setCheckedStatus] = useState(false);
return (
<RadioButton
id="radio-button"
label="Click me to toggle me"
subLabel="I am only a radio button input"
checked={checkedStatus}
onClick={() => setCheckedStatus(!checkedStatus)}
/>
);
}
RadioButtonGroup
import React, { useState } from 'react';
import { RadioButtonGroup } from '@highlight-ui/radio-button';
export default function RadioButtonGroupExample() {
const [checked, setChecked] = useState<string | number | undefined>(
undefined,
);
const options = [
{ value: 'option-a', label: 'Option A', subLabel: 'Most important' },
{ value: 'option-b', label: 'Option B', subLabel: 'Average' },
{ value: 'option-c', label: 'Option C', subLabel: 'Lowest priority' },
];
return (
<RadioButtonGroup
name="RadioButton-group"
orientation="horizontal"
options={options}
value={checked}
onChange={(option) => setChecked(option.value)}
/>
);
}
Props 📜
RadioButton
All HTMLInputElement
and [PropsWithMetadata(https://gitlab.personio-internal.de/personio/platform/highlight-ui/-/blob/master/packages/utils/commons/src/types.ts#L24)] props are accepted with this component. In addition to these, this component has the following props
Prop | Type | Required | Default | Description |
---|
label | string | No | null | Text displayed next to the radio button input |
subLabel | string | No | null | Text displayed below the main label |
tooltipContent | React.ReactNode | No | null | The content of the tooltip pop-out. When supplied, a tooltip will be placed next to the label. This maps to the TooltipProps['content'] prop types. |
tooltipMouseOutDelay | 'none' , 'medium' , 'long' , or number | No | null | Specifies how to to keep the tooltip opened after the mouse has left the tooltip icon. This maps to the TooltipProps['mouseOutDelay'] prop types. |
tone | default or error | No | default | Sets the tone of the radio button |
RadioButtonGroup
Note that the RadioButtonGroupOption
type matches the RadioButton
listed properties above.
Prop | Type | Required | Default | Description |
---|
value | RadioButtonGroupOption['value'] | Yes | | Currently checked value |
onChange | function(option: RadioButtonGroupOption): void | Yes | | Function called when the checked status of an option changes |
orientation | vertical or horizontal | No | vertical | Display of the radio button group |
options | RadioButtonGroupOption[] | Yes | | Options to render as a group |
Accessibility ♿️
Following base accesibility guidelines, the radio-button input currently:
- Allows clicking radio button input and main label to check or uncheck
- Associates the radio button input with its label through the
for
prop referring to the id
Potential future improvements to make it more accessible:
- Adding focus on the whole radio button and label container
- Including
aria
tags to indicate checked and disabled states - Tooltip accessibility will be addressed in a future release as it is currently not adequate
Testing
There are a number of unit tests covering the RadioButton
and RadioButtonGroup
components, the snippets below can serve as a base to expand future testing if new behaviours are added.
The relevant render methods provide the option to add or override prop values.
RadioButton
import React from 'react';
import { render } from '@testing-library/react';
import { RadioButton, RadioButtonProps } from '@highlight-ui/radio-button';
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
type RadioButtonWrapperProps = Optional<
RadioButtonProps,
'checked' | 'onClick'
>;
function RadioButtonWrapper(props: RadioButtonWrapperProps) {
const [checked, setChecked] = useState(false);
return (
<RadioButton
checked={checked}
onClick={() => setChecked(!checked)}
{...props}
/>
);
}
describe('RadioButtonTest', () => {
const renderRadioButtonWrapper = (props: RadioButtonWrapperProps) => {
return render(<RadioButtonWrapper {...props} />);
};
it('test description', () => {
renderRadioButtonWrapper({});
});
});
RadioButtonGroup
import React from 'react';
import { render } from '@testing-library/react';
import { RadioButtonGroup, RadioButtonGroupProps, RadioButtonGroupOption } from '@highlight-ui/radio-button';
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
type RadioButtonGroupWrapperProps = Optional<
RadioButtonGroupProps,
'value' | 'onChange' | 'options'
>;
function RadioButtonGroupWrapper(props: RadioButtonGroupWrapperProps) {
const [checked, setChecked] = useState<string | number | undefined>(
undefined,
);
const options = [
{ value: 'option-a', label: 'Option A', subLabel: 'Most important' },
{ value: 'option-b', label: 'Option B', subLabel: 'Average' },
{ value: 'option-c', label: 'Option C', subLabel: 'Lowest priority' },
];
return (
<RadioButtonGroup
name="RadioButton-group"
options={options}
value={checked}
onChange={(option) => setChecked(option.value)}
{...props}
/>
);
}
describe('RadioButtonGroupTest', () => {
const renderRadioButtonGroupWrapper = (props: RadioButtonGroupWrapperProps) => {
return render(<RadioButtonWrapper {...props} />);
};
it('test description', () => {
renderRadioButtonGroupWrapper({});
});
};
Place in design system 💻
The radio button and radio button group are components currently unused in other components and packages.
Contributing 🖌️
Please visit personio.design for usage guidelines and visual examples.
If you're interested in contributing, please visit our contribution page.