LeafyGreen UI Kit Menu
npm install @leafygreen-ui/menu``shell`
pnpm add @leafygreen-ui/menu
`shell`
yarn add @leafygreen-ui/menu
`shell`
npm install @leafygreen-ui/menu
| Package | Version |
| ------------------------------------ | -------- |
| @leafygreen-ui/leafygreen-provider | ^1.1.0 |
`tsx
import { Menu, MenuItem } from '@leafygreen-ui/menu';
function BasicExample() {
const [open, setOpen] = useState(false);
return (
$3
`tsx
import { Menu, MenuItem } from '@leafygreen-ui/menu';
import Icon from '@leafygreen-ui/icon';;
`$3
`tsx
import {
Menu,
MenuItem,
SubMenu,
MenuGroup,
MenuSeparator,
} from '@leafygreen-ui/menu';
import Icon from '@leafygreen-ui/icon';;
`$3
`tsx
// Controlled Menu
function ControlledExample() {
const [isOpen, setIsOpen] = useState(false); return (
trigger={}
open={isOpen}
setOpen={setIsOpen}
>
);
}// Uncontrolled Menu with initial state
;
`$3
`tsx
trigger={({ onClick, children }) => (
}>
Custom Trigger
{children}
)}
>
`$3
Use
FocusableMenuItem when you need to include interactive elements like inputs within menu items:`tsx
import { Menu, MenuItem, FocusableMenuItem } from '@leafygreen-ui/menu';
import TextInput from '@leafygreen-ui/text-input';;
`$3
`tsx
variant={MenuVariant.Compact}
trigger={}
>
`Usage with NextJS Link components
We recommend using
Menu with NextJS's link components in the following pattern:`tsx
import NextLink from 'next/link';function CustomLink({ href, children, ...props }) {
return (
{children}
);
}
;
`This pattern is recommended because the
SubMenu component expects to pass styling through the className prop, which would not apply correctly if it was passed to NextLink.Accessibility
The Menu component includes comprehensive keyboard navigation and accessibility features:
$3
- Arrow Keys: Navigate between menu items
-
↓ (Down): Move to next menu item, or first item if at the end
- ↑ (Up): Move to previous menu item, or last item if at the beginning
- → (Right): Open SubMenu or move to first item in SubMenu
- ← (Left): Close SubMenu or move to parent menu
- Enter/Space: Activate the focused menu item
- Escape: Close the menu
- Tab: Close the menu and move focus to the next focusable element$3
- Menu elements have appropriate
role="menu" and role="menuitem" attributes
- SubMenus include aria-expanded and aria-haspopup attributes
- Active items are marked with aria-current="true"
- Disabled items have aria-disabled="true"
- Menu groups are properly labeled with aria-labelledbyAPI
Menu
Properties
| Prop | Type | Description | Default |
| ------------------ | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------- |
|
children | ReactNode | The menu items, submenus, groups, and separators | |
| trigger | ReactElement \| function | Element or function that triggers the menu. Function signature: ({ onClick, children }) => ReactElement | |
| open | boolean | Controls whether the menu is open or closed | false |
| setOpen | function | Callback to control the open state: (open: boolean) => void | |
| initialOpen | boolean | Initial open state for uncontrolled usage | false |
| shouldClose | function | Callback to determine if menu should close: () => boolean | () => true |
| onOpen | function | Callback fired when menu opens (after transition) | |
| onClose | function | Callback fired when menu closes (after transition) | |
| align | 'top' \| 'bottom' \| 'left' \| 'right' | Alignment of the menu relative to its trigger | 'bottom' |
| justify | 'start' \| 'middle' \| 'end' | Justification of the menu relative to its trigger | 'end' |
| maxHeight | number | Maximum height of the menu in pixels | 256 |
| darkMode | boolean | Determines if the component renders in dark mode | false |
| renderDarkMenu | boolean | Whether the menu should always render dark, regardless of theme context | true |
| variant | 'default' \| 'compact' | Visual variant of the menu. Compact hides descriptions | 'default' |
| refEl | HTMLElement | Reference element for positioning (alternative to trigger) | |
| adjustOnMutation | boolean | Whether menu should reposition on DOM mutations | false |
| renderMode | 'inline' \| 'portal' \| 'top-layer' | Rendering mode. Use 'top-layer' for modern browsers | 'top-layer' |
| id | string | ID for the menu dropdown element | |
| data-testid | string | Test ID for the menu element | |
| ... | native ul attributes | Any other props are spread to the root ul element | |_Note: Some props like
portalContainer, scrollContainer, portalClassName, and popoverZIndex are deprecated. Use renderMode="top-layer" instead._MenuItem
Properties
| Prop | Type | Description | Default |
| ------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------- | ----------- |
|
children | ReactNode | Content to appear inside of the MenuItem | |
| href | string | If supplied, renders the MenuItem as an tag instead of a