What is @chakra-ui/menu?
@chakra-ui/menu is a component library for creating accessible and customizable menu components in React applications. It is part of the Chakra UI library, which provides a set of accessible, reusable, and composable React components.
What are @chakra-ui/menu's main functionalities?
Basic Menu
This code demonstrates how to create a basic menu with a button that triggers a dropdown list of menu items.
```jsx
import { Menu, MenuButton, MenuList, MenuItem, Button } from '@chakra-ui/react';
function BasicMenu() {
return (
<Menu>
<MenuButton as={Button}>
Actions
</MenuButton>
<MenuList>
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
<MenuItem>Mark as Draft</MenuItem>
<MenuItem>Delete</MenuItem>
<MenuItem>Attend a Workshop</MenuItem>
</MenuList>
</Menu>
);
}
```
Menu with Submenu
This code demonstrates how to create a menu with grouped items and a submenu, providing a more organized structure for menu options.
```jsx
import { Menu, MenuButton, MenuList, MenuItem, MenuGroup, MenuDivider, Button } from '@chakra-ui/react';
function MenuWithSubmenu() {
return (
<Menu>
<MenuButton as={Button}>
File
</MenuButton>
<MenuList>
<MenuGroup title="Profile">
<MenuItem>My Account</MenuItem>
<MenuItem>Payments </MenuItem>
</MenuGroup>
<MenuDivider />
<MenuGroup title="Help">
<MenuItem>Docs</MenuItem>
<MenuItem>FAQ</MenuItem>
</MenuGroup>
</MenuList>
</Menu>
);
}
```
Menu with Icons
This code demonstrates how to add icons to menu items, enhancing the visual appeal and usability of the menu.
```jsx
import { Menu, MenuButton, MenuList, MenuItem, Button } from '@chakra-ui/react';
import { FaDownload, FaCopy, FaTrash } from 'react-icons/fa';
function MenuWithIcons() {
return (
<Menu>
<MenuButton as={Button}>
Actions
</MenuButton>
<MenuList>
<MenuItem icon={<FaDownload />}>Download</MenuItem>
<MenuItem icon={<FaCopy />}>Create a Copy</MenuItem>
<MenuItem icon={<FaTrash />}>Delete</MenuItem>
</MenuList>
</Menu>
);
}
```
Other packages similar to @chakra-ui/menu
react-select
react-select is a flexible and customizable library for building dropdowns and select inputs in React. It offers a wide range of features including multi-select, async options, and customizable styles. Compared to @chakra-ui/menu, react-select is more focused on select inputs rather than general-purpose menus.
rc-menu
rc-menu is a React component library for creating menu components. It provides a set of features for building complex menus, including nested menus and keyboard navigation. While rc-menu offers similar functionalities to @chakra-ui/menu, it may require more customization to achieve the same level of accessibility and styling provided by Chakra UI.
react-burger-menu
react-burger-menu is a library for creating off-canvas side menus in React. It is highly customizable and supports various animations and styles. Unlike @chakra-ui/menu, which focuses on dropdown menus, react-burger-menu is designed for creating sidebar menus.
An accessible dropdown menu for the common dropdown menu button design pattern.
Menu uses roving tabIndex for focus management.
Installation
yarn add @chakra-ui/menu
npm i @chakra-ui/menu
Import components
import {
Menu,
MenuButton,
MenuList,
MenuItem,
MenuGroup,
MenuDivider,
MenuOptionGroup,
MenuItemOption,
} from "@chakra-ui/core"
Usage
<Menu>
<MenuButton>Actions</MenuButton>
<MenuList>
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
<MenuItem>Mark as Draft</MenuItem>
<MenuItem>Delete</MenuItem>
<MenuItem as="a" href="#">
Attend a Workshop
</MenuItem>
</MenuList>
</Menu>
Accessing the internal state
To access the internal state of the Menu, use a function as a children
(commonly known as a render prop). You'll get access to the internal state
isOpen
and method onClose
.
<Menu>
{({ isOpen }) => (
<React.Fragment>
<MenuButton>{isOpen ? "Close" : "Open"}</MenuButton>
<MenuList>
<MenuItem>Download</MenuItem>
<MenuItem onClick={() => alert("Kagebunshin")}>Create a Copy</MenuItem>
</MenuList>
</React.Fragment>
)}
</Menu>
Letter Navigation
When focus is on the MenuButton
or within the MenuList
and you type a letter
key, a search begins. Focus will move to the first MenuItem
that starts with
the letter you typed.
Open the menu, try and type any letter, say "S" to see the focus movement.
<Menu>
<MenuButton
px={4}
py={2}
transition="all 0.2s"
borderRadius="md"
borderWidth="1px"
_hover={{ bg: "gray.100" }}
_expanded={{ bg: "red.200" }}
_focus={{ outline: 0, boxShadow: "outline" }}
>
File <ChevronDownIcon />
</MenuButton>
<MenuList>
<MenuItem>New File</MenuItem>
<MenuItem>New Window</MenuItem>
<MenuDivider />
<MenuItem>Open...</MenuItem>
<MenuItem>Save File</MenuItem>
</MenuList>
</Menu>
Just another example.
<Menu>
<MenuButton>Your Cats</MenuButton>
<MenuList>
<MenuItem minH="48px">
<Image
size="2rem"
borderRadius="full"
src="https://placekitten.com/100/100"
alt="Fluffybuns the destroyer"
mr="12px"
/>
<span>Fluffybuns the Destroyer</span>
</MenuItem>
<MenuItem minH="40px">
<Image
size="2rem"
borderRadius="full"
src="https://placekitten.com/120/120"
alt="Simon the pensive"
mr="12px"
/>
<span>Simon the pensive</span>
</MenuItem>
</MenuList>
</Menu>
To group related MenuItems
, use the MenuGroup
component and pass it a label
for the group name.
<Menu>
<MenuButton>Profile</MenuButton>
<MenuList>
<MenuGroup title="Profile">
<MenuItem>My Account</MenuItem>
<MenuItem>Payments </MenuItem>
</MenuGroup>
<MenuDivider />
<MenuGroup title="Help">
<MenuItem>Docs</MenuItem>
<MenuItem>FAQ</MenuItem>
</MenuGroup>
</MenuList>
</Menu>
You can compose a menu for table headers to help with sorting and filtering
options. Use the MenuOptionGroup
and MenuItemOption
components.
<Menu closeOnSelect={false}>
<MenuButton>MenuItem</MenuButton>
<MenuList minWidth="240px">
<MenuOptionGroup defaultValue="asc" title="Order" type="radio">
<MenuItemOption value="asc">Ascending</MenuItemOption>
<MenuItemOption value="desc">Descending</MenuItemOption>
</MenuOptionGroup>
<MenuDivider />
<MenuOptionGroup title="Country" type="checkbox">
<MenuItemOption value="email">Email</MenuItemOption>
<MenuItemOption value="phone">Phone</MenuItemOption>
<MenuItemOption value="country">Country</MenuItemOption>
</MenuOptionGroup>
</MenuList>
</Menu>