UNPKG

@primer/components

Version:
125 lines (100 loc) 3.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ActionMenu = exports.MenuContext = void 0; var _Button = _interopRequireDefault(require("./Button")); var _react = _interopRequireDefault(require("react")); var _AnchoredOverlay = require("./AnchoredOverlay"); var _hooks = require("./hooks"); var _Divider = require("./ActionList2/Divider"); var _ActionListContainerContext = require("./ActionList2/ActionListContainerContext"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const MenuContext = /*#__PURE__*/_react.default.createContext({ renderAnchor: null, open: false }); exports.MenuContext = MenuContext; const Menu = ({ anchorRef: externalAnchorRef, open, onOpenChange, children }) => { const [combinedOpenState, setCombinedOpenState] = (0, _hooks.useProvidedStateOrCreate)(open, onOpenChange, false); const onOpen = _react.default.useCallback(() => setCombinedOpenState(true), [setCombinedOpenState]); const onClose = _react.default.useCallback(() => setCombinedOpenState(false), [setCombinedOpenState]); const anchorRef = (0, _hooks.useProvidedRefOrCreate)(externalAnchorRef); let renderAnchor = null; // 🚨 Hack for good API! // we strip out Anchor from children and pass it to AnchoredOverlay to render // with additional props for accessibility const contents = _react.default.Children.map(children, child => { if (child.type === MenuButton || child.type === Anchor) { renderAnchor = anchorProps => /*#__PURE__*/_react.default.cloneElement(child, anchorProps); return null; } return child; }); return /*#__PURE__*/_react.default.createElement(MenuContext.Provider, { value: { anchorRef, renderAnchor, open: combinedOpenState, onOpen, onClose } }, contents); }; Menu.displayName = "Menu"; const Anchor = /*#__PURE__*/_react.default.forwardRef(({ children, ...anchorProps }, anchorRef) => { return /*#__PURE__*/_react.default.cloneElement(children, { ...anchorProps, ref: anchorRef }); }); /** this component is syntactical sugar 🍭 */ const MenuButton = /*#__PURE__*/_react.default.forwardRef((props, anchorRef) => { return /*#__PURE__*/_react.default.createElement(Anchor, { ref: anchorRef }, /*#__PURE__*/_react.default.createElement(_Button.default, props)); }); const Overlay = ({ children, ...overlayProps }) => { // we typecast anchorRef as required instead of optional // because we know that we're setting it in context in Menu const { anchorRef, renderAnchor, open, onOpen, onClose } = _react.default.useContext(MenuContext); return /*#__PURE__*/_react.default.createElement(_AnchoredOverlay.AnchoredOverlay, { anchorRef: anchorRef, renderAnchor: renderAnchor, open: open, onOpen: onOpen, onClose: onClose, overlayProps: overlayProps }, /*#__PURE__*/_react.default.createElement(_ActionListContainerContext.ActionListContainerContext.Provider, { value: { container: 'ActionMenu', listRole: 'menu', itemRole: 'menuitem', afterSelect: onClose } }, children)); }; Overlay.displayName = "Overlay"; Menu.displayName = 'ActionMenu'; const ActionMenu = Object.assign(Menu, { Button: MenuButton, Anchor, Overlay, Divider: _Divider.Divider }); exports.ActionMenu = ActionMenu;