Default

Loading interactive example. Full source is available below.

View example source
Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import * as React from 'react';

export const Default = (): JSXElement => (<Menu positioning={{ autoSize: true }}>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuItem>New </MenuItem>
        <MenuItem>New Window</MenuItem>
        <MenuItem disabled>Open File</MenuItem>
        <MenuItem>Open Folder</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default Default;

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 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.

Setup and dependencies.

Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.

Aligning With Icons

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import * as React from 'react';

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

export const AligningWithIcons = (): JSXElement => (<Menu hasIcons>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>
    <MenuPopover>
      <MenuList>
        <MenuItem>Cut</MenuItem>
        <MenuItem icon={<PasteIcon />}>Paste</MenuItem>
        <MenuItem>Edit</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default AligningWithIcons;

Aligning With Selectable Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItemCheckbox } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { MenuItem } from "@coreai-ds/react-components";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

export const AligningWithSelectableItems = (): JSXElement => (<Menu hasIcons hasCheckmarks>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>
    <MenuPopover>
      <MenuList>
        <MenuItemCheckbox icon={<CutIcon />} name="edit" value="cut">
          Checkbox item
        </MenuItemCheckbox>
        <MenuItem>Menu item</MenuItem>
        <MenuItem>Menu item</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default AligningWithSelectableItems;

Anchor To Custom Target

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { PositioningImperativeRef } from "@coreai-ds/react-components";
import type { MenuProps } from "@coreai-ds/react-components";
import { useRestoreFocusTarget } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

export const AnchorToCustomTarget = (): JSXElement => {
    const buttonRef = React.useRef<HTMLButtonElement>(null);
    const customAnchorRef = React.useRef<HTMLButtonElement>(null);
    const positioningRef = React.useRef<PositioningImperativeRef>(null);
    const [open, setOpen] = React.useState(false);
    const onOpenChange: MenuProps['onOpenChange'] = (e, data) => {
        // do not close menu as an outside click if clicking on the custom trigger/target
        // this prevents it from closing & immediately re-opening when clicking custom triggers
        if (data.type === 'clickOutside' && (e.target === customAnchorRef.current || e.target === buttonRef.current)) {
            return;
        }
        setOpen(data.open);
    };
    React.useEffect(() => {
        if (buttonRef.current) {
            positioningRef.current?.setTarget(buttonRef.current);
        }
    }, [buttonRef, positioningRef]);
    const restoreFocusTargetAttribute = useRestoreFocusTarget();
    return (<>
      <Button {...restoreFocusTargetAttribute} ref={customAnchorRef} onClick={() => setOpen(s => !s)}>
        Open menu
      </Button>
      <Button {...restoreFocusTargetAttribute} ref={buttonRef} onClick={() => setOpen(s => !s)}>
        Custom target
      </Button>
      <Menu open={open} onOpenChange={onOpenChange} positioning={{ positioningRef }}>
        <MenuPopover>
          <MenuList>
            <MenuItem>New </MenuItem>
            <MenuItem>New Window</MenuItem>
            <MenuItem disabled>Open File</MenuItem>
            <MenuItem>Open Folder</MenuItem>
          </MenuList>
        </MenuPopover>
      </Menu>
    </>);
};

export default AnchorToCustomTarget;

Checkbox Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItemCheckbox } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

export const CheckboxItems = (): JSXElement => {
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <Button>Toggle menu</Button>
      </MenuTrigger>
      <MenuPopover>
        <MenuList>
          <MenuItemCheckbox icon={<CutIcon />} name="edit" value="cut">
            Cut
          </MenuItemCheckbox>
          <MenuItemCheckbox icon={<PasteIcon />} name="edit" value="paste">
            Paste
          </MenuItemCheckbox>
          <MenuItemCheckbox icon={<EditIcon />} name="edit" value="edit">
            Edit
          </MenuItemCheckbox>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default CheckboxItems;

Controlled Checkbox Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MenuProps } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItemCheckbox } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

export const ControlledCheckboxItems = (): JSXElement => {
    const [checkedValues, setCheckedValues] = React.useState<Record<string, string[]>>({ edit: ['cut', 'paste'] });
    const onChange: MenuProps['onCheckedValueChange'] = (e, { name, checkedItems }) => {
        setCheckedValues(s => {
            return s ? { ...s, [name]: checkedItems } : { [name]: checkedItems };
        });
    };
    return (<Menu checkedValues={checkedValues} onCheckedValueChange={onChange}>
      <MenuTrigger disableButtonEnhancement>
        <Button>Toggle menu</Button>
      </MenuTrigger>
      <MenuPopover>
        <MenuList>
          <MenuItemCheckbox icon={<CutIcon />} name="edit" value="cut">
            Cut
          </MenuItemCheckbox>
          <MenuItemCheckbox icon={<PasteIcon />} name="edit" value="paste">
            Paste
          </MenuItemCheckbox>
          <MenuItemCheckbox icon={<EditIcon />} name="edit" value="edit">
            Edit
          </MenuItemCheckbox>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default ControlledCheckboxItems;

Controlled Radio Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MenuProps } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItemRadio } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

export const ControlledRadioItems = (): JSXElement => {
    const [checkedValues, setCheckedValues] = React.useState<Record<string, string[]>>({ font: ['calibri'] });
    const onChange: MenuProps['onCheckedValueChange'] = (e, { name, checkedItems }) => {
        setCheckedValues(s => ({ ...s, [name]: checkedItems }));
    };
    return (<Menu checkedValues={checkedValues} onCheckedValueChange={onChange}>
      <MenuTrigger disableButtonEnhancement>
        <Button>Toggle menu</Button>
      </MenuTrigger>
      <MenuPopover>
        <MenuList>
          <MenuItemRadio icon={<CutIcon />} name="font" value="segoe">
            Segoe
          </MenuItemRadio>
          <MenuItemRadio icon={<PasteIcon />} name="font" value="calibri">
            Calibri
          </MenuItemRadio>
          <MenuItemRadio icon={<EditIcon />} name="font" value="arial">
            Arial
          </MenuItemRadio>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default ControlledRadioItems;

Controlling Open And Close

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MenuProps } from "@coreai-ds/react-components";
import type { CheckboxProps } from "@coreai-ds/react-components";
import { Checkbox } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

export const ControllingOpenAndClose = (): JSXElement => {
    const [open, setOpen] = React.useState(false);
    const onOpenChange: MenuProps['onOpenChange'] = (e, data) => {
        setOpen(data.open);
    };
    const onChange: CheckboxProps['onChange'] = (e, { checked }) => {
        if (typeof checked === 'boolean') {
            setOpen(checked);
        }
    };
    return (<div>
      <div>
        <Checkbox label="Open" checked={open} onChange={onChange}/>
      </div>

      <Menu open={open} onOpenChange={onOpenChange}>
        <MenuTrigger disableButtonEnhancement>
          <Button>Toggle menu</Button>
        </MenuTrigger>

        <MenuPopover>
          <MenuList>
            <MenuItem>New </MenuItem>
            <MenuItem>New Window</MenuItem>
            <MenuItem disabled>Open File</MenuItem>
            <MenuItem>Open Folder</MenuItem>
          </MenuList>
        </MenuPopover>
      </Menu>
    </div>);
};

export default ControllingOpenAndClose;

Custom Trigger

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MenuProps } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import type { MenuTriggerChildProps } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const CustomMenuTrigger = React.forwardRef<HTMLButtonElement, Partial<MenuTriggerChildProps>>((props, ref) => {
    return (<Button {...props} ref={ref}>
      Custom Trigger
    </Button>);
});

export const CustomTrigger = (): JSXElement => {
    const [open, setOpen] = React.useState(false);
    const onOpenChange: MenuProps['onOpenChange'] = (e, data) => {
        setOpen(data.open);
    };
    return (<Menu open={open} onOpenChange={onOpenChange}>
      <MenuTrigger disableButtonEnhancement>
        <CustomMenuTrigger />
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>New </MenuItem>
          <MenuItem>New Window</MenuItem>
          <MenuItem disabled>Open File</MenuItem>
          <MenuItem>Open Folder</MenuItem>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default CustomTrigger;

Grouping Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuGroup } from "@coreai-ds/react-components";
import { MenuGroupHeader } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";
import { MenuDivider } from "@coreai-ds/react-components";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

export const GroupingItems = (): JSXElement => (<Menu>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuGroup>
          <MenuGroupHeader>Section header</MenuGroupHeader>
          <MenuItem icon={<CutIcon />}>Cut</MenuItem>
          <MenuItem icon={<PasteIcon />}>Paste</MenuItem>
          <MenuItem icon={<EditIcon />}>Edit</MenuItem>
        </MenuGroup>
        <MenuDivider />
        <MenuGroup>
          <MenuGroupHeader>Section header</MenuGroupHeader>
          <MenuItem icon={<CutIcon />}>Cut</MenuItem>
          <MenuItem icon={<PasteIcon />}>Paste</MenuItem>
          <MenuItem icon={<EditIcon />}>Edit</MenuItem>
        </MenuGroup>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default GroupingItems;

Interaction

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { MenuProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { CopyFilled } from "@fluentui/react-icons";
import { CopyRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

const CopyIcon = bundleIcon(CopyFilled, CopyRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

export const Interaction = (props: Partial<MenuProps>): JSXElement => {
    return (<Menu {...props}>
      <MenuTrigger disableButtonEnhancement>
        <Button>Edit content</Button>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem icon={<CutIcon />} onClick={() => alert('Cut to clipboard')}>
            Cut
          </MenuItem>
          <MenuItem icon={<CopyIcon />} onClick={() => alert('Copied to clipboard')}>
            Copy
          </MenuItem>
          <MenuItem icon={<PasteIcon />} onClick={() => alert('Pasted from clipboard')}>
            Paste
          </MenuItem>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default Interaction;

Memoized Menu Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MenuItemCheckboxProps } from "@coreai-ds/react-components";
import { MenuItemCheckbox } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";

const EditIcon = bundleIcon(EditFilled, EditRegular);

const MemoCheckbox = React.memo((props: MenuItemCheckboxProps) => {
    // use icons in the memo because JSX will always create a new object
    // possible to memoize icons but it can be overkill
    return (<MenuItemCheckbox icon={<EditIcon />} name={props.name} value={props.value}>
      {props.children}
    </MenuItemCheckbox>);
});

export const MemoizedMenuItems = (): JSXElement => {
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <Button>Toggle menu</Button>
      </MenuTrigger>
      <MenuPopover>
        <MenuList>
          <MemoCheckbox name="font" value="segoe">
            Segoe
          </MemoCheckbox>
          <MemoCheckbox name="font" value="calibri">
            Calibri
          </MemoCheckbox>
          <MemoCheckbox name="font" value="arial">
            Arial
          </MemoCheckbox>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default MemoizedMenuItems;

Menu Items With Icons

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

export const MenuItemsWithIcons = (): JSXElement => (<Menu>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuItem icon={<CutIcon />}>Cut</MenuItem>
        <MenuItem icon={<PasteIcon />}>Paste</MenuItem>
        <MenuItem icon={<EditIcon />}>Edit</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default MenuItemsWithIcons;

Menu Trigger With Tooltip

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import * as React from 'react';

export const MenuTriggerWithTooltip = (): JSXElement => (<Menu>
    <Tooltip content="This is a tooltip" relationship="description">
      <MenuTrigger disableButtonEnhancement>
        <Button>Toggle menu</Button>
      </MenuTrigger>
    </Tooltip>

    <MenuPopover>
      <MenuList>
        <MenuItem>New </MenuItem>
        <MenuItem>New Window</MenuItem>
        <MenuItem disabled>Open File</MenuItem>
        <MenuItem>Open Folder</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default MenuTriggerWithTooltip;

Motion Custom

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { createPresenceComponent } from "@coreai-ds/react-components";
import { fadeAtom } from "@fluentui/react-motion-components-preview";
import { blurAtom } from "@fluentui/react-motion-components-preview";
import { motionTokens } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import * as React from 'react';

const FadeInBlurOut = createPresenceComponent({
    enter: fadeAtom({ direction: 'enter', duration: 500 }),
    exit: [
        fadeAtom({ direction: 'exit', duration: 500 }),
        blurAtom({ direction: 'exit', duration: 500, easing: motionTokens.curveEasyEase }),
    ],
});

export const MotionCustom = (): JSXElement => (<Menu surfaceMotion={{
        children: (_, motionProps) => <FadeInBlurOut {...motionProps}/>,
    }}>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuItem>New</MenuItem>
        <MenuItem>New Window</MenuItem>
        <MenuItem disabled>Open File</MenuItem>
        <MenuItem>Open Folder</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default MotionCustom;

Motion Disabled

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import * as React from 'react';

export const MotionDisabled = (): JSXElement => (<Menu surfaceMotion={null}>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuItem>New</MenuItem>
        <MenuItem>New Window</MenuItem>
        <MenuItem disabled>Open File</MenuItem>
        <MenuItem>Open Folder</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default MotionDisabled;

Multiline Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";
import { DeleteFilled } from "@fluentui/react-icons";
import { DeleteRegular } from "@fluentui/react-icons";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

const DeleteIcon = bundleIcon(DeleteFilled, DeleteRegular);

export const MultilineItems = (): JSXElement => {
    return (<Menu>
      <MenuTrigger>
        <Button>Multiline items</Button>
      </MenuTrigger>
      <MenuPopover>
        <MenuList>
          <MenuItem subText="Cut to clipboard" icon={<CutIcon />}>
            Cut
          </MenuItem>
          <MenuItem subText="Paste from clipboard" icon={<PasteIcon />}>
            Paste
          </MenuItem>
          <MenuItem subText="Edit file" icon={<EditIcon />} disabled>
            Edit
          </MenuItem>
          <MenuItem subText="Delete file" icon={<DeleteIcon />}>
            Delete
          </MenuItem>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default MultilineItems;

Nested Submenus

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import * as React from 'react';

const AppearanceSubMenu = () => {
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuItem>Appearance</MenuItem>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>Centered Layout</MenuItem>
          <MenuItem>Zen</MenuItem>
          <MenuItem disabled>Zoom In</MenuItem>
          <MenuItem>Zoom Out</MenuItem>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

const EditorLayoutSubMenu = () => {
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuItem>Editor Layout</MenuItem>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>Split Up</MenuItem>
          <MenuItem>Split Down</MenuItem>
          <MenuItem>Single</MenuItem>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

const PreferencesSubMenu = () => {
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <MenuItem>Preferences</MenuItem>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>Settings</MenuItem>
          <MenuItem>Online Services Settings</MenuItem>
          <MenuItem>Extensions</MenuItem>
          <AppearanceSubMenu />
          <EditorLayoutSubMenu />
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const NestedSubmenus = (): JSXElement => {
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <Button>Toggle menu</Button>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>New </MenuItem>
          <MenuItem>New Window</MenuItem>
          <MenuItem disabled>Open File</MenuItem>
          <MenuItem>Open Folder</MenuItem>
          <PreferencesSubMenu />
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default NestedSubmenus;

Nested Submenus Controlled

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MenuProps } from "@coreai-ds/react-components";

const AppearanceSubMenu = () => {
    const [open, setOpen] = React.useState(false);
    const onOpenChange: MenuProps['onOpenChange'] = (e, data) => {
        setOpen(data.open);
    };
    return (<Menu open={open} onOpenChange={onOpenChange}>
      <MenuTrigger disableButtonEnhancement>
        <MenuItem>Appearance</MenuItem>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>Centered Layout</MenuItem>
          <MenuItem>Zen</MenuItem>
          <MenuItem disabled>Zoom In</MenuItem>
          <MenuItem>Zoom Out</MenuItem>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

const EditorLayoutSubMenu = () => {
    const [open, setOpen] = React.useState(false);
    const onOpenChange: MenuProps['onOpenChange'] = (e, data) => {
        setOpen(data.open);
    };
    return (<Menu open={open} onOpenChange={onOpenChange}>
      <MenuTrigger disableButtonEnhancement>
        <MenuItem>Editor Layout</MenuItem>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>Split Up</MenuItem>
          <MenuItem>Split Down</MenuItem>
          <MenuItem>Single</MenuItem>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

const PreferencesSubMenu = () => {
    const [open, setOpen] = React.useState(false);
    const onOpenChange: MenuProps['onOpenChange'] = (e, data) => {
        setOpen(data.open);
    };
    return (<Menu open={open} onOpenChange={onOpenChange}>
      <MenuTrigger disableButtonEnhancement>
        <MenuItem>Preferences</MenuItem>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>Settings</MenuItem>
          <MenuItem>Online Services Settings</MenuItem>
          <MenuItem>Extensions</MenuItem>
          <AppearanceSubMenu />
          <EditorLayoutSubMenu />
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export const NestedSubmenusControlled = (): JSXElement => {
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <Button>Toggle menu</Button>
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>New </MenuItem>
          <MenuItem>New Window</MenuItem>
          <MenuItem disabled>Open File</MenuItem>
          <MenuItem>Open Folder</MenuItem>
          <PreferencesSubMenu />
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default NestedSubmenusControlled;

Nested Submenus Responsiveness

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import type { PositioningImperativeRef } from "@coreai-ds/react-components";
import type { MenuProps } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
const useStyles = makeStyles({
    container: {
        width: '500px',
        height: '400px',
    },
    resizableArea: {
        width: '500px',
        height: '400px',
        position: 'relative',
        border: `2px solid ${tokens.colorBrandBackground}`,
        padding: '20px 10px 10px 10px',
        resize: 'both',
        backgroundImage: `linear-gradient(-45deg, ${tokens.colorBrandBackground} 20px, transparent 20px)`,
        overflow: 'hidden',
        '::after': {
            content: `'Resizable Area'`,
            position: 'absolute',
            padding: '1px 4px 1px',
            top: '-2px',
            left: '-2px',
            fontFamily: 'monospace',
            fontSize: '15px',
            fontWeight: 900,
            lineHeight: 1,
            letterSpacing: '1px',
            color: tokens.colorNeutralForegroundOnBrand,
            backgroundColor: tokens.colorBrandBackground,
        },
    },
});
export const NestedSubmenusResponsiveness = (): JSXElement => {
    const styles = useStyles();
    const [open, setOpen] = React.useState(false);
    const [boundary, setBoundary] = React.useState<HTMLElement | null>(null);
    const positioningRefSubmenu = React.useRef<PositioningImperativeRef>(null);
    const positioningRefRoot = React.useRef<PositioningImperativeRef>(null);
    // Fluent UI handles window resizing by default.
    // Custom boundary resizing is not handled by default.
    React.useEffect(() => {
        if (boundary) {
            const resizeObserver = new ResizeObserver(() => {
                positioningRefSubmenu.current?.updatePosition();
                positioningRefRoot.current?.updatePosition();
            });
            resizeObserver.observe(boundary);
            return () => {
                resizeObserver.unobserve(boundary);
                resizeObserver.disconnect();
            };
        }
    }, [boundary]);
    React.useEffect(() => {
        if (open) {
            // defer position update of the nested menu the root menu hasn't been positioned yet
            const timeout = setTimeout(() => positioningRefSubmenu.current?.updatePosition());
            positioningRefRoot.current?.updatePosition();
            return () => clearTimeout(timeout);
        }
    }, [open]);
    const onOpenChange: MenuProps['onOpenChange'] = (e, data) => {
        if (boundary?.contains(e.target as HTMLElement)) {
            setOpen(true);
        }
        else {
            setOpen(data.open);
        }
    };
    return (<div className={styles.container}>
      <div id="components-menu-menu--nested-submenus-responsiveness-boundary" className={mergeClasses(styles.container, styles.resizableArea)} ref={setBoundary}>
        <Menu open={open} onOpenChange={onOpenChange} positioning={{ positioningRef: positioningRefRoot, overflowBoundary: boundary, flipBoundary: boundary }}>
          <MenuTrigger disableButtonEnhancement>
            <Button style={{ position: 'absolute', left: '40%' }}>Menu</Button>
          </MenuTrigger>

          <MenuPopover>
            <MenuList>
              <MenuItem>New </MenuItem>
              <MenuItem>New Window</MenuItem>
              <MenuItem disabled>Open File</MenuItem>
              <MenuItem>Open Folder</MenuItem>
              <Menu open positioning={{
            overflowBoundary: boundary,
            flipBoundary: boundary,
            positioningRef: positioningRefSubmenu,
        }}>
                <MenuTrigger disableButtonEnhancement>
                  <MenuItem>Toggle menu</MenuItem>
                </MenuTrigger>

                <MenuPopover>
                  <MenuList>
                    <MenuItem>New </MenuItem>
                    <MenuItem>New Window</MenuItem>
                    <MenuItem disabled>Open File</MenuItem>
                    <MenuItem>Open Folder</MenuItem>
                  </MenuList>
                </MenuPopover>
              </Menu>
            </MenuList>
          </MenuPopover>
        </Menu>
      </div>
    </div>);
};

export default NestedSubmenusResponsiveness;

Radio Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItemRadio } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

export const RadioItems = (): JSXElement => {
    return (<Menu>
      <MenuTrigger disableButtonEnhancement>
        <Button>Toggle menu</Button>
      </MenuTrigger>
      <MenuPopover>
        <MenuList>
          <MenuItemRadio icon={<CutIcon />} name="font" value="segoe">
            Segoe
          </MenuItemRadio>
          <MenuItemRadio icon={<PasteIcon />} name="font" value="calibri">
            Calibri
          </MenuItemRadio>
          <MenuItemRadio icon={<EditIcon />} name="font" value="arial">
            Arial
          </MenuItemRadio>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default RadioItems;

Render Function Trigger

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MenuProps } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import type { MenuTriggerChildProps } from "@coreai-ds/react-components";
import { ChevronDownRegular } from "@fluentui/react-icons";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";

const buttonStyle = { height: 22, verticalAlign: 'middle' };

export const RenderFunctionTrigger = (): JSXElement => {
    const [open, setOpen] = React.useState(false);
    const onOpenChange: MenuProps['onOpenChange'] = (e, data) => {
        setOpen(data.open);
    };
    return (<Menu open={open} onOpenChange={onOpenChange}>
      <MenuTrigger disableButtonEnhancement>
        {(props: MenuTriggerChildProps<'button'>) => (<div>
            <button style={buttonStyle}>Custom Trigger</button>
            <button {...props} style={buttonStyle}>
              <ChevronDownRegular fontSize={16}/>
            </button>
          </div>)}
      </MenuTrigger>

      <MenuPopover>
        <MenuList>
          <MenuItem>New </MenuItem>
          <MenuItem>New Window</MenuItem>
          <MenuItem disabled>Open File</MenuItem>
          <MenuItem>Open Folder</MenuItem>
        </MenuList>
      </MenuPopover>
    </Menu>);
};

export default RenderFunctionTrigger;

Secondary Content For Menu Items

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import * as React from 'react';

export const SecondaryContentForMenuItems = (): JSXElement => (<Menu>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuItem secondaryContent="Ctrl+N">New File</MenuItem>
        <MenuItem secondaryContent="Ctrl+Shift+N">New Window</MenuItem>
        <MenuItem secondaryContent="Ctrl+T" disabled>
          New Tab
        </MenuItem>
        <MenuItem secondaryContent="Ctrl+O">Open File</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default SecondaryContentForMenuItems;

Selection Group

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuGroup } from "@coreai-ds/react-components";
import { MenuGroupHeader } from "@coreai-ds/react-components";
import { MenuItemCheckbox } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";
import { MenuDivider } from "@coreai-ds/react-components";
import { MenuItemRadio } from "@coreai-ds/react-components";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

export const SelectionGroup = (): JSXElement => (<Menu>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuGroup>
          <MenuGroupHeader>Checkbox group</MenuGroupHeader>
          <MenuItemCheckbox secondaryContent="Ctrl+N" icon={<CutIcon />} name="edit" value="cut">
            Show Menu Bar
          </MenuItemCheckbox>
          <MenuItemCheckbox secondaryContent="Ctrl+Shift+N" icon={<PasteIcon />} name="edit" value="paste">
            Show Side Bar
          </MenuItemCheckbox>
          <MenuItemCheckbox secondaryContent="Ctrl+Shift+O" icon={<EditIcon />} name="edit" value="edit">
            Show Status Bar
          </MenuItemCheckbox>
          <MenuItemCheckbox disabled icon={<EditIcon />} name="disabled" value="disabled">
            Show Debug Panel
          </MenuItemCheckbox>
        </MenuGroup>
        <MenuDivider />
        <MenuGroup>
          <MenuGroupHeader>Radio group</MenuGroupHeader>
          <MenuItemRadio secondaryContent="Ctrl+N" icon={<CutIcon />} name="font" value="segoe">
            Segoe
          </MenuItemRadio>
          <MenuItemRadio secondaryContent="Ctrl+Shift+N" icon={<PasteIcon />} name="font" value="calibri">
            Caliri
          </MenuItemRadio>
          <MenuItemRadio secondaryContent="Ctrl+Shift+N" icon={<EditIcon />} name="font" value="arial">
            Arial
          </MenuItemRadio>
        </MenuGroup>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default SelectionGroup;

Split Menu Item

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { MenuSplitGroup } from "@coreai-ds/react-components";
import * as React from 'react';

export const SplitMenuItem = (): JSXElement => (<Menu>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>
    <MenuPopover>
      <MenuList>
        <MenuItem>New </MenuItem>
        <MenuItem>New Window</MenuItem>
        <Menu>
          <MenuSplitGroup>
            <MenuItem>Open</MenuItem>
            <MenuTrigger disableButtonEnhancement>
              <MenuItem aria-label="Open on platform"/>
            </MenuTrigger>
          </MenuSplitGroup>
          <MenuPopover>
            <MenuList>
              <MenuItem>In browser</MenuItem>
              <MenuItem>In desktop app</MenuItem>
              <MenuItem>In mobile</MenuItem>
            </MenuList>
          </MenuPopover>
        </Menu>
        <MenuItem>Preferences</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default SplitMenuItem;

Switch Item

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { MenuItemSwitch } from "@coreai-ds/react-components";
import * as React from 'react';

export const SwitchItem = (): JSXElement => (<Menu>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuItem>New</MenuItem>
        <MenuItem>New Window</MenuItem>
        <MenuItem disabled>Open File</MenuItem>
        <MenuItem>Open Folder</MenuItem>
        <MenuItemSwitch name="new-explorer" value="new-explorer">
          Try V2
        </MenuItemSwitch>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default SwitchItem;

Visual Divider Only

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CutFilled } from "@fluentui/react-icons";
import { CutRegular } from "@fluentui/react-icons";
import { ClipboardPasteFilled } from "@fluentui/react-icons";
import { ClipboardPasteRegular } from "@fluentui/react-icons";
import { EditFilled } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";
import { MenuDivider } from "@coreai-ds/react-components";
import * as React from 'react';

const CutIcon = bundleIcon(CutFilled, CutRegular);

const PasteIcon = bundleIcon(ClipboardPasteFilled, ClipboardPasteRegular);

const EditIcon = bundleIcon(EditFilled, EditRegular);

export const VisualDividerOnly = (): JSXElement => (<Menu>
    <MenuTrigger disableButtonEnhancement>
      <Button>Toggle menu</Button>
    </MenuTrigger>

    <MenuPopover>
      <MenuList>
        <MenuItem icon={<CutIcon />}>Cut</MenuItem>
        <MenuItem icon={<PasteIcon />}>Paste</MenuItem>
        <MenuItem icon={<EditIcon />}>Edit</MenuItem>
        <MenuDivider />
        <MenuItem icon={<CutIcon />}>Cut</MenuItem>
        <MenuItem icon={<PasteIcon />}>Paste</MenuItem>
        <MenuItem icon={<EditIcon />}>Edit</MenuItem>
      </MenuList>
    </MenuPopover>
  </Menu>);

export default VisualDividerOnly;