Skip to main content

Dropdown

See React Bootstrap/Dropdowns for full documentation and props.

Dropdowns in react-bootstrap provide some level of accessibility but in most cases roles or ids will need to be specifically associated with the menu elements themselves.

Dropdowns can be created with a Dropdown.Toggle component or a DropdownButton component.

Result
Loading...
Live Editor
<div data-testid="pw-dropdown">
	<Dropdown>
		<Dropdown.Toggle>Toggle</Dropdown.Toggle>

		<Dropdown.Menu>
			<Dropdown.Item>Apple</Dropdown.Item>
			<Dropdown.Item>Banana</Dropdown.Item>
			<Dropdown.Item>Cantaloupe</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>
</div>

With headers and dividers​

Result
Loading...
Live Editor
<div data-testid="pw-dropdown-header">
	<Dropdown.Menu show className="position-relative">
		<Dropdown.Header>Fruit</Dropdown.Header>
		<Dropdown.Item>Apple</Dropdown.Item>
		<Dropdown.Item>Banana</Dropdown.Item>
		<Dropdown.Item>Cantaloupe</Dropdown.Item>
		<Dropdown.Divider />
		<Dropdown.Header>Vegetables</Dropdown.Header>
		<Dropdown.Item>Asparagus</Dropdown.Item>
		<Dropdown.Item>Broccoli</Dropdown.Item>
		<Dropdown.Item>Carrot</Dropdown.Item>
	</Dropdown.Menu>
</div>

With multiline items​

Result
Loading...
Live Editor
<Dropdown>
	<Dropdown.Toggle>Toggle</Dropdown.Toggle>

	<Dropdown.Menu>
		<MultiLineDropdownItem title="Apple">Description 1</MultiLineDropdownItem>
		<MultiLineDropdownItem title="Banana">Description 2</MultiLineDropdownItem>
		<MultiLineDropdownItem title="Cantaloupe">Description 3</MultiLineDropdownItem>
	</Dropdown.Menu>
</Dropdown>

With multiple columns​

Columns can be created with layout options (flex, grid, etc.).

Result
Loading...
Live Editor
<Dropdown>
	<Dropdown.Toggle>Toggle</Dropdown.Toggle>

	<Dropdown.Menu role="menu">
		<div className="d-flex align-items-stretch">
			<div>
				<Dropdown.Header>Fruit</Dropdown.Header>
				<Dropdown.Item>Apple</Dropdown.Item>
				<Dropdown.Item>Banana</Dropdown.Item>
				<Dropdown.Item>Cantaloupe</Dropdown.Item>
			</div>
			<div className="vr" />
			<div>
				<Dropdown.Header>Vegetables</Dropdown.Header>
				<Dropdown.Item>Asparagus</Dropdown.Item>
				<Dropdown.Item>Broccoli</Dropdown.Item>
				<Dropdown.Item>Carrot</Dropdown.Item>
			</div>
		</div>
	</Dropdown.Menu>
</Dropdown>

With non-interactive items​

The Dropdown.ItemText component can be used to create non-interactive items.

Result
Loading...
Live Editor
<Dropdown>
	<Dropdown.Toggle>Toggle</Dropdown.Toggle>

	<Dropdown.Menu>
		<Dropdown.Item>Apple</Dropdown.Item>
		<Dropdown.Item>Banana</Dropdown.Item>
		<Dropdown.Item>Cantaloupe</Dropdown.Item>
		<Dropdown.ItemText>There are no more fruit to see here.</Dropdown.ItemText>
	</Dropdown.Menu>
</Dropdown>

With form inputs​

Dropdown.Items are anchor tags by default, so it's important to use Dropdown.ItemText when putting inputs inside them to make sure clicking it doesn't append a # to the end of the page URL and scroll to the top of the page.

Result
Loading...
Live Editor
function Example() {
	const [show, setShow] = useState(false);

	return (
		<Dropdown show={show} onToggle={setShow}>
			<Dropdown.Toggle>Toggle</Dropdown.Toggle>
			<Dropdown.Menu>
				<Dropdown.ItemText>
					<Radio label="Radio" onChange={() => setShow(false)} />
				</Dropdown.ItemText>
				<Dropdown.ItemText>
					<Checkbox label="Checkbox" onChange={() => setShow(false)} />
				</Dropdown.ItemText>
				<Dropdown.ItemText>
					<Switch label="Switch" onChange={() => setShow(false)} />
				</Dropdown.ItemText>
			</Dropdown.Menu>
		</Dropdown>
	);
}
Result
Loading...
Live Editor
<div data-testid="pw-dropdown-helper">
	<Dropdown>
		<Dropdown.Toggle>Toggle</Dropdown.Toggle>
		<Dropdown.Menu>
			<Dropdown.Item>
				<ListGroup.Item.Header title="Menu Item" />
			</Dropdown.Item>
			<Dropdown.Item>
				<ListGroup.Item.Header title="Menu Item w/Helper" helper="⌘C" />
			</Dropdown.Item>
			<Dropdown.Item>
				<ListGroup.Item.Header
					title="Menu Item w/Helper and Action"
					helper="⌘C"
					actions={<a href="#">Link</a>}
				/>
			</Dropdown.Item>
			<Dropdown.Item>
				<ListGroup.Item.Header
					title="Menu Item w/Helper, Action, and Icon"
					helper="⌘C"
					actions={<a href="#">Link</a>}
					icon={<span className="icon-chevron-right" />}
				/>
			</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>
</div>

With nested items​

Result
Loading...
Live Editor
function NestedItems() {
	const menu = {
		header: 'Very Awesome Column',
		options: [
			{
				label: 'Option 1',
				value: 'option1',
				header: 'Awesome Sub-Column 1',
				options: [
					{
						label: 'Option 1-1',
						value: 'option1-1',
					},
					{
						label: 'Option 1-2',
						value: 'option1-2',
					},
				],
			},
			{
				label: 'Option 2',
				value: 'option2',
				header: 'Awesome Sub-Column 2',
				options: [
					{
						label: 'Option 2-1',
						value: 'option2-1',
					},
				],
			},
			{
				label: 'Option 3',
				value: 'option3',
				header: 'Awesome Sub-Column 3',
				options: [
					{
						label: 'Option 3-1',
						value: 'option3-1',
					},
					{
						label: 'Option 3-2',
						value: 'option3-2',
					},
					{
						label: 'Option 3-3',
						value: 'option3-3',
					},
					{
						label: 'Option 4-3',
						value: 'option4-3',
					},
				],
			},
			{
				label: 'Option 4',
				value: 'option4',
			},
		],
	};

	const [activeOption, setActiveOption] = useState(null);
	const activeColumn = menu.options.find((column) => column.value === activeOption);

	const renderMenu = () => (
		<Dropdown.Menu>
			<div className="d-flex align-items-stretch">
				<div>
					<Dropdown.Header>{menu.header}</Dropdown.Header>
					{menu.options.map((column, index) => (
						<Dropdown.Item
							key={index}
							active={activeOption === column.value}
							onClick={(e) => {
								e.stopPropagation();
								setActiveOption(column.value);
							}}
						>
							<ListGroup.Item.Header
								title={column.label}
								icon={<span className="icon-chevron-right" />}
							/>
						</Dropdown.Item>
					))}
				</div>
				{activeColumn && activeColumn.options && (
					<>
						<div className="vr"></div>
						<div>
							<Dropdown.Header>{activeColumn.header}</Dropdown.Header>
							{activeColumn.options.map((option, index) => (
								<Dropdown.Item key={index}>{option.label}</Dropdown.Item>
							))}
						</div>
					</>
				)}
			</div>
		</Dropdown.Menu>
	);

	return (
		<div className="d-flex justify-content-between">
			<Dropdown align="start" onToggle={() => setActiveOption(null)}>
				<Dropdown.Toggle>Nested Dropdown</Dropdown.Toggle>
				{renderMenu()}
			</Dropdown>

			<Dropdown align="end" onToggle={() => setActiveOption(null)}>
				<Dropdown.Toggle>Nested Dropdown</Dropdown.Toggle>
				{renderMenu()}
			</Dropdown>
		</div>
	);
}

Split Dropdowns​

Result
Loading...
Live Editor
<Dropdown as={ButtonGroup}>
	<Button variant="primary">Split Button</Button>

	<Dropdown.Toggle aria-label="toggle menu" split variant="primary" />

	<Dropdown.Menu>
		<Dropdown.Item onClick={() => console.log('foo')}>Action</Dropdown.Item>
		<Dropdown.Item onClick={() => console.log('foo')}>Another action</Dropdown.Item>
		<Dropdown.Item onClick={() => console.log('foo')}>Something else</Dropdown.Item>
	</Dropdown.Menu>
</Dropdown>

Size variants​

The Dropdown.Menu component can be sized with the size prop.

Result
Loading...
Live Editor
<div className="d-flex gap-3">
	<Dropdown>
		<Dropdown.Toggle>Small</Dropdown.Toggle>

		<Dropdown.Menu role="menu" size="sm">
			<Dropdown.Header>Fruits and Melons</Dropdown.Header>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header title="Apple" icon={<span className="icon-chevron-right" />} />
					}
				/>
			</Dropdown.Item>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header title="Banana" icon={<span className="icon-chevron-right" />} />
					}
				/>
			</Dropdown.Item>

			<Dropdown.Divider />

			<Dropdown.Header>Berries</Dropdown.Header>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header
							title="Strawberry"
							icon={<span className="icon-chevron-right" />}
						/>
					}
				/>
			</Dropdown.Item>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header
							title="Raspberry"
							icon={<span className="icon-chevron-right" />}
						/>
					}
				/>
			</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>

	<Dropdown>
		<Dropdown.Toggle>Medium</Dropdown.Toggle>

		<Dropdown.Menu role="menu" size="md">
			<Dropdown.Header>Fruits and Melons</Dropdown.Header>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header title="Apple" icon={<span className="icon-chevron-right" />} />
					}
				/>
			</Dropdown.Item>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header title="Banana" icon={<span className="icon-chevron-right" />} />
					}
				/>
			</Dropdown.Item>

			<Dropdown.Divider />

			<Dropdown.Header>Berries</Dropdown.Header>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header
							title="Strawberry"
							icon={<span className="icon-chevron-right" />}
						/>
					}
				/>
			</Dropdown.Item>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header
							title="Raspberry"
							icon={<span className="icon-chevron-right" />}
						/>
					}
				/>
			</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>

	<Dropdown>
		<Dropdown.Toggle>Large</Dropdown.Toggle>

		<Dropdown.Menu role="menu" size="lg">
			<Dropdown.Header>Fruits and Melons</Dropdown.Header>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header title="Apple" icon={<span className="icon-chevron-right" />} />
					}
				/>
			</Dropdown.Item>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header title="Banana" icon={<span className="icon-chevron-right" />} />
					}
				/>
			</Dropdown.Item>

			<Dropdown.Divider />

			<Dropdown.Header>Berries</Dropdown.Header>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header
							title="Strawberry"
							icon={<span className="icon-chevron-right" />}
						/>
					}
				/>
			</Dropdown.Item>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header
							title="Raspberry"
							icon={<span className="icon-chevron-right" />}
						/>
					}
				/>
			</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>

	<Dropdown>
		<Dropdown.Toggle>Extra Large</Dropdown.Toggle>

		<Dropdown.Menu role="menu" size="xl">
			<Dropdown.Header>Fruits and Melons</Dropdown.Header>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header title="Apple" icon={<span className="icon-chevron-right" />} />
					}
				/>
			</Dropdown.Item>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header title="Banana" icon={<span className="icon-chevron-right" />} />
					}
				/>
			</Dropdown.Item>

			<Dropdown.Divider />

			<Dropdown.Header>Berries</Dropdown.Header>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header
							title="Strawberry"
							icon={<span className="icon-chevron-right" />}
						/>
					}
				/>
			</Dropdown.Item>
			<Dropdown.Item as="div">
				<ListGroup.Item.Template
					header={
						<ListGroup.Item.Header
							title="Raspberry"
							icon={<span className="icon-chevron-right" />}
						/>
					}
				/>
			</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>
</div>

With ListGroupItem​

It is possible to use the ListGroup.Item.Template, Header, and Body components to create more complex dropdowns with headers, descriptions, icons, and other details. See ListGroup for more options.

Result
Loading...
Live Editor
<Dropdown>
	<Dropdown.Toggle>Dropdown</Dropdown.Toggle>

	<Dropdown.Menu role="menu">
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={<ListGroup.Item.Header title="Apple" helper="🍎" />}
				body={
					<ListGroup.Item.Body description="An apple is a round, edible fruit that typically grows on trees." />
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={<ListGroup.Item.Header title="Banana" helper="🍌" />}
				body={
					<ListGroup.Item.Body description="A banana is an elongated, curved fruit with a thick, usually yellow peel that encases soft, sweet flesh. " />
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={<ListGroup.Item.Header title="Cantaloupe" helper="🍈" />}
				body={
					<ListGroup.Item.Body description="Cantaloupe is a type of muskmelon with sweet, orange flesh and a rough, netted rind, often round or oblong in shape." />
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={<ListGroup.Item.Header title="Watermelon" helper="🍉" />}
				body={
					<ListGroup.Item.Body description="A watermelon is a large, round or oblong fruit with a hard, green rind, typically striped or mottled." />
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={<ListGroup.Item.Header title="Strawberry" helper="🍓" />}
				body={
					<ListGroup.Item.Body description="A strawberry is a bright red, heart-shaped fruit with a distinctive aroma and sweet-tart flavor." />
				}
			/>
		</Dropdown.Item>
	</Dropdown.Menu>
</Dropdown>

Other examples​

Result
Loading...
Live Editor
<Dropdown>
	<Dropdown.Toggle>Dropdown</Dropdown.Toggle>

	<Dropdown.Menu role="menu">
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={
					<ListGroup.Item.Header
						title="Title"
						helper="Helper"
						icon="Icon"
						actions={<a href="#">Link</a>}
					/>
				}
				body={
					<ListGroup.Item.Body
						description="Description"
						footer="Footer"
						alerts={<Alert variant="secondary">Alerts</Alert>}
						actions={
							<div className="d-flex gap-2">
								<Button variant="outline-primary" size="xs">
									Action 1
								</Button>
								<Button variant="outline-secondary" size="xs">
									Action 2
								</Button>
							</div>
						}
					/>
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={
					<ListGroup.Item.Header
						title="Title"
						helper="Helper"
						icon="Icon"
						actions={<a href="#">Link</a>}
					/>
				}
				body={
					<ListGroup.Item.Body
						description="Description"
						footer="Footer"
						alerts={<Alert variant="secondary">Alerts</Alert>}
						actions={
							<div className="d-flex gap-2">
								<a href="#">Link</a>
								<a href="#">Link</a>
							</div>
						}
					/>
				}
			/>
		</Dropdown.Item>
	</Dropdown.Menu>
</Dropdown>

As a checklist​

Result
Loading...
Live Editor
<Dropdown>
	<Dropdown.Toggle>Dropdown</Dropdown.Toggle>

	<Dropdown.Menu role="menu">
		<Dropdown.Item as="div" active>
			<ListGroup.Item.Template
				header={
					<ListGroup.Item.Header
						title={
							<>
								Apple{' '}
								<Badge variant="primary" className="ms-2">
									Rated Best
								</Badge>
							</>
						}
						helper="🍎"
						actions={
							<IconButton
								variant="outline-secondary"
								size="xs"
								iconClassName="icon-thumbs-up"
								onClick={(e) => {
									e.stopPropagation();
									console.log('Apple action clicked');
								}}
							/>
						}
						icon={<span className="icon-check" />}
					/>
				}
				body={
					<ListGroup.Item.Body description="An apple is a round, edible fruit that typically grows on trees." />
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={<ListGroup.Item.Header title="Banana" helper="🍌" />}
				body={
					<ListGroup.Item.Body description="A banana is an elongated, curved fruit with a thick, usually yellow peel that encases soft, sweet flesh. " />
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div" active>
			<ListGroup.Item.Template
				header={
					<ListGroup.Item.Header
						title="Cantaloupe"
						helper="🍈"
						actions={
							<IconButton
								variant="outline-secondary"
								size="xs"
								iconClassName="icon-thumbs-up"
								onClick={(e) => {
									e.stopPropagation();
									console.log('Cantaloupe action clicked');
								}}
							/>
						}
						icon={<span className="icon-check" />}
					/>
				}
				body={
					<ListGroup.Item.Body description="Cantaloupe is a type of muskmelon with sweet, orange flesh and a rough, netted rind, often round or oblong in shape." />
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={<ListGroup.Item.Header title="Watermelon" helper="🍉" />}
				body={
					<ListGroup.Item.Body description="A watermelon is a large, round or oblong fruit with a hard, green rind, typically striped or mottled." />
				}
			/>
		</Dropdown.Item>
		<Dropdown.Item as="div">
			<ListGroup.Item.Template
				header={<ListGroup.Item.Header title="Strawberry" helper="🍓" />}
				body={
					<ListGroup.Item.Body description="A strawberry is a bright red, heart-shaped fruit with a distinctive aroma and sweet-tart flavor." />
				}
			/>
		</Dropdown.Item>
	</Dropdown.Menu>
</Dropdown>

Using IconButton​

Result
Loading...
Live Editor
<div className="d-flex gap-3">
	<Dropdown>
		<Dropdown.Toggle as={IconButton} iconClassName="icon-settings-01" aria-label="Toggle" />

		<Dropdown.Menu>
			<Dropdown.Item>Apple</Dropdown.Item>
			<Dropdown.Item>Banana</Dropdown.Item>
			<Dropdown.Item>Cantaloupe</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>

	<Dropdown>
		<Dropdown.Toggle
			variant="link"
			as={IconButton}
			iconClassName="icon-settings-01"
			aria-label="Toggle"
		/>

		<Dropdown.Menu>
			<Dropdown.Item>Apple</Dropdown.Item>
			<Dropdown.Item>Banana</Dropdown.Item>
			<Dropdown.Item>Cantaloupe</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>
</div>

Hiding the chevron​

To hide the chevron icon in the dropdown toggle, use the hideChevron prop.

Result
Loading...
Live Editor
<div className="d-flex gap-3">
	<Dropdown hideChevron>
		<Dropdown.Toggle as={IconButton} iconClassName="icon-settings-01" aria-label="Toggle" />

		<Dropdown.Menu>
			<Dropdown.Item>Apple</Dropdown.Item>
			<Dropdown.Item>Banana</Dropdown.Item>
			<Dropdown.Item>Cantaloupe</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>

	<Dropdown hideChevron>
		<Dropdown.Toggle
			variant="link"
			as={IconButton}
			iconClassName="icon-settings-01"
			aria-label="Toggle"
		/>

		<Dropdown.Menu>
			<Dropdown.Item>Apple</Dropdown.Item>
			<Dropdown.Item>Banana</Dropdown.Item>
			<Dropdown.Item>Cantaloupe</Dropdown.Item>
		</Dropdown.Menu>
	</Dropdown>
</div>

Large lists of items​

Result
Loading...
Live Editor
function Example() {
	const [activeItemId, setActiveItemId] = useState(null);

	return (
		<Dropdown>
			<Dropdown.Toggle>Toggle</Dropdown.Toggle>

			<Dropdown.Menu className="overflow-auto" style={{ maxHeight: '300px' }}>
				{Array.from({ length: 100 }, (_, i) => {
					const itemId = `item-${i + 1}`;

					return (
						<Dropdown.Item
							active={activeItemId === itemId}
							id={itemId}
							onClick={() => setActiveItemId(itemId)}
							key={i}
						>
							Item {i + 1}
						</Dropdown.Item>
					);
				})}
			</Dropdown.Menu>
		</Dropdown>
	);
}

Analytics​

The DropdownItem component is trackable through Kyber Analytics. This is the default analytics config.

export default {
value: 'DropdownItem',
actions: {
onClick: { type: 'DROPDOWNITEM_CLICK', payload: 'Click' },
},
};

Props​

🛑 We recommend using ListGroup.Item.Template, ListGroup.Item.Header, and ListGroup.Item.Body to create more complex dropdown items. These components provide more customization and better fit for the Design System.

MultiLineDropdownItem​

The MultiLineDropdownItem component is trackable through Kyber Analytics. This is the default analytics config.

export default {
value: 'MultiLineDropdownItem',
actions: {
onClick: { type: 'DROPDOWNITEM_CLICK', payload: 'Click' },
},
};