Overview
Menu displays a list of choices on a temporary surface. It appears when users interact with a button, action, or other control. Menus are ideal for displaying contextual options and actions.
Installation
npm install @naturacosmeticos/natds-web
Import
import { Menu, MenuItem } from '@naturacosmeticos/natds-web';
Props
Inherits all props from Material-UI’s Menu component.
If true, the menu is visible.
A HTML element, or a function that returns it. Used to position the menu.
Callback fired when the component requests to be closed.
Menu contents, typically MenuItem components.
Position of the menu relative to the anchor element. Default: { vertical: 'top', horizontal: 'left' }
Position on the menu which will align with the anchor’s origin. Default: { vertical: 'top', horizontal: 'left' }
If true, the menu will not unmount when closed, improving performance.
The variant to use. Use "selectedMenu" for select-like behavior.
Inherits all props from Material-UI’s MenuItem component.
The content of the menu item.
Callback fired when the menu item is clicked.
If true, the menu item is highlighted.
If true, the menu item is disabled.
If true, the menu item will behave like a button.
Usage
import { Menu, MenuItem, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';
function BasicMenu() {
const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<>
<Button onClick={handleClick}>
Open menu
</Button>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</>
);
}
import { Menu, MenuItem, Button, Icon } from '@naturacosmeticos/natds-web';
import { useState } from 'react';
function MenuWithIcons() {
const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<>
<Button onClick={handleClick}>Options</Button>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>
<Icon name="outlined-action-edit" style={{ marginRight: 16 }} />
Edit
</MenuItem>
<MenuItem onClick={handleClose}>
<Icon name="outlined-content-copy" style={{ marginRight: 16 }} />
Copy
</MenuItem>
<MenuItem onClick={handleClose}>
<Icon name="outlined-action-delete" style={{ marginRight: 16 }} />
Delete
</MenuItem>
</Menu>
</>
);
}
import { Menu, MenuItem, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';
function MenuWithSelection() {
const [anchorEl, setAnchorEl] = useState(null);
const [selectedIndex, setSelectedIndex] = useState(1);
const options = ['Profile', 'My account', 'Logout'];
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const handleMenuItemClick = (event, index) => {
setSelectedIndex(index);
handleClose();
};
return (
<>
<Button onClick={handleClick}>
Open menu
</Button>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleClose}
keepMounted
>
{options.map((option, index) => (
<MenuItem
key={option}
button
selected={index === selectedIndex}
onClick={(event) => handleMenuItemClick(event, index)}
>
{option}
</MenuItem>
))}
</Menu>
</>
);
}
import { Menu, MenuItem } from '@naturacosmeticos/natds-web';
import { useState } from 'react';
function ContextMenu() {
const [contextMenu, setContextMenu] = useState(null);
const handleContextMenu = (event) => {
event.preventDefault();
setContextMenu(
contextMenu === null
? { mouseX: event.clientX - 2, mouseY: event.clientY - 4 }
: null
);
};
const handleClose = () => {
setContextMenu(null);
};
return (
<div
onContextMenu={handleContextMenu}
style={{ cursor: 'context-menu', padding: 40, border: '1px dashed grey' }}
>
Right click here
<Menu
open={contextMenu !== null}
onClose={handleClose}
anchorReference="anchorPosition"
anchorPosition={
contextMenu !== null
? { top: contextMenu.mouseY, left: contextMenu.mouseX }
: undefined
}
>
<MenuItem onClick={handleClose}>Copy</MenuItem>
<MenuItem onClick={handleClose}>Paste</MenuItem>
<MenuItem onClick={handleClose}>Delete</MenuItem>
</Menu>
</div>
);
}
import { Menu, MenuItem, Divider, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';
function MenuWithDividers() {
const [anchorEl, setAnchorEl] = useState(null);
return (
<>
<Button onClick={(e) => setAnchorEl(e.currentTarget)}>
Options
</Button>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
>
<MenuItem onClick={() => setAnchorEl(null)}>New File</MenuItem>
<MenuItem onClick={() => setAnchorEl(null)}>Open</MenuItem>
<Divider />
<MenuItem onClick={() => setAnchorEl(null)}>Save</MenuItem>
<MenuItem onClick={() => setAnchorEl(null)}>Save As</MenuItem>
<Divider />
<MenuItem onClick={() => setAnchorEl(null)}>Exit</MenuItem>
</Menu>
</>
);
}
import { Menu, MenuItem, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';
function PositionedMenu() {
const [anchorEl, setAnchorEl] = useState(null);
return (
<>
<Button onClick={(e) => setAnchorEl(e.currentTarget)}>
Open Menu
</Button>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
<MenuItem onClick={() => setAnchorEl(null)}>Option 1</MenuItem>
<MenuItem onClick={() => setAnchorEl(null)}>Option 2</MenuItem>
<MenuItem onClick={() => setAnchorEl(null)}>Option 3</MenuItem>
</Menu>
</>
);
}
import { Menu, MenuItem, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';
function ScrollableMenu() {
const [anchorEl, setAnchorEl] = useState(null);
const options = Array.from({ length: 20 }, (_, i) => `Option ${i + 1}`);
return (
<>
<Button onClick={(e) => setAnchorEl(e.currentTarget)}>
Long Menu
</Button>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
PaperProps={{
style: {
maxHeight: 300,
width: '20ch',
},
}}
>
{options.map((option) => (
<MenuItem key={option} onClick={() => setAnchorEl(null)}>
{option}
</MenuItem>
))}
</Menu>
</>
);
}
import { Menu, MenuItem, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';
function NestedMenu() {
const [mainAnchor, setMainAnchor] = useState(null);
const [subAnchor, setSubAnchor] = useState(null);
return (
<>
<Button onClick={(e) => setMainAnchor(e.currentTarget)}>
Open Menu
</Button>
<Menu
anchorEl={mainAnchor}
open={Boolean(mainAnchor)}
onClose={() => setMainAnchor(null)}
>
<MenuItem onClick={() => setMainAnchor(null)}>Profile</MenuItem>
<MenuItem onClick={(e) => setSubAnchor(e.currentTarget)}>
Settings
</MenuItem>
<MenuItem onClick={() => setMainAnchor(null)}>Logout</MenuItem>
</Menu>
<Menu
anchorEl={subAnchor}
open={Boolean(subAnchor)}
onClose={() => setSubAnchor(null)}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'left' }}
>
<MenuItem onClick={() => { setSubAnchor(null); setMainAnchor(null); }}>
Account
</MenuItem>
<MenuItem onClick={() => { setSubAnchor(null); setMainAnchor(null); }}>
Privacy
</MenuItem>
<MenuItem onClick={() => { setSubAnchor(null); setMainAnchor(null); }}>
Notifications
</MenuItem>
</Menu>
</>
);
}
Composition
Menu works well with:
- MenuItem: Individual items in the menu
- MenuList: Wrapper for menu items when not using Menu
- Divider: Separates groups of menu items
- ListItemIcon: Icons within menu items
- ListItemText: Text content within menu items
Best Practices
- Keep menu options focused and relevant to the context
- Use icons sparingly and consistently
- Group related items and separate groups with dividers
- Limit menu items to 7-10 for better usability
- Use scrollable menus for longer lists
- Disable unavailable options rather than hiding them
- Provide keyboard navigation support
Accessibility
- Menu items should be keyboard navigable (Arrow keys, Enter, Escape)
- Press ESC to close the menu
- Use ARIA labels for icon-only menu items
- Disabled items should not be keyboard focusable
- Ensure adequate color contrast for menu items
- Screen readers announce menu state and selected items
Common Use Cases
- User account menus
- Context menus (right-click)
- Action overflow menus (three-dot menus)
- Dropdown selectors
- Navigation menus
- Settings and preferences
Related Components
Material-UI Reference
This component is based on Material-UI’s Menu. For advanced usage, see the Material-UI Menu documentation.