UNPKG

zmp-ui

Version:

Zalo Mini App framework

491 lines (485 loc) 22.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports["default"] = void 0; exports.generateTrigger = generateTrigger; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _clsx = _interopRequireDefault(require("clsx")); var _context = _interopRequireDefault(require("./context")); var _addEventListener = _interopRequireDefault(require("../../utils/addEventListener")); var _raf = _interopRequireDefault(require("../../utils/raf")); var _contains = _interopRequireDefault(require("../../utils/contains")); var _ref3 = require("../../utils/ref"); var _portal = _interopRequireDefault(require("../portal")); var _sheet = _interopRequireDefault(require("../sheet")); 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) { (0, _defineProperty2["default"])(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; } var noop = function noop() { return {}; }; function returnEmptyString() { return ""; } function returnDocument(element) { if (element) { return element.ownerDocument; } return window.document; } var ALL_HANDLERS = ["onClick", "onMouseDown", "onTouchStart", "onMouseEnter", "onMouseLeave", "onFocus", "onBlur", "onContextMenu"]; function generateTrigger(PortalComponent) { var Trigger = /*#__PURE__*/function (_React$Component) { (0, _inheritsLoose2["default"])(Trigger, _React$Component); function Trigger(props) { var _this; _this = _React$Component.call(this, props) || this; (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "sheetRef", /*#__PURE__*/_react["default"].createRef()); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "triggerRef", /*#__PURE__*/_react["default"].createRef()); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "portalContainer", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "attachId", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "clickOutsideHandler", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "touchOutsideHandler", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "mouseDownTimeout", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "focusTime", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "preClickTime", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "preTouchTime", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "delayTimer", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "hasPopupMouseDown", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "eventHandlers", {}); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onFocus", function (e) { var focusDelay = _this.props.focusDelay; _this.fireEvents("onFocus", e); // incase focusin and focusout _this.clearDelayTimer(); if (_this.isFocusToShow()) { _this.focusTime = Date.now(); if (focusDelay) _this.delaySetPopupVisible(true, focusDelay); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onMouseDown", function (e) { _this.fireEvents("onMouseDown", e); _this.preClickTime = Date.now(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onTouchStart", function (e) { _this.fireEvents("onTouchStart", e); _this.preTouchTime = Date.now(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onBlur", function (e) { var blurDelay = _this.props.blurDelay; _this.fireEvents("onBlur", e); _this.clearDelayTimer(); if (_this.isBlurToHide() && blurDelay) { _this.delaySetPopupVisible(false, blurDelay); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onClick", function (event) { event.stopPropagation(); var popupVisible = _this.state.popupVisible; _this.fireEvents("onClick", event); // focus will trigger click if (_this.focusTime) { var preTime; if (_this.preClickTime && _this.preTouchTime) { preTime = Math.min(_this.preClickTime, _this.preTouchTime); } else if (_this.preClickTime) { preTime = _this.preClickTime; } else if (_this.preTouchTime) { preTime = _this.preTouchTime; } if (preTime && Math.abs(preTime - _this.focusTime) < 20) { return; } _this.focusTime = 0; } _this.preClickTime = 0; _this.preTouchTime = 0; if (_this.isClickToShow() && (_this.isClickToHide() || _this.isBlurToHide()) && event && event.preventDefault) { event.preventDefault(); } var nextVisible = !popupVisible; if (_this.isClickToHide() && !nextVisible || nextVisible && _this.isClickToShow()) { _this.setPopupVisible(!popupVisible); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onPopupMouseDown", function () { _this.hasPopupMouseDown = true; clearTimeout(_this.mouseDownTimeout); _this.mouseDownTimeout = window.setTimeout(function () { _this.hasPopupMouseDown = false; }, 0); if (_this.context) { var _ref = _this.context, onPopupMouseDown = _ref.onPopupMouseDown; onPopupMouseDown.apply(void 0, arguments); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onDocumentClick", function (event) { var _this$props = _this.props, mask = _this$props.mask, maskClosable = _this$props.maskClosable, popupType = _this$props.popupType; if (mask && !maskClosable || popupType === "sheet") { return; } var target = event.target; var root = _this.getRootDomNode(); var popupNode = _this.getPopupDomNode(); if (!(0, _contains["default"])(root, target) && !(0, _contains["default"])(popupNode, target) && !_this.hasPopupMouseDown) { _this.close(); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getRootDomNode", function () { var _this$triggerRef$curr; return ((_this$triggerRef$curr = _this.triggerRef.current) == null ? void 0 : _this$triggerRef$curr.input) || _this.triggerRef.current; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getComponent", function () { var _this$props2 = _this.props, popupClassName = _this$props2.popupClassName, popupStyle = _this$props2.popupStyle, mask = _this$props2.mask, maskClosable = _this$props2.maskClosable, zIndex = _this$props2.zIndex, popup = _this$props2.popup, onPopupVisibleChange = _this$props2.onPopupVisibleChange; var sheetAnimationVisible = _this.state.sheetAnimationVisible; var mouseProps = {}; mouseProps.onMouseDown = _this.onPopupMouseDown; mouseProps.onTouchStart = _this.onPopupMouseDown; return /*#__PURE__*/_react["default"].createElement(_sheet["default"], (0, _extends2["default"])({ visible: sheetAnimationVisible, className: popupClassName }, mouseProps, { style: popupStyle, mask: mask, maskClosable: maskClosable, onClose: function onClose() { _this.close(); }, afterClose: function afterClose() { _this.setState({ popupVisible: false, sheetAnimationVisible: false, prevPopupVisible: false }); onPopupVisibleChange == null || onPopupVisibleChange(false); }, zIndex: zIndex, handler: false, contentRef: _this.sheetRef }), typeof popup === "function" ? popup() : popup); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "attachParent", function (popupContainer) { if (_this.attachId) _raf["default"].cancel(_this.attachId); var _this$props3 = _this.props, getPopupContainer = _this$props3.getPopupContainer, getDocument = _this$props3.getDocument; var domNode = _this.getRootDomNode(); var mountNode; if (!getPopupContainer) { mountNode = getDocument == null ? void 0 : getDocument(_this.getRootDomNode()).body; } else if (domNode || getPopupContainer.length === 0) { mountNode = getPopupContainer(domNode); } if (mountNode) { mountNode.appendChild(popupContainer); } else { // Retry after frame render in case parent not ready _this.attachId = (0, _raf["default"])(function () { _this.attachParent(popupContainer); }); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getContainer", function () { if (!_this.portalContainer) { var getDocument = _this.props.getDocument; var popupContainer = getDocument == null ? void 0 : getDocument(_this.getRootDomNode()).createElement("div"); // Make sure default popup container will never cause scrollbar appearing if (popupContainer) { popupContainer.style.position = "absolute"; popupContainer.style.top = "0"; popupContainer.style.left = "0"; popupContainer.style.width = "100%"; } _this.portalContainer = popupContainer; } if (_this.portalContainer) _this.attachParent(_this.portalContainer); return _this.portalContainer; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handlePortalUpdate", function () { var _this$state = _this.state, prevPopupVisible = _this$state.prevPopupVisible, popupVisible = _this$state.popupVisible; var afterPopupVisibleChange = _this.props.afterPopupVisibleChange; if (prevPopupVisible !== popupVisible) { afterPopupVisibleChange == null || afterPopupVisibleChange(popupVisible); } }); // eslint-disable-next-line react/sort-comp (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "triggerContextValue", { onPopupMouseDown: _this.onPopupMouseDown }); var _popupVisible; if ("popupVisible" in props) { _popupVisible = !!props.popupVisible; } else { _popupVisible = !!props.defaultPopupVisible; } _this.state = { prevPopupVisible: _popupVisible, popupVisible: _popupVisible, sheetAnimationVisible: false }; ALL_HANDLERS.forEach(function (h) { _this.eventHandlers["fire" + h] = function (e) { _this.fireEvents(h, e); }; }); return _this; } var _proto = Trigger.prototype; _proto.componentDidMount = function componentDidMount() { this.componentDidUpdate(); }; _proto.componentDidUpdate = function componentDidUpdate() { var props = this.props; var state = this.state; if (state.popupVisible) { var currentDocument; if (!this.clickOutsideHandler && this.isClickToHide()) { currentDocument = props.getDocument == null ? void 0 : props.getDocument(this.getRootDomNode()); this.clickOutsideHandler = (0, _addEventListener["default"])(currentDocument, "mousedown", this.onDocumentClick); } if (!this.touchOutsideHandler) { currentDocument = currentDocument || (props.getDocument == null ? void 0 : props.getDocument(this.getRootDomNode())); this.touchOutsideHandler = (0, _addEventListener["default"])(currentDocument, "touchstart", this.onDocumentClick); } return; } this.clearOutsideHandler(); }; _proto.componentWillUnmount = function componentWillUnmount() { this.clearDelayTimer(); this.clearOutsideHandler(); clearTimeout(this.mouseDownTimeout); if (this.attachId) _raf["default"].cancel(this.attachId); } /** * @param popupVisible Show or not the popup element * @param event SyntheticEvent, used for `pointAlign` */; _proto.setPopupVisible = function setPopupVisible(popupVisible) { var onPopupVisibleChange = this.props.onPopupVisibleChange; var prevPopupVisible = this.state.popupVisible; this.clearDelayTimer(); if (prevPopupVisible !== popupVisible) { if (popupVisible) { if (!("popupVisible" in this.props)) { this.setState({ popupVisible: popupVisible, prevPopupVisible: prevPopupVisible, sheetAnimationVisible: popupVisible }); } else { this.setState({ sheetAnimationVisible: popupVisible, prevPopupVisible: prevPopupVisible }); } onPopupVisibleChange == null || onPopupVisibleChange(popupVisible); } else { this.setState({ sheetAnimationVisible: popupVisible, prevPopupVisible: prevPopupVisible }); } } }; Trigger.getDerivedStateFromProps = function getDerivedStateFromProps(_ref2, prevState) { var popupVisible = _ref2.popupVisible; var newState = {}; if (popupVisible !== undefined && prevState.popupVisible !== popupVisible) { if (popupVisible) { newState.popupVisible = popupVisible; newState.prevPopupVisible = prevState.popupVisible; newState.sheetAnimationVisible = true; } else { newState.sheetAnimationVisible = popupVisible; newState.prevPopupVisible = prevState.prevPopupVisible; } } return newState; }; _proto.getPopupDomNode = function getPopupDomNode() { return this.sheetRef.current || null; }; _proto.delaySetPopupVisible = function delaySetPopupVisible(visible, delayS) { var _this2 = this; var delay = delayS * 1000; this.clearDelayTimer(); if (delay) { this.delayTimer = window.setTimeout(function () { _this2.setPopupVisible(visible); _this2.clearDelayTimer(); }, delay); } else { this.setPopupVisible(visible); } }; _proto.clearDelayTimer = function clearDelayTimer() { if (this.delayTimer) { clearTimeout(this.delayTimer); this.delayTimer = null; } }; _proto.clearOutsideHandler = function clearOutsideHandler() { if (this.clickOutsideHandler) { this.clickOutsideHandler.remove(); this.clickOutsideHandler = null; } if (this.touchOutsideHandler) { this.touchOutsideHandler.remove(); this.touchOutsideHandler = null; } }; _proto.createTwoChains = function createTwoChains(event) { var children = this.props.children; var childPros = children.props; var props = this.props; if (childPros[event] && props[event]) { return this.eventHandlers["fire" + event]; } return childPros[event] || props[event]; }; _proto.isClickToShow = function isClickToShow() { var _this$props4 = this.props, action = _this$props4.action, showAction = _this$props4.showAction; return (action == null ? void 0 : action.indexOf("click")) !== -1 || (showAction == null ? void 0 : showAction.indexOf("click")) !== -1; }; _proto.isClickToHide = function isClickToHide() { var _this$props5 = this.props, action = _this$props5.action, hideAction = _this$props5.hideAction; return (action == null ? void 0 : action.indexOf("click")) !== -1 || (hideAction == null ? void 0 : hideAction.indexOf("click")) !== -1; }; _proto.isFocusToShow = function isFocusToShow() { var _this$props6 = this.props, action = _this$props6.action, showAction = _this$props6.showAction; return (action == null ? void 0 : action.indexOf("focus")) !== -1 || (showAction == null ? void 0 : showAction.indexOf("focus")) !== -1; }; _proto.isBlurToHide = function isBlurToHide() { var _this$props7 = this.props, action = _this$props7.action, hideAction = _this$props7.hideAction; return (action == null ? void 0 : action.indexOf("focus")) !== -1 || (hideAction == null ? void 0 : hideAction.indexOf("blur")) !== -1; }; _proto.fireEvents = function fireEvents(type, e) { var children = this.props.children; var childCallback = children.props[type]; if (childCallback) { childCallback(e); } // eslint-disable-next-line react/destructuring-assignment var callback = this.props[type]; if (callback) { callback(e); } }; _proto.close = function close() { this.setPopupVisible(false); }; _proto.render = function render() { var popupVisible = this.state.popupVisible; var _this$props8 = this.props, children = _this$props8.children, forceRender = _this$props8.forceRender, className = _this$props8.className, autoDestroy = _this$props8.autoDestroy; var child = _react["default"].Children.only(children); var newChildProps = { key: "trigger" }; // ============================== Visible Handlers ============================== // >>> Click if (this.isClickToHide() || this.isClickToShow()) { newChildProps.onClick = this.onClick; newChildProps.onInputTriggerClick = this.onClick; newChildProps.onMouseDown = this.onMouseDown; newChildProps.onTouchStart = this.onTouchStart; } else { newChildProps.onClick = this.createTwoChains("onClick"); newChildProps.onInputTriggerClick = this.createTwoChains("onClick"); newChildProps.onMouseDown = this.createTwoChains("onMouseDown"); newChildProps.onTouchStart = this.createTwoChains("onTouchStart"); } // >>> Focus if (this.isFocusToShow() || this.isBlurToHide()) { newChildProps.onFocus = this.onFocus; newChildProps.onBlur = this.onBlur; } else { newChildProps.onFocus = this.createTwoChains("onFocus"); newChildProps.onBlur = this.createTwoChains("onBlur"); } // =================================== Render =================================== var childrenClassName = (0, _clsx["default"])(child && child.props && child.props.className, className); if (childrenClassName) { newChildProps.className = childrenClassName; } var cloneProps = _objectSpread({}, newChildProps); if ((0, _ref3.supportRef)(child)) { cloneProps.ref = (0, _ref3.composeRef)(this.triggerRef, child.ref); } var trigger = /*#__PURE__*/_react["default"].cloneElement(child, cloneProps); var portal = null; // prevent unmounting after it's rendered if (popupVisible || forceRender) { portal = /*#__PURE__*/_react["default"].createElement(PortalComponent, { key: "portal", getContainer: this.getContainer, didUpdate: this.handlePortalUpdate }, this.getComponent()); } if (!popupVisible && autoDestroy) { portal = null; } return /*#__PURE__*/_react["default"].createElement(_context["default"].Provider, { value: this.triggerContextValue }, trigger, portal); }; return Trigger; }(_react["default"].Component); // eslint-disable-next-line react/static-property-placement (0, _defineProperty2["default"])(Trigger, "defaultProps", void 0); Trigger.contextType = _context["default"]; Trigger.defaultProps = { getPopupClassNameFromAlign: returnEmptyString, getDocument: returnDocument, onPopupVisibleChange: noop, afterPopupVisibleChange: noop, onPopupAlign: noop, popupClassName: "", mouseEnterDelay: 0, mouseLeaveDelay: 0.1, focusDelay: 0, blurDelay: 0.15, popupStyle: {}, destroyPopupOnHide: false, popupAlign: {}, defaultPopupVisible: false, mask: false, maskClosable: true, action: [], showAction: [], hideAction: [], autoDestroy: false, zIndex: 1001, popupType: "sheet" }; return Trigger; } var _default = exports["default"] = generateTrigger(_portal["default"]);