wix-style-react
Version:
515 lines (431 loc) • 22.3 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
import React, { Component, cloneElement } from 'react';
import PropTypes from 'prop-types';
import { st, classes } from './Sidebar.st.css';
import { SidebarItem } from './SidebarItem';
import { SidebarPersistentHeader } from './SidebarPersistentHeader';
import { SidebarPersistentFooter } from './SidebarPersistentFooter';
import { SidebarBackButton } from './SidebarBackButton';
import { SidebarContext } from './SidebarAPI';
import { dataHooks, sidebarSkins } from './constants';
import { SidebarContentWrapper } from './SidebarContentWrapper';
import { WixStyleReactContext } from '../WixStyleReactProvider/context';
var CollapsibeInnerMenuOpenChildren = function CollapsibeInnerMenuOpenChildren(props) {
var children = props.children,
waitForOtherMenuToClose = props.waitForOtherMenuToClose,
skin = props.skin,
isAlreadyOpen = props.isAlreadyOpen;
return /*#__PURE__*/React.createElement("div", {
"data-hook": 'open-inner-menu-children',
className: isAlreadyOpen ? '' : st(waitForOtherMenuToClose ? classes.innerMenuWrapperInToPlaceAfterClosingOther : classes.innerMenuWrapperInToPlace)
}, /*#__PURE__*/React.createElement(SidebarContentWrapper, {
containerClasses: st(classes.innerMenu),
containerDataHook: dataHooks.drivenInChildren,
skin: skin
}, children));
};
var CollapsibeInnerMenuCloseChildren = function CollapsibeInnerMenuCloseChildren(props) {
var children = props.children;
return /*#__PURE__*/React.createElement("div", {
"data-hook": 'closed-inner-menu-children',
className: st(classes.innerMenuWrapperOutOfPlace)
}, /*#__PURE__*/React.createElement("div", {
className: st(classes.innerMenu),
"data-hook": dataHooks.drivenOutChildren
}, children));
};
var CollapsibeInnerMenuCloseParent = function CollapsibeInnerMenuCloseParent(props) {
var isAlreadyClosed = props.isAlreadyClosed,
children = props.children;
var closeParentClass = st(isAlreadyClosed ? classes.closedInnerMenu : classes.closingInnerMenu);
return /*#__PURE__*/React.createElement("div", {
"data-hook": "closed-inner-menu",
className: closeParentClass
}, children);
};
var CollapsibeInnerMenuOpenParent = function CollapsibeInnerMenuOpenParent(props) {
var isAlreadyOpen = props.isAlreadyOpen,
children = props.children,
waitForOtherMenuToClose = props.waitForOtherMenuToClose;
var openParentClass = waitForOtherMenuToClose ? st(classes.openingInnerMenuAfterClosingOther) : st(isAlreadyOpen ? classes.openInnerMenu : classes.openingInnerMenu);
return /*#__PURE__*/React.createElement("div", {
"data-hook": 'open-inner-menu',
className: openParentClass
}, children);
};
/** A sidebar navigation component */
var Sidebar = /*#__PURE__*/function (_Component) {
_inherits(Sidebar, _Component);
var _super = _createSuper(Sidebar);
function Sidebar(props) {
var _this;
_classCallCheck(this, Sidebar);
_this = _super.call(this, props);
_defineProperty(_assertThisInitialized(_this), "_getInnerMenuCollapsibleState", function (options) {
var _this$itemKeyToChildr, _this$itemKeyToChildr2;
var menuToClose = options.menuToClose,
menuToOpen = options.menuToOpen,
selected = options.selected;
var expandedInnerMenu = undefined;
var openMenuChildren = ((_this$itemKeyToChildr = _this.itemKeyToChildren[menuToOpen]) === null || _this$itemKeyToChildr === void 0 ? void 0 : _this$itemKeyToChildr.children) || [];
var closeMenuChildren = ((_this$itemKeyToChildr2 = _this.itemKeyToChildren[menuToClose]) === null || _this$itemKeyToChildr2 === void 0 ? void 0 : _this$itemKeyToChildr2.children) || [];
var collapsibleOnScreenChildren = _this.firstLevelItems.reduce(function (accumalator, child) {
var shouldExpand = menuToOpen && child.props.itemKey === menuToOpen && (openMenuChildren === null || openMenuChildren === void 0 ? void 0 : openMenuChildren.length) > 0;
var shouldCollapse = _this.state.expandedInnerMenu && menuToClose && (closeMenuChildren === null || closeMenuChildren === void 0 ? void 0 : closeMenuChildren.length) > 0 && child.props.itemKey === menuToClose && _this.state.expandedInnerMenu === menuToClose;
var waitForOtherMenuToClose = _this.state.expandedInnerMenu && menuToClose && _this.state.expandedInnerMenu === menuToClose && menuToClose !== menuToOpen;
if (shouldExpand) {
expandedInnerMenu = menuToOpen;
return [].concat(_toConsumableArray(accumalator), [/*#__PURE__*/React.createElement(CollapsibeInnerMenuOpenParent, {
key: "open-parent-".concat(menuToOpen),
isAlreadyOpen: _this._isAlreadyOpen(menuToOpen),
waitForOtherMenuToClose: waitForOtherMenuToClose
}, child), /*#__PURE__*/React.createElement(CollapsibeInnerMenuOpenChildren, {
key: "open-children-".concat(menuToOpen),
waitForOtherMenuToClose: waitForOtherMenuToClose,
skin: _this.props.skin,
isAlreadyOpen: _this._isAlreadyOpen(menuToOpen)
}, openMenuChildren)]);
}
if (shouldCollapse) {
return [].concat(_toConsumableArray(accumalator), [/*#__PURE__*/React.createElement(CollapsibeInnerMenuCloseParent, {
key: "closed-parent-".concat(menuToClose),
isAlreadyClosed: _this._isAlreadyClosed(selected, menuToClose)
}, child), /*#__PURE__*/React.createElement(CollapsibeInnerMenuCloseChildren, {
key: "closed-children-".concat(menuToClose)
}, closeMenuChildren)]);
}
return [].concat(_toConsumableArray(accumalator), [child]);
}, []);
return {
collapsibleOnScreenChildren: collapsibleOnScreenChildren,
expandedInnerMenu: expandedInnerMenu
};
});
_defineProperty(_assertThisInitialized(_this), "_shouldCollapseInnerMenu", function (itemKey) {
return _this.state.expandedInnerMenu === itemKey && (itemKey === _this.state.selectedKey && _this.state.expandedInnerMenu || itemKey !== _this.state.selectedKey);
});
_defineProperty(_assertThisInitialized(_this), "_shouldExpandInnerMenu", function (parentKey, itemKey) {
return parentKey === _this.state.lastSelectedKey && !_this.state.expandedInnerMenu || _this.itemKeyToParentKey[itemKey] === parentKey || parentKey !== _this.state.lastSelectedKey;
});
_defineProperty(_assertThisInitialized(_this), "_navigateTo", function (itemKey) {
if (_this._isChild(itemKey)) {
_this._selectItem(itemKey);
_this.sidebarContext = _this._getSidebarContext();
return;
}
if (_this._isParent(itemKey)) {
_this._openInnerMenu(itemKey);
_this.sidebarContext = _this._getSidebarContext();
return;
}
if (itemKey) {
_this._closeInnerMenu(itemKey);
_this.sidebarContext = _this._getSidebarContext();
return;
}
});
_defineProperty(_assertThisInitialized(_this), "_getSidebarContext", function () {
return {
itemClicked: _this._navigateTo,
backClicked: function backClicked() {
_this._closeInnerMenu();
_this.sidebarContext = _this._getSidebarContext();
},
getSelectedKey: function getSelectedKey() {
return _this.state.selectedKey;
},
getSkin: function getSkin() {
return _this.props.skin;
},
getIsMenuExpanded: function getIsMenuExpanded() {
return _this.state.expandedInnerMenu;
}
};
});
_defineProperty(_assertThisInitialized(_this), "sidebarContext", _this._getSidebarContext());
_defineProperty(_assertThisInitialized(_this), "_getInnerChildSelectedState", function (itemKey) {
var collapsibleInnerMenuState = _this._getInnerMenuCollapsibleState({
menuToClose: _this.state.lastSelectedKey,
menuToOpen: _this.itemKeyToParentKey[itemKey],
selected: itemKey
});
if (_this.itemKeyToParentKey[itemKey] !== _this.state.lastSelectedKey) {
return _objectSpread({
drivenInChildren: _this.itemKeyToChildren[_this.itemKeyToParentKey[itemKey]].children,
selectedKey: itemKey,
lastSelectedKey: _this.itemKeyToParentKey[itemKey]
}, collapsibleInnerMenuState);
} else {
return _objectSpread(_objectSpread({}, collapsibleInnerMenuState), {}, {
selectedKey: itemKey
});
}
});
_defineProperty(_assertThisInitialized(_this), "_getInnerMenuOpenState", function (itemKey) {
var _this$itemKeyToChildr3 = _this.itemKeyToChildren[itemKey],
children = _this$itemKeyToChildr3.children,
selectedKey = _this$itemKeyToChildr3.selectedKey;
var selected = _this.itemKeyToParentKey[_this.state.lastSelectedKey] === itemKey ? _this.state.lastSelectedKey : selectedKey;
var parentKey = _this.itemKeyToParentKey[selected];
var parentItemKeyToOpen = _this._getItemToOpenKey(parentKey, itemKey);
var parentItemKeyToClose = _this._getItemToCloseKey(_this.state.lastSelectedKey);
return _objectSpread(_objectSpread({}, _this._getInnerMenuCollapsibleState({
menuToClose: parentItemKeyToClose,
menuToOpen: parentItemKeyToOpen,
selected: selected
})), {}, {
drivenInChildren: children,
drivenOutChildren: [],
selectedKey: selected,
lastSelectedKey: itemKey
});
});
_defineProperty(_assertThisInitialized(_this), "_getItemToCloseKey", function (itemKey) {
if (_this._shouldCollapseInnerMenu(itemKey)) {
return _this.itemKeyToParentKey[itemKey] || itemKey;
}
if (_this._shouldCollapseInnerMenu(_this.state.lastSelectedKey)) {
return _this.itemKeyToParentKey[_this.state.lastSelectedKey] || _this.state.lastSelectedKey;
}
return undefined;
});
_defineProperty(_assertThisInitialized(_this), "_getItemToOpenKey", function (parentKey, itemKey) {
return _this._shouldExpandInnerMenu(parentKey, itemKey) ? parentKey : undefined;
});
_defineProperty(_assertThisInitialized(_this), "_getInnerMenuCloseState", function (itemKey, updateCollapsibleOnlyOnChange) {
var selectedKey = _this.state.lastSelectedKey || itemKey;
var parentItemKeyToClose = _this._getItemToCloseKey(selectedKey);
return _objectSpread(_objectSpread({}, _this._getInnerMenuCollapsibleState({
menuToClose: parentItemKeyToClose,
selected: selectedKey
})), {}, {
selectedKey: itemKey || _this.state.lastSelectedKey,
lastSelectedKey: selectedKey,
drivenInChildren: [],
drivenOutChildren: _this.state.drivenInChildren
});
});
_defineProperty(_assertThisInitialized(_this), "_getItemWithKey", function (item, itemKey) {
return item.props.itemKey ? item : /*#__PURE__*/cloneElement(item, _objectSpread(_objectSpread({}, item.props), {}, {
itemKey: itemKey
}));
});
_defineProperty(_assertThisInitialized(_this), "_getChildrenWithKeys", function (child) {
var _child$props$innerMen;
return ((_child$props$innerMen = child.props.innerMenu) === null || _child$props$innerMen === void 0 ? void 0 : _child$props$innerMen.map(function (innerChild, index) {
return _this._getItemWithKey(innerChild, child.props.itemKey + index);
})) || [];
});
_defineProperty(_assertThisInitialized(_this), "_isParent", function (itemKey) {
return _this.itemKeyToChildren[itemKey];
});
_defineProperty(_assertThisInitialized(_this), "_isChild", function (itemKey) {
return _this.itemKeyToParentKey[itemKey];
});
_defineProperty(_assertThisInitialized(_this), "_isAlreadyOpen", function (menuToOpen) {
return _this.state.lastSelectedKey === menuToOpen && _this.itemKeyToParentKey[_this.props.selectedKey] === menuToOpen && _this.state.expandedInnerMenu === menuToOpen;
});
_defineProperty(_assertThisInitialized(_this), "_isAlreadyClosed", function (selected, menuToClose) {
return _this.itemKeyToParentKey[selected] !== menuToClose;
});
_defineProperty(_assertThisInitialized(_this), "_selectItem", function (itemKey) {
return _this.setState(_this._getInnerChildSelectedState(itemKey));
});
_defineProperty(_assertThisInitialized(_this), "_openInnerMenu", function (itemKey) {
return _this.setState(_this._getInnerMenuOpenState(itemKey));
});
_defineProperty(_assertThisInitialized(_this), "_closeInnerMenu", function (itemKey) {
return _this.setState(_this._getInnerMenuCloseState(itemKey));
});
_this.itemKeyToChildren = {};
_this.itemKeyToParentKey = {};
_this.firstLevelItems = [];
_this.state = {
persistentTopChildren: [],
drivenOutChildren: [],
onScreenChildren: [],
collapsibleOnScreenChildren: [],
drivenInChildren: [],
persistentBottomChildren: [],
selectedKey: '',
lastSelectedKey: '',
expandedInnerMenu: undefined
};
return _this;
}
_createClass(Sidebar, [{
key: "UNSAFE_componentWillMount",
value: function UNSAFE_componentWillMount() {
this._setInnerMenus(this.props);
}
}, {
key: "UNSAFE_componentWillReceiveProps",
value: function UNSAFE_componentWillReceiveProps(props) {
this._setInnerMenus(props);
}
}, {
key: "_setInnerMenus",
value: function _setInnerMenus(props) {
var _this2 = this;
var persistentTopChildren = [];
var persistentBottomChildren = [];
var onScreenChildren = [];
var findEnabledChild = function findEnabledChild(item) {
return item.props.innerMenu && item.props.innerMenu.find(function (c) {
return c.type === SidebarItem && !c.props.disable;
});
};
var handleChild = function handleChild(child) {
if (child.type === SidebarItem) {
var enabledChild = findEnabledChild(child);
var innerChildrenWithKeys = _this2._getChildrenWithKeys(child);
_this2.itemKeyToChildren[child.props.itemKey] = {
selectedKey: enabledChild ? enabledChild.props.itemKey : child.props.itemKey,
children: innerChildrenWithKeys
};
if (child.props.innerMenu) {
innerChildrenWithKeys.forEach(function (innerChild) {
if (innerChild.type !== SidebarBackButton) {
_this2.itemKeyToParentKey[innerChild.props.itemKey] = child.props.itemKey;
}
});
}
onScreenChildren.push(child);
} else if (child.type === SidebarPersistentHeader) {
persistentTopChildren.push(child);
} else if (child.type === SidebarPersistentFooter) {
persistentBottomChildren.push(child);
} else {
onScreenChildren.push(child);
}
};
if (props.children) {
if (props.children.length) {
props.children.forEach(function (child) {
if (child) {
if (child.length > 0) {
child.forEach(handleChild);
} else {
handleChild(child);
}
}
});
} else {
handleChild(props.children);
}
}
this.firstLevelItems = onScreenChildren.slice();
var newState = {
persistentTopChildren: persistentTopChildren,
persistentBottomChildren: persistentBottomChildren,
onScreenChildren: onScreenChildren,
selectedKey: props.selectedKey
};
var selectedItemParentKey = this.itemKeyToParentKey[props.selectedKey];
if (selectedItemParentKey) {
this.setState(_objectSpread(_objectSpread({}, newState), {}, {
drivenInChildren: this.itemKeyToChildren[selectedItemParentKey].children,
lastSelectedKey: selectedItemParentKey
}, this._getInnerMenuCollapsibleState({
menuToClose: this.itemKeyToParentKey[this.props.selectedKey] || this.props.selctedKey,
menuToOpen: selectedItemParentKey,
selected: props.selectedKey
})));
} else {
var updateCollapsibleOnlyOnChange = true;
this.setState(_objectSpread(_objectSpread({}, newState), {}, {
drivenInChildren: []
}, this._getInnerMenuCloseState(props.selectedKey, updateCollapsibleOnlyOnChange)));
}
}
}, {
key: "render",
value: function render() {
var _this3 = this;
var _this$props = this.props,
isHidden = _this$props.isHidden,
skin = _this$props.skin;
var css = _objectSpread(_objectSpread({}, classes), this.props.classNames);
var sliderClasses = st(css.slider, {
skin: skin
}, this.state.drivenInChildren.length !== 0 && css.sliderOutToLeft, this.state.drivenInChildren.length === 0 && this.state.drivenOutChildren.length !== 0 && css.sliderInFromLeft);
var collapsibleSliderClasses = st(css.slider, {
skin: skin
});
var sliderOutToRightClasses = st(css.slider, {
skin: skin
}, !this.props.isHidden && css.sliderOutToRight);
var sliderInFromRightClasses = st(css.slider, {
skin: skin
}, !this.props.isHidden && css.sliderInFromRight);
var rootClasses = st(css.sideBar || classes.root, {
hidden: isHidden,
skin: skin
});
return /*#__PURE__*/React.createElement(WixStyleReactContext.Consumer, null, function (_ref) {
var sidebarExperimentCollapsible = _ref.sidebarExperimentCollapsible;
return /*#__PURE__*/React.createElement(SidebarContext.Provider, {
value: _this3.sidebarContext
}, /*#__PURE__*/React.createElement("div", {
className: rootClasses,
"data-hook": _this3.props.dataHook
}, _this3.state.persistentTopChildren, /*#__PURE__*/React.createElement("div", {
className: st(css.content)
}, !sidebarExperimentCollapsible && _this3.state.drivenInChildren.length === 0 && _this3.state.drivenOutChildren.length !== 0 && /*#__PURE__*/React.createElement("div", {
className: sliderOutToRightClasses,
"data-hook": dataHooks.drivenOutChildren
}, _this3.state.drivenOutChildren), /*#__PURE__*/React.createElement(SidebarContentWrapper, {
containerClasses: sidebarExperimentCollapsible ? collapsibleSliderClasses : sliderClasses,
skin: skin
}, sidebarExperimentCollapsible ? _this3.state.collapsibleOnScreenChildren : _this3.state.onScreenChildren), !sidebarExperimentCollapsible && _this3.state.drivenInChildren.length !== 0 && /*#__PURE__*/React.createElement(SidebarContentWrapper, {
key: "collapsiblle",
containerClasses: sliderInFromRightClasses,
containerDataHook: dataHooks.drivenInChildren,
skin: skin
}, _this3.state.drivenInChildren)), _this3.state.persistentBottomChildren));
});
}
}]);
return Sidebar;
}(Component);
_defineProperty(Sidebar, "displayName", 'Sidebar');
_defineProperty(Sidebar, "Item", SidebarItem);
_defineProperty(Sidebar, "PersistentHeader", SidebarPersistentHeader);
_defineProperty(Sidebar, "PersistentFooter", SidebarPersistentFooter);
_defineProperty(Sidebar, "BackButton", SidebarBackButton);
_defineProperty(Sidebar, "propTypes", {
/** classNames overrides */
classNames: PropTypes.shape({
sideBar: PropTypes.string,
content: PropTypes.string,
slider: PropTypes.string,
sliderOutToLeft: PropTypes.string,
sliderOutToRight: PropTypes.string,
sliderInFromLeft: PropTypes.string,
sliderInFromRight: PropTypes.string
}),
/** The dataHook of the Sidebar */
dataHook: PropTypes.string,
/** Sidebar menu children */
children: PropTypes.node,
/** Sidebar indicator for animating out or in */
isHidden: PropTypes.bool,
/** Sets the skin of the Sidebar */
skin: PropTypes.oneOf(['dark', 'light'])
});
_defineProperty(Sidebar, "defaultProps", {
skin: sidebarSkins.dark,
isHidden: false
});
export default Sidebar;