Select is a native HTML select element styled to match the Paste design system, allowing users to choose one or multiple options from a dropdown list.
Installation
yarn add @twilio-paste/select @twilio-paste/label @twilio-paste/help-text
Usage
import { Select, Option } from '@twilio-paste/select';
import { Label } from '@twilio-paste/label';
const MyComponent = () => {
const [value, setValue] = React.useState('');
return (
<>
<Label htmlFor="country">Country</Label>
<Select
id="country"
value={value}
onChange={(e) => setValue(e.target.value)}
>
<Option value="">Select a country</Option>
<Option value="us">United States</Option>
<Option value="uk">United Kingdom</Option>
<Option value="ca">Canada</Option>
</Select>
</>
);
};
Props
Select Props
Must contain Option or OptionGroup components.
Sets the id of the select. Should match the htmlFor of the Label.
The controlled value of the select. Use array when multiple is true.
The default value for uncontrolled selects.
Disables the select, preventing user interaction.
Marks the select as required for form validation.
Sets the select to an error state with error styling.
Allows selection of multiple options. Changes the visual appearance.
When multiple is true, controls how many options are visible at once.
Add a prefix element like an icon to the select.
Add a suffix element to the select.
variant
'default' | 'inverse'
default:"'default'"
Visual style variant. Use inverse for dark backgrounds.
onChange
(event: React.ChangeEvent<HTMLSelectElement>) => void
Callback fired when the selected value changes.
Overrides the default element name for customization.
Examples
With Option Groups
import { Select, Option, OptionGroup } from '@twilio-paste/select';
import { Label } from '@twilio-paste/label';
<>
<Label htmlFor="region">Region</Label>
<Select id="region">
<OptionGroup label="North America">
<Option value="us">United States</Option>
<Option value="ca">Canada</Option>
<Option value="mx">Mexico</Option>
</OptionGroup>
<OptionGroup label="Europe">
<Option value="uk">United Kingdom</Option>
<Option value="de">Germany</Option>
<Option value="fr">France</Option>
</OptionGroup>
</Select>
</>
With Error State
import { Select, Option } from '@twilio-paste/select';
import { Label } from '@twilio-paste/label';
import { HelpText } from '@twilio-paste/help-text';
<>
<Label htmlFor="priority" required>
Priority
</Label>
<Select id="priority" hasError value="">
<Option value="">Select priority</Option>
<Option value="low">Low</Option>
<Option value="medium">Medium</Option>
<Option value="high">High</Option>
</Select>
<HelpText variant="error">
Please select a priority level.
</HelpText>
</>
Multiple Selection
import { Select, Option } from '@twilio-paste/select';
import { Label } from '@twilio-paste/label';
const [values, setValues] = React.useState<string[]>([]);
<>
<Label htmlFor="skills">Skills</Label>
<Select
id="skills"
multiple
size={5}
value={values}
onChange={(e) => {
const selected = Array.from(e.target.selectedOptions, option => option.value);
setValues(selected);
}}
>
<Option value="react">React</Option>
<Option value="typescript">TypeScript</Option>
<Option value="node">Node.js</Option>
<Option value="python">Python</Option>
<Option value="go">Go</Option>
</Select>
</>
With Icon Prefix
import { Select, Option } from '@twilio-paste/select';
import { ProductMessagingIcon } from '@twilio-paste/icons/esm/ProductMessagingIcon';
<Select
insertBefore={<ProductMessagingIcon decorative />}
>
<Option value="sms">SMS</Option>
<Option value="whatsapp">WhatsApp</Option>
<Option value="email">Email</Option>
</Select>
Accessibility
- Always pair Select with a Label using matching
id and htmlFor
- Use
required prop and RequiredDot for required fields
- Group related options with OptionGroup for better organization
- Provide clear option text - avoid abbreviations
- Include a default “Select…” option to make selection explicit
- Use HelpText to provide additional context or error messages
Best Practices
- Use Select when there are 5+ options; for fewer options, consider Radio Group
- Keep option text concise and descriptive
- Order options logically (alphabetically, by popularity, etc.)
- Use OptionGroup to organize large lists of options
- For searchable dropdowns with many options, use Combobox instead
- Always include a default empty option for single selects
- Validate selection server-side even with required attribute