# Combobox

**📖 Live documentation:** https://cds.coinbase.com/components/inputs/Combobox/?platform=mobile

A flexible combobox component for both single and multi-selection, built for mobile applications with comprehensive accessibility support.

## Import

```tsx
import { Combobox } from '@coinbase/cds-mobile/alpha/combobox'
```

## Examples

### Basics

To start, you can provide a label, an array of options, control state.

```jsx
function SingleSelect() {
  const singleSelectOptions = [
    { value: null, label: 'Remove selection' },
    { value: '1', label: 'Option 1' },
    { value: '2', label: 'Option 2' },
    { value: '3', label: 'Option 3' },
  ];
  const [value, setValue] = useState(null);

  return (
    <Combobox
      label="Single Select"
      onChange={setValue}
      options={singleSelectOptions}
      placeholder="Search..."
      value={value}
    />
  );
}
```

#### Multiple Selections

You can also allow users to select multiple options with `type="multi"`.

```jsx
function MultiSelect() {
  const multiSelectOptions = [
    { 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: ['1'] });

  return (
    <Combobox
      label="Multi Select"
      onChange={onChange}
      options={multiSelectOptions}
      placeholder="Search..."
      type="multi"
      value={value}
    />
  );
}
```

### Search

We use [fuse.js](https://www.fusejs.io/) for fuzzy search by default. You can override with `filterFunction`.

```jsx
function CustomFilter() {
  const cryptoOptions = [
    { value: 'btc', label: 'Bitcoin', description: 'BTC • Digital Gold' },
    { value: 'eth', label: 'Ethereum', description: 'ETH • Smart Contracts' },
    { value: 'usdc', label: 'USD Coin', description: 'USDC • Stablecoin' },
    { value: 'sol', label: 'Solana', description: 'SOL • High Performance' },
  ];
  const { value, onChange } = useMultiSelect({ initialValue: [] });

  const filterFunction = (options, searchText) => {
    const search = searchText.toLowerCase().trim();
    if (!search) return options;
    return options.filter((option) => {
      const label = typeof option.label === 'string' ? option.label.toLowerCase() : '';
      const description =
        typeof option.description === 'string' ? option.description.toLowerCase() : '';
      return label.startsWith(search) || description.startsWith(search);
    });
  };

  return (
    <Combobox
      filterFunction={filterFunction}
      label="Custom filter (starts with)"
      onChange={onChange}
      options={cryptoOptions}
      placeholder="Type to filter..."
      type="multi"
      value={value}
    />
  );
}
```

### Grouped

Display options under headers using `label` and `options`. Sort options by the same dimension you group by.

```jsx
function GroupedOptions() {
  const groupedOptions = [
    {
      label: 'Fruits',
      options: [
        { value: 'apple', label: 'Apple' },
        { value: 'banana', label: 'Banana' },
        { value: 'cherry', label: 'Cherry' },
      ],
    },
    {
      label: 'Vegetables',
      options: [
        { value: 'carrot', label: 'Carrot' },
        { value: 'broccoli', label: 'Broccoli' },
        { value: 'spinach', label: 'Spinach' },
      ],
    },
  ];
  const { value, onChange } = useMultiSelect({ initialValue: [] });

  return (
    <Combobox
      label="Category"
      onChange={onChange}
      options={groupedOptions}
      placeholder="Search by category..."
      type="multi"
      value={value}
    />
  );
}
```

### Accessibility

Use `accessibilityLabel` and `accessibilityHint` to describe purpose and additional context. For multi-select, add hidden-selection labels so screen readers can describe +X summaries.

```jsx
function AccessibilityProps() {
  const priorityOptions = [
    { value: 'high', label: 'High Priority' },
    { value: 'medium', label: 'Medium Priority' },
    { value: 'low', label: 'Low Priority' },
  ];

  const { value, onChange } = useMultiSelect({ initialValue: ['medium'] });

  return (
    <Combobox
      accessibilityHint="Select one or more priorities"
      accessibilityLabel="Task priority combobox"
      accessibilityRoles={{ option: 'button' }}
      hiddenSelectedOptionsLabel="priorities"
      label="Task Priority"
      maxSelectedOptionsToShow={1}
      onChange={onChange}
      options={priorityOptions}
      placeholder="Choose priority..."
      type="multi"
      value={value}
    />
  );
}
```

### Styling

#### Selection Display Limit

Cap visible chips with `maxSelectedOptionsToShow`; the rest show as +X more. Pair with `hiddenSelectedOptionsLabel` for screen readers.

```jsx
function LimitDisplayedSelections() {
  const countryOptions = [
    { value: 'us', label: 'United States', description: 'North America' },
    { value: 'ca', label: 'Canada', description: 'North America' },
    { value: 'mx', label: 'Mexico', description: 'North America' },
    { value: 'uk', label: 'United Kingdom', description: 'Europe' },
    { value: 'fr', label: 'France', description: 'Europe' },
    { value: 'de', label: 'Germany', description: 'Europe' },
  ];
  const { value, onChange } = useMultiSelect({
    initialValue: ['us', 'ca', 'mx', 'uk'],
  });

  return (
    <Combobox
      hiddenSelectedOptionsLabel="countries"
      label="Countries"
      maxSelectedOptionsToShow={2}
      onChange={onChange}
      options={countryOptions}
      placeholder="Select countries..."
      type="multi"
      value={value}
    />
  );
}
```

#### Alignment

Align selected values with the `align` prop.

```jsx
function AlignmentExample() {
  const fruitOptions = [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'cherry', label: 'Cherry' },
    { value: 'date', label: 'Date' },
  ];
  const { value, onChange } = useMultiSelect({ initialValue: ['apple', 'banana'] });

  return (
    <VStack gap={2}>
      <Combobox
        align="start"
        label="Align start"
        onChange={onChange}
        options={fruitOptions}
        placeholder="Search..."
        type="multi"
        value={value}
      />
      <Combobox
        align="end"
        label="Align end"
        onChange={onChange}
        options={fruitOptions}
        placeholder="Search..."
        type="multi"
        value={value}
      />
    </VStack>
  );
}
```

#### Borderless

Remove the border with `bordered={false}`.

```jsx
function BorderlessExample() {
  const fruitOptions = [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'cherry', label: 'Cherry' },
  ];
  const [value, setValue] = useState('apple');

  return (
    <Combobox
      bordered={false}
      label="Borderless"
      onChange={setValue}
      options={fruitOptions}
      placeholder="Search..."
      value={value}
    />
  );
}
```

#### Compact

Use smaller sizing with `compact`.

```jsx
function CompactExample() {
  const fruitOptions = [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'cherry', label: 'Cherry' },
  ];
  const { value, onChange } = useMultiSelect({ initialValue: ['apple'] });

  return (
    <Combobox
      compact
      label="Compact"
      onChange={onChange}
      options={fruitOptions}
      placeholder="Compact combobox..."
      type="multi"
      value={value}
    />
  );
}
```

#### Helper Text

Add guidance with `helperText`.

```jsx
function HelperTextExample() {
  const { value, onChange } = useMultiSelect({ initialValue: [] });
  const fruitOptions = [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'cherry', label: 'Cherry' },
    { value: 'date', label: 'Date' },
  ];

  return (
    <Combobox
      helperText="Choose more than one fruit"
      label="Select fruits"
      onChange={onChange}
      options={fruitOptions}
      placeholder="Search and select fruits..."
      type="multi"
      value={value}
    />
  );
}
```

### Composed Examples

#### Country Selection

You can include flag emoji in labels to create a country selector.

```jsx
function CountrySelectionExample() {
  const getFlagEmoji = (cc) =>
    cc
      .toUpperCase()
      .split('')
      .map((c) => String.fromCodePoint(0x1f1e6 - 65 + c.charCodeAt(0)))
      .join('');

  const countryOptions = [
    {
      label: 'North America',
      options: [
        { value: 'us', label: `${getFlagEmoji('us')} United States` },
        { value: 'ca', label: `${getFlagEmoji('ca')} Canada` },
        { value: 'mx', label: `${getFlagEmoji('mx')} Mexico` },
      ],
    },
    {
      label: 'Europe',
      options: [
        { value: 'uk', label: `${getFlagEmoji('gb')} United Kingdom` },
        { value: 'fr', label: `${getFlagEmoji('fr')} France` },
        { value: 'de', label: `${getFlagEmoji('de')} Germany` },
      ],
    },
    {
      label: 'Asia',
      options: [
        { value: 'jp', label: `${getFlagEmoji('jp')} Japan` },
        { value: 'cn', label: `${getFlagEmoji('cn')} China` },
        { value: 'in', label: `${getFlagEmoji('in')} India` },
      ],
    },
  ];

  const { value, onChange } = useMultiSelect({ initialValue: [] });

  return (
    <Combobox
      label="Country"
      maxSelectedOptionsToShow={3}
      onChange={onChange}
      options={countryOptions}
      placeholder="Select countries..."
      type="multi"
      value={value}
    />
  );
}
```

#### Free Solo

You can add a dynamic option to Combobox to enable free solo where users can provide their own value.

```jsx
function FreeSoloComboboxExample() {
  const CREATE_OPTION_PREFIX = '__create__';

  function FreeSoloCombobox({
    freeSolo = false,
    options: initialOptions,
    value,
    onChange,
    placeholder = 'Search or type to add...',
    ...comboboxProps
  }) {
    const [searchText, setSearchText] = useState('');
    const [options, setOptions] = useState(initialOptions);

    useEffect(() => {
      if (!freeSolo) return;
      const initialSet = new Set(initialOptions.map((o) => o.value));
      const valueSet = new Set(Array.isArray(value) ? value : value != null ? [value] : []);
      setOptions((prev) => {
        const addedStillSelected = prev.filter(
          (o) => !initialSet.has(o.value) && valueSet.has(o.value),
        );
        return [...initialOptions, ...addedStillSelected];
      });
    }, [value, freeSolo, initialOptions]);

    const optionsWithCreate = useMemo(() => {
      if (!freeSolo) return options;
      const trimmed = searchText.trim();
      if (!trimmed) return options;
      const alreadyExists = options.some(
        (o) => typeof o.label === 'string' && o.label.toLowerCase() === trimmed.toLowerCase(),
      );
      if (alreadyExists) return options;
      return [
        ...options,
        { value: `${CREATE_OPTION_PREFIX}${trimmed}`, label: `Add "${trimmed}"` },
      ];
    }, [options, searchText, freeSolo]);

    const handleChange = useCallback(
      (newValue) => {
        if (!freeSolo) {
          onChange(newValue);
          return;
        }
        const values = Array.isArray(newValue) ? newValue : newValue ? [newValue] : [];
        const createValue = values.find((v) => String(v).startsWith(CREATE_OPTION_PREFIX));
        if (createValue) {
          const newLabel = String(createValue).slice(CREATE_OPTION_PREFIX.length);
          const newOption = { value: newLabel.toLowerCase(), label: newLabel };
          setOptions((prev) => [...prev, newOption]);
          const updatedValues = values
            .filter((v) => !String(v).startsWith(CREATE_OPTION_PREFIX))
            .concat(newOption.value);
          onChange(comboboxProps.type === 'multi' ? updatedValues : newOption.value);
          setSearchText('');
        } else {
          onChange(newValue);
        }
      },
      [onChange, freeSolo, comboboxProps.type],
    );

    return (
      <Combobox
        {...comboboxProps}
        {...(freeSolo ? { searchText, onSearch: setSearchText } : {})}
        onChange={handleChange}
        options={freeSolo ? optionsWithCreate : initialOptions}
        placeholder={placeholder}
        value={value}
      />
    );
  }

  const [standardSingleValue, setStandardSingle] = useState(null);
  const [freeSoloSingleValue, setFreeSoloSingle] = useState(null);
  const standardMulti = useMultiSelect({ initialValue: [] });
  const freeSoloMulti = useMultiSelect({ initialValue: [] });

  const fruitOptions = [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'cherry', label: 'Cherry' },
    { value: 'date', label: 'Date' },
    { value: 'elderberry', label: 'Elderberry' },
    { value: 'fig', label: 'Fig' },
  ];

  return (
    <VStack gap={4}>
      <FreeSoloCombobox
        freeSolo={false}
        label="Standard single"
        onChange={setStandardSingle}
        options={fruitOptions}
        placeholder="Search fruits..."
        type="single"
        value={standardSingleValue}
      />
      <FreeSoloCombobox
        freeSolo
        label="FreeSolo single"
        onChange={setFreeSoloSingle}
        options={fruitOptions}
        placeholder="Search or type to add..."
        type="single"
        value={freeSoloSingleValue}
      />
      <FreeSoloCombobox
        freeSolo={false}
        label="Standard multi"
        onChange={standardMulti.onChange}
        options={fruitOptions}
        placeholder="Search fruits..."
        type="multi"
        value={standardMulti.value}
      />
      <FreeSoloCombobox
        freeSolo
        label="FreeSolo multi"
        onChange={freeSoloMulti.onChange}
        options={fruitOptions}
        placeholder="Search or type to add..."
        type="multi"
        value={freeSoloMulti.value}
      />
    </VStack>
  );
}
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `onChange` | `(value: Type extends multi ? SelectOptionValue \| SelectOptionValue[] \| null : SelectOptionValue \| null) => void` | Yes | `-` | - |
| `options` | `SelectOptionList<Type, SelectOptionValue>` | 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 | `-` | - |
| `ComboboxControlComponent` | `ComboboxControlComponent` | No | `-` | - |
| `ComboboxDropdownComponent` | `SelectDropdownComponent` | No | `-` | - |
| `SelectAllOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the Select All option |
| `SelectControlComponent` | `SelectControlComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the select control |
| `SelectDropdownComponent` | `SelectDropdownComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render the dropdown container |
| `SelectEmptyDropdownContentsComponent` | `SelectEmptyDropdownContentComponent` | No | `-` | Custom component to render when no options are available |
| `SelectOptionComponent` | `SelectOptionComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render individual options |
| `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
| `accessibilityRoles` | `{ option?: AccessibilityRole; } \| undefined` | No | `-` | Accessibility roles for dropdown elements |
| `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | Accessory element rendered at the end of the cell (e.g., chevron). |
| `align` | `end \| start \| center` | No | `'start'` | Alignment of the value node. |
| `borderRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `200` | Leverage one of the borderRadius styles we offer to round the corners of the input. |
| `borderWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `100 when bordered is true, 0 otherwise` | Width of the border. |
| `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Determines if the control should have a default border. |
| `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
| `closeButtonLabel` | `string` | No | `-` | Label for close button when combobox is open (mobile only) |
| `compact` | `boolean` | No | `-` | Whether to use compact styling for the select |
| `defaultOpen` | `boolean` | No | `-` | Initial open state when component mounts (uncontrolled mode) |
| `defaultSearchText` | `string` | No | `-` | Default search text value for 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 \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | End-aligned content (e.g., value, status). Replaces the deprecated detail prop. |
| `endNode` | `null \| string \| number \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | Adds content to the end of the inner input. Refer to diagram for location of endNode in InputStack component |
| `filterFunction` | `((options: SelectOptionList<Type, SelectOptionValue>, searchText: string) => SelectOption<SelectOptionValue>[])` | No | `-` | Custom filter function for searching options |
| `focusedBorderWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `200 when bordered is false, otherwise equals borderWidth` | Additional border width when focused. |
| `font` | `display1 \| display2 \| display3 \| title1 \| title2 \| title3 \| title4 \| headline \| body \| label1 \| label2 \| caption \| legal` | No | `body` | Typography font token for the field (passed through to NativeInput as font), same token family as align. |
| `helperText` | `null \| string \| number \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | Helper text displayed below the select |
| `hiddenSelectedOptionsLabel` | `string` | No | `-` | Label to show for showcasing count of hidden selected options |
| `hideSearchInput` | `boolean` | No | `-` | Hide the search input |
| `hideSelectAll` | `boolean` | No | `-` | Whether to hide the Select All option in multi-select mode |
| `inputBackground` | `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 | `'bgSecondary' when readOnly and not disabled, 'bg' otherwise` | Background of the input. |
| `label` | `null \| string \| number \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | Label displayed above the control |
| `labelColor` | `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 | `-` | Color token for the field label. |
| `labelFont` | `display1 \| display2 \| display3 \| title1 \| title2 \| title3 \| title4 \| headline \| body \| label1 \| label2 \| caption \| legal` | No | `-` | Typography token for the field label. |
| `labelVariant` | `inside \| outside` | No | `'outside'` | The variant of the label. Only used when compact is not true. |
| `maxSelectedOptionsToShow` | `number` | No | `-` | Maximum number of selected options to show before truncating |
| `media` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | No | `-` | Media rendered at the start of the cell (icon, avatar, image, etc). |
| `onSearch` | `((searchText: string) => void)` | No | `-` | Search text change handler |
| `open` | `boolean` | No | `-` | Controlled open state of the dropdown |
| `placeholder` | `null \| string \| number \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | Placeholder text displayed when no option is selected |
| `readOnly` | `boolean` | No | `-` | When true, the value cannot be edited but the control may remain focusable (unlike disabled). |
| `ref` | `null \| (instance: SelectRef \| null) => void \| (() => VoidOrUndefinedOnly) \| RefObject<SelectRef \| null>` | No | `-` | - |
| `removeSelectedOptionAccessibilityLabel` | `string` | No | `-` | Accessibility label for each chip in a multi-select |
| `searchText` | `string` | No | `-` | Controlled search text value |
| `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 \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | Adds content to the start of the inner input. Refer to diagram for location of startNode in InputStack component |
| `style` | `null \| false \|  \| ViewStyle \| RegisteredStyle<ViewStyle> \| RecursiveArray<Falsy \| ViewStyle \| RegisteredStyle<ViewStyle>>` | No | `-` | Inline styles for the root element |
| `styles` | `{ root?: StyleProp<ViewStyle>; control?: StyleProp<ViewStyle>; controlStartNode?: StyleProp<ViewStyle>; controlInputNode?: StyleProp<ViewStyle>; controlValueNode?: StyleProp<ViewStyle>; controlLabelNode?: StyleProp<ViewStyle>; controlHelperTextNode?: StyleProp<ViewStyle>; controlEndNode?: StyleProp<ViewStyle>; controlBlendStyles?: InteractableBlendStyles; dropdown?: StyleProp<ViewStyle>; option?: StyleProp<ViewStyle>; optionCell?: StyleProp<ViewStyle>; optionContent?: StyleProp<ViewStyle>; optionLabel?: StyleProp<ViewStyle>; optionDescription?: StyleProp<ViewStyle>; optionBlendStyles?: InteractableBlendStyles \| undefined; selectAllDivider?: StyleProp<ViewStyle>; emptyContentsContainer?: StyleProp<ViewStyle>; emptyContentsText?: StyleProp<ViewStyle>; optionGroup?: StyleProp<ViewStyle>; } \| undefined` | No | `-` | Custom styles for individual elements of the Select component |
| `testID` | `string` | No | `-` | Test ID for the root element |
| `type` | `multi \| single` | No | `-` | Whether the select allows single or multiple selections |
| `variant` | `primary \| secondary \| positive \| negative \| foregroundMuted \| foreground` | No | `-` | Determines the sentiment of the input. Because we allow startContent and endContent to be custom ReactNode, the content placed inside these slots will not change colors according to the variant. You will have to add that yourself |


## Styles

| Selector | Static class name | Description |
| --- | --- | --- |
| `root` | `-` | Root element |
| `control` | `-` | Control element |
| `controlStartNode` | `-` | Start node element |
| `controlInputNode` | `-` | Input node element |
| `controlValueNode` | `-` | Value node element |
| `controlLabelNode` | `-` | Label node element |
| `controlHelperTextNode` | `-` | Helper text node element |
| `controlEndNode` | `-` | End node element |
| `controlBlendStyles` | `-` | Blend styles for control interactivity |
| `dropdown` | `-` | Dropdown container element |
| `option` | `-` | Option element |
| `optionCell` | `-` | Option cell element |
| `optionContent` | `-` | Option content wrapper |
| `optionLabel` | `-` | Option label element |
| `optionDescription` | `-` | Option description element |
| `optionBlendStyles` | `-` | Option blend styles for interactivity |
| `selectAllDivider` | `-` | Select all divider element |
| `emptyContentsContainer` | `-` | Empty contents container element |
| `emptyContentsText` | `-` | Empty contents text element |
| `optionGroup` | `-` | Option group element |


