# SelectChip A Chip and Select control for selecting from a list of options. ## Import ```tsx import { SelectChip } from '@coinbase/cds-web/controls/SelectChip' ``` ## Examples ### Descriptive menu Use when needing to explain an item in detail. Once selected, only show the title within the chip ```jsx live function SelectChipExample() { const options = [ { title: 'All time return', description: 'Lifetime return of each crypto' }, { title: 'Past day’s return', description: "Past day's return on your assets", id: 1 }, { title: 'Balance', description: 'The amount you own of each asset', id: 2 }, { title: 'Price', description: 'The current price of each asset', id: 3 }, ]; const [value, setValue] = useState(options[0].title); const content = ( Metric {options.map(({ title, description, id }) => ( ))} ); return ( ); } ``` ### Simple menu A select chip with dropdown menu. Use when changing format of data ```jsx live function SelectChipExample() { const options = ['USD', 'CAD', 'GBP', 'JPY']; const [value, setValue] = useState(options[0]); const content = ( {options.map((option) => ( ))} ); return ( ); } ``` ### Single selection When utilizing single select, replace the label with the selection. ```jsx live function SelectChipExample() { const options = [ { title: 'Polygon', value: 'polygon', imageUrl: assets.polygon.imageUrl }, { title: 'Ethereum', value: 'ethereum', imageUrl: assets.eth.imageUrl }, { title: 'DAI', value: 'dai', imageUrl: assets.dai.imageUrl }, ]; const [value, setValue] = useState(); const handleChange = (newValue) => { setValue(options.find(({ value }) => value === newValue)); }; const content = ( Networks All networks {options.map(({ title, value, imageUrl }) => { return ( } /> ); })} ); return ( handleChange(newValue)} content={content} minWidth={200} active={value !== undefined} /> ); } ``` ### Sort by Use sort when giving the user the ability to change the order in which data is shown. Avoid using in conjunction with table data as that function is already built into the cells, and this would be duplicative. ```jsx live function SelectChipExample() { const options = [ { label: 'Price', title: 'Price (High to Low)', value: 'price-high-low', iconName: 'arrowDown', }, { label: 'Price', title: 'Price (Low to High)', value: 'price-low-high', iconName: 'arrowUp' }, { label: 'Market Cap', title: 'Market Cap (High to Low)', value: 'market-cap-high-low', iconName: 'arrowDown', }, { label: 'Market Cap', title: 'Market Cap (Low to High)', value: 'market-cap-low-high', iconName: 'arrowUp', }, ]; const [value, setValue] = useState(options[0]); const handleChange = (newValue) => { setValue(options.find(({ value }) => value === newValue)); }; const content = ( Sort by {options.map(({ title, value }) => ( ))} ); return ( } onChange={(newValue) => handleChange(newValue)} content={content} /> ); } ``` ## Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `content` | `null \| string \| number \| false \| true \| ReactElement> \| Iterable \| ReactPortal` | Yes | `-` | - | | `active` | `boolean` | No | `-` | Indicates that the control is being used to manipulate data elsewhere | | `alignContent` | `ResponsiveProp
` | No | `-` | - | | `alignItems` | `ResponsiveProp
` | No | `-` | - | | `alignSelf` | `ResponsiveProp
` | No | `-` | - | | `as` | `button` | No | `-` | - | | `aspectRatio` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - | | `background` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | Background color of the overlay (element being interacted with). | | `blendStyles` | `InteractableBlendStyles` | No | `-` | - | | `block` | `boolean` | No | `false` | Set element to block and expand to 100% width. Makes the Popover Subject fill the width of the parent container | | `borderBottomLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - | | `borderBottomRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - | | `borderBottomWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - | | `borderColor` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | Border color of the element. | | `borderEndWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - | | `borderRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - | | `borderStartWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - | | `borderTopLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - | | `borderTopRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - | | `borderTopWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - | | `borderWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - | | `bordered` | `boolean` | No | `-` | Add a border around all sides of the box. | | `borderedBottom` | `boolean` | No | `-` | Add a border to the bottom side of the box. | | `borderedEnd` | `boolean` | No | `-` | Add a border to the trailing side of the box. | | `borderedHorizontal` | `boolean` | No | `-` | Add a border to the leading and trailing sides of the box. | | `borderedStart` | `boolean` | No | `-` | Add a border to the leading side of the box. | | `borderedTop` | `boolean` | No | `-` | Add a border to the top side of the box. | | `borderedVertical` | `boolean` | No | `-` | Add a border to the top and bottom sides of the box. | | `bottom` | `ResponsiveProp>` | No | `-` | - | | `className` | `string` | No | `-` | Apply class names to the outer container. | | `classNames` | `{ root?: string; content?: string \| undefined; } \| undefined` | No | `-` | Class names for the components | | `color` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - | | `columnGap` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `compact` | `boolean` | No | `-` | Reduces spacing around Chip content | | `contentPosition` | `PopoverContentPositionConfig` | No | `-` | Override content positioning defaults | | `contentStyle` | `CSSProperties` | No | `-` | - | | `controlledElementAccessibilityProps` | `{ id: string; accessibilityLabel?: string; } \| undefined` | No | `-` | - | | `dangerouslySetBackground` | `string` | No | `-` | - | | `disableCloseOnOptionChange` | `boolean` | No | `-` | Prevent menu from closing when an option is selected | | `disablePortal` | `boolean` | No | `-` | Does not render the Dropdown inside of a portal (react-dom createPortal). Portal is automatically disabled for SSR | | `disableTypeFocus` | `boolean` | No | `-` | Use for editable Search Input components to ensure focus is correctly applied | | `disabled` | `boolean` | No | `-` | Is the element currently disabled. Prevents the Dropdown menu from opening. Youll need to surface disabled state on the trigger manually. | | `display` | `ResponsiveProp` | No | `-` | - | | `elevation` | `0 \| 1 \| 2` | No | `-` | - | | `enableMobileModal` | `boolean` | No | `-` | Enable to have Dropdown render its content inside a Modal as opposed to a relatively positioned Popover Ideal for mobile or smaller devices. | | `end` | `null \| string \| number \| false \| true \| ReactElement> \| Iterable \| ReactPortal` | No | `-` | ReactNode placed after the value | | `flexBasis` | `ResponsiveProp>` | No | `-` | - | | `flexDirection` | `ResponsiveProp` | No | `-` | - | | `flexGrow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset` | No | `-` | - | | `flexShrink` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset` | No | `-` | - | | `flexWrap` | `ResponsiveProp` | No | `-` | - | | `focusable` | `boolean` | No | `-` | - | | `font` | `ResponsiveProp` | No | `-` | - | | `fontFamily` | `ResponsiveProp` | No | `-` | - | | `fontSize` | `ResponsiveProp` | No | `-` | - | | `fontWeight` | `ResponsiveProp` | No | `-` | - | | `gap` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `grid` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none` | No | `-` | - | | `gridArea` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - | | `gridAutoColumns` | `ResponsiveProp>` | No | `-` | - | | `gridAutoFlow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| row \| column \| dense` | No | `-` | - | | `gridAutoRows` | `ResponsiveProp>` | No | `-` | - | | `gridColumn` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - | | `gridColumnEnd` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - | | `gridColumnStart` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - | | `gridRow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - | | `gridRowEnd` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - | | `gridRowStart` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - | | `gridTemplate` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none` | No | `-` | - | | `gridTemplateAreas` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none` | No | `-` | - | | `gridTemplateColumns` | `ResponsiveProp>` | No | `-` | - | | `gridTemplateRows` | `ResponsiveProp>` | No | `-` | - | | `height` | `ResponsiveProp>` | No | `-` | - | | `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. | | `justifyContent` | `ResponsiveProp` | No | `-` | - | | `key` | `Key \| null` | No | `-` | - | | `left` | `ResponsiveProp>` | No | `-` | - | | `lineHeight` | `ResponsiveProp` | No | `-` | - | | `margin` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - | | `marginBottom` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - | | `marginEnd` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - | | `marginStart` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - | | `marginTop` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - | | `marginX` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - | | `marginY` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - | | `maxHeight` | `((MaxHeight \| { base?: MaxHeight; phone?: MaxHeight \| undefined; tablet?: MaxHeight \| undefined; desktop?: MaxHeight \| undefined; }) & MaxHeight) \| undefined` | No | `300` | Can optionally pass a maxHeight. | | `maxWidth` | `(((MaxWidth \| { base?: MaxWidth; phone?: MaxWidth \| undefined; tablet?: MaxWidth \| undefined; desktop?: MaxWidth \| undefined; }) & DimensionValue) & MaxWidth) \| undefined` | No | `200` | If text content overflows, it will get truncated with an ellipsis. Maximum width of input as a percentage string or number converted to pixels. | | `minHeight` | `ResponsiveProp>` | No | `-` | - | | `minWidth` | `((MinWidth \| { base?: MinWidth; phone?: MinWidth \| undefined; tablet?: MinWidth \| undefined; desktop?: MinWidth \| undefined; }) & MinWidth) \| undefined` | No | `-` | Minimum width of input as a percentage string or number converted to pixels. | | `numberOfLines` | `number` | No | `1` | How many lines the text in the chip will be broken into. | | `onBlur` | `(() => void)` | No | `-` | Callback that fires when Dropdown or trigger are blurred | | `onChange` | `((newValue: string) => void) \| Dispatch>` | No | `-` | Callback that is fired whenever a select option is selected | | `onCloseMenu` | `(() => void)` | No | `-` | Callback that fires when Dropdown is closed | | `onOpenMenu` | `(() => void)` | No | `-` | Callback that fires when Dropdown is opened | | `opacity` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset` | No | `-` | - | | `overflow` | `ResponsiveProp` | No | `-` | - | | `padding` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `paddingBottom` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `paddingEnd` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `paddingStart` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `paddingTop` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `paddingX` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `paddingY` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `pin` | `top \| bottom \| left \| right \| all` | No | `-` | Direction in which to absolutely pin the box. | | `placeholder` | `string` | No | `-` | Placeholder text displayed inside of the input. Will be replaced if there is a value. | | `position` | `ResponsiveProp` | No | `-` | - | | `pressed` | `boolean` | No | `-` | Is the element being pressed. Primarily a mobile feature, but can be used on the web. | | `ref` | `((instance: unknown) => void) \| RefObject \| null` | No | `-` | - | | `respectNegativeTabIndex` | `boolean` | No | `false` | If true, the focus trap will respect negative tabIndex values, removing them from the list of focusable elements. | | `restoreFocusOnUnmount` | `boolean` | No | `true` | If true, the focus trap will restore focus to the previously focused element when it unmounts. WARNING: If you disable this, you need to ensure that focus is restored properly so it doesnt end up on the body | | `right` | `ResponsiveProp>` | No | `-` | - | | `rowGap` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - | | `showOverlay` | `boolean` | No | `false` | Display an overlay over all content below the Popover menu | | `start` | `null \| string \| number \| false \| true \| ReactElement> \| Iterable \| ReactPortal` | No | `-` | ReactNode placed before the value | | `style` | `CSSProperties` | No | `-` | - | | `styles` | `{ root?: CSSProperties; content?: CSSProperties \| undefined; } \| undefined` | No | `-` | Apply styles to the container and content. | | `testID` | `string` | No | `-` | Used to locate this element in unit and end-to-end tests. Under the hood, testID translates to data-testid on Web. On Mobile, testID stays the same - testID | | `textAlign` | `ResponsiveProp
` | No | `-` | - | | `textDecoration` | `ResponsiveProp` | No | `-` | - | | `textTransform` | `ResponsiveProp` | No | `-` | - | | `top` | `ResponsiveProp>` | No | `-` | - | | `transform` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none` | No | `-` | - | | `transparentWhileInactive` | `boolean` | No | `-` | Mark the background and border as transparent until the element is interacted with (hovered, pressed, etc). Must be used in conjunction with the pressed prop | | `transparentWhilePressed` | `boolean` | No | `-` | Mark the background and border as transparent even while element is interacted with (elevation underlay issue). Must be used in conjunction with the pressed prop | | `type` | `button \| submit \| reset` | No | `-` | - | | `userSelect` | `ResponsiveProp` | No | `-` | - | | `value` | `string` | No | `-` | Pass a value that will prepopulate the select input. This will replace the placeholder text. Default selected value, or preselected value | | `valueLabel` | `string` | No | `-` | Optional label for selected value when using a value/label object model | | `visibility` | `ResponsiveProp` | No | `-` | - | | `width` | `((Width \| { base?: Width; phone?: Width \| undefined; tablet?: Width \| undefined; desktop?: Width \| undefined; }) & Width) \| undefined` | No | `100%` | Width of input as a percentage string or number converted to pixels. | | `zIndex` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |