Select
Used to allow a user to select a value from a list of options.
Import
import { Select, Option } from '@pluralsight/react'
Anatomy
- Container
- Select
- Icon
- Option
Usage
Basic Select
function BasicSelect() {
const [fruit, setFruit] = useState('')
function handleChange(e) {
setFruit(e.target.value)
}
return (
<FormControlProvider required={true}>
<Label htmlFor="fruit">Select Fruit</Label>
<Select
describedBy="select:help"
id="fruit"
name="fruit"
onChange={handleChange}
>
<Option value="apple">Apple</Option>
<Option value="banana">Banana</Option>
<Option value="Passionfruit">Passionfruit</Option>
</Select>
<FieldMessage id="select:help">Please choose a fruit.</FieldMessage>
</FormControlProvider>
)
}
States
The Select shares the same UI states as every field in Pando.
Customizing
There are 3 ways to customize the Select component.
1. Unused Classes
Each component layer of the Select has a unused class name that can be utilized in your local CSS to customize the Select at any level.
pando-select-fieldwrapper
: The container of the Select.pando-select
: The Select element.pando-select-icon
: The Icon element.pando-select-wrapper
: The wrapper of the Select.pando-select-option
: The Option element.
2. Passing a className
prop
You can pass a className
prop to the Select component to customize the Select. This is useful if your project uses CSS Modules or a CSS-in-JS library like Emotion.
import customStyles from './customStyles.module.css'
function CustomSelect(props) {
return <Select className={customStyles.custom} {...props} />
}
function CustomOption(props) {
return <Option className={customStyles.customOption} {...props} />
}
3. Ejected Select
For a low-level "ejected" approach, you can use the Headless-styles API to customize the Select however you prefer while keeping the accessibility behavior.
import {
getSelectProps,
getSelectOptionProps,
} from '@pluralsight/headless-styles'
To learn more about the Headless-styles API, check out the Headless-styles documentation.
Behavior
Layout
Do use a hidden label when using a Select within a Table Cell.
Don't exclude a label when using a Select within a Table Cell, which is not accessible.
Usage
Do use a Select when the list of options exceeds 5 items.
Don't use a Select when the list of options is less than 5 items. Instead, use a Radio group.
Do use a Select when a single option choice is needed from a user.
Don't use a Select to navigate to another location. Instead use a Menu.
Do use a Modal with a Checkbox List when you need to use a multi-select field.
Don't use Select to create a multi-select field.
Do use the styles provided by the Select Option to keep the experience native to the OS/Browser.
Don't re-style or fake a Select Option which is not accessbile and creates a poor user experience for all platforms.
API
Select: FC<SelectProps>
interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
describedBy?: string
pandoSize: 'm' | 'l'
}
Parameters
- Any props that can be passed to a
select
element. describedBy
: The id of the element that describes the Select.pandoSize
: The size of the Select.
Option: FC<OptionProps>
interface OptionProps extends HTMLAttributes<OptionHTMLElement> {
value: string
}
Parameters
- Any props that can be passed to an
option
element. value
: The value of the option.
Accessibility
The Pando Select/Option is fully accessible and screen-readable through the following features:
- The
aria-invalid
attribute is set totrue
when the select is invalid. - The
aria-describedby
attribute is set to theid
of the FieldMessage or ErrorMessage that describes the select. - The
aria-required
attribute is set totrue
when the select is required. - When no value is passed to an Option, the
hidden
anddisabled
attributes are set totrue
. - All icons are hidden from screen readers.