import React from 'react';
import {createContainer} from '@workday/canvas-kit-react/common';
import {MenuCard} from './MenuCard';
import {MenuDivider} from './MenuDivider';
import {MenuGroup} from './MenuGroup';
import {MenuItem} from './MenuItem';
import {MenuList} from './MenuList';
import {MenuOption} from './MenuOption';
import {MenuPopper} from './MenuPopper';
import {MenuTarget, MenuTargetContext} from './MenuTarget';
import {Submenu} from './Submenu';
import {useMenuModel} from './useMenuModel';
export interface MenuProps {
/**
* The contents of the Menu. Can be `Menu` children or any valid elements.
*/
children: React.ReactNode;
}
/**
* `Menu` is a combination of a popup and a list. It usually has some type of target element that
* expands/collapses the menu and a `menu` role and and several `menuitem` roles. Focus is managed
* using [roving tabindex](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex) for maximum
* compatibility. A `Menu` can have two modes: `single` and `multiple`. This mode determines both
* how many items can be selected as well as the default behavior when a `menuitem` is clicked. For
* the `single` mode, selecting a `menuitem` will select and close the menu. For the `multiple`
* mode, clicking a `menuitem` will toggle selection and will not close the menu.
*
* ```tsx
*
* ```
*/
export const Menu = createContainer()({
displayName: 'Menu',
modelHook: useMenuModel,
subComponents: {
/**
* `Menu.Target` is similar to all {@link PopupTarget Popup.Target} types. The component only
* provides behavior and no styling. The `as` prop is used to determine which component is
* rendered. This component should forward the `ref` and apply any additional props directly to
* an element. The default `as` is a {@link SecondaryButton}. Any Canvas Kit component should
* work with an `as`.
*
* An example changing to a {@link PrimaryButton}
*
* ```tsx
* Primary Button Text
* ```
*
* This element will apply `aria-haspopup` and `aria-expanded` to inform screen readers there's
* a popup associated with the element.
*/
Target: MenuTarget,
/**
* The menu card is a non-semantic element used to give the dropdown menu its distinct visual
* cue that the dropdown menu is floating above other content. A menu card usually contains a
* menu list, but can also contain other elements like a header or footer.
*/
Card: MenuCard,
/**
* The menu list follows the Collections API. A list can either contain static items
* or a render prop and `items` to the model.
*
* ```tsx
* const MyComponent = () => {
* const model = useMenuModel({
* items: [
* { id: 'first', text: 'First Item' },
* { id: 'second', text: 'Second Item' },
* ]
* })
*
* return (
*
* )
* }
* ```
*/
List: MenuList,
/**
* A `Menu.Item` has an optional `data-id` prop that identifies the item in the `Menu.List` and
* will be passed to the optional `onSelect` callback of the `Menu` model. A `Menu.Item` can
* contain any HTML. If more complex HTML is provided, add `data-text` to the `Menu.Item`
* component if using the static API. If you're using the dynamic API, pass `getTextValue` to
* the model.
*/
Item: MenuItem,
Group: MenuGroup,
/**
* A `Menu.Option` is similar to the `Menu.Item`, but has a `role=option` and works with
* `aria-activedescendant` and is selectable with a selected checkmark. It adds the
* `aria-selected="true/false"` attribute. `Menu.Option` requires much more accessibility
* behavior composed into the `Menu.Target` and `Menu.List` component. The `Combobox` and
* `Select` components make use of the `Menu.Option`. See those components for a better idea of
* how behavior is composed.
*/
Option: MenuOption,
Divider: MenuDivider,
/**
* A `Menu.TargetContext` is the same as a {@link MenuTarget Menu.Target}, except it adds a
* `context` event handler instead of a `click` handler to trigger context menus.
*/
TargetContext: MenuTargetContext,
/**
* The "Popper" of a menu. The popper will appear around the {@link MenuTarget Menu.Target}. It
* renders a `div` element that is portalled to the `document.body` which is controlled by the
* {@link PopupStack}. The `PopupStack` is not part of React. This means no extra props given to
* this component will be forwarded to the `div` element, but the `ref` will be forwarded.
*/
Popper: MenuPopper,
Submenu: Submenu,
},
})(({children}) => {
return <>{children}>;
});