@react-md/menu
Version:
Create menus that auto-position themselves within the viewport and adhere to the accessibility guidelines
185 lines • 10.8 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from "react";
import { useUserInteractionMode } from "@react-md/utils";
import { useMenuBarContext } from "./MenuBarProvider";
import { MenuButton } from "./MenuButton";
import { useMenuConfiguration } from "./MenuConfigurationProvider";
import { MenuItemButton } from "./MenuItemButton";
import { MenuRenderer } from "./MenuRenderer";
import { MenuVisibilityProvider } from "./MenuVisibilityProvider";
import { useMenu } from "./useMenu";
/**
* This component is a preset for creating dropdown menus using the
* {@link useMenu} hook which provides the visibility behavior and other
* functionality for menus. This will render as a `<Button>` by default but can
* be rendered as a `<MenuItem>` by existing as a child of another
* `DropdownMenu`.
*
* Most of the top-level props will be passed directly to the `Button` or
* `MenuItem` components with the exception for the `children`. The children for
* the `Button` or `MenuItem` can be set with the `buttonChildren` prop since
* the main `children` should be the `Menu`'s children.
*
* @example
* Simple Example
* ```tsx
* import type { ReactElement } from "react";
* import { DropdownMenu, MenuItem } from "@react-md/menu";
*
* function Example() {
* return (
* <DropdownMenu id="example-dropdown-menu" buttonChildren="Dropdown">
* <MenuItem onClick={() => console.log('Clicked Item 1')}>
* Item 1
* </MenuItem>
* <MenuItem onClick={() => console.log('Clicked Item 2')}>
* Item 2
* </MenuItem>
* </DropdownMenu>
* );
* }
* ```
*
* @example
* Nested Dropdown Menus
* ```tsx
* import type { ReactElement } from "react";
* import { DropdownMenu, MenuItem } from "@react-md/menu";
*
* function Example() {
* return (
* <DropdownMenu id="example-dropdown-menu" buttonChildren="Dropdown">
* <MenuItem onClick={() => console.log('Clicked Item 1')}>
* Item 1
* </MenuItem>
* <MenuItem onClick={() => console.log('Clicked Item 2')}>
* Item 2
* </MenuItem>
* <DropdownMenu
* id="nested-dropdown-menu"
* buttonChildren="Nested Dropdown"
* >
* <MenuItem onClick={() => console.log('Clicked Item 1')}>
* Nested Item 1
* </MenuItem>
* <MenuItem onClick={() => console.log('Clicked Item 2')}>
* Nested Item 2
* </MenuItem>
* </DropdownMenu>
* </DropdownMenu>
* );
* }
* ```
*
* @remarks \@since 5.0.0
*/
export function DropdownMenu(_a) {
var _b;
var id = _a.id, onClick = _a.onClick, onKeyDown = _a.onKeyDown, onMouseEnter = _a.onMouseEnter, onMouseLeave = _a.onMouseLeave, menuLabel = _a.menuLabel, propMenuProps = _a.menuProps, menuStyle = _a.menuStyle, menuClassName = _a.menuClassName, sheetProps = _a.sheetProps, sheetMenuProps = _a.sheetMenuProps, sheetStyle = _a.sheetStyle, sheetClassName = _a.sheetClassName, propSheetHeader = _a.sheetHeader, propSheetFooter = _a.sheetFooter, propRenderAsSheet = _a.renderAsSheet, propSheetPosition = _a.sheetPosition, propSheetVerticalSize = _a.sheetVerticalSize, listStyle = _a.listStyle, listClassName = _a.listClassName, listProps = _a.listProps, appear = _a.appear, enter = _a.enter, exit = _a.exit, propTimeout = _a.timeout, classNames = _a.classNames, anchor = _a.anchor, fixedPositionOptions = _a.fixedPositionOptions, getFixedPositionOptions = _a.getFixedPositionOptions, temporary = _a.temporary, portal = _a.portal, portalInto = _a.portalInto, portalIntoId = _a.portalIntoId, onEnter = _a.onEnter, onEntering = _a.onEntering, onEntered = _a.onEntered, onExit = _a.onExit, onExiting = _a.onExiting, onExited = _a.onExited, propHorizontal = _a.horizontal, children = _a.children, preventScroll = _a.preventScroll, closeOnResize = _a.closeOnResize, closeOnScroll = _a.closeOnScroll, propIconRotatorProps = _a.iconRotatorProps, propDisableFocusOnMount = _a.disableFocusOnMount, propDisableFocusOnUnmount = _a.disableFocusOnUnmount, props = __rest(_a, ["id", "onClick", "onKeyDown", "onMouseEnter", "onMouseLeave", "menuLabel", "menuProps", "menuStyle", "menuClassName", "sheetProps", "sheetMenuProps", "sheetStyle", "sheetClassName", "sheetHeader", "sheetFooter", "renderAsSheet", "sheetPosition", "sheetVerticalSize", "listStyle", "listClassName", "listProps", "appear", "enter", "exit", "timeout", "classNames", "anchor", "fixedPositionOptions", "getFixedPositionOptions", "temporary", "portal", "portalInto", "portalIntoId", "onEnter", "onEntering", "onEntered", "onExit", "onExiting", "onExited", "horizontal", "children", "preventScroll", "closeOnResize", "closeOnScroll", "iconRotatorProps", "disableFocusOnMount", "disableFocusOnUnmount"]);
var disabled = props.disabled;
var _c = useMenuConfiguration({
horizontal: propHorizontal,
sheetFooter: propSheetFooter,
sheetHeader: propSheetHeader,
renderAsSheet: propRenderAsSheet,
sheetPosition: propSheetPosition,
sheetVerticalSize: propSheetVerticalSize,
}), horizontal = _c.horizontal, sheetHeader = _c.sheetHeader, sheetFooter = _c.sheetFooter, renderAsSheet = _c.renderAsSheet, sheetPosition = _c.sheetPosition, sheetVerticalSize = _c.sheetVerticalSize;
var mode = useUserInteractionMode();
var mouse = mode === "mouse";
var keyboard = mode === "keyboard";
var _d = useMenuBarContext(), root = _d.root, menubar = _d.menubar, menuitem = _d.menuitem, activeId = _d.activeId, animatedOnce = _d.animatedOnce;
var disableTransition = animatedOnce && menubar && !!activeId && (mouse || keyboard);
var timeout = propTimeout !== null && propTimeout !== void 0 ? propTimeout : (disableTransition ? 0 : undefined);
var disableFocusOnMount = propDisableFocusOnMount !== null && propDisableFocusOnMount !== void 0 ? propDisableFocusOnMount : (mouse && timeout === 0);
var disableFocusOnUnmount = propDisableFocusOnUnmount !== null && propDisableFocusOnUnmount !== void 0 ? propDisableFocusOnUnmount : (mouse && timeout === 0);
var iconRotatorProps = propIconRotatorProps;
if (disableTransition) {
iconRotatorProps = __assign({ animate: false }, propIconRotatorProps);
}
var floating = null;
if (!menuitem) {
(_b = props.floating, floating = _b === void 0 ? null : _b);
}
var _e = __read(useState(false), 2), visible = _e[0], setVisible = _e[1];
var _f = useMenu({
baseId: id,
visible: visible,
setVisible: setVisible,
disabled: disabled,
menuLabel: menuLabel,
horizontal: horizontal,
onToggleClick: onClick,
onToggleKeyDown: onKeyDown,
onToggleMouseEnter: onMouseEnter,
onToggleMouseLeave: onMouseLeave,
onMenuClick: propMenuProps === null || propMenuProps === void 0 ? void 0 : propMenuProps.onClick,
onMenuKeyDown: propMenuProps === null || propMenuProps === void 0 ? void 0 : propMenuProps.onKeyDown,
floating: floating,
onEnter: onEnter,
onEntering: onEntering,
onEntered: onEntered,
onExited: onExited,
anchor: anchor,
style: menuStyle,
fixedPositionOptions: fixedPositionOptions,
getFixedPositionOptions: getFixedPositionOptions,
menuitem: !root && menuitem,
preventScroll: preventScroll,
closeOnResize: closeOnResize,
closeOnScroll: closeOnScroll,
disableFocusOnMount: disableFocusOnMount,
disableFocusOnUnmount: disableFocusOnUnmount,
}), menuRef = _f.menuRef, menuProps = _f.menuProps, toggleRef = _f.toggleRef, toggleProps = _f.toggleProps;
var toggle;
if (menuitem) {
// see `DropdownMenuProps` about this typecast
var _g = props, buttonChildren = _g.buttonChildren, itemProps = __rest(_g, ["buttonChildren"]);
toggle = (_jsx(MenuItemButton, __assign({}, itemProps, { iconRotatorProps: iconRotatorProps }, toggleProps, { ref: toggleRef, visible: visible }, { children: buttonChildren })));
}
else {
// see `DropdownMenuProps` about this typecast
var _h = props, buttonChildren = _h.buttonChildren, buttonProps = __rest(_h, ["buttonChildren"]);
toggle = (_jsx(MenuButton, __assign({}, buttonProps, { iconRotatorProps: iconRotatorProps }, toggleProps, { ref: toggleRef, visible: visible }, { children: buttonChildren })));
}
return (_jsxs(MenuVisibilityProvider, __assign({ visible: visible, setVisible: setVisible }, { children: [toggle, _jsx(MenuRenderer, __assign({}, menuProps, { menuRef: menuRef, menuProps: propMenuProps, menuStyle: menuProps.style, menuClassName: menuClassName, sheetProps: sheetProps, sheetStyle: sheetStyle, sheetClassName: sheetClassName, sheetMenuProps: sheetMenuProps, sheetHeader: sheetHeader, sheetFooter: sheetFooter, sheetPosition: sheetPosition, sheetVerticalSize: sheetVerticalSize, listStyle: listStyle, listClassName: listClassName, listProps: listProps, onRequestClose: function () { return setVisible(false); }, horizontal: horizontal, renderAsSheet: renderAsSheet, temporary: temporary, portal: portal, portalInto: portalInto, portalIntoId: portalIntoId, appear: appear, enter: enter, exit: exit, onExit: onExit, onExiting: onExiting, timeout: timeout, classNames: classNames }, { children: children }))] })));
}
//# sourceMappingURL=DropdownMenu.js.map