Skip to content

Multi Select

Edit on GitHub

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
Electric
EX30
EX40
EX90
Traditional
XC40
XC60
XC90
Show codeHide 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>
);
}

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.

EX30
EX90
XC60
V90
S60
Show codeHide 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>
);
}

Use description for an option’s supplementary line. Pass a plain-text label when children contain custom markup so type-ahead can match it.

EX30
Small SUV
EX90
Large SUV
XC40
Compact crossover
XC60
Midsize crossover
XC90
Large premium SUV
Show codeHide 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>
);
}
EX30
EX90
XC40
XC60
Pick every model you're interested in.
Show codeHide 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>
);
}
EX30
EX90 (sold out)
XC40
Show codeHide 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>
);
}
EX30
EX90
XC40
XC60
XC90

Please select at least one model

Show codeHide 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>
);
}