@activecollab/components
Version:
ActiveCollab Components
105 lines (103 loc) • 3.6 kB
JavaScript
import React, { useRef, useState, useCallback, useEffect } from "react";
import classnames from "classnames";
import { MenuContextProvider } from "./context";
import { StyledMenu } from "./Styles";
import useForkRef from "../../utils/useForkRef";
import { Overlay } from "../Overlay";
import { Popper } from "../Popper";
import { Window } from "../Window";
// source: https://twitter.com/mattpocockuk/status/1671908303918473217/photo/1
// eslint-disable-next-line @typescript-eslint/ban-types
export const Menu = _ref => {
let {
children,
disableFocusLock = false,
onMenuClick,
handleScroll = true,
mode = "normal",
open: defaultOpen = false,
onOpen,
onClose,
onBeforeClose,
position = "bottom-start",
target,
className,
menuClassName,
popperClassName,
backgroundElementClass,
windowAbsolutelyPositioned = false,
onPopperOpen
} = _ref;
const [open, setOpen] = useState(defaultOpen);
const [childNode, setChildNode] = useState();
const elementRef = useRef(null);
const isOpenAtLeastOnce = useRef(false);
useEffect(() => {
setOpen(defaultOpen);
}, [defaultOpen]);
const handleRefRef = useForkRef(target ? target.ref : undefined, setChildNode);
const handleRef = useForkRef(handleRefRef, elementRef);
const handleOpen = useCallback(event => {
var _target$props;
event == null || event.preventDefault();
event == null || event.stopPropagation();
setOpen(true);
typeof onOpen === "function" && onOpen();
typeof (target == null || (_target$props = target.props) == null ? void 0 : _target$props.onClick) === "function" && target.props.onClick(event);
}, [onOpen, target == null ? void 0 : target.props]);
const handleClose = useCallback(() => {
if (typeof onBeforeClose === "function" && !onBeforeClose()) {
return;
}
setOpen(false);
typeof onClose === "function" && onClose();
}, [onClose, onBeforeClose]);
const childProps = {
forceClose: handleClose
};
const targetProps = {
open,
ref: handleRef,
onClick: handleOpen
};
useEffect(() => {
if (open) {
isOpenAtLeastOnce.current = true;
} else if (!open && isOpenAtLeastOnce.current) {
var _elementRef$current;
(_elementRef$current = elementRef.current) == null || _elementRef$current.focus();
isOpenAtLeastOnce.current = false;
}
}, [open]);
return /*#__PURE__*/React.createElement(React.Fragment, null, target && /*#__PURE__*/React.cloneElement(target, targetProps), open ? /*#__PURE__*/React.createElement(Window, {
onClose: handleClose,
disableScrollLock: !handleScroll,
disableFocusLock: disableFocusLock,
style: {
position: windowAbsolutelyPositioned ? "absolute" : "fixed"
}
}, /*#__PURE__*/React.createElement(Overlay, {
className: backgroundElementClass,
onClick: handleClose,
tabIndex: -1,
disableBackgroundColor: true
}), /*#__PURE__*/React.createElement(Popper, {
anchorEl: childNode,
open: childNode ? open : false,
placement: position,
className: popperClassName,
tabIndex: -1,
afterWrite: onPopperOpen
}, /*#__PURE__*/React.createElement(StyledMenu, {
className: classnames("c-simple-menu__paper", "c-simple-menu__" + mode, menuClassName, className),
$mode: mode,
onMouseDown: onMenuClick
}, /*#__PURE__*/React.createElement(MenuContextProvider, {
value: {
open,
setOpen
}
}, typeof children === "function" ? children(childProps) : children)))) : null);
};
Menu.displayName = "Menu";
//# sourceMappingURL=Menu.js.map