1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | import * as tslib_1 from "tslib";
|
24 | import { MDCFoundation } from '@material/base/foundation';
|
25 | import { cssClasses, strings } from './constants';
|
26 | var INTERACTION_EVENTS = ['touchstart', 'mousedown', 'focus'];
|
27 | var MDCTabBarScrollerFoundation = (function (_super) {
|
28 | tslib_1.__extends(MDCTabBarScrollerFoundation, _super);
|
29 | function MDCTabBarScrollerFoundation(adapter) {
|
30 | var _this = _super.call(this, tslib_1.__assign({}, MDCTabBarScrollerFoundation.defaultAdapter, adapter)) || this;
|
31 | _this.pointerDownRecognized_ = false;
|
32 | _this.currentTranslateOffset_ = 0;
|
33 | _this.focusedTarget_ = null;
|
34 | _this.layoutFrame_ = 0;
|
35 | _this.scrollFrameScrollLeft_ = 0;
|
36 | _this.forwardIndicatorClickHandler_ = function (evt) { return _this.scrollForward(evt); };
|
37 | _this.backIndicatorClickHandler_ = function (evt) { return _this.scrollBack(evt); };
|
38 | _this.resizeHandler_ = function () { return _this.layout(); };
|
39 | _this.interactionHandler_ = function (evt) {
|
40 | if (evt.type === 'touchstart' || evt.type === 'mousedown') {
|
41 | _this.pointerDownRecognized_ = true;
|
42 | }
|
43 | _this.handlePossibleTabKeyboardFocus_(evt);
|
44 | if (evt.type === 'focus') {
|
45 | _this.pointerDownRecognized_ = false;
|
46 | }
|
47 | };
|
48 | return _this;
|
49 | }
|
50 | Object.defineProperty(MDCTabBarScrollerFoundation, "cssClasses", {
|
51 | get: function () {
|
52 | return cssClasses;
|
53 | },
|
54 | enumerable: true,
|
55 | configurable: true
|
56 | });
|
57 | Object.defineProperty(MDCTabBarScrollerFoundation, "strings", {
|
58 | get: function () {
|
59 | return strings;
|
60 | },
|
61 | enumerable: true,
|
62 | configurable: true
|
63 | });
|
64 | Object.defineProperty(MDCTabBarScrollerFoundation, "defaultAdapter", {
|
65 | get: function () {
|
66 |
|
67 | return {
|
68 | addClass: function () { return undefined; },
|
69 | removeClass: function () { return undefined; },
|
70 | eventTargetHasClass: function () { return false; },
|
71 | addClassToForwardIndicator: function () { return undefined; },
|
72 | removeClassFromForwardIndicator: function () { return undefined; },
|
73 | addClassToBackIndicator: function () { return undefined; },
|
74 | removeClassFromBackIndicator: function () { return undefined; },
|
75 | isRTL: function () { return false; },
|
76 | registerBackIndicatorClickHandler: function () { return undefined; },
|
77 | deregisterBackIndicatorClickHandler: function () { return undefined; },
|
78 | registerForwardIndicatorClickHandler: function () { return undefined; },
|
79 | deregisterForwardIndicatorClickHandler: function () { return undefined; },
|
80 | registerCapturedInteractionHandler: function () { return undefined; },
|
81 | deregisterCapturedInteractionHandler: function () { return undefined; },
|
82 | registerWindowResizeHandler: function () { return undefined; },
|
83 | deregisterWindowResizeHandler: function () { return undefined; },
|
84 | getNumberOfTabs: function () { return 0; },
|
85 | getComputedWidthForTabAtIndex: function () { return 0; },
|
86 | getComputedLeftForTabAtIndex: function () { return 0; },
|
87 | getOffsetWidthForScrollFrame: function () { return 0; },
|
88 | getScrollLeftForScrollFrame: function () { return 0; },
|
89 | setScrollLeftForScrollFrame: function () { return undefined; },
|
90 | getOffsetWidthForTabBar: function () { return 0; },
|
91 | setTransformStyleForTabBar: function () { return undefined; },
|
92 | getOffsetLeftForEventTarget: function () { return 0; },
|
93 | getOffsetWidthForEventTarget: function () { return 0; },
|
94 | };
|
95 |
|
96 | },
|
97 | enumerable: true,
|
98 | configurable: true
|
99 | });
|
100 | MDCTabBarScrollerFoundation.prototype.init = function () {
|
101 | var _this = this;
|
102 | this.adapter_.registerBackIndicatorClickHandler(this.backIndicatorClickHandler_);
|
103 | this.adapter_.registerForwardIndicatorClickHandler(this.forwardIndicatorClickHandler_);
|
104 | this.adapter_.registerWindowResizeHandler(this.resizeHandler_);
|
105 | INTERACTION_EVENTS.forEach(function (evtType) {
|
106 | _this.adapter_.registerCapturedInteractionHandler(evtType, _this.interactionHandler_);
|
107 | });
|
108 | this.layout();
|
109 | };
|
110 | MDCTabBarScrollerFoundation.prototype.destroy = function () {
|
111 | var _this = this;
|
112 | this.adapter_.deregisterBackIndicatorClickHandler(this.backIndicatorClickHandler_);
|
113 | this.adapter_.deregisterForwardIndicatorClickHandler(this.forwardIndicatorClickHandler_);
|
114 | this.adapter_.deregisterWindowResizeHandler(this.resizeHandler_);
|
115 | INTERACTION_EVENTS.forEach(function (evtType) {
|
116 | _this.adapter_.deregisterCapturedInteractionHandler(evtType, _this.interactionHandler_);
|
117 | });
|
118 | };
|
119 | MDCTabBarScrollerFoundation.prototype.scrollBack = function (evt) {
|
120 | if (evt) {
|
121 | evt.preventDefault();
|
122 | }
|
123 | var tabWidthAccumulator = 0;
|
124 | var scrollTargetIndex = 0;
|
125 | for (var i = this.adapter_.getNumberOfTabs() - 1; i > 0; i--) {
|
126 | var tabOffsetLeft = this.adapter_.getComputedLeftForTabAtIndex(i);
|
127 | var tabBarWidthLessTabOffsetLeft = this.adapter_.getOffsetWidthForTabBar() - tabOffsetLeft;
|
128 | var tabIsNotOccluded = tabOffsetLeft > this.currentTranslateOffset_;
|
129 | if (this.isRTL_()) {
|
130 | tabIsNotOccluded = tabBarWidthLessTabOffsetLeft > this.currentTranslateOffset_;
|
131 | }
|
132 | if (tabIsNotOccluded) {
|
133 | continue;
|
134 | }
|
135 | tabWidthAccumulator += this.adapter_.getComputedWidthForTabAtIndex(i);
|
136 | var scrollTargetDetermined = tabWidthAccumulator > this.adapter_.getOffsetWidthForScrollFrame();
|
137 | if (scrollTargetDetermined) {
|
138 | scrollTargetIndex = this.isRTL_() ? i + 1 : i;
|
139 | break;
|
140 | }
|
141 | }
|
142 | this.scrollToTabAtIndex(scrollTargetIndex);
|
143 | };
|
144 | MDCTabBarScrollerFoundation.prototype.scrollForward = function (evt) {
|
145 | if (evt) {
|
146 | evt.preventDefault();
|
147 | }
|
148 | var scrollFrameOffsetWidth = this.adapter_.getOffsetWidthForScrollFrame() + this.currentTranslateOffset_;
|
149 | var scrollTargetIndex = 0;
|
150 | for (var i = 0; i < this.adapter_.getNumberOfTabs(); i++) {
|
151 | var tabOffsetLeftAndWidth = this.adapter_.getComputedLeftForTabAtIndex(i) + this.adapter_.getComputedWidthForTabAtIndex(i);
|
152 | var scrollTargetDetermined = tabOffsetLeftAndWidth > scrollFrameOffsetWidth;
|
153 | if (this.isRTL_()) {
|
154 | var frameOffsetAndTabWidth = scrollFrameOffsetWidth - this.adapter_.getComputedWidthForTabAtIndex(i);
|
155 | var tabRightOffset = this.adapter_.getOffsetWidthForTabBar() - tabOffsetLeftAndWidth;
|
156 | scrollTargetDetermined = tabRightOffset > frameOffsetAndTabWidth;
|
157 | }
|
158 | if (scrollTargetDetermined) {
|
159 | scrollTargetIndex = i;
|
160 | break;
|
161 | }
|
162 | }
|
163 | this.scrollToTabAtIndex(scrollTargetIndex);
|
164 | };
|
165 | MDCTabBarScrollerFoundation.prototype.layout = function () {
|
166 | var _this = this;
|
167 | cancelAnimationFrame(this.layoutFrame_);
|
168 | this.scrollFrameScrollLeft_ = this.adapter_.getScrollLeftForScrollFrame();
|
169 | this.layoutFrame_ = requestAnimationFrame(function () { return _this.layout_(); });
|
170 | };
|
171 | MDCTabBarScrollerFoundation.prototype.scrollToTabAtIndex = function (index) {
|
172 | var _this = this;
|
173 | var scrollTargetOffsetLeft = this.adapter_.getComputedLeftForTabAtIndex(index);
|
174 | var scrollTargetOffsetWidth = this.adapter_.getComputedWidthForTabAtIndex(index);
|
175 | this.currentTranslateOffset_ =
|
176 | this.normalizeForRTL_(scrollTargetOffsetLeft, scrollTargetOffsetWidth);
|
177 | requestAnimationFrame(function () { return _this.shiftFrame_(); });
|
178 | };
|
179 | MDCTabBarScrollerFoundation.prototype.layout_ = function () {
|
180 | var frameWidth = this.adapter_.getOffsetWidthForScrollFrame();
|
181 | var isOverflowing = this.adapter_.getOffsetWidthForTabBar() > frameWidth;
|
182 | if (!isOverflowing) {
|
183 | this.currentTranslateOffset_ = 0;
|
184 | }
|
185 | this.shiftFrame_();
|
186 | this.updateIndicatorEnabledStates_();
|
187 | };
|
188 | MDCTabBarScrollerFoundation.prototype.shiftFrame_ = function () {
|
189 | var shiftAmount = this.isRTL_() ?
|
190 | this.currentTranslateOffset_ : -this.currentTranslateOffset_;
|
191 | this.adapter_.setTransformStyleForTabBar("translateX(" + shiftAmount + "px)");
|
192 | this.updateIndicatorEnabledStates_();
|
193 | };
|
194 | MDCTabBarScrollerFoundation.prototype.handlePossibleTabKeyboardFocus_ = function (evt) {
|
195 | var target = evt.target;
|
196 | if (!this.adapter_.eventTargetHasClass(target, cssClasses.TAB) || this.pointerDownRecognized_) {
|
197 | return;
|
198 | }
|
199 | var resetAmt = this.isRTL_() ? this.scrollFrameScrollLeft_ : 0;
|
200 | this.adapter_.setScrollLeftForScrollFrame(resetAmt);
|
201 | this.focusedTarget_ = target;
|
202 | var scrollFrameWidth = this.adapter_.getOffsetWidthForScrollFrame();
|
203 | var tabBarWidth = this.adapter_.getOffsetWidthForTabBar();
|
204 | var leftEdge = this.adapter_.getOffsetLeftForEventTarget(this.focusedTarget_);
|
205 | var rightEdge = leftEdge + this.adapter_.getOffsetWidthForEventTarget(this.focusedTarget_);
|
206 | var shouldScrollBack = rightEdge <= this.currentTranslateOffset_;
|
207 | var shouldScrollForward = rightEdge > this.currentTranslateOffset_ + scrollFrameWidth;
|
208 | if (this.isRTL_()) {
|
209 | var normalizedLeftOffset = tabBarWidth - leftEdge;
|
210 | shouldScrollBack = leftEdge >= tabBarWidth - this.currentTranslateOffset_;
|
211 | shouldScrollForward = normalizedLeftOffset > scrollFrameWidth + this.currentTranslateOffset_;
|
212 | }
|
213 | if (shouldScrollForward) {
|
214 | this.scrollForward();
|
215 | }
|
216 | else if (shouldScrollBack) {
|
217 | this.scrollBack();
|
218 | }
|
219 | this.pointerDownRecognized_ = false;
|
220 | };
|
221 | MDCTabBarScrollerFoundation.prototype.updateIndicatorEnabledStates_ = function () {
|
222 | var INDICATOR_ENABLED = cssClasses.INDICATOR_ENABLED;
|
223 | if (this.currentTranslateOffset_ === 0) {
|
224 | this.adapter_.removeClassFromBackIndicator(INDICATOR_ENABLED);
|
225 | }
|
226 | else {
|
227 | this.adapter_.addClassToBackIndicator(INDICATOR_ENABLED);
|
228 | }
|
229 | var remainingTabBarWidth = this.adapter_.getOffsetWidthForTabBar() - this.currentTranslateOffset_;
|
230 | if (remainingTabBarWidth > this.adapter_.getOffsetWidthForScrollFrame()) {
|
231 | this.adapter_.addClassToForwardIndicator(INDICATOR_ENABLED);
|
232 | }
|
233 | else {
|
234 | this.adapter_.removeClassFromForwardIndicator(INDICATOR_ENABLED);
|
235 | }
|
236 | };
|
237 | MDCTabBarScrollerFoundation.prototype.normalizeForRTL_ = function (left, width) {
|
238 | return this.isRTL_() ? this.adapter_.getOffsetWidthForTabBar() - (left + width) : left;
|
239 | };
|
240 | MDCTabBarScrollerFoundation.prototype.isRTL_ = function () {
|
241 | return this.adapter_.isRTL();
|
242 | };
|
243 | return MDCTabBarScrollerFoundation;
|
244 | }(MDCFoundation));
|
245 | export { MDCTabBarScrollerFoundation };
|
246 |
|
247 | export default MDCTabBarScrollerFoundation;
|
248 |
|
\ | No newline at end of file |