Toggle contextual overlays for displaying lists of links and more with the Bootstrap dropdown plugin
Overview
Dropdowns are toggleable, contextual overlays for displaying lists of
links and more. Like overlays, Dropdowns are built using a third-party
library Popper.js, which provides
dynamic positioning and viewport detection.
Accessibility
The WAI ARIA standard
defines a role="menu"
widget, but it's very specific to a certain kind of menu. ARIA menus, must
only contain role="menuitem"
, role="menuitemcheckbox"
, or role="menuitemradio"
.
On the other hand, Bootstrap's dropdowns are designed to more generic
and application in a variety of situations. For this reason we don't
automatically add the menu roles to the markup. We do implement some
basic keyboard navigation, and if you do provide the "menu" role,
react-bootstrap will do its best to ensure the focus management is
compliant with the ARIA authoring guidelines for menus.
Examples
The basic Dropdown is composed of a wrapping Dropdown
and
inner <DropdownMenu>
, and <DropdownToggle>
. By
default the <DropdownToggle>
will render a
Button
component and accepts all the same props.
import Dropdown from 'react-bootstrap/Dropdown';
function BasicExample() {
return (
<Dropdown>
<Dropdown.Toggle variant="success" id="dropdown-basic">
Dropdown Button
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item href="#/action-1">Action</Dropdown.Item>
<Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
<Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
);
}
export default BasicExample;
Since the above is such a common configuration react-bootstrap provides
the <DropdownButton>
component to help reduce typing. Provide
a title
prop and some <DropdownItem>
s and you're
ready to go.
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
function BasicButtonExample() {
return (
<DropdownButton id="dropdown-basic-button" title="Dropdown button">
<Dropdown.Item href="#/action-1">Action</Dropdown.Item>
<Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
<Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
</DropdownButton>
);
}
export default BasicButtonExample;
DropdownButton will forward Button props to the underlying Toggle
component
import ButtonGroup from 'react-bootstrap/ButtonGroup';
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
function VariantsExample() {
return (
<>
{['Primary', 'Secondary', 'Success', 'Info', 'Warning', 'Danger'].map(
(variant) => (
<DropdownButton
as={ButtonGroup}
key={variant}
id={`dropdown-variants-${variant}`}
variant={variant.toLowerCase()}
title={variant}
>
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3" active>
Active Item
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</DropdownButton>
),
)}
</>
);
}
export default VariantsExample;
Similarly, You create a split dropdown by combining the Dropdown
components with another Button and a ButtonGroup.
import Button from 'react-bootstrap/Button';
import ButtonGroup from 'react-bootstrap/ButtonGroup';
import Dropdown from 'react-bootstrap/Dropdown';
function SplitBasicExample() {
return (
<Dropdown as={ButtonGroup}>
<Button variant="success">Split Button</Button>
<Dropdown.Toggle split variant="success" id="dropdown-split-basic" />
<Dropdown.Menu>
<Dropdown.Item href="#/action-1">Action</Dropdown.Item>
<Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
<Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
);
}
export default SplitBasicExample;
As with DropdownButton, SplitButton
is provided as
convenience component.
import Dropdown from 'react-bootstrap/Dropdown';
import SplitButton from 'react-bootstrap/SplitButton';
function SplitVariantExample() {
return (
<>
{['Primary', 'Secondary', 'Success', 'Info', 'Warning', 'Danger'].map(
(variant) => (
<SplitButton
key={variant}
id={`dropdown-split-variants-${variant}`}
variant={variant.toLowerCase()}
title={variant}
>
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3" active>
Active Item
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</SplitButton>
),
)}
</>
);
}
export default SplitVariantExample;
Sizing
Dropdowns work with buttons of all sizes.
import ButtonGroup from 'react-bootstrap/ButtonGroup';
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
import SplitButton from 'react-bootstrap/SplitButton';
function ButtonSizesExample() {
return (
<>
<div className="mb-2">
{[DropdownButton, SplitButton].map((DropdownType, idx) => (
<DropdownType
as={ButtonGroup}
key={idx}
id={`dropdown-button-drop-${idx}`}
size="lg"
title="Drop large"
>
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3">Something else here</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</DropdownType>
))}
</div>
<div>
{[DropdownButton, SplitButton].map((DropdownType, idx) => (
<DropdownType
as={ButtonGroup}
key={idx}
id={`dropdown-button-drop-${idx}`}
size="sm"
variant="secondary"
title="Drop small"
>
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3">Something else here</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</DropdownType>
))}
</div>
</>
);
}
export default ButtonSizesExample;
Dark dropdowns
Opt into darker dropdowns to match a dark navbar or custom style by adding
variant="dark"
onto an existing DropdownMenu
. Alternatively, use
menuVariant="dark"
when using the DropdownButton
component.
Dark variants for components were deprecated in Bootstrap v5.3.0 with the introduction
of color modes. Instead of adding variant="dark"
, set data-bs-theme="dark"
on the root
element, a parent wrapper, or the component itself.
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
function ButtonDarkExample() {
return (
<>
<Dropdown data-bs-theme="dark">
<Dropdown.Toggle id="dropdown-button-dark-example1" variant="secondary">
Dropdown Button
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item href="#/action-1" active>
Action
</Dropdown.Item>
<Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
<Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item href="#/action-4">Separated link</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<DropdownButton
id="dropdown-button-dark-example2"
variant="secondary"
title="Dropdown button"
className="mt-2"
data-bs-theme="dark"
>
<Dropdown.Item href="#/action-1" active>
Action
</Dropdown.Item>
<Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
<Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item href="#/action-4">Separated link</Dropdown.Item>
</DropdownButton>
</>
);
}
export default ButtonDarkExample;
Using menuVariant="dark"
in a NavDropdown
:
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import NavDropdown from 'react-bootstrap/NavDropdown';
function NavbarDarkExample() {
return (
<Navbar variant="dark" bg="dark" expand="lg">
<Container fluid>
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="navbar-dark-example" />
<Navbar.Collapse id="navbar-dark-example">
<Nav>
<NavDropdown
id="nav-dropdown-dark-example"
title="Dropdown"
menuVariant="dark"
>
<NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
<NavDropdown.Item href="#action/3.2">
Another action
</NavDropdown.Item>
<NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action/3.4">
Separated link
</NavDropdown.Item>
</NavDropdown>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
}
export default NavbarDarkExample;
Drop directions
Trigger dropdown menus above, below, left, or to the right of their
toggle elements, with the drop
prop.
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
import SplitButton from 'react-bootstrap/SplitButton';
function DropDirectioExample() {
return (
<>
<div className="mb-2">
{['up', 'up-centered', 'down', 'down-centered', 'start', 'end'].map(
(direction) => (
<DropdownButton
as={ButtonGroup}
key={direction}
id={`dropdown-button-drop-${direction}`}
drop={direction}
variant="secondary"
title={` Drop ${direction} `}
>
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3">Something else here</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</DropdownButton>
),
)}
</div>
<div>
{['up', 'up-centered', 'down', 'down-centered', 'start', 'end'].map(
(direction) => (
<SplitButton
key={direction}
id={`dropdown-button-drop-${direction}`}
drop={direction}
variant="secondary"
title={`Drop ${direction}`}
>
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3">Something else here</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</SplitButton>
),
)}
</div>
</>
);
}
export default DropDirectioExample;
Dropdown items
Historically dropdown menu contents had to be links, but that’s no
longer the case with v4. Now you can optionally use
<button>
elements in your dropdowns instead of just <a>
s.
You can also create non-interactive dropdown items with <Dropdown.ItemText>
.
Feel free to style further with custom CSS or text utilities.
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
function DropdownItemTagsExample() {
return (
<DropdownButton id="dropdown-item-button" title="Dropdown button">
<Dropdown.ItemText>Dropdown item text</Dropdown.ItemText>
<Dropdown.Item as="button">Action</Dropdown.Item>
<Dropdown.Item as="button">Another action</Dropdown.Item>
<Dropdown.Item as="button">Something else</Dropdown.Item>
</DropdownButton>
);
}
export default DropdownItemTagsExample;
By default, a dropdown menu is aligned to the left, but you can switch
it by passing align="end"
to a <Dropdown>
, <DropdownButton>
, or <SplitButton>
.
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
function MenuAlignEndExample() {
return (
<DropdownButton
align="end"
title="Dropdown end"
id="dropdown-menu-align-end"
>
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3">Something else here</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</DropdownButton>
);
}
export default MenuAlignEndExample;
Responsive alignment
If you want to use responsive menu alignment, pass an object containing a breakpoint to the
align
prop on the <DropdownMenu>
, <DropdownButton>
, or <SplitButton>
.
You can specify start
or end
for the various breakpoints.
Using responsive alignment will disable Popper usage so any dynamic
positioning features such as flip
will not work.
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';
import SplitButton from 'react-bootstrap/SplitButton';
function MenuAlignResponsiveExample() {
return (
<>
<div>
<DropdownButton
as={ButtonGroup}
align={{ lg: 'end' }}
title="Left-aligned but right aligned when large screen"
id="dropdown-menu-align-responsive-1"
>
<Dropdown.Item eventKey="1">Action 1</Dropdown.Item>
<Dropdown.Item eventKey="2">Action 2</Dropdown.Item>
</DropdownButton>
</div>
<div className="mt-2">
<SplitButton
align={{ lg: 'start' }}
title="Right-aligned but left aligned when large screen"
id="dropdown-menu-align-responsive-2"
>
<Dropdown.Item eventKey="1">Action 1</Dropdown.Item>
<Dropdown.Item eventKey="2">Action 2</Dropdown.Item>
</SplitButton>
</div>
</>
);
}
export default MenuAlignResponsiveExample;
Add a header to label sections of actions.
import Dropdown from 'react-bootstrap/Dropdown';
function MenuHeadersExample() {
return (
<Dropdown.Menu show>
<Dropdown.Header>Dropdown header</Dropdown.Header>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3">Something else here</Dropdown.Item>
</Dropdown.Menu>
);
}
export default MenuHeadersExample;
Separate groups of related menu items with a divider.
import Dropdown from 'react-bootstrap/Dropdown';
function MenuDividersExample() {
return (
<Dropdown.Menu show>
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3">Something else here</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</Dropdown.Menu>
);
}
export default MenuDividersExample;
AutoClose
By default, the dropdown menu is closed when selecting a menu item or clicking outside of the
dropdown menu. This behaviour can be changed by using the autoClose
property.
By default, autoClose
is set to the default value true
and behaves like expected. By choosing false
, the dropdown
menu can only be toggled by clicking on the dropdown button. inside
makes the dropdown disappear only
by choosing a menu item and outside
closes the dropdown menu only by clicking outside.
Notice how the dropdown is toggled in each scenario by clicking on the button.
import Dropdown from 'react-bootstrap/Dropdown';
function AutoCloseExample() {
return (
<>
<Dropdown className="d-inline mx-2">
<Dropdown.Toggle id="dropdown-autoclose-true">
Default Dropdown
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown className="d-inline mx-2" autoClose="inside">
<Dropdown.Toggle id="dropdown-autoclose-inside">
Clickable Outside
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown className="d-inline mx-2" autoClose="outside">
<Dropdown.Toggle id="dropdown-autoclose-outside">
Clickable Inside
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Dropdown className="d-inline mx-2" autoClose={false}>
<Dropdown.Toggle id="dropdown-autoclose-false">
Manual Close
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
<Dropdown.Item href="#">Menu Item</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</>
);
}
export default AutoCloseExample;
Customization
If the default handling of the dropdown menu and toggle components
aren't to your liking, you can customize them, by using the more basic
<Dropdown>
Component to explicitly specify the Toggle and
Menu components
import Button from 'react-bootstrap/Button';
import ButtonGroup from 'react-bootstrap/ButtonGroup';
import Dropdown from 'react-bootstrap/Dropdown';
function ButtonCustomExample() {
return (
<>
<Dropdown as={ButtonGroup}>
<Dropdown.Toggle id="dropdown-custom-1">Pow! Zoom!</Dropdown.Toggle>
<Dropdown.Menu className="super-colors">
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3" active>
Active Item
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>{' '}
<Dropdown as={ButtonGroup}>
<Button variant="info">mix it up style-wise</Button>
<Dropdown.Toggle split variant="success" id="dropdown-custom-2" />
<Dropdown.Menu className="super-colors">
<Dropdown.Item eventKey="1">Action</Dropdown.Item>
<Dropdown.Item eventKey="2">Another action</Dropdown.Item>
<Dropdown.Item eventKey="3" active>
Active Item
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item eventKey="4">Separated link</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</>
);
}
export default ButtonCustomExample;
Custom Dropdown Components
For those that want to customize everything, you can forgo the included
Toggle and Menu components, and create your own. By providing custom
components to the as
prop, you can control how each
component behaves. Custom toggle and menu components must be able to accept refs.
import React, { useState } from 'react';
import Dropdown from 'react-bootstrap/Dropdown';
import Form from 'react-bootstrap/Form';
const CustomToggle = React.forwardRef(({ children, onClick }, ref) => (
<a
href=""
ref={ref}
onClick={(e) => {
e.preventDefault();
onClick(e);
}}
>
{children}
▼
</a>
));
const CustomMenu = React.forwardRef(
({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
const [value, setValue] = useState('');
return (
<div
ref={ref}
style={style}
className={className}
aria-labelledby={labeledBy}
>
<Form.Control
autoFocus
className="mx-3 my-2 w-auto"
placeholder="Type to filter..."
onChange={(e) => setValue(e.target.value)}
value={value}
/>
<ul className="list-unstyled">
{React.Children.toArray(children).filter(
(child) =>
!value || child.props.children.toLowerCase().startsWith(value),
)}
</ul>
</div>
);
},
);
render(
<Dropdown>
<Dropdown.Toggle as={CustomToggle} id="dropdown-custom-components">
Custom toggle
</Dropdown.Toggle>
<Dropdown.Menu as={CustomMenu}>
<Dropdown.Item eventKey="1">Red</Dropdown.Item>
<Dropdown.Item eventKey="2">Blue</Dropdown.Item>
<Dropdown.Item eventKey="3" active>
Orange
</Dropdown.Item>
<Dropdown.Item eventKey="1">Red-Orange</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>,
);
API
Dropdown
DropdownToggle
DropdownItem
DropdownDivider