# 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 |