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 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);

	return (
		<Dropdown onToggle={() => setActiveOption(null)}>
			<Dropdown.Toggle>Nested Dropdown</Dropdown.Toggle>
			<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>
		</Dropdown>
	);
}

Split Dropdowns

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

	<Dropdown.Toggle 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' },
},
};