|
1 | 1 | import ElManagement from './distanceFromFactory.js';
|
2 |
| -/** |
3 |
| - * |
4 |
| - * @param {Object} options |
5 |
| - * @param {HTMLElement} options.containerElement - the first ancestor of the Tablist element which has a hidden overflow |
6 |
| - * @param {HTMLElement} options.buttonElement - should be next sibling element of the Tablist element |
7 |
| - * @param {String} [options.tabDisplay="flex"] - default value is "inline-flex". would be display of li tag |
8 |
| - * @param {String} [options.containerDisplay="flex"] - default value is "inline-flex". would be display of containerElement |
9 |
| - */ |
10 |
| -const Api = function (options = {}) { |
11 |
| - this._setOptions(options); |
12 |
| - this._tablistEl = null; |
13 |
| - this._getElManagementIns = (param) => new ElManagement(param); |
14 |
| - this._tabs = null; |
15 |
| - this._tabsCount = null; |
16 |
| - this._setEls(); |
17 |
| -}; |
18 |
| -Api.prototype = { |
19 |
| - _setOptions: function (options) { |
20 |
| - this._options = Object.assign( |
21 |
| - {}, |
22 |
| - {containerDisplay: 'flex', tabDisplay: 'flex', buttonElement: null, containerElement: null}, |
23 |
| - options, |
24 |
| - ); |
25 |
| - }, |
26 |
| - _setEls: function () { |
27 |
| - this._tablistEl = this._options.buttonElement.previousElementSibling; |
28 |
| - this._tablistEl.style.overflow = 'visible'; |
29 |
| - this._options.containerElement.style.overflow = 'hidden'; |
30 |
| - return this; |
31 |
| - }, |
32 |
| - _showBtn: function () { |
33 |
| - this._options.buttonElement.style.opacity = 1; |
34 |
| - this._options.buttonElement.style.position = 'relative'; |
35 |
| - this._options.buttonElement.style.pointerEvents = 'all'; |
36 |
| - }, |
37 |
| - _hideBtn: function () { |
38 |
| - this._options.buttonElement.style.opacity = 0; |
39 |
| - this._options.buttonElement.style.position = 'absolute'; |
40 |
| - this._options.buttonElement.style.pointerEvents = 'none'; |
41 |
| - }, |
42 |
| - _checkOverflow: function (lastTab) { |
43 |
| - return this.els.getDistance(lastTab).value < 0; |
44 |
| - }, |
45 |
| - _showAll: function () { |
46 |
| - this._options.containerElement.style.display = 'none'; |
47 |
| - const tabDisplay = this._options.tabDisplay; |
48 |
| - for (let i = 0, tabs = this._tablistEl.children, tabsCount = tabs.length; i < tabsCount; i++) { |
49 |
| - tabs[i].style.display = tabDisplay; |
50 |
| - } |
51 |
| - this._hideBtn(); |
52 |
| - this._options.containerElement.style.display = this._options.containerDisplay; |
53 |
| - }, |
54 |
| - _hideTabs: function (firstHiddenTabIndex, selectedTabInfo, includeSelectedTab) { |
55 |
| - const hiddenTabs = []; |
56 |
| - this._options.containerElement.style.display = 'none'; |
57 |
| - const {index: selectedTabIndex} = selectedTabInfo; |
58 |
| - for (let i = firstHiddenTabIndex, tabsCount = this._tabsCount; i < tabsCount; i++) { |
59 |
| - if (includeSelectedTab || i !== selectedTabIndex) { |
60 |
| - this._tabs[i].style.display = 'none'; |
61 |
| - hiddenTabs.push({el: this._tabs[i], index: i}); |
62 |
| - } |
63 |
| - } |
64 |
| - this._showBtn(); |
65 |
| - this._options.containerElement.style.display = this._options.containerDisplay; |
66 |
| - return hiddenTabs; |
67 |
| - }, |
68 |
| - _getSelectedTabInfo: function (tabs, selectedTabIndex) { |
69 |
| - const index = selectedTabIndex; |
70 |
| - const el = index >= 0 ? tabs[index] : null; |
71 |
| - const overflow = el |
72 |
| - ? this.els.getDistance(el).sub(this.els.getEl(this._options.buttonElement).getFullSize()).value <= 0 |
73 |
| - : false; |
74 |
| - const overflowFullSize = overflow ? this.els.getEl(el).getFullSize() : 0; |
75 |
| - return {index, overflowFullSize}; |
76 |
| - }, |
77 |
| - _validateTabsCount: function () { |
78 |
| - this._tabs = this._tablistEl.children; |
79 |
| - this._tabsCount = this._tabs.length; |
80 |
| - return this._tabsCount ? true : false; |
81 |
| - }, |
82 |
| - /** |
83 |
| - * |
84 |
| - * @param {Number} selectedTabIndex |
85 |
| - * @param {"ltr"|"rtl"} [direction="ltr"] |
86 |
| - * @param {Boolean} [isVertical=false] |
87 |
| - * @returns {Array.<{el: HTMLElement , index: Number}>} |
88 |
| - */ |
89 |
| - resize: function (selectedTabIndex = '', direction = 'ltr', isVertical = false) { |
90 |
| - if (this._validateTabsCount() === false) { |
91 |
| - return []; |
92 |
| - } |
93 |
| - this._showAll(); |
94 |
| - this.els = this._getElManagementIns({ |
95 |
| - baseEl: this._options.containerElement, |
96 |
| - isVertical, |
97 |
| - dir: direction, |
98 |
| - }); |
99 |
| - const _lastTab = this._tabs[this._tabsCount - 1]; |
100 |
| - if (this._checkOverflow(_lastTab) === false) { |
101 |
| - return []; |
102 |
| - } |
103 |
| - const selectedTabInfo = this._getSelectedTabInfo(this._tabs, selectedTabIndex); |
104 |
| - return this._validateSliderMinSize(selectedTabInfo) |
105 |
| - ? this._hideTabs( |
106 |
| - this._findFirstHiddenTabIndexFactory( |
107 |
| - selectedTabInfo, |
108 |
| - this._getSearchBoundries(selectedTabInfo), |
109 |
| - this._getOrder(_lastTab), |
110 |
| - ), |
111 |
| - selectedTabInfo, |
112 |
| - ) |
113 |
| - : this._hideTabs(0, selectedTabInfo, true); |
114 |
| - }, |
115 |
| - _validateSliderMinSize: function (selectedTabInfo) { |
116 |
| - //the slider's size should greater than size of selected tab + more button |
117 |
| - return selectedTabInfo.overflowFullSize + this.els.getEl(this._options.buttonElement).getFullSize() >= |
118 |
| - this.els.getEl(this._options.containerElement).getSize() |
119 |
| - ? false |
120 |
| - : true; |
121 |
| - }, |
122 |
| - _getOrder: function (lastTab) { |
123 |
| - return Math.abs(this.els.getDistance(lastTab).value) > this.els.getEl(this._options.containerElement).getSize() |
124 |
| - ? 'asc' |
125 |
| - : 'desc'; |
126 |
| - }, |
127 |
| - _getSearchBoundries: function (selectedTabInfo) { |
128 |
| - const {overflowFullSize, index: pivotIndex} = selectedTabInfo; |
129 |
| - //if selected tab is not existed |
130 |
| - if (pivotIndex < 0) { |
131 |
| - return [0, this._tabsCount - 2]; |
132 |
| - } |
133 |
| - const isSelectedTabOverflow = overflowFullSize > 0; |
134 |
| - return isSelectedTabOverflow ? [0, pivotIndex - 1] : [pivotIndex + 1, this._tabsCount - 2]; |
135 |
| - }, |
136 |
| - _getTabDis: function (selectedTabInfo, el) { |
137 |
| - return this.els |
138 |
| - .getDistance(el) |
139 |
| - .sub(selectedTabInfo.overflowFullSize) |
140 |
| - .sub(this.els.getEl(this._options.buttonElement).getFullSize()); |
141 |
| - }, |
142 |
| - _findFirstHiddenTabIndexDSCE: function (selectedTabInfo, start, stop) { |
143 |
| - let value = this._tabsCount - 1; |
144 |
| - for (let i = stop; i >= start; i--) { |
145 |
| - if (this._getTabDis(selectedTabInfo, this._tabs[i]).value <= 0) { |
146 |
| - value = i; |
147 |
| - } else { |
148 |
| - break; |
149 |
| - } |
150 |
| - } |
151 |
| - return value; |
152 |
| - }, |
153 |
| - _findFirstHiddenTabIndexASC: function (selectedTabInfo, start, stop) { |
154 |
| - for (let i = start; i <= stop; i++) { |
155 |
| - if (this._getTabDis(selectedTabInfo, this._tabs[i]).value <= 0) { |
156 |
| - return i; |
157 |
| - } |
158 |
| - } |
159 |
| - return this._tabsCount - 1; |
160 |
| - }, |
161 |
| - _findFirstHiddenTabIndexFactory: function (selectedTabInfo, [start, stop], order) { |
162 |
| - return order === 'asc' |
163 |
| - ? this._findFirstHiddenTabIndexASC(selectedTabInfo, start, stop) |
164 |
| - : this._findFirstHiddenTabIndexDSCE(selectedTabInfo, start, stop); |
165 |
| - }, |
166 |
| -}; |
167 |
| -export default Api; |
| 2 | +import ApiFactory from './api.factory.js'; |
| 3 | +export default ApiFactory.bind(undefined, () => ({getElManagementIns: (param) => new ElManagement(param)})); |
0 commit comments