UNPKG

@chayns-components/core

Version:

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

239 lines (234 loc) • 9.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = require("motion/react"); var _react2 = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _uuid = require("../../hooks/uuid"); var _popup = require("../../types/popup"); var _AreaContextProvider = _interopRequireDefault(require("../area-provider/AreaContextProvider")); var _PopupContentWrapper = _interopRequireDefault(require("./popup-content-wrapper/PopupContentWrapper")); var _Popup = require("./Popup.styles"); var _element = require("../../hooks/element"); 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 Popup = /*#__PURE__*/(0, _react2.forwardRef)(({ alignment, content, onShow, container, onHide, children, shouldHideOnChildrenLeave, shouldShowOnHover = false, shouldUseChildrenWidth = true, shouldScrollWithContent = false, shouldUseFullWidth = false, yOffset = 0 }, ref) => { const [coordinates, setCoordinates] = (0, _react2.useState)({ x: 0, y: 0 }); const [internalAlignment, setInternalAlignment] = (0, _react2.useState)(_popup.PopupAlignment.TopLeft); const [offset, setOffset] = (0, _react2.useState)(0); const [isOpen, setIsOpen] = (0, _react2.useState)(false); const [portal, setPortal] = (0, _react2.useState)(); const [pseudoSize, setPseudoSize] = (0, _react2.useState)(); const [newContainer, setNewContainer] = (0, _react2.useState)(container ?? null); const timeout = (0, _react2.useRef)(); const uuid = (0, _uuid.useUuid)(); const { height, width, measuredElement } = (0, _element.useMeasuredClone)({ content }); // ToDo: Replace with hook if new chayns api is ready const popupContentRef = (0, _react2.useRef)(null); const popupRef = (0, _react2.useRef)(null); (0, _react2.useEffect)(() => { if (popupRef.current && !container) { const el = popupRef.current; const element = el.closest('.dialog-inner, .page-provider, .tapp, body'); setNewContainer(element); } }, [container]); (0, _react2.useEffect)(() => { if (container instanceof Element) { setNewContainer(container); } }, [container]); (0, _react2.useEffect)(() => { setPseudoSize({ height, width }); }, [height, width]); const handleShow = (0, _react2.useCallback)(() => { if (popupRef.current && pseudoSize) { if (!newContainer) { return; } const { height: pseudoHeight, width: pseudoWidth } = pseudoSize; const { height: childrenHeight, left: childrenLeft, top: childrenTop, width: childrenWidth } = popupRef.current.getBoundingClientRect(); const { height: containerHeight, width: containerWidth, top, left } = newContainer.getBoundingClientRect(); const zoomX = containerWidth / newContainer.offsetWidth; const zoomY = containerHeight / newContainer.offsetHeight; if (pseudoHeight > childrenTop - 25 || alignment === _popup.PopupAlignment.BottomLeft || alignment === _popup.PopupAlignment.BottomRight) { let isRight = false; if (pseudoWidth > childrenLeft + childrenWidth / 2 - 25 || alignment === _popup.PopupAlignment.BottomRight) { setInternalAlignment(_popup.PopupAlignment.BottomRight); isRight = true; } else { setInternalAlignment(_popup.PopupAlignment.BottomLeft); } const x = (childrenLeft + childrenWidth / 2 - left) / zoomX + newContainer.scrollLeft; const y = (childrenTop + childrenHeight / 2 - top) / zoomY + newContainer.scrollTop - yOffset; let newOffset; if (isRight) { newOffset = x + pseudoWidth >= window.innerWidth ? x + pseudoWidth - window.innerWidth : 0; } else { newOffset = 0; const right = window.innerWidth - (childrenLeft + childrenWidth / 2); newOffset = right + pseudoWidth >= window.innerWidth ? right + pseudoWidth - window.innerWidth : 0; } setOffset(newOffset); const newX = x - newOffset; setCoordinates({ x: newX < 23 ? 23 : newX, y }); } else { let isRight = false; if (pseudoWidth > childrenLeft + childrenWidth / 2 - 25 || alignment === _popup.PopupAlignment.TopRight) { setInternalAlignment(_popup.PopupAlignment.TopRight); isRight = true; } else { setInternalAlignment(_popup.PopupAlignment.TopLeft); } const x = (childrenLeft + childrenWidth / 2 - left) / zoomX + newContainer.scrollLeft; const y = (childrenTop + childrenHeight / 2 - top) / zoomY + newContainer.scrollTop - yOffset; let newOffset; if (isRight) { newOffset = x + pseudoWidth >= window.innerWidth ? x + pseudoWidth - window.innerWidth : 0; } else { newOffset = 0; const right = window.innerWidth - (childrenLeft + childrenWidth / 2); newOffset = right + pseudoWidth >= window.innerWidth ? right + pseudoWidth - window.innerWidth : 0; } setOffset(newOffset); const newX = x - newOffset; setCoordinates({ x: newX < 23 ? 23 : newX, y }); } setIsOpen(true); } }, [alignment, newContainer, pseudoSize, yOffset]); const handleChildrenClick = () => { handleShow(); }; const handleHide = (0, _react2.useCallback)(() => { setIsOpen(false); }, []); const handleMouseEnter = (0, _react2.useCallback)(() => { if (shouldShowOnHover) { window.clearTimeout(timeout.current); handleShow(); } }, [handleShow, shouldShowOnHover]); const handleMouseLeave = (0, _react2.useCallback)(() => { if (!shouldShowOnHover) { return; } if (shouldHideOnChildrenLeave) { handleHide(); return; } timeout.current = window.setTimeout(() => { handleHide(); }, 500); }, [handleHide, shouldHideOnChildrenLeave, shouldShowOnHover]); const handleDocumentClick = (0, _react2.useCallback)(event => { var _popupContentRef$curr; if (!((_popupContentRef$curr = popupContentRef.current) !== null && _popupContentRef$curr !== void 0 && _popupContentRef$curr.contains(event.target))) { handleHide(); } }, [handleHide]); (0, _react2.useImperativeHandle)(ref, () => ({ hide: handleHide, show: handleShow }), [handleHide, handleShow]); // useEffect(() => { // void getWindowMetrics().then((result) => { // if (result.topBarHeight) { // setMenuHeight(result.topBarHeight); // } // }); // }, []); (0, _react2.useEffect)(() => { if (isOpen) { 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, isOpen, onHide, onShow]); (0, _react2.useEffect)(() => { if (!newContainer) { return; } setPortal(() => /*#__PURE__*/(0, _reactDom.createPortal)(/*#__PURE__*/_react2.default.createElement(_react.AnimatePresence, { initial: false }, isOpen && /*#__PURE__*/_react2.default.createElement(_PopupContentWrapper.default, { width: (pseudoSize === null || pseudoSize === void 0 ? void 0 : pseudoSize.width) ?? 0, offset: offset, shouldScrollWithContent: shouldScrollWithContent, coordinates: coordinates, key: `tooltip_${uuid}`, alignment: internalAlignment, ref: popupContentRef, onMouseLeave: handleMouseLeave, onMouseEnter: handleMouseEnter }, /*#__PURE__*/_react2.default.createElement(_AreaContextProvider.default, { shouldChangeColor: false }, content))), newContainer)); }, [internalAlignment, newContainer, content, coordinates, handleMouseEnter, handleMouseLeave, isOpen, offset, pseudoSize === null || pseudoSize === void 0 ? void 0 : pseudoSize.width, uuid, shouldScrollWithContent]); return /*#__PURE__*/_react2.default.createElement(_react2.default.Fragment, null, measuredElement, /*#__PURE__*/_react2.default.createElement(_Popup.StyledPopup, { className: "beta-chayns-popup", ref: popupRef, onClick: handleChildrenClick, onMouseLeave: handleMouseLeave, onMouseEnter: handleMouseEnter, $shouldUseChildrenWidth: shouldUseChildrenWidth, $shouldUseFullWidth: shouldUseFullWidth }, children), portal); }); Popup.displayName = 'Popup'; var _default = exports.default = Popup; //# sourceMappingURL=Popup.js.map