UNPKG

@chayns-components/core

Version:

A set of beautiful React components for developing your own applications with chayns.

185 lines (183 loc) • 7.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _chaynsApi = require("chayns-api"); var _react = require("motion/react"); var _react2 = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _uuid = require("../../hooks/uuid"); var _contextMenu = require("../../types/contextMenu"); var _environment = require("../../utils/environment"); var _Icon = _interopRequireDefault(require("../icon/Icon")); var _ContextMenuContent = _interopRequireDefault(require("./context-menu-content/ContextMenuContent")); var _ContextMenu = require("./ContextMenu.styles"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const ContextMenu = /*#__PURE__*/(0, _react2.forwardRef)(({ alignment, children = /*#__PURE__*/_react2.default.createElement(_Icon.default, { icons: ['ts-ellipsis_v'], size: 18 }), container, coordinates, shouldHidePopupArrow = false, items, headline, onHide, onShow, shouldCloseOnPopupClick = true, shouldSeparateLastItem = false, shouldShowHoverEffect = false, zIndex = 20 }, ref) => { const [internalCoordinates, setInternalCoordinates] = (0, _react2.useState)({ x: 0, y: 0 }); const [newContainer, setNewContainer] = (0, _react2.useState)(container ?? null); const [internalAlignment, setInternalAlignment] = (0, _react2.useState)(_contextMenu.ContextMenuAlignment.TopLeft); const [isContentShown, setIsContentShown] = (0, _react2.useState)(false); const [portal, setPortal] = (0, _react2.useState)(); const uuid = (0, _uuid.useUuid)(); // ToDo: Replace with hook if new chayns api is ready const contextMenuContentRef = (0, _react2.useRef)(null); const contextMenuRef = (0, _react2.useRef)(null); const isTouch = (0, _environment.getIsTouch)(); (0, _react2.useEffect)(() => { if (contextMenuRef.current && !container) { const el = contextMenuRef.current; const element = el.closest('.dialog-inner, .page-provider, .tapp, body'); setNewContainer(element); } }, [container]); (0, _react2.useEffect)(() => { if (container instanceof Element) { setNewContainer(container); } }, [container]); const handleHide = (0, _react2.useCallback)(() => { setIsContentShown(false); }, []); const handleShow = (0, _react2.useCallback)(async () => { if (isTouch) { const { result } = await (0, _chaynsApi.createDialog)({ type: _chaynsApi.DialogType.SELECT, buttons: [], list: items.map(({ icons, text, isSelected }, index) => ({ name: text, id: index, isSelected, icon: icons[0] })) }).open(); if (result && typeof result[0] === 'number') { var _items$result$; void ((_items$result$ = items[result[0]]) === null || _items$result$ === void 0 ? void 0 : _items$result$.onClick()); } } else if (contextMenuRef.current) { if (!newContainer) { return; } const { height: childrenHeight, left: childrenLeft, top: childrenTop, width: childrenWidth } = contextMenuRef.current.getBoundingClientRect(); const { height, width, top, left } = newContainer.getBoundingClientRect(); const zoomX = width / newContainer.offsetWidth; const zoomY = height / newContainer.offsetHeight; const x = (childrenLeft + childrenWidth / 2 - left) / zoomX + newContainer.scrollLeft; const y = (childrenTop + childrenHeight / 2 - top) / zoomY + newContainer.scrollTop; setInternalCoordinates({ x, y }); if (x < width / 2) { if (y < height / 2) { setInternalAlignment(_contextMenu.ContextMenuAlignment.BottomRight); } else { setInternalAlignment(_contextMenu.ContextMenuAlignment.TopRight); } } else if (y < height / 2) { setInternalAlignment(_contextMenu.ContextMenuAlignment.BottomLeft); } else { setInternalAlignment(_contextMenu.ContextMenuAlignment.TopLeft); } setIsContentShown(true); } }, [isTouch, items, newContainer]); const handleClick = (0, _react2.useCallback)(event => { event.preventDefault(); event.stopPropagation(); void handleShow(); }, [handleShow]); const handleDocumentClick = (0, _react2.useCallback)(event => { var _contextMenuContentRe; if (!shouldCloseOnPopupClick && (_contextMenuContentRe = contextMenuContentRef.current) !== null && _contextMenuContentRe !== void 0 && _contextMenuContentRe.contains(event.target)) { return; } handleHide(); }, [handleHide, shouldCloseOnPopupClick]); (0, _react2.useImperativeHandle)(ref, () => ({ hide: handleHide, show: handleShow }), [handleHide, handleShow]); (0, _react2.useEffect)(() => { if (isContentShown) { document.addEventListener('click', handleDocumentClick, true); window.addEventListener('blur', handleHide); if (typeof onShow === 'function') { onShow(); } } else if (typeof onHide === 'function') { onHide(); } return () => { document.removeEventListener('click', handleDocumentClick, true); window.removeEventListener('blur', handleHide); }; }, [handleDocumentClick, handleHide, isContentShown, onHide, onShow]); (0, _react2.useEffect)(() => { if (!newContainer) { return; } setPortal(() => /*#__PURE__*/(0, _reactDom.createPortal)(/*#__PURE__*/_react2.default.createElement(_react.AnimatePresence, { initial: false }, isContentShown && /*#__PURE__*/_react2.default.createElement(_ContextMenuContent.default, { coordinates: coordinates ?? internalCoordinates, items: items, shouldSeparateLastItem: shouldSeparateLastItem, zIndex: zIndex, headline: headline, shouldHidePopupArrow: shouldHidePopupArrow, key: `contextMenu_${uuid}`, alignment: alignment ?? internalAlignment, ref: contextMenuContentRef })), newContainer)); }, [alignment, newContainer, coordinates, internalAlignment, internalCoordinates, isContentShown, items, uuid, zIndex, shouldHidePopupArrow, headline, shouldSeparateLastItem]); return /*#__PURE__*/_react2.default.createElement(_react2.default.Fragment, null, /*#__PURE__*/_react2.default.createElement(_ContextMenu.StyledContextMenu, { className: "beta-chayns-context-menu", $isActive: isContentShown && shouldShowHoverEffect, $shouldAddHoverEffect: !isTouch && shouldShowHoverEffect, onClick: handleClick, ref: contextMenuRef }, children), portal); }); ContextMenu.displayName = 'ContextMenu'; var _default = exports.default = ContextMenu; //# sourceMappingURL=ContextMenu.js.map