UNPKG

@momentum-ui/react-collaboration

Version:

Cisco Momentum UI Framework for React Collaboration Applications

111 lines 5.66 kB
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); }; import React, { forwardRef, useContext, useRef, useCallback } from 'react'; import classnames from 'classnames'; import { STYLE, DEFAULTS } from './Menu.constants'; import './Menu.style.scss'; import { useMenu } from '@react-aria/menu'; import { useTreeState } from '@react-stately/tree'; import MenuItem from '../MenuItem'; import { mergeProps } from '@react-aria/utils'; import MenuSection from '../MenuSection'; import MenuSelectionGroup from '../MenuSelectionGroup'; import ContentSeparator from '../ContentSeparator'; import { defaults } from 'lodash'; import { ListContext } from '../List/List.utils'; import { useCheckAriaLabel } from '../../utils/a11y'; /** * @deprecated Use the equivalent from momentum.design (NPM: `@momentum-design/components/dist/react`) */ export var MenuContext = React.createContext({}); export function useMenuContext(props) { if (props === void 0) { props = {}; } var context = useContext(MenuContext); return defaults({}, props, context); } export var MenuAppearanceContext = React.createContext({}); export function useMenuAppearanceContext(props) { if (props === void 0) { props = {}; } var menuAppearance = useContext(MenuAppearanceContext); return defaults({}, props, menuAppearance); } var Menu = function (props, providedRef) { var className = props.className, classNameSelectedItem = props.classNameSelectedItem, id = props.id, style = props.style, _a = props.tickPosition, tickPosition = _a === void 0 ? DEFAULTS.TICK_POSITION : _a, _b = props.itemShape, itemShape = _b === void 0 ? DEFAULTS.ITEM_SHAPE : _b, _c = props.itemSize, itemSize = _c === void 0 ? DEFAULTS.ITEM_SIZE : _c, shouldItemFocusBeInset = props.shouldItemFocusBeInset; var contextProps = useMenuContext(); // if an explicit aria-label is provided, discard the auto aria-labelledby provided by MenuTrigger if (contextProps['aria-labelledby'] && props['aria-label']) { delete contextProps['aria-labelledby']; } var _props = __assign({}, mergeProps(contextProps, props)); var state = useTreeState(__assign({}, _props)); var internalRef = useRef(); var ref = providedRef || internalRef; var itemArray = Array.from(state.collection.getKeys()); // Ensure all separators are in the disabledKeys set so they are not interactable // This may need copying instead of modifying due to how React works itemArray.forEach(function (key) { var _a; var item = state.collection.getItem(key); if ((_a = item.props) === null || _a === void 0 ? void 0 : _a._isSeparator) { state.disabledKeys.add(key); } }); var menuProps = useMenu(_props, state, ref).menuProps; var renderItem = useCallback(function (item, state) { var _a, _b; if (item.type === 'section') { if ((_a = item.props) === null || _a === void 0 ? void 0 : _a.selectionGroup) { return (React.createElement(MenuSelectionGroup, __assign({ item: item, state: state, onAction: _props.onAction, key: item.key }, item.props))); } return React.createElement(MenuSection, { key: item.key, item: item, state: state, onAction: _props.onAction }); } else { // collection.getKeys() return all keys (including sub-keys of child elements) // and we don't want to render items twice if (item.parentKey !== null) { return; } if ((_b = item.props) === null || _b === void 0 ? void 0 : _b._isSeparator) { var props_1 = __assign({}, item.props); delete props_1._isSeparator; return React.createElement(ContentSeparator, __assign({}, props_1)); } var menuItem = (React.createElement(MenuItem, { key: item.key, item: item, state: state, onAction: _props.onAction })); if (item.wrapper) { menuItem = item.wrapper(menuItem); } return menuItem; } }, // eslint-disable-next-line react-hooks/exhaustive-deps [state]); // the label can be specified as part of the props, or part of the menu context (e.g. provided by MenuTrigger) useCheckAriaLabel('Menu', menuProps); // ListContext is necessary to prevent changes in parent ListContext // for example when Menu is inside a list row return (React.createElement(MenuAppearanceContext.Provider, { value: { itemShape: itemShape, itemSize: itemSize, tickPosition: tickPosition, classNameSelectedItem: classNameSelectedItem } }, React.createElement(ListContext.Provider, { value: { shouldItemFocusBeInset: shouldItemFocusBeInset } }, React.createElement("div", __assign({ className: classnames(className, STYLE.wrapper), id: id, style: style, ref: ref }, menuProps), itemArray.map(function (key) { var item = state.collection.getItem(key); return renderItem(item, state); }))))); }; /** * Menu Element which displays a list of options/actions. */ /** * @deprecated Use the equivalent from momentum.design (NPM: `@momentum-design/components/dist/react`) */ var _Menu = forwardRef(Menu); _Menu.displayName = '_Menu'; export default _Menu; //# sourceMappingURL=Menu.js.map