UNPKG

@material/tabs

Version:
248 lines 12.9 kB
/** * @license * Copyright 2017 Google Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ import * as tslib_1 from "tslib"; import { MDCFoundation } from '@material/base/foundation'; import { cssClasses, strings } from './constants'; var INTERACTION_EVENTS = ['touchstart', 'mousedown', 'focus']; var MDCTabBarScrollerFoundation = /** @class */ (function (_super) { tslib_1.__extends(MDCTabBarScrollerFoundation, _super); function MDCTabBarScrollerFoundation(adapter) { var _this = _super.call(this, tslib_1.__assign({}, MDCTabBarScrollerFoundation.defaultAdapter, adapter)) || this; _this.pointerDownRecognized_ = false; _this.currentTranslateOffset_ = 0; _this.focusedTarget_ = null; _this.layoutFrame_ = 0; _this.scrollFrameScrollLeft_ = 0; _this.forwardIndicatorClickHandler_ = function (evt) { return _this.scrollForward(evt); }; _this.backIndicatorClickHandler_ = function (evt) { return _this.scrollBack(evt); }; _this.resizeHandler_ = function () { return _this.layout(); }; _this.interactionHandler_ = function (evt) { if (evt.type === 'touchstart' || evt.type === 'mousedown') { _this.pointerDownRecognized_ = true; } _this.handlePossibleTabKeyboardFocus_(evt); if (evt.type === 'focus') { _this.pointerDownRecognized_ = false; } }; return _this; } Object.defineProperty(MDCTabBarScrollerFoundation, "cssClasses", { get: function () { return cssClasses; }, enumerable: true, configurable: true }); Object.defineProperty(MDCTabBarScrollerFoundation, "strings", { get: function () { return strings; }, enumerable: true, configurable: true }); Object.defineProperty(MDCTabBarScrollerFoundation, "defaultAdapter", { get: function () { // tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface. return { addClass: function () { return undefined; }, removeClass: function () { return undefined; }, eventTargetHasClass: function () { return false; }, addClassToForwardIndicator: function () { return undefined; }, removeClassFromForwardIndicator: function () { return undefined; }, addClassToBackIndicator: function () { return undefined; }, removeClassFromBackIndicator: function () { return undefined; }, isRTL: function () { return false; }, registerBackIndicatorClickHandler: function () { return undefined; }, deregisterBackIndicatorClickHandler: function () { return undefined; }, registerForwardIndicatorClickHandler: function () { return undefined; }, deregisterForwardIndicatorClickHandler: function () { return undefined; }, registerCapturedInteractionHandler: function () { return undefined; }, deregisterCapturedInteractionHandler: function () { return undefined; }, registerWindowResizeHandler: function () { return undefined; }, deregisterWindowResizeHandler: function () { return undefined; }, getNumberOfTabs: function () { return 0; }, getComputedWidthForTabAtIndex: function () { return 0; }, getComputedLeftForTabAtIndex: function () { return 0; }, getOffsetWidthForScrollFrame: function () { return 0; }, getScrollLeftForScrollFrame: function () { return 0; }, setScrollLeftForScrollFrame: function () { return undefined; }, getOffsetWidthForTabBar: function () { return 0; }, setTransformStyleForTabBar: function () { return undefined; }, getOffsetLeftForEventTarget: function () { return 0; }, getOffsetWidthForEventTarget: function () { return 0; }, }; // tslint:enable:object-literal-sort-keys }, enumerable: true, configurable: true }); MDCTabBarScrollerFoundation.prototype.init = function () { var _this = this; this.adapter_.registerBackIndicatorClickHandler(this.backIndicatorClickHandler_); this.adapter_.registerForwardIndicatorClickHandler(this.forwardIndicatorClickHandler_); this.adapter_.registerWindowResizeHandler(this.resizeHandler_); INTERACTION_EVENTS.forEach(function (evtType) { _this.adapter_.registerCapturedInteractionHandler(evtType, _this.interactionHandler_); }); this.layout(); }; MDCTabBarScrollerFoundation.prototype.destroy = function () { var _this = this; this.adapter_.deregisterBackIndicatorClickHandler(this.backIndicatorClickHandler_); this.adapter_.deregisterForwardIndicatorClickHandler(this.forwardIndicatorClickHandler_); this.adapter_.deregisterWindowResizeHandler(this.resizeHandler_); INTERACTION_EVENTS.forEach(function (evtType) { _this.adapter_.deregisterCapturedInteractionHandler(evtType, _this.interactionHandler_); }); }; MDCTabBarScrollerFoundation.prototype.scrollBack = function (evt) { if (evt) { evt.preventDefault(); } var tabWidthAccumulator = 0; var scrollTargetIndex = 0; for (var i = this.adapter_.getNumberOfTabs() - 1; i > 0; i--) { var tabOffsetLeft = this.adapter_.getComputedLeftForTabAtIndex(i); var tabBarWidthLessTabOffsetLeft = this.adapter_.getOffsetWidthForTabBar() - tabOffsetLeft; var tabIsNotOccluded = tabOffsetLeft > this.currentTranslateOffset_; if (this.isRTL_()) { tabIsNotOccluded = tabBarWidthLessTabOffsetLeft > this.currentTranslateOffset_; } if (tabIsNotOccluded) { continue; } tabWidthAccumulator += this.adapter_.getComputedWidthForTabAtIndex(i); var scrollTargetDetermined = tabWidthAccumulator > this.adapter_.getOffsetWidthForScrollFrame(); if (scrollTargetDetermined) { scrollTargetIndex = this.isRTL_() ? i + 1 : i; break; } } this.scrollToTabAtIndex(scrollTargetIndex); }; MDCTabBarScrollerFoundation.prototype.scrollForward = function (evt) { if (evt) { evt.preventDefault(); } var scrollFrameOffsetWidth = this.adapter_.getOffsetWidthForScrollFrame() + this.currentTranslateOffset_; var scrollTargetIndex = 0; for (var i = 0; i < this.adapter_.getNumberOfTabs(); i++) { var tabOffsetLeftAndWidth = this.adapter_.getComputedLeftForTabAtIndex(i) + this.adapter_.getComputedWidthForTabAtIndex(i); var scrollTargetDetermined = tabOffsetLeftAndWidth > scrollFrameOffsetWidth; if (this.isRTL_()) { var frameOffsetAndTabWidth = scrollFrameOffsetWidth - this.adapter_.getComputedWidthForTabAtIndex(i); var tabRightOffset = this.adapter_.getOffsetWidthForTabBar() - tabOffsetLeftAndWidth; scrollTargetDetermined = tabRightOffset > frameOffsetAndTabWidth; } if (scrollTargetDetermined) { scrollTargetIndex = i; break; } } this.scrollToTabAtIndex(scrollTargetIndex); }; MDCTabBarScrollerFoundation.prototype.layout = function () { var _this = this; cancelAnimationFrame(this.layoutFrame_); this.scrollFrameScrollLeft_ = this.adapter_.getScrollLeftForScrollFrame(); this.layoutFrame_ = requestAnimationFrame(function () { return _this.layout_(); }); }; MDCTabBarScrollerFoundation.prototype.scrollToTabAtIndex = function (index) { var _this = this; var scrollTargetOffsetLeft = this.adapter_.getComputedLeftForTabAtIndex(index); var scrollTargetOffsetWidth = this.adapter_.getComputedWidthForTabAtIndex(index); this.currentTranslateOffset_ = this.normalizeForRTL_(scrollTargetOffsetLeft, scrollTargetOffsetWidth); requestAnimationFrame(function () { return _this.shiftFrame_(); }); }; MDCTabBarScrollerFoundation.prototype.layout_ = function () { var frameWidth = this.adapter_.getOffsetWidthForScrollFrame(); var isOverflowing = this.adapter_.getOffsetWidthForTabBar() > frameWidth; if (!isOverflowing) { this.currentTranslateOffset_ = 0; } this.shiftFrame_(); this.updateIndicatorEnabledStates_(); }; MDCTabBarScrollerFoundation.prototype.shiftFrame_ = function () { var shiftAmount = this.isRTL_() ? this.currentTranslateOffset_ : -this.currentTranslateOffset_; this.adapter_.setTransformStyleForTabBar("translateX(" + shiftAmount + "px)"); this.updateIndicatorEnabledStates_(); }; MDCTabBarScrollerFoundation.prototype.handlePossibleTabKeyboardFocus_ = function (evt) { var target = evt.target; if (!this.adapter_.eventTargetHasClass(target, cssClasses.TAB) || this.pointerDownRecognized_) { return; } var resetAmt = this.isRTL_() ? this.scrollFrameScrollLeft_ : 0; this.adapter_.setScrollLeftForScrollFrame(resetAmt); this.focusedTarget_ = target; var scrollFrameWidth = this.adapter_.getOffsetWidthForScrollFrame(); var tabBarWidth = this.adapter_.getOffsetWidthForTabBar(); var leftEdge = this.adapter_.getOffsetLeftForEventTarget(this.focusedTarget_); var rightEdge = leftEdge + this.adapter_.getOffsetWidthForEventTarget(this.focusedTarget_); var shouldScrollBack = rightEdge <= this.currentTranslateOffset_; var shouldScrollForward = rightEdge > this.currentTranslateOffset_ + scrollFrameWidth; if (this.isRTL_()) { var normalizedLeftOffset = tabBarWidth - leftEdge; shouldScrollBack = leftEdge >= tabBarWidth - this.currentTranslateOffset_; shouldScrollForward = normalizedLeftOffset > scrollFrameWidth + this.currentTranslateOffset_; } if (shouldScrollForward) { this.scrollForward(); } else if (shouldScrollBack) { this.scrollBack(); } this.pointerDownRecognized_ = false; }; MDCTabBarScrollerFoundation.prototype.updateIndicatorEnabledStates_ = function () { var INDICATOR_ENABLED = cssClasses.INDICATOR_ENABLED; if (this.currentTranslateOffset_ === 0) { this.adapter_.removeClassFromBackIndicator(INDICATOR_ENABLED); } else { this.adapter_.addClassToBackIndicator(INDICATOR_ENABLED); } var remainingTabBarWidth = this.adapter_.getOffsetWidthForTabBar() - this.currentTranslateOffset_; if (remainingTabBarWidth > this.adapter_.getOffsetWidthForScrollFrame()) { this.adapter_.addClassToForwardIndicator(INDICATOR_ENABLED); } else { this.adapter_.removeClassFromForwardIndicator(INDICATOR_ENABLED); } }; MDCTabBarScrollerFoundation.prototype.normalizeForRTL_ = function (left, width) { return this.isRTL_() ? this.adapter_.getOffsetWidthForTabBar() - (left + width) : left; }; MDCTabBarScrollerFoundation.prototype.isRTL_ = function () { return this.adapter_.isRTL(); }; return MDCTabBarScrollerFoundation; }(MDCFoundation)); export { MDCTabBarScrollerFoundation }; // tslint:disable-next-line:no-default-export Needed for backward compatibility with MDC Web v0.44.0 and earlier. export default MDCTabBarScrollerFoundation; //# sourceMappingURL=foundation.js.map