UNPKG

@orca-fe/pocket

Version:

UI components by orca-team

337 lines (335 loc) 17.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.MenuItem = exports.MenuContainer = void 0; var _react = _interopRequireWildcard(require("react")); var _reactTransitionGroup = require("react-transition-group"); var _ahooks = require("ahooks"); var _reactDom = _interopRequireDefault(require("react-dom")); var _classnames = _interopRequireDefault(require("classnames")); var _hooks = require("@orca-fe/hooks"); var _ContextMenu = _interopRequireDefault(require("./ContextMenu.style")); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["className", "text", "menuKey", "children", "disabled", "icon", "extra", "hasIcon", "onMenuClick"], _excluded2 = ["className", "data", "bounds", "onMenuClick", "style"], _excluded3 = ["className", "data", "children", "onMenuClick", "getContainer", "menuContainerClassName", "mainMenuMinWidth", "wrapperStyle", "disabled"]; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var arrowPath = // eslint-disable-next-line max-len 'M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z'; var ef = function ef() {}; var emptyBounds = { top: 0, left: 0, width: 1, height: 1 }; var eArr = []; var transitionStyles = { entering: { opacity: 1 }, entered: { opacity: 1 }, exiting: { opacity: 0 }, exited: { opacity: 0, pointerEvents: 'none' } }; var MenuItem = exports.MenuItem = function MenuItem(props) { var _props$className = props.className, className = _props$className === void 0 ? '' : _props$className, text = props.text, menuKey = props.menuKey, _props$children = props.children, children = _props$children === void 0 ? eArr : _props$children, disabled = props.disabled, icon = props.icon, extra = props.extra, hasIcon = props.hasIcon, _props$onMenuClick = props.onMenuClick, onMenuClick = _props$onMenuClick === void 0 ? ef : _props$onMenuClick, otherProps = _objectWithoutProperties(props, _excluded); var styles = (0, _ContextMenu.default)(); var rootRef = (0, _react.useRef)(null); var hasChildren = Array.isArray(children) && children.length > 0; var _useBoolean = (0, _ahooks.useBoolean)(false), _useBoolean2 = _slicedToArray(_useBoolean, 2), showSubMenu = _useBoolean2[0], _useBoolean2$ = _useBoolean2[1], setFalse = _useBoolean2$.setFalse, setTrue = _useBoolean2$.setTrue; var bounds = (0, _react.useMemo)(function () { var dom = rootRef.current; if (hasChildren && dom) { var _bounds = dom.getBoundingClientRect(); return { top: _bounds.top, height: _bounds.height, width: _bounds.width - 20, left: _bounds.left + 20 }; } return undefined; }, [showSubMenu]); return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", _objectSpread(_objectSpread({ ref: rootRef, className: "".concat((0, _classnames.default)(styles.item, _defineProperty({}, styles.disabled, disabled)), " ").concat(className) }, otherProps), {}, { onMouseEnter: setTrue, onMouseLeave: setFalse, children: [hasIcon && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { className: styles.icon, children: icon }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { className: styles.text, children: text }), extra && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { className: styles.extra, children: extra }), hasChildren && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { className: styles.arrow, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", { viewBox: "64 64 896 896", version: "1.1", focusable: false, xmlns: "http://www.w3.org/2000/svg", style: { width: '1em', height: '1em' }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", { d: arrowPath }) }) }), hasChildren && bounds && showSubMenu && /*#__PURE__*/ // eslint-disable-next-line @typescript-eslint/no-use-before-define (0, _jsxRuntime.jsx)(MenuContainer, { data: children, bounds: bounds, onMenuClick: onMenuClick })] })); }; var MenuContainer = exports.MenuContainer = function MenuContainer(props) { var _props$className2 = props.className, className = _props$className2 === void 0 ? '' : _props$className2, _props$data = props.data, data = _props$data === void 0 ? eArr : _props$data, _props$bounds = props.bounds, bounds = _props$bounds === void 0 ? emptyBounds : _props$bounds, _props$onMenuClick2 = props.onMenuClick, onMenuClick = _props$onMenuClick2 === void 0 ? ef : _props$onMenuClick2, style = props.style, otherProps = _objectWithoutProperties(props, _excluded2); var styles = (0, _ContextMenu.default)(); var hasIcon = data.some(function (item) { return _typeof(item) === 'object' && item.icon != null; }); var rootRef = (0, _react.useRef)(null); var _useState = (0, _react.useState)('right'), _useState2 = _slicedToArray(_useState, 2), h = _useState2[0], setH = _useState2[1]; var _useState3 = (0, _react.useState)('bottom'), _useState4 = _slicedToArray(_useState3, 2), v = _useState4[0], setV = _useState4[1]; (0, _react.useEffect)(function () { var dom = rootRef.current; if (dom) { var _dom$getBoundingClien = dom.getBoundingClientRect(), width = _dom$getBoundingClien.width, height = _dom$getBoundingClien.height; var _h = bounds.left + bounds.width + width > window.innerWidth ? 'left' : 'right'; var _v = bounds.top + height > window.innerHeight ? 'top' : 'bottom'; if (_h !== h) { setH(_h); } if (_v !== v) { setV(_v); } } }, [bounds]); var fixedStyle = (0, _react.useMemo)(function () { var style = {}; if (h === 'left') { style.right = Math.min(window.innerWidth - bounds.left, window.innerWidth - bounds.width); } else { style.left = bounds.left + bounds.width; } if (v === 'top') { style.bottom = Math.min(window.innerHeight - bounds.top - bounds.height, window.innerHeight - bounds.height); } else { style.top = bounds.top; } return style; }, [h, v, bounds]); return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", _objectSpread(_objectSpread({ ref: rootRef, className: "".concat(styles.container, " ").concat(className) }, otherProps), {}, { style: _objectSpread(_objectSpread({}, style), fixedStyle), children: data.map(function (item, index) { return item === 'split-line' ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { className: styles.splitLine }, index) : /*#__PURE__*/(0, _react.createElement)(MenuItem, _objectSpread(_objectSpread({ menuKey: item.key, hasIcon: hasIcon }, item), {}, { onMenuClick: onMenuClick, onClick: function onClick(event) { event.stopPropagation(); if (Array.isArray(item.children)) return; if (!item.disabled) { var _item$onClick; onMenuClick(item, event); (_item$onClick = item.onClick) === null || _item$onClick === void 0 || _item$onClick.call(item, event); } }, key: index })); }) })); }; var ContextMenu = function ContextMenu(props, pRef) { var _props$className3 = props.className, className = _props$className3 === void 0 ? '' : _props$className3, _props$data2 = props.data, data = _props$data2 === void 0 ? eArr : _props$data2, children = props.children, _props$onMenuClick3 = props.onMenuClick, _onMenuClick = _props$onMenuClick3 === void 0 ? ef : _props$onMenuClick3, _props$getContainer = props.getContainer, getContainer = _props$getContainer === void 0 ? ef : _props$getContainer, _props$menuContainerC = props.menuContainerClassName, menuContainerClassName = _props$menuContainerC === void 0 ? '' : _props$menuContainerC, _props$mainMenuMinWid = props.mainMenuMinWidth, mainMenuMinWidth = _props$mainMenuMinWid === void 0 ? 300 : _props$mainMenuMinWid, wrapperStyle = props.wrapperStyle, disabled = props.disabled, otherProps = _objectWithoutProperties(props, _excluded3); var styles = (0, _ContextMenu.default)(); var triggerTarget = (0, _react.useRef)(document.body); var _useState5 = (0, _react.useState)(), _useState6 = _slicedToArray(_useState5, 2), position = _useState6[0], setPosition = _useState6[1]; var _useState7 = (0, _react.useState)({ lastTriggerElement: null }), _useState8 = _slicedToArray(_useState7, 1), _this = _useState8[0]; var _useState9 = (0, _react.useState)(false), _useState10 = _slicedToArray(_useState9, 2), visible = _useState10[0], setVisible = _useState10[1]; var bounds = (0, _react.useMemo)(function () { return position ? _objectSpread(_objectSpread({}, position), {}, { width: 1, height: 1 }) : undefined; }, [position]); var rootRef = (0, _react.useRef)(null); var menuRef = (0, _react.useRef)(null); var mergedRef = (0, _hooks.useMergedRefs)(rootRef, pRef); // hide menu (0, _ahooks.useClickAway)(function () { if (visible) { setVisible(false); _this.lastTriggerElement = null; } }, menuRef); (0, _ahooks.useEventListener)('contextmenu', function (event) { // check is prevented if (event.defaultPrevented) { if (visible) { setVisible(false); _this.lastTriggerElement = null; } return; } if (disabled) return; if (event.shiftKey) return; event.preventDefault(); if (event.target instanceof HTMLElement) { triggerTarget.current = event.target; } var clientX = event.clientX, clientY = event.clientY; setPosition({ left: clientX, top: clientY }); setVisible(true); _this.lastTriggerElement = event.target; }, { target: rootRef }); (0, _ahooks.useEventListener)('contextmenu', function (event) { var _menuRef$current, _rootRef$current; if ((_menuRef$current = menuRef.current) !== null && _menuRef$current !== void 0 && _menuRef$current.contains(event.target)) { return; } // check is container if (!((_rootRef$current = rootRef.current) !== null && _rootRef$current !== void 0 && _rootRef$current.contains(event.target))) { setVisible(false); _this.lastTriggerElement = null; } }); return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", _objectSpread(_objectSpread({ ref: mergedRef, className: "".concat(styles.root, " ").concat(className) }, otherProps), {}, { children: [children, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactTransitionGroup.Transition, { appear: true, unmountOnExit: true, in: visible && bounds != null, timeout: 300, children: function children(state) { var _getContainer; return /*#__PURE__*/_reactDom.default.createPortal( /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { ref: menuRef, className: styles.wrapper, style: _objectSpread(_objectSpread({}, transitionStyles[state]), wrapperStyle), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(MenuContainer, { className: menuContainerClassName, bounds: bounds, data: typeof data === 'function' ? data(_this.lastTriggerElement) : data, style: { minWidth: mainMenuMinWidth }, onMenuClick: function onMenuClick(item, e) { _onMenuClick(item, e); setVisible(false); _this.lastTriggerElement = null; } }) }), (_getContainer = getContainer(triggerTarget.current)) !== null && _getContainer !== void 0 ? _getContainer : document.body); } }, "".concat(position === null || position === void 0 ? void 0 : position.left, ",").concat(position === null || position === void 0 ? void 0 : position.top))] })); }; var _default = exports.default = /*#__PURE__*/(0, _react.forwardRef)(ContextMenu);