Skip to Content

AI Dropdown

A powerful dropdown component supporting single select, multi-select, search, grouping, and multiple visual appearances.

Loading...

Overview

Resources

Loading...

Loading...

Loading...

Loading...

Loading...

Install

yarn add @camp/ai-dropdown

Usage

Set up ThemeProvider

The AiDropdown component requires a styled-components ThemeProvider to be set up in your application. See the Styled Components & ThemeProvider guide for more details on setting up the ThemeProvider.

Single select (basic)

import { AiDropdown, DropdownMenuItem } from '@camp/ai-dropdown'; import { useState } from 'react'; // This matches the basicOptions used in the Default story const options = [ { label: 'Option 1', id: 'opt-1' }, { label: 'Option 2', id: 'opt-2' }, { label: 'Option 3', id: 'opt-3' }, ]; const MyDropdown = () => { const [value, setValue] = useState(); return ( <AiDropdown appearance="default" type="single" options={options} value={value} onSelect={setValue} renderDisplayValue={(option) => option.label} renderMenuItem={(option, args) => ( <DropdownMenuItem {...args} id={option.id}> {option.label} </DropdownMenuItem> )} placeholder="Select an option" /> ); };
import { AiDropdown, DropdownMenuItem } from '@camp/ai-dropdown'; import { useState } from 'react'; const options = [ { label: 'List Item 1', id: 'list-item-1' }, { label: 'List Item 2', id: 'list-item-2' }, { label: 'List Item 3', invalid: true, id: 'list-item-3' }, { label: 'List Item 4', id: 'list-item-4' }, { label: 'List Item 5', id: 'list-item-5' }, ]; const MyMultiDropdown = () => { const [selectedOptions, setSelectedOptions] = useState([]); return ( <AiDropdown appearance="default" type="multi" options={options} value={selectedOptions} onSelect={setSelectedOptions} renderDisplayValue={(option) => option.label} renderMenuItem={(option, args) => ( <DropdownMenuItem {...args} id={option.id} invalid={option.invalid}> {option.label} </DropdownMenuItem> )} showSearch={true} placeholder="Select an option..." /> ); };

Grouped options with accordion

Options with the same group property are automatically grouped together and sorted alphabetically by group name.

import { AiDropdown, DropdownMenuItem } from '@camp/ai-dropdown'; import { useState } from 'react'; const groupedOptions = [ { label: 'React', group: 'Frontend Frameworks' }, { label: 'Angular', group: 'Frontend Frameworks' }, { label: 'Vue.js', group: 'Frontend Frameworks' }, { label: 'Node.js', group: 'Backend Technologies' }, { label: 'Python', group: 'Backend Technologies' }, { label: 'PostgreSQL', group: 'Databases' }, { label: 'Redis', group: 'Databases', invalid: true }, { label: 'MongoDB', group: 'Databases' }, { label: 'Git' }, ]; const GroupedDropdown = () => { const [value, setValue] = useState(); return ( <AiDropdown appearance="default" type="single" value={value} onSelect={setValue} options={groupedOptions} renderDisplayValue={(option) => option.label} renderMenuItem={(option, args) => ( <DropdownMenuItem {...args} id={option.id} invalid={option.invalid}> {option.label} </DropdownMenuItem> )} placeholder="Select an option..." accordionGroups={['Backend Technologies', 'Databases']} /> ); };

With label and custom styling

import { AiDropdown, DropdownMenuItem } from '@camp/ai-dropdown'; import { useState } from 'react'; const options = [ { id: 'opt-1', label: 'Option 1' }, { id: 'opt-2', label: 'Option 2' }, { id: 'opt-3', label: 'Option 3' }, ]; const LabeledDropdown = () => { const [value, setValue] = useState(); return ( <AiDropdown appearance="default" type="single" value={value} onSelect={setValue} options={options} label="Category" labelPosition="left" // or "top" renderDisplayValue={(option) => option.label} renderMenuItem={(option, args) => ( <DropdownMenuItem {...args} id={option.id}> {option.label} </DropdownMenuItem> )} placeholder="Select" /> ); };

Variations

Toggle theming

Prop: themed
Type: boolean
Default value: true

The themed prop toggles light and dark mode support for the AiDropdown component. This makes the component adaptable to areas of the product that support theme switching, such as AI agent interfaces or other areas with dark mode capabilities, as well as standard application areas that only support light mode.

When to use themed:

  • If you need light mode support only, use themed={false}. This is useful in standard application areas that only support light mode.
  • If you need light and dark mode support, themed is not required as it is set to true by default. This is useful in AI agent interfaces or other areas with dark mode capabilities.
  • 🔨 If light and dark mode support is not working as expected, try explicitly setting themed={true} (and check that your component has been updated to the latest version).

Behavior:

  • Without themed prop (or with themed={true}): AiDropdown will be themed, supporting light and dark mode styling
  • With themed={false}: AiDropdown will not respond to theme changes and display in light mode only
import { AiDropdown } from '@camp/ai-dropdown'; function UnthemedDropdown() { return ( <AiDropdown<OptionType> themed={false} // explicitly set to false to disable theming type="single" appearance="default" value={undefined} onSelect={() => {}} renderDisplayValue={(option) => option.label} options={basicOptions} placeholder="Unthemed default dropdown" renderMenuItem={(option, args) => ( <DropdownMenuItem {...args} id={option.id} invalid={option.invalid}> {option.label} </DropdownMenuItem> )} /> ); }

Invalid states

Invalid styling adapts to each appearance - red borders for default and inline, red text for floating.

Default

Inline

Floating

const InvalidDropdown = () => { return ( <AiDropdown invalid={true} ...{/* your other props here */} /> ); };

Value prefix

Add visual indicators like color dots or icons before the display value.

const Dot = ({ color }) => ( <span style={{ display: 'inline-block', width: 10, height: 10, borderRadius: '50%', background: color, marginRight: 8, flex: '0 0 auto', }} /> ); const ColorDropdown = () => { return ( <AiDropdown renderValuePrefix={(current) => current && !Array.isArray(current) ? <Dot color={current.color} /> : null } ...{/* your other props here */} /> ); };

Custom trigger

Replace the default button with any custom trigger element like icon buttons.

import { AiIconButton } from '@camp/ai-icon-button'; import { SettingsCogMedium } from '@camp/icon'; const CustomTriggerDropdown = () => {return ( <AiDropdown renderTrigger={(props) => ( <AiIconButton appearance="secondary" shape="rectangle" size="medium" {...props}> <SettingsCogMedium title="Settings" /> </AiIconButton> )} ...{/* your other props here */} /> ); };

Add custom buttons or actions at the bottom of the dropdown menu with the renderMenuActions prop.

import { AiButton } from '@camp/ai-button'; const MenuActionsDropdown = () => { return ( <AiDropdown renderMenuActions={() => ( <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '8px 12px', }} > <AiButton appearance="secondary" size="small" onClick={() => alert('Add new label')} style={{ width: '100%' }} > Add new label </AiButton> </div> )} ...{/* your other props here */} /> ); };

Search functionality

The search input filters options by both label and group name, with a “No results” state when no matches exist.

const SearchableDropdown = () => { return ( <AiDropdown showSearch={true} ...{/* your other props here */} /> ); };

Disabled state

To achieve a disabled state, the disabled value should be passed to the default trigger button using buttonProps.

const DisabledDropdown = () => ( <AiDropdown buttonProps={{ disabled: true }} ...{/* your other props here */} /> );

Advanced configurations

The dropdown supports several advanced configuration options for fine-tuning behavior and appearance.

const AdvancedDropdown = () => { return ( <AiDropdown // Portal rendering to avoid clipping issues usePortal={true} // Custom z-index for stacking control zIndex={1000} // Minimum menu width minMenuWidth="200px" // Theme support (defaults to true) themed={true} // Custom placement placement="bottom-start" // Full width menu fullWidthMenu={true} // Maximum menu height (defaults to 300px) maxMenuHeight={400} ...{/* your other props here */} /> ); };

Props reference

The AI Dropdown component supports a comprehensive set of props for customization:

Core Props:

  • appearance: Visual style - "default" | "inline" | "floating"
  • type: Selection type - "single" | "multi"
  • options: Array of options to display
  • value: Current selected value(s)
  • onSelect: Callback when selection changes
  • renderDisplayValue: Function to render option display text
  • renderMenuItem: Function to render each menu item

Layout & Styling:

  • label: Optional label text
  • labelPosition: Label position - "left" | "top"
  • placeholder: Placeholder text when no selection
  • invalid: Invalid state styling
  • buttonProps: Props passed to the trigger button
  • maxTriggerWidth: Maximum trigger width
  • minTriggerWidth: Minimum trigger width
  • themed: Enable or disable theme support (default: true)

Menu Configuration:

  • maxMenuHeight: Maximum menu height (default: 300px)
  • minMenuWidth: Minimum menu width
  • fullWidthMenu: Match menu width to trigger
  • placement: Menu placement (default: “bottom-end”)
  • zIndex: Custom z-index for stacking
  • usePortal: Render menu in portal to avoid clipping

Features:

  • showSearch: Enable search functionality
  • showSelectAll: Show select all option (multi-select only)
  • accordionGroups: Array of group names to make collapsible
  • renderMenuActions: Custom actions at menu bottom
  • renderTrigger: Custom trigger element
  • renderValuePrefix: Prefix element in trigger value area
  • themed: Enable theme support (default: true)

Best practices

  • Dropdown menus work best for small data sets where a user has anywhere from 5 to 15 items to choose from. For smaller datasets, checkboxes or radios should be used (depending on single or multiselect), and for datasets larger than 15, it is recommended to use a combobox instead.
  • When grouped, listed items should be in some logical order that makes it easy for the user to read and understand, whether that is numerical or alphabetical or some other contextually-based grouping.

Accessibility

Keyboard support

  • Tab: Navigate to/from the dropdown trigger
  • Space/Enter: Open dropdown when focused on trigger
  • Arrow keys: Navigate options when menu is open
  • Enter: Select focused option
  • Escape: Close dropdown menu

Similar components

Radio Button

Radio Button

Allows the user to select one option from a set.

Checkbox

Checkbox

Allows users to select one or more items from a set.

Combobox

Combobox

A combination of a text input field and a dropdown list.

Last updated on