SelectChip (Alpha)
A chip-styled Select control built on top of the Alpha Select component. Supports both single and multi selection.@coinbase/cds-web@8.38.5
Alpha componentAlpha components are stable and safe to use. They allow us to provide new and powerful features quickly, without forcing breaking changes. Components will exit the alpha status when their deprecated counterpart is removed in the next major version.
import { SelectChip } from '@coinbase/cds-web/alpha/select-chip/SelectChip'
Related components
SelectChip is built on top of the Alpha Select component. It provides a chip-styled interface while maintaining all the functionality of Select, including support for single and multi-selection, option groups, and custom components.
Duplicate Values
Avoid using options with duplicate values. Each option's value should be unique within the options array to ensure proper selection behavior.
Basic usage
Loading...
Live Codefunction ExampleDefault() { const exampleOptions = [ { value: null, label: 'Clear selection' }, { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }, { value: '4', label: 'Option 4' }, ]; const [value, setValue] = useState(null); return ( <SelectChip accessibilityLabel="Select a value" onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> ); }
Single select with groups
Loading...
Live Codefunction ExampleSingleGroups() { const exampleOptions = [ { label: 'Group A', options: [ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }, ], }, { label: 'Group B', options: [ { value: '4', label: 'Option 4' }, { value: '5', label: 'Option 5' }, ], }, { label: 'Group C', options: [{ value: '6', label: 'Option 6' }], }, ]; const [value, setValue] = useState(null); return ( <SelectChip accessibilityLabel="Select a value" onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> ); }
With disabled option group
Loading...
Live Codefunction ExampleDisabledGroup() { const exampleOptions = [ { label: 'Group A', options: [ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }, ], }, { label: 'Group B', disabled: true, options: [ { value: '4', label: 'Option 4' }, { value: '5', label: 'Option 5' }, ], }, { label: 'Group C', options: [{ value: '6', label: 'Option 6' }], }, ]; const [value, setValue] = useState(null); return ( <SelectChip accessibilityLabel="Select a value" onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> ); }
Multi-select
Disabled Options and Select All
Disabled options and options inside disabled groups will be skipped when "Select all" is pressed. Only enabled options will be selected.
Loading...
Live Codefunction ExampleMulti() { const exampleOptions = [ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2', disabled: true }, { value: '3', label: 'Option 3' }, { value: '4', label: 'Option 4' }, { value: '5', label: 'Option 5' }, ]; const { value, onChange } = useMultiSelect({ initialValue: [] }); return ( <SelectChip controlAccessibilityLabel="Select multiple values" onChange={onChange} options={exampleOptions} placeholder="Choose options" type="multi" value={value} /> ); }
Multi-select with groups
Loading...
Live Codefunction ExampleMultiGroups() { const exampleOptions = [ { label: 'Group A', options: [ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }, ], }, { label: 'Group B', options: [ { value: '4', label: 'Option 4' }, { value: '5', label: 'Option 5' }, ], }, { label: 'Group C', options: [{ value: '6', label: 'Option 6' }], }, ]; const { value, onChange } = useMultiSelect({ initialValue: [] }); return ( <SelectChip controlAccessibilityLabel="Select multiple values" onChange={onChange} options={exampleOptions} placeholder="Choose options" type="multi" value={value} /> ); }
Multi-select with assets
Loading...
Live Codefunction ExampleMultiAssets() { const assetImageMap: Record<string, string> = { btc: assets.btc.imageUrl, eth: assets.eth.imageUrl, dai: assets.dai.imageUrl, ltc: assets.ltc.imageUrl, xrp: assets.xrp.imageUrl, }; const exampleOptions = [ { value: 'btc', label: assets.btc.name }, { value: 'eth', label: assets.eth.name }, { value: 'dai', label: assets.dai.name }, { value: 'ltc', label: assets.ltc.name }, { value: 'xrp', label: assets.xrp.name }, ]; const { value, onChange } = useMultiSelect({ initialValue: ['eth', 'btc'], }); // Get startNode based on selected assets const startNode = useMemo(() => { if (value.length === 0) return null; // Multiple assets selected - use RemoteImageGroup return ( <RemoteImageGroup shape="circle" size={24}> {value.map((assetValue) => { const imageUrl = assetImageMap[assetValue]; if (!imageUrl) return null; return <RemoteImage key={assetValue} source={imageUrl} />; })} </RemoteImageGroup> ); }, [value]); return ( <SelectChip controlAccessibilityLabel="Select multiple assets" maxWidth={400} onChange={onChange} options={exampleOptions} placeholder="Choose assets" startNode={startNode} type="multi" value={value} /> ); }
Compact
Loading...
Live Codefunction ExampleCompact() { const exampleOptions = [ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }, { value: '4', label: 'Option 4' }, ]; const [value, setValue] = useState('1'); return ( <SelectChip compact onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> ); }
With start and end nodes
Loading...
Live Codefunction ExampleWithNodes() { const exampleOptions = [ { value: 'btc', label: assets.btc.name }, { value: 'eth', label: assets.eth.name }, { value: 'dai', label: assets.dai.name }, ]; const [value, setValue] = useState('eth'); const getStartNode = (selectedValue) => { if (!selectedValue) return null; const assetMap = { btc: assets.btc.imageUrl, eth: assets.eth.imageUrl, dai: assets.dai.imageUrl, }; const imageUrl = assetMap[selectedValue]; if (!imageUrl) return null; return <RemoteImage height={24} shape="circle" source={imageUrl} width={24} />; }; return ( <SelectChip onChange={setValue} options={exampleOptions} placeholder="Choose an asset" startNode={getStartNode(value)} value={value} /> ); }
Empty options
Loading...
Live Codefunction ExampleEmptyOptions() { const [value, setValue] = useState(null); return <SelectChip onChange={setValue} options={[]} placeholder="Select ..." value={value} />; }
Options with descriptions
Loading...
Live Codefunction ExampleDescriptions() { const exampleOptions = [ { value: '1', label: 'Option 1', description: 'First option description' }, { value: '2', label: 'Option 2', description: 'Second option description' }, { value: '3', label: 'Option 3', description: 'Third option description' }, { value: '4', label: 'Option 4', description: 'Fourth option description' }, ]; const [value, setValue] = useState(null); return ( <SelectChip accessibilityLabel="Select a value" onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> ); }
With display value
Use the displayValue prop to override the displayed value and avoid truncation, especially in multi-select scenarios where multiple option labels might be too long to display.
Loading...
Live Codefunction ExampleDisplayValue() { const exampleOptions = [ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }, { value: '4', label: 'Option 4' }, { value: '5', label: 'Option 5' }, ]; const { value, onChange } = useMultiSelect({ initialValue: [] }); const displayValue = Array.isArray(value) && value.length > 0 ? `${value.length} ${value.length === 1 ? 'option' : 'options'} selected` : undefined; return ( <SelectChip controlAccessibilityLabel="Select multiple values" displayValue={displayValue} onChange={onChange} options={exampleOptions} placeholder="Choose options" type="multi" value={value} /> ); }
With max width
Loading...
Live Codefunction ExampleMaxWidth() { const exampleOptions = [ { value: '1', label: 'Very Long Option Name That Exceeds Default Width' }, { value: '2', label: 'Another Extremely Long Option Label' }, { value: '3', label: 'Short' }, { value: '4', label: 'Medium Length Option' }, ]; const [value, setValue] = useState(null); return ( <VStack gap={2}> <VStack gap={1}> <Text>Default maxWidth (200px):</Text> <SelectChip accessibilityLabel="Select a value" onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> </VStack> <VStack gap={1}> <Text>Custom maxWidth (150px):</Text> <SelectChip accessibilityLabel="Select a value" maxWidth={150} onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> </VStack> <VStack gap={1}> <Text>No maxWidth constraint:</Text> <SelectChip accessibilityLabel="Select a value" maxWidth="100%" onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> </VStack> </VStack> ); }
Disabled
Loading...
Live Codefunction ExampleDisabled() { const exampleOptions = [ { value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }, { value: '4', label: 'Option 4' }, ]; const [value, setValue] = useState('1'); return ( <VStack gap={2}> <SelectChip disabled accessibilityLabel="Select a value" onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={null} /> <SelectChip disabled accessibilityLabel="Select a value" onChange={setValue} options={exampleOptions} placeholder="Choose an option" value={value} /> </VStack> ); }