UNPKG

react-dyn-tabs

Version:
1,391 lines (1,354 loc) 48.6 kB
/** * react-dyn-tabs - React dynamic tabs with full API * * @version v6.2.2 * @homepage https://dev-javascript.github.io/react-dyn-tabs/ * @author dev-javascript javascript.code.dev@gmail.com * @license MIT */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react'), require('prop-types')) : typeof define === 'function' && define.amd ? define(['react', 'prop-types'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.useDynTabs = factory(global.React)); })(this, (function (React) { 'use strict'; var actions = { open: 'open', close: 'close', active: 'active', refresh: 'refresh', sort: 'sort' }; var counter = 1; var helper = { checkArrIndex: function checkArrIndex(index, arrLength) { return index >= 0 && index < arrLength; }, resolve: function resolve(result) { return Promise.resolve(result); }, getCopyState: function getCopyState(state) { return { selectedTabID: state.selectedTabID, openTabIDs: (state.openTabIDs || []).slice() }; }, assingAll: function assingAll(targetObj) { for (var _len = arguments.length, sourcObjs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { sourcObjs[_key - 1] = arguments[_key]; } // copy all enumerable and not enumerable properties into the target sourcObjs.forEach(function (sourcObj) { var enum_only = Object.keys(sourcObj); Object.getOwnPropertyNames(sourcObj).forEach(function (prop) { if (enum_only.indexOf(prop) >= 0) targetObj[prop] = sourcObj[prop];else Object.defineProperty(targetObj, prop, { value: sourcObj[prop], writable: true }); }); }); return targetObj; }, setNoneEnumProps: function setNoneEnumProps(obj, props) { var noneEnum = {}; Object.keys(props).forEach(function (prop) { noneEnum[prop] = { writable: true, value: props[prop] }; }); return Object.defineProperties(obj, noneEnum); }, getArraysDiff: function getArraysDiff(arr1, arr2) { var arr1Copy = [].concat(arr1), arr2Copy = [].concat(arr2); arr1.forEach(function (item) { if (arr2.indexOf(item) >= 0) { arr1Copy.splice(arr1Copy.indexOf(item), 1); arr2Copy.splice(arr2Copy.indexOf(item), 1); } }); return [arr1Copy, arr2Copy]; }, filterArrayUntilFirstValue: function filterArrayUntilFirstValue(arr, callback, isRightToLeft) { isRightToLeft && arr.reverse(); for (var i = 0, l = arr.length; i < l; i++) { if (callback(arr[i], i, arr)) return arr[i]; } return null; }, throwMissingParam: function throwMissingParam(FnName) { throw new Error("Missing parameter in \"" + FnName + "\" function"); }, thorwInvalidParam: function thorwInvalidParam(FnName) { throw new Error("Invalid parameter values passed to " + FnName + " function"); }, isObj: function isObj(obj) { return Object.prototype.toString.call(obj) === '[object Object]'; }, isArray: function isArray(arr) { return typeof arr === 'object' && arr.constructor === Array; }, module: function module(fn, obj, noneEnums) { return this.assingAll(fn.prototype, noneEnums ? this.setNoneEnumProps(obj, noneEnums) : obj).constructor; }, uuid: function uuid() { counter++; return "" + new Date().getTime() + Math.random() + counter; } }; function reducer(state, action) { switch (action.type) { case actions.close: { var arr = state.openTabIDs, removedItemIndex = arr.indexOf(action.tabId); if (removedItemIndex >= 0) { var newArr = arr.slice(); newArr.splice(removedItemIndex, 1); return { selectedTabID: state.selectedTabID, openTabIDs: newArr }; } return state; } case actions.open: { var _arr = state.openTabIDs, tabId = action.tabId; if (_arr.indexOf(tabId) === -1) { var _newArr = _arr.slice(); _newArr.push(tabId); return { selectedTabID: state.selectedTabID, openTabIDs: _newArr }; } return state; } case actions.refresh: return helper.getCopyState(state); case actions.active: { var _tabId = action.tabId; if (state.selectedTabID !== _tabId) return { selectedTabID: _tabId, openTabIDs: state.openTabIDs }; return state; } case actions.sort: { var _arr2 = state.openTabIDs, _newArr2 = action.tabId, newArrCount = _newArr2.length; if (_arr2.length !== newArrCount) return state; for (var i = 0; i < newArrCount; i++) { if (_arr2.indexOf(_newArr2[i]) === -1) return state; } return { selectedTabID: state.selectedTabID, openTabIDs: _newArr2 }; } default: throw new Error("Undefined action type '" + action.type + "'"); } } var missingParamEr$1 = helper.throwMissingParam, isArray = helper.isArray, thorwInvalidParam = helper.thorwInvalidParam; var apiConstructor = function apiConstructor(getDeps, param, modules, Components) { var _this = this; if (param === void 0) { param = { options: {} }; } if (modules === void 0) { modules = []; } var _getDeps$call = getDeps.call(this, param.options), optionsManager = _getDeps$call.optionsManager, helper = _getDeps$call.helper, activedTabsHistory = _getDeps$call.activedTabsHistory; helper.setNoneEnumProps(this, { optionsManager: optionsManager, helper: helper, activedTabsHistory: activedTabsHistory, userProxy: {} }); this._setUserProxy()._subscribeOnReadyEvent()._createReadyFunction()._subscribeSelectedTabsHistory()._subscribeCallbacksOptions(); modules.forEach(function (module) { return module(_this, Components); }); }; var _apiProps = { _setUserProxy: function _setUserProxy() { var _this2 = this; var userProxy = {}; var _loop = function _loop(prop) { if (prop[0] !== '_' && prop !== 'constructor') { (function (that) { var propValue = that[prop]; if (typeof propValue === 'function') { userProxy[prop] = function () { var result = propValue.apply(that, arguments); return result === that ? userProxy : result; }; } else { userProxy[prop] = propValue; } })(_this2); } }; for (var prop in this) { _loop(prop); } this.userProxy = userProxy; return this; }, _subscribeOnReadyEvent: function _subscribeOnReadyEvent() { var _this3 = this; this.one('_onReady', function () { _this3._isReady = true; }); return this; }, _createReadyFunction: function _createReadyFunction() { var _this4 = this; var ready = function ready(fn) { if (_this4._isReady === true) { fn.call(_this4.userProxy, _this4.userProxy); } else { _this4.one('_onReady', function () { fn.call(_this4.userProxy, _this4.userProxy); }); } }; ready = ready.bind(this); this.helper.setNoneEnumProps(this, { ready: ready }); return this; }, _subscribeSelectedTabsHistory: function _subscribeSelectedTabsHistory() { var _this5 = this; this.on('onChange', function (_ref) { var currentData = _ref.currentData, previousData = _ref.previousData, closedTabIDs = _ref.closedTabIDs; for (var i = 0, l = closedTabIDs.length; i < l; i++) { _this5.activedTabsHistory.remove(closedTabIDs[i]); } var isSwitched = previousData.selectedTabID !== currentData.selectedTabID; if (isSwitched && _this5.isOpen(previousData.selectedTabID) && !_this5.isSelected(previousData.selectedTabID)) _this5.activedTabsHistory.add(previousData.selectedTabID); }); return this; }, _subscribeCallbacksOptions: function _subscribeCallbacksOptions() { var _this6 = this; var op = this.optionsManager.options; Object.keys(this._publishers).forEach(function (eventName) { if (eventName[0] !== '_') _this6.on(eventName, function () { op[eventName].apply(this, arguments); }); }); return this; }, getOption: function getOption(name) { return this.optionsManager.getOption(name); }, setOption: function setOption(name, value) { this.optionsManager.setOption(name, value); return this; }, getPreviousData: function getPreviousData() { return this.helper.getCopyState(this.previousState); }, getCopyPerviousData: function getCopyPerviousData() { return this.getPreviousData(); }, getData: function getData() { return this.helper.getCopyState(this.stateRef); }, getCopyData: function getCopyData() { return this.getData(); }, isSelected: function isSelected(id) { if (id === void 0) { id = missingParamEr$1('isSelected'); } return this.stateRef.selectedTabID == id; }, isOpen: function isOpen(id) { if (id === void 0) { id = missingParamEr$1('isOpen'); } return this.stateRef.openTabIDs.indexOf(id) >= 0; }, _getFlushEffectsPromise: function _getFlushEffectsPromise() { var _this7 = this; return new Promise(function (resolve) { _this7.one('_onFlushEffects', function () { resolve.apply(this, arguments); }); }); }, select: function select(id) { if (id === void 0) { id = missingParamEr$1('select'); } if (id) id = id + ''; //make sure id is string var result = this._getFlushEffectsPromise(); this._select(id); return result; }, _getPreSelectedTabId: function _getPreSelectedTabId() { var selectedTabHistory = [].concat(this.activedTabsHistory.tabsId); var tabID = ''; while (!tabID && selectedTabHistory.length) { var _tabID = selectedTabHistory.pop(); if (_tabID) { var _tabData = this.getTab(_tabID); if (_tabData && !_tabData.disable && this.isOpen(_tabID) && !this.isSelected(_tabID)) tabID = _tabID; } } return tabID; }, _getPreSiblingTabId: function _getPreSiblingTabId() { var _this8 = this; var _this$stateRef = this.stateRef, selectedTabID = _this$stateRef.selectedTabID, openTabIDs = _this$stateRef.openTabIDs; var isRightToLeft = true; var arr = openTabIDs.slice(0, openTabIDs.indexOf(selectedTabID)); return this.helper.filterArrayUntilFirstValue(arr, function (id) { return !_this8.getTab(id).disable; }, isRightToLeft); }, _getNextSiblingTabId: function _getNextSiblingTabId() { var _this9 = this; var _this$stateRef2 = this.stateRef, selectedTabID = _this$stateRef2.selectedTabID, openTabIDs = _this$stateRef2.openTabIDs; var isRightToLeft = false; var arr = openTabIDs.slice(openTabIDs.indexOf(selectedTabID) + 1); return this.helper.filterArrayUntilFirstValue(arr, function (id) { return !_this9.getTab(id).disable; }, isRightToLeft); }, _findTabIdForSwitching: function _findTabIdForSwitching() { var tabId = ''; tabId = this._getPreSelectedTabId(); tabId = tabId || this._getPreSiblingTabId(); tabId = tabId || this._getNextSiblingTabId(); return tabId || ''; }, setTab: function setTab(id, newData) { if (newData === void 0) { newData = {}; } this.optionsManager.validateObjectiveTabData(newData).validatePanelComponent(newData); this._setTab(id, newData); return this; }, open: function open(tabObj) { if (tabObj === void 0) { tabObj = missingParamEr$1('open'); } var newTabObj = this.optionsManager.validateTabData(tabObj); var result = this._getFlushEffectsPromise(); this._addTab(newTabObj); this._open(newTabObj.id); return result; }, sort: function sort(tabIDs) { if (tabIDs === void 0) { tabIDs = missingParamEr$1('sort'); } if (!isArray(tabIDs)) { thorwInvalidParam('sort'); } var result = this._getFlushEffectsPromise(); this._sort(tabIDs); return result; }, __close: function __close(id) { var result = this._getFlushEffectsPromise(); this._close(id); this._removeTab(id); return result; }, close: function close(id, switching) { if (id === void 0) { id = missingParamEr$1('close'); } if (switching === void 0) { switching = true; } if (id) id = id + ''; //make sure id is string if (switching && this.isOpen(id) && this.isSelected(id)) { var _openTabsId = [].concat(this.stateRef.openTabIDs); _openTabsId.splice(_openTabsId.indexOf(id), 1); this.select(this._findTabIdForSwitching()); return this.__close(id); } else return this.__close(id); }, refresh: function refresh() { var result = this._getFlushEffectsPromise(); this._refresh(); return result; } }; helper.setNoneEnumProps(_apiProps, { onChange: function onChange(_ref2) { var _this10 = this; var newState = _ref2.newState, oldState = _ref2.oldState, closedTabIDs = _ref2.closedTabIDs, openedTabIDs = _ref2.openedTabIDs, isSwitched = _ref2.isSwitched; if (isSwitched || openedTabIDs.length || closedTabIDs.length) { this.trigger('onChange', this.userProxy, function () { return [{ currentData: _this10.helper.getCopyState(newState), previousData: _this10.helper.getCopyState(oldState), closedTabIDs: closedTabIDs.slice(), openedTabIDs: openedTabIDs.slice() }]; }); openedTabIDs.length && this.trigger('onOpen', this.userProxy, function () { return [openedTabIDs.slice()]; }); closedTabIDs.length && this.trigger('onClose', this.userProxy, function () { return [closedTabIDs.slice()]; }); if (isSwitched) { if (newState.selectedTabID && this.activedTabsHistory.tabsId.indexOf(newState.selectedTabID) === -1) { this.trigger('onFirstSelect', this.userProxy, function () { return [{ currentSelectedTabId: newState.selectedTabID, previousSelectedTabId: oldState.selectedTabID }]; }); } this.trigger('onSelect', this.userProxy, function () { return [{ currentSelectedTabId: newState.selectedTabID, previousSelectedTabId: oldState.selectedTabID }]; }); } } return this; }, eventHandlerFactory: function eventHandlerFactory(_ref3) { var e = _ref3.e, id = _ref3.id; var el = e.target, parentEl = el.parentElement, _this$optionsManager$ = this.optionsManager.setting, closeClass = _this$optionsManager$.closeClass, tabClass = _this$optionsManager$.tabClass; if (el.className.includes(closeClass) && parentEl && parentEl.lastChild && parentEl.lastChild == el && parentEl.className.includes(tabClass)) { this.getOption('beforeClose').call(this.userProxy, e, id) !== false && this.close(id, true); } else { this.getOption('beforeSelect').call(this.userProxy, e, id) !== false && this.select(id); } }, getSetting: function getSetting(settingName) { var st = this.optionsManager.setting; if (Object.prototype.hasOwnProperty.call(st, settingName)) { if (typeof st[settingName] === 'function') { return st[settingName].apply(st, Array.prototype.slice.call(arguments, 1)); } return st[settingName]; } } }); var apiProps = _apiProps; function _extends$3() { return _extends$3 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$3.apply(null, arguments); } var missingParamEr = helper.throwMissingParam, uuid = helper.uuid; var factory = helper.module(function (getDeps, _ref) { var options = _ref.options; var _getDeps = getDeps(), globalDefaultOptions = _getDeps.globalDefaultOptions; this._defaultOptions = globalDefaultOptions; this._validateOptions(options); this.options = Object.assign({}, this._defaultOptions, options); this.setting = {}; this.initialState = {}; this.initialTabs = []; this._setSetting()._setInitialData(); }, { getOption: function getOption(optionName) { if (optionName === 'tabs') { // returned result should be immutable var arr = []; for (var i = 0, tabs = this.options.tabs, l = tabs.length; i < l; i++) { arr.push(_extends$3({}, tabs[i])); } return arr; } return this.options[optionName]; }, setOption: function setOption(name, value) { if (name === void 0) { name = missingParamEr('setOption'); } if (value === void 0) { value = missingParamEr('setOption'); } if (['SELECTEDTABID', 'TABS'].indexOf(name.toUpperCase()) >= 0) return this; this.options[name] = value; return this; }, validatePanelComponent: function validatePanelComponent(tabData) { // convert panel element into a function component. if (tabData.panelComponent && typeof tabData.panelComponent !== 'function' && /*#__PURE__*/React.isValidElement(tabData.panelComponent)) { var PanelElement = tabData.panelComponent; tabData.panelComponent = function () { return PanelElement; }; } return this; }, validateObjectiveTabData: function validateObjectiveTabData(tabData) { if (Object.prototype.toString.call(tabData) !== '[object Object]') throw new Error('tabData must be type of Object'); return this; }, validateTabData: function validateTabData(tabData) { this.validateObjectiveTabData(tabData).validatePanelComponent(tabData); tabData = Object.assign(this.setting.getDefaultTabData(), tabData); tabData.id = tabData.id + ''; //make sure id is string return tabData; }, _validateOptions: function _validateOptions(options) { if (Object.prototype.toString.call(options) !== '[object Object]') throw 'Invalid argument in "useDynamicTabs" function. Argument must be type of an object'; return this; }, _setInitialData: function _setInitialData() { var _this = this; // set this.initialTabs and this.initialState var _this$options = this.options, selectedTabID = _this$options.selectedTabID, tabs = _this$options.tabs, openTabIDs = []; tabs.forEach(function (tab) { var newTab = _this.validateTabData(tab); _this.initialTabs.push(newTab); openTabIDs.push(newTab.id); }); this.initialState = { selectedTabID: selectedTabID + '', //make sure it is type of string openTabIDs: openTabIDs }; return this; }, _setSetting: function _setSetting() { var _this2 = this; this.setting = { tabClass: 'rc-dyn-tabs-tab', titleClass: 'rc-dyn-tabs-title', iconClass: 'rc-dyn-tabs-icon', selectedClass: 'rc-dyn-tabs-selected', hoverClass: 'rc-dyn-tabs-hover', closeClass: 'rc-dyn-tabs-close', panelClass: 'rc-dyn-tabs-panel', panellistClass: 'rc-dyn-tabs-panellist', disableClass: 'rc-dyn-tabs-disable', ltrClass: 'rc-dyn-tabs-ltr', rtlClass: 'rc-dyn-tabs-rtl', verticalClass: 'rc-dyn-tabs-vertical', tablistViewClass: 'rc-dyn-tabs-tablist-view', tablistContainerClass: 'rc-dyn-tabs-tablist-container', tablistOverflowClass: 'rc-dyn-tabs-tablist-overflow', tablistClass: 'rc-dyn-tabs-tablist', panelIdTemplate: function panelIdTemplate(id) { return "rc-dyn-tabs-p-" + id; }, ariaLabelledbyIdTemplate: function ariaLabelledbyIdTemplate(id) { return "rc-dyn-tabs-l-" + id; }, getDefaultTabData: function getDefaultTabData() { return { title: '', tooltip: '', panelComponent: _this2.options.defaultPanelComponent, closable: true, iconClass: '', disable: false, lazy: false, id: "tab_" + uuid() }; } }; return this; } }); var DefaulTabInner = function DefaulTabInner(props) { return /*#__PURE__*/React.createElement("button", props.tabProps, props.children, Object.prototype.hasOwnProperty.call(props, 'iconProps') && /*#__PURE__*/React.createElement("span", props.iconProps)); }; /* eslint react/prop-types: 0 */ var DefaultOptions = helper.module(function (DefaulTabInnerComponent) { if (DefaulTabInnerComponent === void 0) { DefaulTabInnerComponent = null; } this.defaultDirection = 'ltr'; this._DefaulTabInnerComponent = DefaulTabInnerComponent; this.directionsRange = ['ltr', 'rtl']; }, { getOptions: function getOptions() { return this._getOptions(); }, _getOptions: function _getOptions() { var _options = { tabs: [], selectedTabID: '', theme: 'all-themes', tablistStyle: {}, beforeSelect: function beforeSelect() { return true; }, beforeClose: function beforeClose() { return true; }, onOpen: function onOpen() {}, onClose: function onClose() {}, onFirstSelect: function onFirstSelect() {}, onSelect: function onSelect() {}, onChange: function onChange() {}, onLoad: function onLoad() {}, onDestroy: function onDestroy() {}, onInit: function onInit() {}, accessibility: true, isVertical: false, defaultPanelComponent: function defaultPanelComponent() { return /*#__PURE__*/React.createElement("div", null); } }; var _direction = this.defaultDirection, _tabComponent = this._DefaulTabInnerComponent; var that = this; Object.defineProperties(_options, { direction: { get: function get() { return _direction; }, set: function set(value) { if (that.directionsRange.indexOf(value) === -1) throw 'Invalid direction value! it can be eather of "ltr" or "rtl" '; _direction = value; }, enumerable: true }, tabComponent: { get: function get() { return _tabComponent; }, set: function set(fn) { if (fn && typeof fn !== 'function') throw 'tabComponent property must be type of a function.'; _tabComponent = fn ? fn : that._DefaulTabInnerComponent; }, enumerable: true } }); return _options; } }); var getDeps$2 = function getDeps() { var op = new DefaultOptions(DefaulTabInner); return { globalDefaultOptions: op.getOptions() }; }; var OptionManager = factory.bind(null, getDeps$2); var ActivedTabsHistory = helper.module(function () { this.tabsId = []; }, { reset: function reset() { this.tabsId = []; }, add: function add(id) { if (id) this.tabsId.push(id); }, remove: function remove(id) { var tabIDs = this.tabsId; while (tabIDs.indexOf(id) >= 0) { tabIDs.splice(tabIDs.indexOf(id), 1); } return this; } }); var Pub_Sub = helper.module(function () { this._publishers = { onChange: [], onLoad: [], onDestroy: [], onOpen: [], onClose: [], onSelect: [], onInit: [], _onFlushEffects: [], _onReady: [], onFirstSelect: [] }; }, { //unSubscribe off: function off(publisherName, fn) { if (typeof fn === 'function' && Object.prototype.hasOwnProperty.call(this._publishers, publisherName)) { var _index = this._publishers[publisherName].indexOf(fn); _index >= 0 && this._publishers[publisherName].splice(_index, 1); } return this; }, //subscribe on: function on(publisherName, fn) { if (typeof fn === 'function' && Object.prototype.hasOwnProperty.call(this._publishers, publisherName)) { // check if it has not existed if (this._publishers[publisherName].indexOf(fn) === -1) { this._publishers[publisherName].push(fn); } } return this; }, //oneSubscribe one: function one(publisherName, fn) { if (typeof fn === 'function' && Object.prototype.hasOwnProperty.call(this._publishers, publisherName)) { var _fn = function _fn() { fn.apply(this, arguments); this.off(publisherName, _fn); }; return this.on(publisherName, _fn); } return this; } }, { trigger: function trigger(publisherName, context, generateParamsCallback) { if (generateParamsCallback === void 0) { generateParamsCallback = function generateParamsCallback() { return []; }; } context = context || null; var result = []; var _subscribers = [].concat(this._publishers[publisherName]); _subscribers.forEach(function (subscriber) { result.push(subscriber.apply(context, generateParamsCallback())); }); return result; } }); var BaseApi = helper.module(function (_ref) { var helper = _ref.helper, initialState = _ref.initialState; this._helper = helper; this._dispatch = null; this._setFlushState = null; this._isReady = false; helper.setNoneEnumProps(this, { state: this._helper.getCopyState(initialState), // it will be updated after each render forceUpdateState: {}, previousState: this._helper.getCopyState(initialState), // it is a previous value of this.state stateRef: {} // have a same reference with state . It will be updated in each execution of useDynamicTabs.js }); }, { _select: function _select(tabId) { this._dispatch({ type: actions.active, tabId: tabId }); this.__flushEffects(); }, _close: function _close(tabId) { this._dispatch({ type: actions.close, tabId: tabId }); this.__flushEffects(); }, _open: function _open(tabId) { this._dispatch({ type: actions.open, tabId: tabId }); this.__flushEffects(); }, _refresh: function _refresh() { this.forceUpdateState = {}; this._dispatch({ type: actions.refresh }); this.__flushEffects(); }, _sort: function _sort(tabId) { this._dispatch({ type: actions.sort, tabId: tabId }); this.__flushEffects(); }, __flushEffects: function __flushEffects() { this._setFlushState({}); } }, { updateStateRef: function updateStateRef(state, dispatch) { this.stateRef = state; this._dispatch = dispatch; return this; }, updateState: function updateState(state) { this.previousState = this._helper.getCopyState(this.state); this.state = this._helper.getCopyState(state); return this; }, updateFlushState: function updateFlushState(setFlushState) { this._setFlushState = setFlushState; return this; } }); var Tabs$1 = helper.module(function Tabs(_temp) { var _this = this; var _ref = _temp === void 0 ? { initialTabs: [] } : _temp, initialTabs = _ref.initialTabs; this._data = []; if (initialTabs && initialTabs.constructor === Array && initialTabs.length) { initialTabs.forEach(function (tab) { _this._addTab(tab); }); } }, { _addTab: function _addTab(tabObj) { this._data.push(tabObj); return this; }, _removeTab: function _removeTab(id) { var delIndex = this._data.findIndex(function (tab) { return tab.id === id; }); delIndex >= 0 && this._data.splice(delIndex, 1); return this; }, getTab: function getTab(id) { return this._data.find(function (tab) { return tab.id === id; }); }, _setTab: function _setTab(id, newData) { var _index = this._data.findIndex(function (tab) { return tab.id == id; }); if (_index >= 0) { var oldData = this._data[_index]; newData.id = oldData.id; // id can not be changed. Object.assign(this._data[_index], newData); } return this; } }); var getDeps$1 = function getDeps(options) { if (options === void 0) { options = {}; } var activedTabsHistory = new ActivedTabsHistory(), optionsManager = new OptionManager({ options: options }); BaseApi.call(this, { helper: helper, initialState: optionsManager.initialState }); Tabs$1.call(this, { initialTabs: optionsManager.initialTabs }); Pub_Sub.call(this); return { activedTabsHistory: activedTabsHistory, helper: helper, optionsManager: optionsManager }; }; apiConstructor.prototype = Object.create(BaseApi.prototype); var Api = (helper.assingAll(apiConstructor.prototype, Tabs$1.prototype, Pub_Sub.prototype, apiProps).constructor = apiConstructor).bind(null, getDeps$1); function _extends$2() { return _extends$2 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$2.apply(null, arguments); } function useDynamicTabs$1(getDeps, options, modules) { if (options === void 0) { options = {}; } var _getDeps = getDeps(), reducer = _getDeps.reducer, getApiInstance = _getDeps.getApiInstance, ApiContext = _getDeps.ApiContext, StateContext = _getDeps.StateContext, ForceUpdateContext = _getDeps.ForceUpdateContext, Components = _getDeps.Components; var ref = React.useRef(null); if (ref.current === null) { ref.current = { Components: _extends$2({}, Components), TabListComponent: null, PanelListComponent: null }; ref.current.api = getApiInstance(options, modules, ref.current.Components); } var api = ref.current.api, _ref = ref.current, _useReducer = React.useReducer(reducer, api.optionsManager.initialState), state = _useReducer[0], dispatch = _useReducer[1], _useState = React.useState({}), flushState = _useState[0], setFlushState = _useState[1]; api.updateStateRef(state, dispatch).updateFlushState(setFlushState); React.useLayoutEffect(function () { api.updateState(state); }, [state]); React.useLayoutEffect(function () { api.trigger('onLoad', api.userProxy); return function () { api.trigger('onDestroy', api.userProxy); }; }, []); React.useLayoutEffect(function () { api.trigger('onInit', api.userProxy); }); React.useLayoutEffect(function () { api.trigger('_onReady', api.userProxy); }, []); React.useLayoutEffect(function () { var oldState = api.previousState, _api$helper$getArrays = api.helper.getArraysDiff(state.openTabIDs, oldState.openTabIDs), openedTabIDs = _api$helper$getArrays[0], closedTabIDs = _api$helper$getArrays[1], isSwitched = oldState.selectedTabID !== state.selectedTabID; api.onChange({ newState: state, oldState: oldState, closedTabIDs: closedTabIDs, openedTabIDs: openedTabIDs, isSwitched: isSwitched }); }, [state]); React.useLayoutEffect(function () { api.trigger('_onFlushEffects', api.userProxy, function () { return [{ currentData: api.getData(), instance: api.userProxy }]; }); }, [flushState]); if (!_ref.TabListComponent) _ref.TabListComponent = function TabListComponent(props) { if (props === void 0) { props = {}; } return /*#__PURE__*/React.createElement(ApiContext.Provider, { value: api }, /*#__PURE__*/React.createElement(StateContext.Provider, { value: api.stateRef }, /*#__PURE__*/React.createElement(ForceUpdateContext.Provider, { value: api.forceUpdateState }, /*#__PURE__*/React.createElement(_ref.Components.TablistView, null, /*#__PURE__*/React.createElement(_ref.Components.TablistContainer, null, /*#__PURE__*/React.createElement(_ref.Components.TablistOverflow, null, /*#__PURE__*/React.createElement(_ref.Components.TabList, props))), props.children)))); }; if (!_ref.PanelListCompoent) _ref.PanelListCompoent = function PanelListCompoent(props) { return /*#__PURE__*/React.createElement(ApiContext.Provider, { value: api }, /*#__PURE__*/React.createElement(StateContext.Provider, { value: api.stateRef }, /*#__PURE__*/React.createElement(ForceUpdateContext.Provider, { value: api.forceUpdateState }, /*#__PURE__*/React.createElement(Components.PanelList, props, "props.children")))); }; return [_ref.TabListComponent, _ref.PanelListCompoent, api.ready]; } var ApiContext = /*#__PURE__*/React.createContext({}); var StateContext = /*#__PURE__*/React.createContext({}); var ForceUpdateContext = /*#__PURE__*/React.createContext({}); function TabList(deps, props, ref) { var state = React.useContext(StateContext); var _deps = deps(React.useContext(ApiContext)), Tabs = _deps.Tabs, tablistPropsManager = _deps.tablistPropsManager; return /*#__PURE__*/React.createElement(Tabs, tablistPropsManager(ref, state)); } function _extends$1() { return _extends$1 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$1.apply(null, arguments); } function TabsComponent(deps, props, ref) { var openTabIDs = props.openTabIDs, selectedTabID = props.selectedTabID; var _deps = deps(React.useContext(ApiContext)), TabsPropsManager = _deps.TabsPropsManager, Tab = _deps.Tab; return /*#__PURE__*/React.createElement("ul", _extends$1({}, TabsPropsManager(props), { ref: ref || null }), openTabIDs.map(function (id) { return /*#__PURE__*/React.createElement(Tab, { key: id, id: id, selectedTabID: selectedTabID }); })); } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } var TabComponent = function TabComponent(deps, props) { React.useContext(ForceUpdateContext); var api = React.useContext(ApiContext); var _deps = deps(api), tabPropsManager = _deps.tabPropsManager, tabInnerPropsManager = _deps.tabInnerPropsManager, closeIconPropsManager = _deps.closeIconPropsManager; var id = props.id; props.selectedTabID; var TabInnerComponent = api.getOption('tabComponent'), tabObj = api.getTab(id), clkHandler = function clkHandler(e) { api.eventHandlerFactory({ e: e, id: id }); }; return /*#__PURE__*/React.createElement("li", _extends({}, tabPropsManager(props), { onClick: function onClick(e) { clkHandler(e); } }), /*#__PURE__*/React.createElement(TabInnerComponent, tabInnerPropsManager(props), tabObj.title), tabObj.closable ? /*#__PURE__*/React.createElement("span", closeIconPropsManager(), "\xD7") : null); }; var memomizeTabComponent = (function (TabComponent) { return /*#__PURE__*/React.memo(TabComponent, function (oldProps, newProps) { var id = oldProps.id, oldActiveId = oldProps.selectedTabID, newActiveId = newProps.selectedTabID; return oldActiveId === newActiveId || id !== oldActiveId && id !== newActiveId; }); }); var _tabPropsManager = function tabPropsManager(ins, props) { var id = props.id, selectedTabID = props.selectedTabID; var isSelected = selectedTabID === id; var _ins$getTab = ins.getTab(id), disable = _ins$getTab.disable, title = _ins$getTab.title, tooltip = _ins$getTab.tooltip; var outputProps = { 'tab-id': id, className: ins.getSetting('tabClass'), tabIndex: -1, title: tooltip || title }; //check if tab is selected if (isSelected) { outputProps.tabIndex = 0; outputProps.className += ' ' + ins.getSetting('selectedClass'); } // check if tab is disable if (disable) { outputProps.tabIndex = -1; outputProps.className += ' ' + ins.getSetting('disableClass'); } // check if accessibility option is enable if (ins.getOption('accessibility')) { outputProps.role = 'tab'; outputProps.id = ins.getSetting('ariaLabelledbyIdTemplate', id); outputProps['aria-controls'] = ins.getSetting('panelIdTemplate', id); outputProps['aria-label'] = tooltip || title; outputProps['aria-selected'] = outputProps['aria-expanded'] = isSelected; } return outputProps; }; var _tabInnerPropsManager = function tabInnerPropsManager(ins, props) { var id = props.id, selectedTabID = props.selectedTabID; var isSelected = selectedTabID == id; var _ins$getTab2 = ins.getTab(id), iconClass = _ins$getTab2.iconClass; var outputProps = { id: id, isSelected: isSelected, api: ins.userProxy, tabProps: { 'tab-id': id, className: ins.getSetting('titleClass'), tabIndex: -1, role: 'presentation' } }; // check if there is a iconClass option if (iconClass) { outputProps.iconProps = { className: ins.getSetting('iconClass') + ' ' + iconClass, role: 'presentation' }; } return outputProps; }; var _closeIconPropsManager = function closeIconPropsManager(ins) { var outputProps = { className: ins.getSetting('closeClass') }; // check if accessibility option is enable if (ins.getOption('accessibility')) { outputProps.role = 'button'; } return outputProps; }; var memomizeTab = memomizeTabComponent; var Tab = memomizeTabComponent(TabComponent.bind(undefined, function (ins) { return { tabPropsManager: function tabPropsManager(props) { return _tabPropsManager(ins, props); }, tabInnerPropsManager: function tabInnerPropsManager(props) { return _tabInnerPropsManager(ins, props); }, closeIconPropsManager: function closeIconPropsManager() { return _closeIconPropsManager(ins); } }; })); var _TabsPropsManager = function TabsPropsManager(ins, props) { var dir = props.dir, isVertical = props.isVertical; var result = { className: ins.getSetting('tablistClass') + ' ' + ins.getSetting(dir + "Class") }; if (isVertical) { result.className += ' ' + ins.getSetting('verticalClass'); } if (ins.getOption('accessibility')) { result.role = 'tablist'; } return result; }; var Tabs = /*#__PURE__*/React.forwardRef(TabsComponent.bind(undefined, function (ins) { return { Tab: Tab, TabsPropsManager: function TabsPropsManager(props) { return _TabsPropsManager(ins, props); } }; })); var _tablistPropsManager = function tablistPropsManager(ins, ref, state) { var openTabIDs = state.openTabIDs, selectedTabID = state.selectedTabID; return { openTabIDs: openTabIDs, selectedTabID: selectedTabID, ref: ref, dir: ins.getOption('direction'), isVertical: ins.getOption('isVertical') }; }; var MemomizedTabList = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef(TabList.bind(undefined, function (ins) { return { Tabs: Tabs, tablistPropsManager: function tablistPropsManager(ref, state) { return _tablistPropsManager(ins, ref, state); } }; })), function () { return true; }); function panelPropsManager (_ref) { var isSelected = _ref.isSelected, api = _ref.api, id = _ref.id; var op = api.optionsManager.options, setting = api.optionsManager.setting, result = { 'tab-id': id, className: setting.panelClass }; // check if it is selected if (isSelected) { result.className += " " + setting.selectedClass; } // check if accessibility is enable if (op.accessibility) { result.role = 'tabpanel'; result.id = setting.panelIdTemplate(id); result['aria-hidden'] = isSelected ? false : true; result['aria-labelledby'] = setting.ariaLabelledbyIdTemplate(id); } return result; } var PanelComponent = function PanelComponent(props) { React.useContext(ForceUpdateContext); var id = props.id, selectedTabID = props.selectedTabID, api = React.useContext(ApiContext), isSelected = id === selectedTabID, panelProps = panelPropsManager({ isSelected: isSelected, api: api, id: id }), previousSelectedTabID = api.state.selectedTabID, _api$getTab = api.getTab(id), PanelComponent = _api$getTab.panelComponent, lazy = _api$getTab.lazy; var hasBeenSelected = false; if (!lazy || isSelected || previousSelectedTabID === id || api.activedTabsHistory.tabsId.indexOf(id) >= 0) { hasBeenSelected = true; } return /*#__PURE__*/React.createElement("div", panelProps, hasBeenSelected ? PanelComponent ? /*#__PURE__*/React.createElement(PanelComponent, { id: id, isSelected: isSelected, api: api.userProxy }) : null : null); }; var Panel = /*#__PURE__*/React.memo(PanelComponent, function (oldProps, newProps) { var id = oldProps.id, oldActiveId = oldProps.selectedTabID, newActiveId = newProps.selectedTabID; return oldActiveId === newActiveId || id !== oldActiveId && id !== newActiveId; }); var PanelList = /*#__PURE__*/React.memo(function PanelList() { var _React$useContext = React.useContext(StateContext), openTabIDs = _React$useContext.openTabIDs, selectedTabID = _React$useContext.selectedTabID, api = React.useContext(ApiContext), setting = api.optionsManager.setting, options = api.optionsManager.options; var className = setting.panellistClass + ' ' + setting[options.direction + 'Class']; if (options.isVertical) { className += ' ' + setting.verticalClass; } return /*#__PURE__*/React.createElement("div", { className: className }, openTabIDs.map(function (id) { return /*#__PURE__*/React.createElement(Panel, { key: id, id: id, selectedTabID: selectedTabID }); })); }, function () { return true; }); function TablistView$1(deps, props) { var _deps = deps(React.useContext(ApiContext)), tablistViewPropsManager = _deps.tablistViewPropsManager; return /*#__PURE__*/React.createElement("div", tablistViewPropsManager(), props.children); } var _tablistViewPropsManager = function tablistViewPropsManager(ins) { var className = ins.getSetting('tablistViewClass') + ' ' + ins.getSetting(ins.getOption('direction') + "Class"); if (ins.getOption('isVertical')) { className += ' ' + ins.getSetting('verticalClass'); } var themeName = ins.getOption('theme'); if (themeName) { className += ' ' + themeName; } var tablistStyle = ins.getOption('tablistStyle') || {}; var result = { className: className }; if (typeof tablistStyle === 'object') { result.style = tablistStyle; } return result; }; var TablistView = TablistView$1.bind(undefined, function (ins) { return { tablistViewPropsManager: function tablistViewPropsManager() { return _tablistViewPropsManager(ins); } }; }); function TablistContainer$1(deps, props) { var _deps = deps(React.useContext(ApiContext)), tablistContainerPropsManager = _deps.tablistContainerPropsManager; return /*#__PURE__*/React.createElement("div", tablistContainerPropsManager(), props.children); } var _tablistContainerPropsManager = function tablistContainerPropsManager(ins) { var className = ins.getSetting('tablistContainerClass'); return { className: className }; }; var TablistContainer = TablistContainer$1.bind(undefined, function (ins) { return { tablistContainerPropsManager: function tablistContainerPropsManager() { return _tablistContainerPropsManager(ins); } }; }); var useApi = function useApi() { return React.useContext(ApiContext); }; var useRootState = function useRootState() { return React.useContext(StateContext); }; var useForceUpdate = function useForceUpdate() { return React.useContext(ForceUpdateContext); }; function TablistOverflow$1(deps, props) { var _deps = deps(useApi()), tablistOverflowPropsManager = _deps.tablistOverflowPropsManager; return /*#__PURE__*/React.createElement("div", tablistOverflowPropsManager(), props.children); } var _tablistOverflowPropsManager = function tablistOverflowPropsManager(ins) { return { style: { overflow: 'visible' }, className: ins.getSetting('tablistOverflowClass') }; }; var TablistOverflow = TablistOverflow$1.bind(undefined, function (ins) { return { tablistOverflowPropsManager: function tablistOverflowPropsManager() { return _tablistOverflowPropsManager(ins); } }; }); var Components = { TablistView: TablistView, tablistViewPropsManager: _tablistViewPropsManager, TablistViewFactory: TablistView$1, TablistContainer: TablistContainer, tablistContainerPropsManager: _tablistContainerPropsManager, TablistContainerFactory: TablistContainer$1, TablistOverflow: TablistOverflow, TablistOverflowFactory: TablistOverflow$1, tablistOverflowPropsManager: _tablistOverflowPropsManager, TabList: MemomizedTabList, tablistPropsManager: _tablistPropsManager, TabListFactory: TabList, Tabs: Tabs, TabsPropsManager: _TabsPropsManager, TabsFactory: TabsComponent, Tab: Tab, tabPropsManager: _tabPropsManager, tabInnerPropsManager: _tabInnerPropsManager, closeIconPropsManager: _closeIconPropsManager, memomizeTab: memomizeTab, TabFactory: TabComponent, PanelList: PanelList, useApi: useApi, useRootState: useRootState, useForceUpdate: useForceUpdate }; var getDeps = function getDeps() { var getApiInstance = function getApiInstance(options, modules, Components) { return new Api({ options: options }, modules, Components); }; return { reducer: reducer, getApiInstance: getApiInstance, ApiContext: ApiContext, StateContext: StateContext, ForceUpdateContext: ForceUpdateContext, Components: Components }; }; var useDynamicTabs = useDynamicTabs$1.bind(null, getDeps); return useDynamicTabs; })); //# sourceMappingURL=react-dyn-tabs.umd.js.map