UNPKG

@atlaskit/dropdown-menu

Version:

A dropdown menu displays a list of actions or options to a user.

102 lines (100 loc) 4.12 kB
/* menu-wrapper.tsx generated by @compiled/babel-plugin v0.36.1 */ import "./menu-wrapper.compiled.css"; import * as React from 'react'; import { ax, ix } from "@compiled/react/runtime"; import { useContext, useEffect, useLayoutEffect } from 'react'; import MenuGroup from '@atlaskit/menu/menu-group'; import { Box } from '@atlaskit/primitives/compiled'; import Spinner from '@atlaskit/spinner'; import isCheckboxItem from '../utils/is-checkbox-item'; import isRadioItem from '../utils/is-radio-item'; import { FocusManagerContext } from './focus-manager'; var styles = { spinnerContainer: "_1e0c1txw _1ul91lit _1bah1h6o _ca0qv47k _u5f3v47k _n3tdv47k _19bvv47k" }; var LoadingIndicator = function LoadingIndicator(_ref) { var _ref$statusLabel = _ref.statusLabel, statusLabel = _ref$statusLabel === void 0 ? 'Loading' : _ref$statusLabel, testId = _ref.testId; return /*#__PURE__*/React.createElement(Box, { xcss: styles.spinnerContainer, role: "menuitem" }, /*#__PURE__*/React.createElement(Spinner, { size: "small", label: statusLabel, testId: testId })); }; /** * * MenuWrapper wraps all the menu items. * It handles the logic to close the menu when a MenuItem is clicked, but leaves it open * if a CheckboxItem or RadioItem is clicked. * It also sets focus to the first menu item when opened. */ var MenuWrapper = function MenuWrapper(_ref2) { var children = _ref2.children, isLoading = _ref2.isLoading, maxHeight = _ref2.maxHeight, maxWidth = _ref2.maxWidth, onClose = _ref2.onClose, onUpdate = _ref2.onUpdate, statusLabel = _ref2.statusLabel, setInitialFocusRef = _ref2.setInitialFocusRef, shouldRenderToParent = _ref2.shouldRenderToParent, spacing = _ref2.spacing, testId = _ref2.testId, isTriggeredUsingKeyboard = _ref2.isTriggeredUsingKeyboard, autoFocus = _ref2.autoFocus; var _useContext = useContext(FocusManagerContext), menuItemRefs = _useContext.menuItemRefs; var closeOnMenuItemClick = function closeOnMenuItemClick(e) { var isTargetMenuItemOrDescendant = menuItemRefs.some(function (menuItemRef) { var menuItem = menuItemRef.current; if (!menuItem) { return false; } var isCheckboxOrRadio = isCheckboxItem(menuItem) || isRadioItem(menuItem); return menuItem.contains(e.target) && !isCheckboxOrRadio; }); // Close menu if the click is triggered from a MenuItem or // its descendant. Don't close the menu if the click is triggered // from a MenuItemRadio or MenuItemCheckbox so that the user can // select multiple items. if (isTargetMenuItemOrDescendant && onClose) { onClose(e); } }; // Using useEffect here causes a flicker. // useLayoutEffect ensures that the update and render happen in the same // rAF tick. useLayoutEffect(function () { onUpdate(); }, [isLoading, onUpdate]); useEffect(function () { var _menuItemRefs$map$fin; var firstFocusableRef = (_menuItemRefs$map$fin = menuItemRefs.map(function (_ref3) { var current = _ref3.current; return current; }).find(function (el) { return !!el && !el.hasAttribute('disabled'); })) !== null && _menuItemRefs$map$fin !== void 0 ? _menuItemRefs$map$fin : null; if (shouldRenderToParent && (isTriggeredUsingKeyboard || autoFocus)) { firstFocusableRef === null || firstFocusableRef === void 0 || firstFocusableRef.focus(); } setInitialFocusRef === null || setInitialFocusRef === void 0 || setInitialFocusRef(firstFocusableRef); }, [menuItemRefs, setInitialFocusRef, autoFocus, shouldRenderToParent, isTriggeredUsingKeyboard]); return /*#__PURE__*/React.createElement(MenuGroup, { isLoading: isLoading, maxHeight: maxHeight, maxWidth: maxWidth, onClick: closeOnMenuItemClick, role: "menu", spacing: spacing, testId: testId && "".concat(testId, "--menu-group") }, isLoading ? /*#__PURE__*/React.createElement(LoadingIndicator, { statusLabel: statusLabel, testId: testId && "".concat(testId, "--loading-indicator") }) : children); }; export default MenuWrapper;