Multi Select
Lets users select multiple options from a dropdown list, with optional grouping.
@volvo-cars/css v3.1.0@volvo-cars/react-forms v3.1.0
Option groups
Section titled “Option groups”Show code
import { MultiSelect, Option, OptionGroup } from '@volvo-cars/react-forms';import { useState } from 'react';
export function MultiSelectGroups() { const [selected, setSelected] = useState<string[]>([]);
return ( <MultiSelect name="models" label="Car models" value={selected} onValueChange={setSelected} > <OptionGroup label="Electric"> <Option value="ex30">EX30</Option> <Option value="ex40">EX40</Option> <Option value="ex90">EX90</Option> </OptionGroup> <OptionGroup label="Traditional"> <Option value="xc40">XC40</Option> <Option value="xc60">XC60</Option> <Option value="xc90">XC90</Option> </OptionGroup> </MultiSelect> );}Selections as chips
Section titled “Selections as chips”Show each selection as a dismissible chip when users need to see and remove selections without opening the list. The chip’s dismiss button removes the value from the same state as the field.
Show code
import { MultiSelect, Option } from '@volvo-cars/react-forms';import { IconButton } from '@volvo-cars/react-icons';import { useState } from 'react';
const models: Record<string, string> = { ex30: 'EX30', ex90: 'EX90', xc60: 'XC60', v90: 'V90', s60: 'S60',};
export function MultiSelectWithChips() { const [selected, setSelected] = useState<string[]>([]);
return ( <div className="stack-16"> <MultiSelect name="models" label="Car models" value={selected} onValueChange={setSelected} > {Object.entries(models).map(([value, label]) => ( <Option key={value} value={value}> {label} </Option> ))} </MultiSelect> {selected.length > 0 && ( <div className="flex flex-wrap gap-8" role="list" aria-label="Selected car models" > {selected.map((value) => ( <div key={value} role="listitem" className="chip-dismissible"> {models[value]} <IconButton aria-label={`Remove ${models[value]}`} slot="dismiss" variant="clear" bleed icon="x" onClick={() => setSelected((current) => current.filter((v) => v !== value)) } /> </div> ))} </div> )} </div> );}Option descriptions
Section titled “Option descriptions”Use description for an option’s supplementary line. Pass a plain-text label when children contain custom markup so type-ahead can match it.
Show code
import { MultiSelect, Option } from '@volvo-cars/react-forms';import { useState } from 'react';
export function MultiSelectMultilineOption() { const [selected, setSelected] = useState<string[]>([]);
return ( <MultiSelect name="models" label="Car models" value={selected} onValueChange={setSelected} > <Option value="ex30" description="Small SUV"> EX30 </Option> <Option value="ex90" description="Large SUV"> EX90 </Option> <Option value="xc40" description="Compact crossover"> XC40 </Option> <Option value="xc60" description="Midsize crossover"> XC60 </Option> <Option value="xc90" description="Large premium SUV"> XC90 </Option> </MultiSelect> );}Show code
import { MultiSelect, Option } from '@volvo-cars/react-forms';import { useState } from 'react';
export function MultiSelectHint() { const [selected, setSelected] = useState<string[]>([]);
return ( <MultiSelect name="models" label="Car models" hint="Pick every model you're interested in." value={selected} onValueChange={setSelected} > <Option value="ex30">EX30</Option> <Option value="ex90">EX90</Option> <Option value="xc40">XC40</Option> <Option value="xc60">XC60</Option> </MultiSelect> );}Disabled option
Section titled “Disabled option”Show code
import { MultiSelect, Option } from '@volvo-cars/react-forms';import { useState } from 'react';
export function MultiSelectDisabledOption() { const [selected, setSelected] = useState<string[]>([]);
return ( <MultiSelect name="models" label="Car models" value={selected} onValueChange={setSelected} > <Option value="ex30">EX30</Option> <Option value="ex90" disabled> EX90 (sold out) </Option> <Option value="xc40">XC40</Option> </MultiSelect> );}Validation error
Section titled “Validation error”Show code
import { MultiSelect, Option } from '@volvo-cars/react-forms';import { useState } from 'react';
export function MultiSelectError() { const [selected, setSelected] = useState<string[]>([]);
return ( <MultiSelect name="models" label="Car models" value={selected} onValueChange={setSelected} errorMessage={ selected.length === 0 ? 'Please select at least one model' : undefined } > <Option value="ex30">EX30</Option> <Option value="ex90">EX90</Option> <Option value="xc40">XC40</Option> <Option value="xc60">XC60</Option> <Option value="xc90">XC90</Option> </MultiSelect> );}