# SelectChipAlpha A chip-styled Select control built on top of the Alpha Select component. Supports both single and multi selection. ## Import ```tsx import { SelectChip } from '@coinbase/cds-web/alpha/select-chip/SelectChip' ``` ## Examples SelectChip is built on top of the [Alpha Select](/components/inputs/SelectAlpha/) 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. :::note 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 ```jsx live function 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 ( ); } ``` ### Single select with groups ```jsx live function 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 ( ); } ``` ### With disabled option group ```jsx live function 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 ( ); } ``` ### Multi-select :::note 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. ::: ```jsx live function 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 ( ); } ``` ### Multi-select with groups ```jsx live function 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 ( ); } ``` ### Compact ```jsx live function 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 ( ); } ``` ### With start and end nodes ```jsx live function 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 ; }; return ( ); } ``` ### Empty options ```jsx live function ExampleEmptyOptions() { const [value, setValue] = useState(null); return ; } ``` ### Options with descriptions ```jsx live function 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 ( ); } ``` ### Disabled ```jsx live function 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 (
); } ``` ## Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `onChange` | `(value: Type extends multi ? SelectOptionValue \| SelectOptionValue[] \| null : SelectOptionValue \| null) => void` | Yes | `-` | - | | `options` | `SelectOptionList` | Yes | `-` | Array of options to display in the select dropdown. Can be individual options or groups with label and options | | `value` | `string \| SelectOptionValue[] \| null` | Yes | `-` | - | | `SelectAllOptionComponent` | `SelectOptionComponent` | No | `-` | Custom component to render the Select All option | | `SelectDropdownComponent` | `SelectDropdownComponent` | No | `-` | Custom component to render the dropdown container | | `SelectEmptyDropdownContentsComponent` | `SelectEmptyDropdownContentComponent` | No | `-` | Custom component to render when no options are available | | `SelectOptionComponent` | `SelectOptionComponent` | No | `-` | Custom component to render individual options | | `SelectOptionGroupComponent` | `SelectOptionGroupComponent` | No | `-` | Custom component to render group headers | | `accessibilityRoles` | `{ dropdown?: AriaHasPopupType; option?: string \| undefined; } \| undefined` | No | `-` | Accessibility roles for dropdown and option elements | | `accessory` | `ReactElement>` | No | `-` | Accessory element rendered at the end of the cell (e.g., chevron). | | `className` | `string` | No | `-` | CSS class name for the root element | | `classNames` | `{ root?: string; control?: string \| undefined; controlStartNode?: string \| undefined; controlInputNode?: string \| undefined; controlValueNode?: string \| undefined; controlLabelNode?: string \| undefined; controlHelperTextNode?: string \| undefined; controlEndNode?: string \| undefined; dropdown?: string \| undefined; option?: string \| undefined; optionCell?: string \| undefined; optionContent?: string \| undefined; optionLabel?: string \| undefined; optionDescription?: string \| undefined; selectAllDivider?: string \| undefined; emptyContentsContainer?: string \| undefined; emptyContentsText?: string \| undefined; optionGroup?: string \| undefined; } \| undefined` | No | `-` | Custom class names for different parts of the select | | `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode | | `compact` | `boolean` | No | `-` | Whether to use compact styling for the select | | `controlAccessibilityLabel` | `string` | No | `-` | Accessibility label for the control | | `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) | | `disableClickOutsideClose` | `boolean` | No | `-` | Whether clicking outside the dropdown should close it | | `disabled` | `boolean` | No | `false` | Toggles input interactability and opacity | | `emptyOptionsLabel` | `string` | No | `-` | Label displayed when there are no options available | | `end` | `null \| string \| number \| false \| true \| ReactElement> \| Iterable \| ReactPortal` | No | `-` | End-aligned content (e.g., value, status). Replaces the deprecated detail prop. | | `endNode` | `null \| string \| number \| false \| true \| ReactElement> \| Iterable \| ReactPortal` | No | `-` | Adds content to the end of the inner input. Refer to diagram for location of endNode in InputStack component | | `hiddenSelectedOptionsLabel` | `string` | No | `-` | Label to show for showcasing count of hidden selected options | | `hideSelectAll` | `boolean` | No | `-` | Whether to hide the Select All option in multi-select mode | | `invertColorScheme` | `boolean` | No | `false` | Invert the foreground and background colors to emphasize the Chip. Depending on your theme, it may be dangerous to use this prop in conjunction with transparentWhileInactive. | | `label` | `null \| string \| number \| false \| true \| ReactElement> \| Iterable \| ReactPortal` | No | `-` | Label displayed above the control | | `maxSelectedOptionsToShow` | `number` | No | `-` | Maximum number of selected options to show before truncating | | `media` | `ReactElement` | No | `-` | Media rendered at the start of the cell (icon, avatar, image, etc). | | `numberOfLines` | `number` | No | `1` | How many lines the text in the chip will be broken into. | | `open` | `boolean` | No | `-` | Controlled open state of the dropdown | | `placeholder` | `null \| string \| number \| false \| true \| ReactElement> \| Iterable \| ReactPortal` | No | `-` | Placeholder text displayed when no option is selected | | `ref` | `null \| (instance: SelectRef \| null) => void \| RefObject` | No | `-` | - | | `removeSelectedOptionAccessibilityLabel` | `string` | No | `-` | Accessibility label for each chip in a multi-select | | `selectAllLabel` | `string` | No | `-` | Label for the Select All option in multi-select mode | | `setOpen` | `((open: boolean \| ((open: boolean) => boolean)) => void)` | No | `-` | Callback to update the open state | | `startNode` | `null \| string \| number \| false \| true \| ReactElement> \| Iterable \| ReactPortal` | No | `-` | Adds content to the start of the inner input. Refer to diagram for location of startNode in InputStack component | | `style` | `CSSProperties` | No | `-` | Inline styles for the root element | | `styles` | `{ root?: CSSProperties; control?: CSSProperties \| undefined; controlStartNode?: CSSProperties \| undefined; controlInputNode?: CSSProperties \| undefined; controlValueNode?: CSSProperties \| undefined; controlLabelNode?: CSSProperties \| undefined; controlHelperTextNode?: CSSProperties \| undefined; controlEndNode?: CSSProperties \| undefined; controlBlendStyles?: InteractableBlendStyles \| undefined; dropdown?: CSSProperties \| undefined; option?: CSSProperties \| undefined; optionCell?: CSSProperties \| undefined; optionContent?: CSSProperties \| undefined; optionLabel?: CSSProperties \| undefined; optionDescription?: CSSProperties \| undefined; optionBlendStyles?: InteractableBlendStyles \| undefined; selectAllDivider?: CSSProperties \| undefined; emptyContentsContainer?: CSSProperties \| undefined; emptyContentsText?: CSSProperties \| undefined; optionGroup?: CSSProperties \| undefined; } \| undefined` | No | `-` | Custom styles for different parts of the select | | `testID` | `string` | No | `-` | Test ID for the root element | | `type` | `single \| multi` | No | `-` | Whether the select allows single or multiple selections |