UNPKG

wix-style-react

Version:
392 lines (327 loc) • 13.3 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 _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _SideMenu = require('../core/SideMenu'); var _SideMenu2 = _interopRequireDefault(_SideMenu); var _SlideAnimation = require('../../Animations/SlideAnimation'); var _SlideAnimation2 = _interopRequireDefault(_SlideAnimation); var _DrillView = require('./DrillView.scss'); var _DrillView2 = _interopRequireDefault(_DrillView); 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 isAnchorTag = function isAnchorTag(item) { return item.type === 'a'; }; var SideMenuDrill = function (_React$Component) { _inherits(SideMenuDrill, _React$Component); function SideMenuDrill(props) { _classCallCheck(this, SideMenuDrill); var _this = _possibleConstructorReturn(this, (SideMenuDrill.__proto__ || Object.getPrototypeOf(SideMenuDrill)).call(this, props)); var state = { menus: {}, currentMenuId: _this.props.menuKey, previousMenuId: null, showMenuA: true, slideDirection: _SlideAnimation.SlideDirection.in }; _this.processChildren({ props: _this.props }, state); _this.state = state; _this.isAnimating = false; return _this; } _createClass(SideMenuDrill, [{ key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var state = { menus: {} }; this.processChildren({ props: nextProps }, state); this.setState(state); } }, { key: 'setSelectedItemMenu', value: function setSelectedItemMenu(selectedItemMenuId, state) { // initial selected menu if (!this.state) { Object.assign(state, { currentMenuId: selectedItemMenuId, selectedItemMenuId: selectedItemMenuId }); return; } // returning to an already selected menu item (force nav) if (this.lastClickedMenuKey === selectedItemMenuId) { this.navigateToMenu(selectedItemMenuId, _SlideAnimation.SlideDirection.in); this.lastClickedMenuKey = null; } if (this.state.selectedItemMenuId === selectedItemMenuId) { return; } this.setState({ selectedItemMenuId: selectedItemMenuId }); if (this.state.currentMenuId !== selectedItemMenuId) { this.navigateToMenu(selectedItemMenuId, this.getSlideDirectionTo(selectedItemMenuId)); } } }, { key: 'getSlideDirectionTo', value: function getSlideDirectionTo(selectedItemMenuId) { var _state = this.state, currentMenuId = _state.currentMenuId, menus = _state.menus; if (!menus[currentMenuId] || !menus[selectedItemMenuId]) { return _SlideAnimation.SlideDirection.in; } return menus[currentMenuId].level < menus[selectedItemMenuId].level ? _SlideAnimation.SlideDirection.in : _SlideAnimation.SlideDirection.out; } }, { key: 'navigateToMenu', value: function navigateToMenu(nextMenuId, slideDirection) { var previousMenuId = this.state.currentMenuId; var showMenuA = !this.state.showMenuA; if (nextMenuId === previousMenuId) { return; } this.setState({ currentMenuId: nextMenuId, previousMenuId: previousMenuId, showMenuA: showMenuA, slideDirection: slideDirection }); } }, { key: 'clickFirstClickableChild', value: function clickFirstClickableChild(item, event) { var _this2 = this; var found = false; if (item.props.onClick && !item.props.disabled) { item.props.onClick(event); return true; } else if (isAnchorTag(item)) { return false; } _react.Children.forEach(item.props.children, function (child) { if (!found && child.props) { found = _this2.clickFirstClickableChild(child, event); } }); return found; } }, { key: 'selectFirstLinkChild', value: function selectFirstLinkChild(menu, event) { var _this3 = this; var found = false; _react.Children.forEach(menu.props.children, function (child) { if (!found && child.type === SideMenuDrill.Link) { _this3.clickFirstClickableChild(child, event); found = true; } if (!found && child.props && child.props.children) { _this3.selectFirstLinkChild(child, event); } }); } }, { key: 'alterMenu', value: function alterMenu(menu, childrenClone, parentMenuKey, isActive) { var _this4 = this; var defaultSubMenProps = { isOpen: false, onSelectHandler: function onSelectHandler(event) { _this4.lastClickedMenuKey = menu.props.menuKey; _this4.selectFirstLinkChild(menu, event); if (menu.props.onSelectHandler) { menu.props.onSelectHandler.apply(menu, [event]); } }, onBackHandler: function onBackHandler(event) { _this4.navigateToMenu(parentMenuKey, _SlideAnimation.SlideDirection.out); if (menu.props.onBackHandler) { menu.props.onBackHandler.apply(menu, [event]); } }, isActive: isActive }; return _react2.default.cloneElement(menu, defaultSubMenProps, childrenClone); } }, { key: 'cloneSubMenu', value: function cloneSubMenu(menu, state, parentMenuKey, childrenClone) { var isMenuActive = state.menus[menu.props.menuKey].isActive; if (isMenuActive && state.menus[parentMenuKey]) { state.menus[parentMenuKey].isActive = true; } var menuClone = this.alterMenu(menu, childrenClone, parentMenuKey, isMenuActive); state.menus[menuClone.props.menuKey].component = menuClone; return menuClone; } }, { key: 'cloneChild', value: function cloneChild(menu, state, parentMenuKey, childrenClone) { if (menu.type === SideMenuDrill.Link && menu.props.isActive) { this.setSelectedItemMenu(parentMenuKey, state); state.menus[parentMenuKey].isActive = true; } if (menu.props.menuKey) { return this.cloneSubMenu(menu, state, parentMenuKey, childrenClone); } return _react2.default.cloneElement(menu, {}, childrenClone); } }, { key: 'processChildren', value: function processChildren(menu, state, parentMenuKey) { var _this5 = this; var level = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; var childrenClone = _react.Children.map(menu.props.children, function (child) { if (child && child.props && child.props.children) { var menuKey = menu.props.menuKey || parentMenuKey; if (!state.menus[menuKey]) { state.menus[menuKey] = { isActive: false, component: null, level: level }; } return _this5.processChildren(child, state, menuKey, level + 1); } return child; }); return this.cloneChild(menu, state, parentMenuKey, childrenClone, level); } }, { key: 'renderNavigation', value: function renderNavigation(menu) { if (!menu) { return null; } if (menu.props.menuKey === this.props.menuKey) { // Render root items return menu.props.children; } // Render open SubMenu return _react2.default.cloneElement(menu, { isOpen: true }); } }, { key: 'renderMenu', value: function renderMenu(menu) { var navigationMenu = this.renderNavigation(menu); return navigationMenu && _react2.default.createElement( 'div', { 'data-hook': 'drill-view-panel', className: _DrillView2.default.drillViewPanel }, navigationMenu ); } }, { key: 'shouldComponentUpdate', value: function shouldComponentUpdate() { if (this.isAnimating) { this.queuedUpdate = true; } return !this.isAnimating; } }, { key: 'animationStart', value: function animationStart() { this.isAnimating = true; } }, { key: 'animationComplete', value: function animationComplete() { this.isAnimating = false; if (this.queuedUpdate) { this.queuedUpdate = false; this.forceUpdate(); } } }, { key: 'getAnimationHandlers', value: function getAnimationHandlers() { var _this6 = this; var enterHandlers = {}; var exitHandlers = {}; var enterPromise = new Promise(function (resolve) { return enterHandlers.onEnter = resolve; }); var enteredPromise = new Promise(function (resolve) { return enterHandlers.onEntered = resolve; }); var exitPromise = new Promise(function (resolve) { return exitHandlers.onExit = resolve; }); var exitedPromise = new Promise(function (resolve) { return exitHandlers.onExited = resolve; }); Promise.race([enterPromise, exitPromise]).then(function () { return _this6.animationStart(); }); Promise.all([enteredPromise, exitedPromise]).then(function () { return _this6.animationComplete(); }); return { enterHandlers: enterHandlers, exitHandlers: exitHandlers }; } }, { key: 'render', value: function render() { var _state2 = this.state, menus = _state2.menus, currentMenuId = _state2.currentMenuId, previousMenuId = _state2.previousMenuId, showMenuA = _state2.showMenuA, slideDirection = _state2.slideDirection; var menuAId = showMenuA ? currentMenuId : previousMenuId; var menuBId = showMenuA ? previousMenuId : currentMenuId; var menuA = menuAId && menus[menuAId].component; var menuB = menuBId && menus[menuBId].component; var _getAnimationHandlers = this.getAnimationHandlers(), enterHandlers = _getAnimationHandlers.enterHandlers, exitHandlers = _getAnimationHandlers.exitHandlers; var menuAHandlers = showMenuA ? enterHandlers : exitHandlers; var menuBHandlers = showMenuA ? exitHandlers : enterHandlers; return _react2.default.createElement( _SideMenu2.default, { dataHook: this.props.dataHook, inFlex: this.props.inFlex }, _react2.default.createElement( 'div', { className: _DrillView2.default.drillViewContainer }, _react2.default.createElement( _SlideAnimation2.default, _extends({ direction: slideDirection, animateAppear: false, isVisible: showMenuA }, menuAHandlers), this.renderMenu(menuA) ), _react2.default.createElement( _SlideAnimation2.default, _extends({ direction: slideDirection, animateAppear: false, isVisible: !showMenuA }, menuBHandlers), this.renderMenu(menuB) ) ), this.props.stickyFooter ); } }]); return SideMenuDrill; }(_react2.default.Component); SideMenuDrill.defaultProps = { inFlex: false, menuKey: 'root' }; SideMenuDrill.propTypes = { dataHook: _propTypes2.default.string, inFlex: _propTypes2.default.bool, menuKey: _propTypes2.default.string, children: _propTypes2.default.node, stickyFooter: _propTypes2.default.node }; exports.default = SideMenuDrill;