UNPKG

organism-react-onboarding

Version:
798 lines (681 loc) 19.9 kB
import _classCallCheck from "reshow-runtime/es/helpers/classCallCheck"; import _createClass from "reshow-runtime/es/helpers/createClass"; import _assertThisInitialized from "reshow-runtime/es/helpers/assertThisInitialized"; import _inherits from "reshow-runtime/es/helpers/inherits"; import _createSuper from "reshow-runtime/es/helpers/createSuper"; import _defineProperty from "reshow-runtime/es/helpers/defineProperty"; require("setimmediate"); import React, { createElement, cloneElement, PureComponent, Children } from "react"; import { lazyInject, Header, Content, Button, Progress, SemanticUI } from "react-atomic-molecule"; import { popupDispatch, PopupModal } from "organism-react-popup"; import { cleanClass, cleanZIndex, setClass, showEl, LightBox } from "organism-react-spotlight"; import query from "css-query-selector"; import getOffset from "getoffset"; import getStyle from "get-style"; import getScrollInfo from "get-scroll-info"; import get from "get-object-value"; import { isFixed } from "get-window-offset"; import { percent } from "to-percent-js"; import scroll from "smooth-scroll-to"; import Beacon from "../organisms/Beacon"; import Tooltip from "../organisms/Tooltip"; import Highlight from "../organisms/Highlight"; import StepNumber from "../organisms/StepNumber"; var keys = Object.keys; var injects; var nodeId = 0; var GROUP_KEY = "react-onboarding"; var GROUP_FLOATS = GROUP_KEY + "-floats"; var classCleanZIndex = GROUP_KEY + "-clean-zindex"; var classShowEl = GROUP_KEY + "-show-el"; var classRelative = GROUP_KEY + "-relative"; var myShowEl = function myShowEl(node) { return showEl(node, classShowEl, classRelative); }; var myCleanZIndex = function myCleanZIndex(node) { return cleanZIndex(node, classCleanZIndex, classShowEl); }; var Step = /*#__PURE__*/function (_PureComponent) { _inherits(Step, _PureComponent); var _super = _createSuper(Step); function Step(props) { var _this; _classCallCheck(this, Step); _this = _super.call(this, props); _defineProperty(_assertThisInitialized(_this), "timerFind", void 0); _defineProperty(_assertThisInitialized(_this), "timerExecute", void 0); _defineProperty(_assertThisInitialized(_this), "timerMonitor", void 0); _defineProperty(_assertThisInitialized(_this), "timerMonitorInit", void 0); _defineProperty(_assertThisInitialized(_this), "handleBack", function () { var _this$props = _this.props, back = _this$props.back, finish = _this$props.finish, stepIndex = _this$props.stepIndex; if (finish) { finish.call(_assertThisInitialized(_this)); } back(stepIndex); }); _defineProperty(_assertThisInitialized(_this), "handleNext", function () { var _this$props2 = _this.props, verify = _this$props2.verify, next = _this$props2.next, finish = _this$props2.finish, stepIndex = _this$props2.stepIndex; var isSuccess = true; if (verify) { isSuccess = verify.call(_assertThisInitialized(_this)); } if (!isSuccess) { console.warn("Handle finish failed."); return isSuccess; } if (finish) { finish.call(_assertThisInitialized(_this)); } next(stepIndex); }); injects = lazyInject(InjectStyles, injects); return _this; } _createClass(Step, [{ key: "addNumber", value: function addNumber(num, node) { if (!node || !num) { return; } if (!this.isDomShow(node)) { return; } var thisStyles; var isSetFixed = isFixed(node); if (isSetFixed) { thisStyles = injects.fixed; } popupDispatch({ type: "dom/update", params: { popup: /*#__PURE__*/React.createElement(StepNumber, { name: "number-" + num, key: "number-" + num, targetEl: node, styles: thisStyles }, num) } }); } }, { key: "addLightBox", value: function addLightBox(node, isHide) { var isSetFixed = isFixed(node); myCleanZIndex(node); var thisStyles; if (isSetFixed) { thisStyles = injects.fixed; } if (!node.id) { node.id = "light-el-" + nodeId; nodeId++; } var nodePos = getOffset(node); if (!isHide) { popupDispatch({ type: "dom/update", params: { popup: /*#__PURE__*/React.createElement(LightBox, { key: node.id, name: node.id, group: GROUP_KEY, wh: [nodePos.w, nodePos.h], targetEl: node, styles: thisStyles }) } }); } if (!isSetFixed) { // need locate after myCleanZIndex(node) myShowEl(node); } } }, { key: "addHighlight", value: function addHighlight(node) { var nodePos = this.isDomShow(node); if (!nodePos) { return; } var thisStyles; var isSetFixed = isFixed(node); if (isSetFixed) { thisStyles = injects.fixed; } if (!node.id) { node.id = "react-onboarding-highlight-" + nodeId; nodeId++; } popupDispatch({ type: "dom/update", params: { popup: /*#__PURE__*/React.createElement(Highlight, { wh: [nodePos.w, nodePos.h], name: "highlight-" + node.id, key: "highlight-" + node.id, targetEl: node, styles: thisStyles }) } }); } }, { key: "setHighlights", value: function setHighlights() { var _this2 = this; var highlights = this.props.highlights; if (!highlights) { return; } highlights.forEach(function (hl, key) { var nodes = query.all(hl); if (nodes.length) { nodes.forEach(function (node, tKey) { _this2.addHighlight(node); }); } }); } }, { key: "setBeacons", value: function setBeacons() { var _this3 = this; var beacons = this.props.beacons; if (!beacons) { return; } beacons.forEach(function (beacon, key) { var node = query.one(beacon); if (!node) { return; } if (!_this3.isDomShow(node)) { return; } var isSetFixed = isFixed(node); var styles; if (isSetFixed) { styles = injects.fixed; } popupDispatch({ type: "dom/update", params: { popup: /*#__PURE__*/React.createElement(Beacon, { name: "react-onboarding-beacon" + key, key: key, targetEl: node, styles: styles }) } }); }); } }, { key: "setNumbers", value: function setNumbers() { var _this4 = this; var numbers = this.props.numbers; if (!numbers) { return; } keys(numbers).forEach(function (key) { var node = query.one(numbers[key]); _this4.addNumber(key, node); }); } }, { key: "initFloat", value: function initFloat() { var _this5 = this; var _this$props3 = this.props, type = _this$props3.type, delay = _this$props3.delay, isReady = _this$props3.isReady, before = _this$props3.before, cook = _this$props3.cook, target = _this$props3.target, onboardingBefore = _this$props3.onboardingBefore; var callback = function callback() { if (onboardingBefore) { onboardingBefore(); } if (cook) { cook.call(_this5); } setImmediate(function () { if (false !== _this5.getTargetEl() || "modal" === type) { popupDispatch({ type: "dom/update", params: { popup: _this5._float } }); } }); }; if (target) { this.tryResetFloats(callback); } else { callback.call(this); } } }, { key: "_resetFloats", value: function _resetFloats(callback, lightEl) { var _this$props4 = this.props, type = _this$props4.type, before = _this$props4.before, hideLightBox = _this$props4.hideLightBox; if (before) { before.call(this); } if (lightEl) { this.addLightBox(lightEl, hideLightBox); var isSetFixed = isFixed(lightEl); var floatProps = {}; if (type !== "modal") { floatProps = { isSetFixed: isSetFixed, targetEl: lightEl }; } this._float = /*#__PURE__*/cloneElement(this._float, floatProps); } this.setHighlights(); this.setNumbers(); this.setBeacons(); if ("function" === typeof callback) { callback.call(this); } this.handleMonitor(); return true; } }, { key: "tryResetFloats", value: function tryResetFloats(callback, isReady) { var _isReady, _this6 = this; var _this$props5 = this.props, delay = _this$props5.delay, target = _this$props5.target; isReady = (_isReady = isReady) !== null && _isReady !== void 0 ? _isReady : this.props.isReady; var maxTry = 100; var tryTime = 0; clearInterval(this.timerFind); this.timerFind = setInterval(function () { tryTime++; var targetEl = _this6.getTargetEl(); if (tryTime > maxTry) { clearInterval(_this6.timerFind); console.warn("Can not find target element. [" + target + "]"); } if (!targetEl) { return; } clearInterval(_this6.timerFind); var thisDelay = delay; if (isReady) { thisDelay = 0; } clearTimeout(_this6.timerExecute); _this6.timerExecute = setTimeout(function () { _this6.handleScrollTo(targetEl, function () { _this6._resetFloats(callback, targetEl); }); }, thisDelay); }, 50); } }, { key: "resetFloats", value: function resetFloats() { var _this7 = this; this.tryResetFloats(function () { popupDispatch({ type: "dom/update", params: { popup: _this7._float } }); }); } }, { key: "handleScrollTo", value: function handleScrollTo(lightEl, callback) { var _this8 = this; var scrollTo = this.props.scrollTo; if (!scrollTo || !lightEl) { callback.call(this); return; } var lightElPos = getOffset(lightEl); var scrollInfo = getScrollInfo(); var halfH; if (scrollInfo.scrollNodeHeight > lightElPos.h) { halfH = (scrollInfo.scrollNodeHeight - lightElPos.h) / 2; } else { halfH = scrollInfo.scrollNodeHeight / 2; } scroll(Math.floor(lightElPos.top - halfH), null, null, function () { callback.call(_this8); }); } }, { key: "handleFinish", value: function handleFinish() { clearInterval(this.timerFind); clearInterval(this.timerMonitor); clearTimeout(this.timerMonitorInit); clearTimeout(this.timerExecute); var finish = this.props.finish; if (finish) { finish.call(this); } popupDispatch({ type: "dom/closeGroup", params: { group: GROUP_KEY } }); cleanClass(classCleanZIndex); cleanClass(classShowEl); cleanClass(classRelative); } }, { key: "handleMonitor", value: function handleMonitor() { var _this9 = this; var _this$props6 = this.props, monitors = _this$props6.monitors, monitorDelay = _this$props6.monitorDelay, next = _this$props6.next, stepIndex = _this$props6.stepIndex; if (!monitors) { return; } clearTimeout(this.timerMonitorInit); this.timerMonitorInit = setTimeout(function () { clearInterval(_this9.timerMonitor); _this9.timerMonitor = setInterval(function () { monitors.forEach(function (sel) { var nodes = query.all(sel); if (nodes.length) { nodes.forEach(function (node) { if (_this9.isDomShow(node)) { next(stepIndex); clearInterval(_this9.timerMonitor); } }); } }); }, 100); }, monitorDelay); } }, { key: "closeFloats", value: function closeFloats() { popupDispatch({ type: "dom/closeGroup", params: { group: GROUP_FLOATS } }); } }, { key: "isDomShow", value: function isDomShow(dom) { var elPos = getOffset(dom); if (!elPos.w || !elPos.h) { return false; } else { return elPos; } } /** * @return null mean not assign target * @return false mean target not exists */ }, { key: "getTargetEl", value: function getTargetEl() { var target = this.props.target; if (!target) { return null; } var targetEl = query.one(target); if (!targetEl) { return false; } if (this.isDomShow(targetEl)) { return targetEl; } else { return false; } } }, { key: "tryOpen", value: function tryOpen() { var host = this.props.host; if (false !== this.getTargetEl()) { this.open(); } else { host.goTo(0); } } }, { key: "open", value: function open() { var _this$props7 = this.props, type = _this$props7.type, scrollTo = _this$props7.scrollTo; var targetEl = this.getTargetEl(); if (type !== "modal" && !targetEl) { console.warn("target not found."); this.handleFinish(); return; } this.resetFloats(); } }, { key: "resetLightBox", value: function resetLightBox() { var _this$props8 = this.props, target = _this$props8.target, hideLightBox = _this$props8.hideLightBox; var lightEl = query.one(target); if (!lightEl) { return; } var isSetFixed = isFixed(lightEl); this.addLightBox(lightEl, hideLightBox); this._float = /*#__PURE__*/cloneElement(this._float, { targetEl: lightEl, isSetFixed: isSetFixed }); popupDispatch({ type: "dom/update", params: { popup: this._float } }); } }, { key: "componentDidMount", value: function componentDidMount() { this.initFloat(); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { this.initFloat(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.handleFinish(); } }, { key: "render", value: function render() { var _this10 = this; var _this$props9 = this.props, maskScroll = _this$props9.maskScroll, backgroundScroll = _this$props9.backgroundScroll, header = _this$props9.header, content = _this$props9.content, actions = _this$props9.actions, type = _this$props9.type, style = _this$props9.style, stepIndex = _this$props9.stepIndex, total = _this$props9.total, I18N = _this$props9.I18N, onClose = _this$props9.onClose; var stepDisplayIndex = stepIndex + 1; var floatEl; var name; switch (type) { case "modal": floatEl = PopupModal; name = GROUP_KEY + "-modal"; break; case "tooltip": default: floatEl = Tooltip; name = GROUP_KEY + "-tooltip"; break; } var child = [/*#__PURE__*/React.createElement(Progress, { styles: injects.progress, percent: percent(stepDisplayIndex / total), className: "attached green" })]; if (header) { child.push( /*#__PURE__*/React.createElement(Header, { styles: injects.header }, header)); } if (content) { child.push( /*#__PURE__*/React.createElement(Content, { styles: injects.content }, content)); } if (actions) { var buttons = []; actions.forEach(function (action, key) { var _onClick; var actionText = get(action, ["text"], ""); var actionClassName = get(action, ["className"], ""); var thisAction = action.action; if ("function" === typeof thisAction) { _onClick = thisAction; } else { switch (thisAction) { case "next": _onClick = _this10.handleNext; actionClassName += " positive"; if (!actionText) { var isLast = stepDisplayIndex >= total; if (isLast) { actionText = I18N.done; } else { actionText = I18N.next + " " + stepDisplayIndex + "/" + total; } } break; case "back": _onClick = _this10.handleBack; if (!actionText) { actionText = I18N.back; } break; default: break; } } buttons.push( /*#__PURE__*/React.createElement(Button, { key: key, onClick: function onClick(e) { e.stopPropagation(); _onClick(e); }, className: actionClassName }, actionText)); }); child.push( /*#__PURE__*/React.createElement(SemanticUI, { className: "actions", styles: injects.actions }, buttons)); } this._float = /*#__PURE__*/createElement(floatEl, { maskScroll: maskScroll, backgroundScroll: backgroundScroll, name: name, onClose: onClose, modalStyle: style, modalClassName: "mini", center: false, group: GROUP_KEY, style: { zIndex: 9999 }, styles: injects.modal }, Children.map(child, function (c) { return c; })); return null; } }]); return Step; }(PureComponent); _defineProperty(Step, "defaultProps", { delay: 100, monitorDelay: 700, scrollTo: true }); export default Step; export { myShowEl as showEl, myCleanZIndex as cleanZIndex }; var InjectStyles = { modal: [{ background: ["-webkit-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%)", "radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%)"] }], fixed: [{ position: "fixed !important" }, ".react-onboarding-fixed", "react-onboarding-fixed"], cleanZIndex: [{ zIndex: "auto !important" }, "." + classCleanZIndex, classCleanZIndex], relative: [{ position: "relative !important" }, "." + classRelative, classRelative], showEl: [{ zIndex: "99999 !important", transform: "translate3d(0,0,0)" }, "." + classShowEl, classShowEl], progress: [{ position: "absolute !important", top: 0, left: 0, right: 0, zIndex: 2 }], header: [{ textAlign: "left" }], content: [{ textAlign: "left", padding: "1rem 1rem" }], actions: [{ textAlign: "right", paddingTop: "1rem", background: "f9fafb", borderTop: "1px solid rgba(34,36,38,.15)" }] };