Dropdown Menu
These components can be used together to create a dropdown menu interface with inbuilt accessibility features.
They contain the bare minimum styling by default, and can be styled however
you prefer. Each element also accepts an as
prop, which can be used to
define what kind of DOM or React element should be rendered.
<DropdownMenu>
<DropdownMenuButton>This button triggers the menu</DropdownMenuButton>
<DropdownMenuItems as="ul">
<DropdownMenuItem as="li">an item</DropdownMenuItem>
<DropdownMenuItem as="li">another item</DropdownMenuItem>
</DropdownMenuItems>
</DropdownMenu>
DropdownMenu
The controller component. This must wrap all other components.
CSS Selectors
-
[data-flight-dropdown]
-
[data-flight-dropdown-open='false']
— styles applied when the items are hidden -
[data-flight-dropdown-open='true']
— styles applied when the items are visible
DropdownMenuButton
The button that triggers hiding/showing of the menu items.
CSS Selectors
-
[data-flight-dropdown-button]
DropdownMenuItems
The container that wraps the items.
CSS Selectors
-
[data-flight-dropdown-items]
DropdownMenuItem
Contains a single item.
The onSelect
prop should be used to determine what happens when the item is selected.
CSS Selectors
-
[data-flight-dropdown-item]
Accessing internal state
The DropdownMenu exposes some internal state, if you'd like to customise the behaviour.
isOpen | Boolean | = false (or the value passed to the DropdownMenu's initialOpen prop) |
---|---|---|
setIsOpen | Function |
If you want to access it, you have a few options:
With onSelect
The onSelect
prop is called with an object containing { isOpen, setIsOpen }
.
<DropdownMenuItem onSelect={({ setIsOpen }) => setIsOpen(false)}>
Close the menu
</DropdownMenuItem>
useDropdownMenu
This hook can be used by any component inside the DropdownMenu in order to access the menu's state.
function Item(props) {
const { setIsOpen } = useDropdownMenu();
return (
<li {...props}>
<button onClick={() => setIsOpen(false)}>Close the menu</button>
</li>
);
}
<DropdownMenu>
<DropdownMenuItems>
<DropdownMenuItem as={Item} />
</DropdownMenuItems>
</DropdownMenu>;
DropdownMenu render callback
Alternatively, you can provide a render callback as the child of the DropdownMenu.
<DropdownMenu>
{({ setIsOpen }) => (
<DropdownMenuItems>
<li>
<button onClick={() => setIsOpen(false)}>Close the menu</button>
</li>
</DropdownMenuItems>
)}
</DropdownMenu>
Complete example
Hint: You can navigate the items with your keyboard
<Playground>
<>
<DropdownMenu>
<DropdownMenuButton>Open</DropdownMenuButton>
<DropdownMenuItems
style={{
background: "white",
padding: "0.25em",
listStyle: "none",
zIndex: 999,
border: "1px solid black",
}}
>
<DropdownMenuItem onSelect={() => alert("hi!")}>
hello!
</DropdownMenuItem>
<DropdownMenuItem onSelect={() => alert("great!")}>
I'm open now
</DropdownMenuItem>
<DropdownMenuItem onSelect={({ setIsOpen }) => setIsOpen(false)}>
<button>Close the menu!</button>
</DropdownMenuItem>
</DropdownMenuItems>
</DropdownMenu>
</>
</Playground>