UNPKG

react-user-tour

Version:

give your user a guided tour around your application

305 lines (261 loc) 11.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require("react"); var _react2 = _interopRequireDefault(_react); var _reactMotion = require("react-motion"); var _tourButton = require("./tour-button"); var _tourButton2 = _interopRequireDefault(_tourButton); var _tourButtonContainer = require("./tour-button-container"); var _tourButtonContainer2 = _interopRequireDefault(_tourButtonContainer); var _arrow = require("./arrow"); var _arrow2 = _interopRequireDefault(_arrow); var _positionHelpers = require("./helpers/position-helpers"); var _positionHelpers2 = _interopRequireDefault(_positionHelpers); var _viewboxHelpers = require("./helpers/viewbox-helpers"); var viewBoxHelpers = _interopRequireWildcard(_viewboxHelpers); var _scrollToPosition = require("./helpers/scroll-to-position"); var _scrollToPosition2 = _interopRequireDefault(_scrollToPosition); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var ReactUserTour = function (_Component) { _inherits(ReactUserTour, _Component); function ReactUserTour(props) { _classCallCheck(this, ReactUserTour); var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ReactUserTour).call(this, props)); _this.prevPos = { top: 0, left: 0 }; _this.getStepPosition = _this.getStepPosition.bind(_this); return _this; } _createClass(ReactUserTour, [{ key: "shouldComponentUpdate", value: function shouldComponentUpdate(nextProps) { return this.props.step !== nextProps.step || this.props.active !== nextProps.active || this.props.hideButtons !== nextProps.hideButtons || this.props.hideClose !== nextProps.hideClose; } }, { key: "getStepPosition", value: function getStepPosition(selector, tourElWidth, tourElHeight, overridePos) { var margin = arguments.length <= 4 || arguments[4] === undefined ? 25 : arguments[4]; var horizontalOffset = arguments.length <= 5 || arguments[5] === undefined ? 0 : arguments[5]; var verticalOffset = arguments.length <= 6 || arguments[6] === undefined ? 0 : arguments[6]; var windowHeight = window.innerHeight; var windowWidth = window.innerWidth; var el = document.querySelector(selector); if (el) { var position = el ? el.getBoundingClientRect() : {}; var isElementBelowViewBox = viewBoxHelpers.isElementBelowViewBox(windowHeight, position.top); var isElementAboveViewBox = viewBoxHelpers.isElementBelowViewBox(position.bottom); if (isElementBelowViewBox) { position = (0, _scrollToPosition2.default)(el, position.bottom); } else if (isElementAboveViewBox) { position = (0, _scrollToPosition2.default)(el, window.pageYOffset + position.top); } var shouldPositionLeft = viewBoxHelpers.shouldPositionLeft(windowWidth, position.left); var shouldPositionAbove = viewBoxHelpers.shouldPositionAbove(windowHeight, position.bottom); var shouldPositionBelow = viewBoxHelpers.shouldPositionBelow(position.top); var elPos = undefined; if (overridePos && _positionHelpers2.default[overridePos]) { elPos = _positionHelpers2.default[overridePos]({ position: position, tourElWidth: tourElWidth, tourElHeight: tourElHeight, arrowSize: this.props.arrowSize, offsetHeight: el.offsetHeight, margin: margin }); } else if (shouldPositionLeft && !shouldPositionAbove && !shouldPositionBelow) { elPos = _positionHelpers2.default.left({ position: position, tourElWidth: tourElWidth, margin: margin }); } else if (shouldPositionAbove) { elPos = shouldPositionLeft ? _positionHelpers2.default.topLeft({ position: position, tourElWidth: tourElWidth, tourElHeight: tourElHeight, arrowSize: this.props.arrowSize, margin: margin }) : _positionHelpers2.default.top({ position: position, tourElHeight: tourElHeight, arrowSize: this.props.arrowSize, margin: margin }); } else if (shouldPositionBelow) { elPos = shouldPositionLeft ? _positionHelpers2.default.bottomLeft({ position: position, tourElWidth: tourElWidth, arrowSize: this.props.arrowSize, offsetHeight: el.offsetHeight, margin: margin }) : _positionHelpers2.default.bottom({ position: position, arrowSize: this.props.arrowSize, offsetHeight: el.offsetHeight, margin: margin }); } else { elPos = _positionHelpers2.default.right({ position: position, margin: margin }); } elPos.left += horizontalOffset; elPos.top += verticalOffset; this.prevPos = elPos; return elPos; } else { return this.prevPos; } } }, { key: "getCustomArrow", value: function getCustomArrow(position) { return typeof this.props.arrow === "function" ? this.props.arrow({ position: position.positioned, width: this.props.style.width, height: this.props.style.height, size: this.props.arrowSize, color: this.props.arrowColor }) : this.props.arrow; } }, { key: "render", value: function render() { var _this2 = this; var currentTourStep = this.props.steps.filter(function (step) { return step.step === _this2.props.step; })[0]; if (!this.props.active || !currentTourStep) { return _react2.default.createElement("span", null); } var position = this.getStepPosition(currentTourStep.selector, this.props.style.width, this.props.style.height, currentTourStep.position, currentTourStep.margin, currentTourStep.horizontalOffset, currentTourStep.verticalOffset); var style = _extends({}, this.props.style); var arrow = this.props.arrow ? this.getCustomArrow(position) : _react2.default.createElement(_arrow2.default, { position: position.positioned, width: this.props.style.width, height: this.props.style.height, size: this.props.arrowSize, color: this.props.arrowColor }); var extraButtonProps = this.props.buttonStyle ? { style: this.props.buttonStyle } : {}; var nextButton = this.props.step !== this.props.steps.length ? _react2.default.createElement( _tourButton2.default, _extends({ onClick: function onClick() { return _this2.props.onNext(_this2.props.step + 1); }, onTouchTap: function onTouchTap() { return _this2.props.onNext(_this2.props.step + 1); } }, extraButtonProps, { className: "react-user-tour-next-button" }), this.props.nextButtonText ) : ""; var backButton = this.props.step !== 1 ? _react2.default.createElement( _tourButton2.default, _extends({ onClick: function onClick() { return _this2.props.onBack(_this2.props.step - 1); }, onTouchTap: function onTouchTap() { return _this2.props.onBack(_this2.props.step - 1); } }, extraButtonProps, { className: "react-user-tour-back-button" }), this.props.backButtonText ) : ""; var doneButton = this.props.step === this.props.steps.length ? _react2.default.createElement( _tourButton2.default, _extends({ onClick: this.props.onCancel, onTouchTap: this.props.onCancel }, extraButtonProps, { className: "react-user-tour-done-button" }), this.props.doneButtonText ) : ""; var tourButtonContainer = !this.props.hideButtons ? _react2.default.createElement( _tourButtonContainer2.default, { style: this.props.buttonContainerStyle }, nextButton, doneButton, backButton ) : ""; var xStyle = { "float": "right", "cursor": "pointer", "paddingRight": 10, "paddingTop": 10 }; var closeButton = !this.props.hideClose ? _react2.default.createElement( "span", { className: "react-user-tour-close", style: xStyle, onClick: this.props.onCancel, onTouchTap: this.props.onCancel }, this.props.closeButtonText ) : ""; return _react2.default.createElement( "div", { className: "react-user-tour-container", style: this.props.containerStyle }, _react2.default.createElement( _reactMotion.Motion, { style: { x: (0, _reactMotion.spring)(position.left), y: (0, _reactMotion.spring)(position.top) } }, function (_ref) { var x = _ref.x; var y = _ref.y; return _react2.default.createElement( "div", { style: _extends({}, style, { transform: "translate3d(" + x + "px, " + y + "px, 0)" }) }, arrow, closeButton, currentTourStep.title, currentTourStep.body, tourButtonContainer ); } ) ); } }]); return ReactUserTour; }(_react.Component); exports.default = ReactUserTour; ReactUserTour.defaultProps = { style: { height: 150, width: 350, position: "absolute", zIndex: 9999, backgroundColor: "#fff", color: "#494949", boxShadow: "0 6px 8px 0 rgba(0, 0, 0, 0.24)" }, containerStyle: {}, onCancel: function onCancel() {}, onNext: function onNext() {}, onBack: function onBack() {}, nextButtonText: "Next", backButtonText: "Back", doneButtonText: "Done", closeButtonText: "Close", buttonContainerStyle: { position: "absolute", bottom: 10, right: 0 }, hideButtons: false, hideClose: false, arrowColor: "#fff", arrowSize: 15 };