Menu
View .mdA menu is a hidden list of options that is shown when someone interacts with a trigger component, like a button, an avatar, or an icon.
Resources
Best practices
Do
- Use menus for immediate actions or navigation.
- Order options logically, such as frequent actions first and dangerous actions last.
- Use brief, verb-led labels for actions.
Don't
- Use a menu to collect information.
- Use long menu-item labels.
- Create deeply nested menu structures.
Behavior and states
- The default menu treats each item as a button that initiates an action.
- Checkbox menus let people select multiple items.
- Radio menus let people select one item that turns a setting on or off.
- Menus have a maximum width of 300 pixels.
- Menu items with long labels wrap onto the next line.
- An option can open related options in a submenu.
- Add an aria-label to submenu trigger components.
API referenceGenerated CoreAI prop and type summaries
API
Generated CoreAI prop summaries, not replacement type declarations. Most native DOM/event and ARIA props are omitted. ? means optional; JSDoc shows defaults, deprecations, and conditional requirements. Defaults assume the standard CoreAI provider.
Menu API
Wrapper component that manages state for a popup MenuList and a MenuTrigger
interface MenuProps {
/**
* Map of all checked values
*/
checkedValues?: Record<string, string[]>;
/**
* Can contain two children including `MenuTrigger` and `MenuPopover`.
* Alternatively can only contain `MenuPopover` if using a custom `target`.
*/
children: JSXElement | [JSXElement, JSXElement];
/**
* Close when scroll outside of it
* @default false
*/
closeOnScroll?: boolean;
/**
* Default values to be checked on mount
*/
defaultCheckedValues?: Record<string, string[]>;
/**
* Whether the popup is open by default
* @default false
*/
defaultOpen?: boolean;
/**
* States that menu items can contain selectable items and reserve slots for item alignment
*/
hasCheckmarks?: boolean;
/**
* States that menu items can contain icons and reserve slots for item alignment
*/
hasIcons?: boolean;
/**
* Sets the delay for mouse open/close for the popover one mouse enter/leave
*/
hoverDelay?: number;
/**
* Root menus are rendered out of DOM order on `document.body`, use this to render the menu in DOM order
* This option is disregarded for submenus
* @default false
*/
inline?: boolean;
/**
* Where the portal children are mounted on DOM
* @default a new element on document.body without any styling
*/
mountNode?: HTMLElement | { element?: HTMLElement | null; className?: string; } | null | undefined;
/**
* Callback when checked items change for value with a name
*/
onCheckedValueChange?: ((e: MenuCheckedValueChangeEvent, data: MenuCheckedValueChangeData) => void);
/**
* Call back when the component requests to change value
* The `open` value is used as a hint when directly controlling the component
*/
onOpenChange?: ((e: MouseEvent | Event | TouchEvent | KeyboardEvent<HTMLElement> | React.MouseEvent<Element, MouseEvent> | React.MouseEvent<HTMLElement, MouseEvent>, data: MenuOpenChangeData) => void);
/**
* Whether the popup is open
* @default false
*/
open?: boolean;
/**
* Opens the menu on right click (context menu), removes all other menu open interactions
* @default false
*/
openOnContext?: boolean;
/**
* Opens the menu on hover
* @default false
*/
openOnHover?: boolean;
/**
* Do not dismiss the menu when a menu item is clicked
* @default false
*/
persistOnItemClick?: boolean;
/**
* Configures the positioned menu
*/
positioning?: PositioningShorthand;
/**
* Slot for the surface motion animation.
* For more information refer to the [Motion docs page](https://react.fluentui.dev/?path=/docs/motion-motion-slot--docs).
*/
surfaceMotion?: PresenceMotionSlotProps | null;
}
MenuDivider API
Define a styled MenuDivider, using the useMenuDivider_unstable hook.
interface MenuDividerProps {
as?: "div";
children?: any;
className?: string;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MenuGroup API
Define a styled MenuGroup, using the useMenuGroup_unstable hook.
interface MenuGroupProps {
as?: "div";
children?: any;
className?: string;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MenuGroupHeader API
Define a styled MenuGroupHeader, using the useMenuGroupHeader_unstable hook.
interface MenuGroupHeaderProps {
as?: "div";
children?: any;
className?: string;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MenuItem API
Define a styled MenuItem, using the useMenuItem_unstable and useMenuItemStyles_unstable hook.
interface MenuItemProps {
as?: "div";
/**
* A helper slot for alignment when a menu item is used with selectable menuitems
* Avoid using this slot as a replacement for MenuItemCheckbox and MenuItemRadio components
*/
checkmark?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
children?: any;
className?: string;
/**
* Component children are placed in this slot
* Avoid using the `children` property in this slot in favour of Component children whenever possible
*/
content?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
disabled?: boolean;
/**
* @deprecated this property does nothing.
* disabled focusable is by default by simply using `disabled` property
*/
disabledFocusable?: boolean;
/**
* If the menu item is a trigger for a submenu
* @default false
*/
hasSubmenu?: boolean;
/**
* Icon slot rendered before children content
*/
icon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Clicking on the menu item will not dismiss an open menu
* @default false
*/
persistOnClick?: boolean;
ref?: Ref<HTMLDivElement>;
/**
* Secondary content rendered opposite the primary content (e.g Shortcut text)
*/
secondaryContent?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
style?: CSSProperties;
/**
* Icon slot that shows the indicator for a submenu
*/
submenuIndicator?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Additional descriptor to main content that creates a multiline layout
*/
subText?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
}
MenuItemCheckbox API
Define a styled MenuItemCheckbox, using the useMenuItemCheckbox_unstable hook.
interface MenuItemCheckboxProps {
as?: "div";
/**
* A helper slot for alignment when a menu item is used with selectable menuitems
* Avoid using this slot as a replacement for MenuItemCheckbox and MenuItemRadio components
*/
checkmark?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
children?: any;
className?: string;
/**
* Component children are placed in this slot
* Avoid using the `children` property in this slot in favour of Component children whenever possible
*/
content?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
disabled?: boolean;
/**
* @deprecated this property does nothing.
* disabled focusable is by default by simply using `disabled` property
*/
disabledFocusable?: boolean;
/**
* If the menu item is a trigger for a submenu
* @default false
*/
hasSubmenu?: boolean;
/**
* Icon slot rendered before children content
*/
icon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Follows input convention
* https://www.w3schools.com/jsref/prop_checkbox_name.asp
*/
name: string;
/**
* Clicking on the menu item will not dismiss an open menu
* @default false
*/
persistOnClick?: boolean;
ref?: Ref<HTMLDivElement>;
/**
* Secondary content rendered opposite the primary content (e.g Shortcut text)
*/
secondaryContent?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
style?: CSSProperties;
/**
* Icon slot that shows the indicator for a submenu
*/
submenuIndicator?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Additional descriptor to main content that creates a multiline layout
*/
subText?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Follows input convention
* https://www.w3schools.com/jsref/prop_checkbox_value.asp
*/
value: string;
}
MenuItemLink API
MenuItemLink component
interface MenuItemLinkProps {
as?: "a";
/**
* A helper slot for alignment when a menu item is used with selectable menuitems
* Avoid using this slot as a replacement for MenuItemCheckbox and MenuItemRadio components
*/
checkmark?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
children?: any;
className?: string;
/**
* Component children are placed in this slot
* Avoid using the `children` property in this slot in favour of Component children whenever possible
*/
content?: ((WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null) & string) | undefined;
disabled?: boolean;
href?: string;
/**
* Icon slot rendered before children content
*/
icon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
ref?: Ref<HTMLAnchorElement>;
/**
* Secondary content rendered opposite the primary content (e.g Shortcut text)
*/
secondaryContent?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
style?: CSSProperties;
}
MenuItemRadio API
Define a styled MenuItemRadio, using the useMenuItemRadio_unstable hook.
interface MenuItemRadioProps {
as?: "div";
/**
* A helper slot for alignment when a menu item is used with selectable menuitems
* Avoid using this slot as a replacement for MenuItemCheckbox and MenuItemRadio components
*/
checkmark?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
children?: any;
className?: string;
/**
* Component children are placed in this slot
* Avoid using the `children` property in this slot in favour of Component children whenever possible
*/
content?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
disabled?: boolean;
/**
* @deprecated this property does nothing.
* disabled focusable is by default by simply using `disabled` property
*/
disabledFocusable?: boolean;
/**
* If the menu item is a trigger for a submenu
* @default false
*/
hasSubmenu?: boolean;
/**
* Icon slot rendered before children content
*/
icon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Follows input convention
* https://www.w3schools.com/jsref/prop_checkbox_name.asp
*/
name: string;
/**
* Clicking on the menu item will not dismiss an open menu
* @default false
*/
persistOnClick?: boolean;
ref?: Ref<HTMLDivElement>;
/**
* Secondary content rendered opposite the primary content (e.g Shortcut text)
*/
secondaryContent?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
style?: CSSProperties;
/**
* Icon slot that shows the indicator for a submenu
*/
submenuIndicator?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Additional descriptor to main content that creates a multiline layout
*/
subText?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Follows input convention
* https://www.w3schools.com/jsref/prop_checkbox_value.asp
*/
value: string;
}
MenuItemSwitch API
interface MenuItemSwitchProps {
as?: "div";
children?: any;
className?: string;
/**
* Component children are placed in this slot
* Avoid using the `children` property in this slot in favour of Component children whenever possible
*/
content?: ((WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null) & string) | undefined;
disabled?: boolean;
/**
* Icon slot rendered before children content
*/
icon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Follows input convention
* https://www.w3schools.com/jsref/prop_checkbox_name.asp
*/
name: string;
/**
* Clicking on the menu item will not dismiss an open menu
* @default false
*/
persistOnClick?: boolean;
ref?: Ref<HTMLDivElement>;
/**
* Secondary content rendered opposite the primary content (e.g Shortcut text)
*/
secondaryContent?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
style?: CSSProperties;
/**
* Additional descriptor to main content that creates a multiline layout
*/
subText?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
switchIndicator?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* Follows input convention
* https://www.w3schools.com/jsref/prop_checkbox_value.asp
*/
value: string;
}
MenuList API
Define a styled MenuList, using the useMenuList_unstable hook.
interface MenuListProps {
as?: "div";
/**
* Map of all checked values
*/
checkedValues?: Record<string, string[]>;
children?: any;
className?: string;
/**
* Default values to be checked on mount
*/
defaultCheckedValues?: Record<string, string[]>;
/**
* States that menu items can contain selectable items and reserve slots for item alignment
*/
hasCheckmarks?: boolean;
/**
* States that menu items can contain icons and reserve slots for item alignment
*/
hasIcons?: boolean;
/**
* Callback when checked items change for value with a name
*/
onCheckedValueChange?: ((e: MenuCheckedValueChangeEvent, data: MenuCheckedValueChangeData) => void);
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MenuPopover API
Popover intended to wrap MenuList and adds styling and interaction support specific to menus
interface MenuPopoverProps {
as?: "div";
children?: any;
className?: string;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MenuSplitGroup API
Layout wrapper that provides extra keyboard navigation behavior for two MenuItem components.
interface MenuSplitGroupProps {
as?: "div";
children?: any;
className?: string;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MenuTrigger API
Wraps a trigger element as an only child and adds the necessary event handling to open a popup menu
interface MenuTriggerProps {
children?: ReactElement<any, string | JSXElementConstructor<any>> | ((props: MenuTriggerChildProps<ARIAButtonType, {}>) => ReactElement<any, string | JSXElementConstructor<any>> | null) | null;
/**
* Disables internal trigger mechanism that ensures a child provided will be a compliant ARIA button.
* @default false
*/
disableButtonEnhancement?: boolean;
}
Implementation
CoreAI 0.12.0; Fluent 9.74.9.
Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.