Dropdowns
The Dropdown
component is used to pass the isOpen
& toggle
props via context to the following components: DropdownToggle
, DropdownMenu
. The DropdownToggle
uses the Button
component internally, meaning it also accepts all the props the Button component accepts.
import React, { useState } from 'react';
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
const Example = (props) => {
const [dropdownOpen, setDropdownOpen] = useState(false);
const toggle = () => setDropdownOpen(prevState => !prevState);
return (
<Dropdown isOpen={dropdownOpen} toggle={toggle}>
<DropdownToggle caret>
Dropdown
</DropdownToggle>
<DropdownMenu>
<DropdownItem header>Header</DropdownItem>
<DropdownItem>Some Action</DropdownItem>
<DropdownItem text>Dropdown Item Text</DropdownItem>
<DropdownItem disabled>Action (disabled)</DropdownItem>
<DropdownItem divider />
<DropdownItem>Foo Action</DropdownItem>
<DropdownItem>Bar Action</DropdownItem>
<DropdownItem>Quo Action</DropdownItem>
</DropdownMenu>
</Dropdown>
);
}
export default Example;
Properties
Dropdown.propTypes = {
a11y: PropTypes.bool, // defaults to true. Set to false to enable more bootstrap like tabbing behavior
className: PropTypes.string,
disabled: PropTypes.bool,
direction: PropTypes.oneOf(['up', 'down', 'left', 'right']),
group: PropTypes.bool,
isOpen: PropTypes.bool,
// For Dropdown usage inside a Nav
nav: PropTypes.bool,
active: PropTypes.bool,
// For Dropdown usage inside a Navbar (disables popper)
inNavbar: PropTypes.bool,
tag: PropTypes.string, // default: 'div' unless nav=true, then 'li'
toggle: PropTypes.func,
setActiveFromChild: PropTypes.bool
};
DropdownToggle.propTypes = {
caret: PropTypes.bool,
color: PropTypes.string,
className: PropTypes.string,
disabled: PropTypes.bool,
onClick: PropTypes.func,
'data-toggle': PropTypes.string,
'aria-haspopup': PropTypes.bool,
// For DropdownToggle usage inside a Nav
nav: PropTypes.bool,
// Defaults to Button component
tag: PropTypes.any
};
DropdownMenu.propTypes = {
tag: PropTypes.string,
children: PropTypes.node.isRequired,
right: PropTypes.bool,
flip: PropTypes.bool, // default: true,
className: PropTypes.string,
cssModule: PropTypes.object,
// Custom modifiers that are passed to DropdownMenu.js, see https://popper.js.org/popper-documentation.html#modifiers
modifiers: PropTypes.object,
persist: PropTypes.bool, // presist the popper, even when closed. See #779 for reasoning
// passed to popper, see https://popper.js.org/popper-documentation.html#Popper.Defaults.positionFixed
positionFixed: PropTypes.bool,
// Element to place the menu in. Used to show the menu as a child of 'body'
// or other elements in the DOM instead of where it naturally is. This can be
// used to make the Dropdown escape a container with overflow: hidden
container: PropTypes.oneOfType([PropTypes.string, PropTypes.func, DOMElement]),
};
DropdownItem.propTypes = {
children: PropTypes.node,
active: PropTypes.bool,
disabled: PropTypes.bool,
divider: PropTypes.bool,
tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
header: PropTypes.bool,
onClick: PropTypes.func,
className: PropTypes.string,
cssModule: PropTypes.object,
toggle: PropTypes.bool, // default: true
text: PropTypes.bool
};
Alignment
To align the DropdownMenu
to the right, add a right
prop to Dropdown
.
<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
<DropdownToggle caret>
Dropdown's menu is right-aligned
</DropdownToggle>
<DropdownMenu right>
<DropdownItem header>Header</DropdownItem>
<DropdownItem disabled>Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem divider/>
<DropdownItem>Another Really Really Long Action (Really!)</DropdownItem>
</DropdownMenu>
</Dropdown>
<DropdownItem header>Header</DropdownItem>
<DropdownItem divider/>
<DropdownItem>Action</DropdownItem>
<DropdownItem disabled>Action</DropdownItem>
<DropdownItem text>Dropdown item text</DropdownItem>
Sizing
<Dropdown group isOpen={this.state.dropdownOpen} size="lg" toggle={this.toggle}>
<DropdownToggle caret>
Dropdown
</DropdownToggle>
<DropdownMenu>
...
</DropdownMenu>
</Dropdown>
<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
<DropdownToggle caret>
Dropdown
</DropdownToggle>
<DropdownMenu>
...
</DropdownMenu>
</Dropdown>
<Dropdown group isOpen={this.state.dropdownOpen} size="sm" toggle={this.toggle}>
<DropdownToggle caret>
Dropdown
</DropdownToggle>
<DropdownMenu>
...
</DropdownMenu>
</Dropdown>
Custom Dropdown
import React, { useState } from 'react';
import { Dropdown, DropdownMenu, DropdownToggle } from 'reactstrap';
const Example = () => {
const [dropdownOpen, setDropdownOpen] = useState(false);
const toggle = () => setDropdownOpen(prevState => !prevState);
return (
<Dropdown isOpen={dropdownOpen} toggle={toggle}>
<DropdownToggle
tag="span"
data-toggle="dropdown"
aria-expanded={dropdownOpen}
>
Custom Dropdown Content
</DropdownToggle>
<DropdownMenu>
<div onClick={toggle}>Custom dropdown item</div>
<div onClick={toggle}>Custom dropdown item</div>
<div onClick={toggle}>Custom dropdown item</div>
<div onClick={toggle}>Custom dropdown item</div>
</DropdownMenu>
</Dropdown>
);
}
export default Example;
Uncontrolled Dropdown
For the most basic use-case an uncontrolled component can provide the functionality wanted without the need to manage/control the state of the component. UncontrolledDropdown
does not require isOpen
nor toggle
props to work. For the ButtonDropdown
flavor, an uncontrolled component have been made as well; UncontrolledButtonDropdown
.
import React from 'react';
import { UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
export default function Example () {
return (
<UncontrolledDropdown>
<DropdownToggle caret>
Dropdown
</DropdownToggle>
<DropdownMenu>
<DropdownItem header>Header</DropdownItem>
<DropdownItem disabled>Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem divider />
<DropdownItem>Another Action</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
);
}
Drop direction variations
<Dropdown direction="up" isOpen={isOpen} toggle={toggle}>
<DropdownToggle caret>
Dropup
</DropdownToggle>
<DropdownMenu>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
</DropdownMenu>
</Dropdown>
<Dropdown direction="left" isOpen={this.state.btnDropleft} toggle={() => { this.setState({ btnDropleft: !this.state.btnDropleft }); }}>
<DropdownToggle caret>
Dropleft
</DropdownToggle>
<DropdownMenu>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
</DropdownMenu>
</Dropdown>
<Dropdown direction="right" isOpen={this.state.btnDropright} toggle={() => { this.setState({ btnDropright: !this.state.btnDropright }); }}>
<DropdownToggle caret>
Dropright
</DropdownToggle>
<DropdownMenu>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
</DropdownMenu>
</Dropdown>
Modifiers
<Dropdown isOpen={isOpen} toggle={toggle}>
<DropdownToggle>
Dropdown
</DropdownToggle>
<DropdownMenu
modifiers={{
setMaxHeight: {
enabled: true,
order: 890,
fn: (data) => {
return {
...data,
styles: {
...data.styles,
overflow: 'auto',
maxHeight: '100px',
},
};
},
},
}}
>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
<DropdownItem>Another Action</DropdownItem>
</DropdownMenu>
</Dropdown>
setActiveFromChild
Use setActiveFromChild
prop to automatically set the dropdown to active when any of the dropdown menu items are active. Note: this prop will not work in conjunction with react-router Link
and activeClassName
.
import React from 'react';
import { Navbar, Nav, NavItem, NavLink, UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
export default function Example () {
return (
<Navbar color="light" light expand="md">
<Nav className="ml-auto" navbar>
<NavItem>
<NavLink href="/components/">Inactive Link</NavLink>
</NavItem>
<UncontrolledDropdown setActiveFromChild>
<DropdownToggle tag="a" className="nav-link" caret>
Dropdown
</DropdownToggle>
<DropdownMenu>
<DropdownItem tag="a" href="/blah" active>Link</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</Nav>
</Navbar>
);
}
container
Use the container
prop to allow the dropdown menu to be placed inside an alternate container through a React Portal. This can be used to allow the dropdown menu to escape a container with the style overflow: hidden
.
Container with overflow: hidden.
Last clicked: null
import React, { useState } from 'react';
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
const Example = (props) => {
const [dropdownOpen, setDropdownOpen] = useState(false);
const toggle = () => setDropdownOpen(prevState => !prevState);
const [lastClicked, setLastClicked] = useState(null);
return (
<div style={{ width: 300, height: 100, border: '1px solid #000', padding: '8px', overflow: 'hidden' }}>
Container with overflow: hidden.<br />
Last clicked: {lastClicked || 'null'}
<Dropdown isOpen={dropdownOpen} toggle={toggle}>
<DropdownToggle caret>
Dropdown
</DropdownToggle>
<DropdownMenu container="body">
<DropdownItem onClick={() => setLastClicked(1)}>Action 1</DropdownItem>
<DropdownItem onClick={() => setLastClicked(2)}>Action 2</DropdownItem>
<DropdownItem onClick={() => setLastClicked(3)}>Action 3</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
);
}
export default Example;