Chips
Chips are compact interactive elements for selecting options or dismissing applied filters.
@volvo-cars/css v2.5.1
Chip Selectable Small
Section titled “Chip Selectable Small”Show code
import { useState } from 'react';
const options = ['Hybrid', 'Electric', 'Petrol'];
export function ChipSelectableSmall() { const [selected, setSelected] = useState<string[]>([]);
const toggle = (option: string) => { setSelected((prev) => prev.includes(option) ? prev.filter((s) => s !== option) : [...prev, option], ); };
return ( <div className="flex gap-8"> {options.map((option) => ( <button key={option} type="button" className="chip-selectable" data-size="small" aria-pressed={selected.includes(option)} onClick={() => toggle(option)} > {option} </button> ))} </div> );}Chip Radio
Section titled “Chip Radio”Show code
import { useState } from 'react';
const options = ['Hybrid', 'Electric', 'Petrol'];
export function ChipRadio() { const [selected, setSelected] = useState('Hybrid');
return ( <div role="radiogroup" aria-label="Powertrain" className="flex gap-8"> {options.map((option) => ( <button key={option} type="button" role="radio" className="chip-selectable" aria-checked={selected === option} onClick={() => setSelected(option)} > {option} </button> ))} </div> );}Chip Dismissible
Section titled “Chip Dismissible”Show code
import { IconButton } from '@volvo-cars/react-icons';import { useState } from 'react';
const initial = ['EX90', 'EX30', 'XC90'];
export function ChipDismissible() { const [chips, setChips] = useState(initial);
return ( <div className="flex flex-wrap gap-8" role="list" aria-label="Selected models" > {chips.map((chip) => ( <div key={chip} role="listitem" className="chip-dismissible"> {chip} <IconButton aria-label={`Remove ${chip}`} slot="dismiss" variant="clear" bleed icon="x" onClick={() => setChips((prev) => prev.filter((c) => c !== chip))} /> </div> ))} </div> );}Chip Dismissible Loading
Section titled “Chip Dismissible Loading”Show code
import { IconButton } from '@volvo-cars/react-icons';import { useState } from 'react';
export function ChipDismissibleLoading() { const [loading, setLoading] = useState(false);
return ( <div className="flex gap-8"> <div className="chip-dismissible" data-loading={loading || undefined} aria-busy={loading} > {loading ? ( <> <span className="invisible">EX90</span> <progress className="spinner" aria-label="Loading" /> </> ) : ( 'EX90' )} <IconButton aria-label="Remove EX90" slot="dismiss" variant="clear" bleed icon="x" onClick={() => { setLoading(true); setTimeout(() => setLoading(false), 2000); }} /> </div> <div className="chip-dismissible"> EX30 <IconButton aria-label="Remove EX30" slot="dismiss" variant="clear" bleed icon="x" /> </div> </div> );}