@material/top-app-bar
Version:
The Material Components for the web top app bar component
168 lines • 7.46 kB
JavaScript
/**
* @license
* Copyright 2018 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 { __extends } from "tslib";
import { numbers } from '../constants';
import { MDCTopAppBarBaseFoundation } from '../foundation';
var INITIAL_VALUE = 0;
var MDCTopAppBarFoundation = /** @class */ (function (_super) {
__extends(MDCTopAppBarFoundation, _super);
/* istanbul ignore next: optional argument is not a branch statement */
function MDCTopAppBarFoundation(adapter) {
var _this = _super.call(this, adapter) || this;
/**
* Indicates if the top app bar was docked in the previous scroll handler iteration.
*/
_this.wasDocked = true;
/**
* Indicates if the top app bar is docked in the fully shown position.
*/
_this.isDockedShowing = true;
/**
* Variable for current scroll position of the top app bar
*/
_this.currentAppBarOffsetTop = 0;
/**
* Used to prevent the top app bar from being scrolled out of view during resize events
*/
_this.isCurrentlyBeingResized = false;
/**
* The timeout that's used to throttle the resize events
*/
_this.resizeThrottleId = INITIAL_VALUE;
/**
* The timeout that's used to debounce toggling the isCurrentlyBeingResized
* variable after a resize
*/
_this.resizeDebounceId = INITIAL_VALUE;
_this.lastScrollPosition = _this.adapter.getViewportScrollY();
_this.topAppBarHeight = _this.adapter.getTopAppBarHeight();
return _this;
}
MDCTopAppBarFoundation.prototype.destroy = function () {
_super.prototype.destroy.call(this);
this.adapter.setStyle('top', '');
};
/**
* Scroll handler for the default scroll behavior of the top app bar.
*/
MDCTopAppBarFoundation.prototype.handleTargetScroll = function () {
var currentScrollPosition = Math.max(this.adapter.getViewportScrollY(), 0);
var diff = currentScrollPosition - this.lastScrollPosition;
this.lastScrollPosition = currentScrollPosition;
// If the window is being resized the lastScrollPosition needs to be updated
// but the current scroll of the top app bar should stay in the same
// position.
if (!this.isCurrentlyBeingResized) {
this.currentAppBarOffsetTop -= diff;
if (this.currentAppBarOffsetTop > 0) {
this.currentAppBarOffsetTop = 0;
}
else if (Math.abs(this.currentAppBarOffsetTop) > this.topAppBarHeight) {
this.currentAppBarOffsetTop = -this.topAppBarHeight;
}
this.moveTopAppBar();
}
};
/**
* Top app bar resize handler that throttle/debounce functions that execute updates.
*/
MDCTopAppBarFoundation.prototype.handleWindowResize = function () {
var _this = this;
// Throttle resize events 10 p/s
if (!this.resizeThrottleId) {
this.resizeThrottleId = setTimeout(function () {
_this.resizeThrottleId = INITIAL_VALUE;
_this.throttledResizeHandler();
}, numbers.DEBOUNCE_THROTTLE_RESIZE_TIME_MS);
}
this.isCurrentlyBeingResized = true;
if (this.resizeDebounceId) {
clearTimeout(this.resizeDebounceId);
}
this.resizeDebounceId = setTimeout(function () {
_this.handleTargetScroll();
_this.isCurrentlyBeingResized = false;
_this.resizeDebounceId = INITIAL_VALUE;
}, numbers.DEBOUNCE_THROTTLE_RESIZE_TIME_MS);
};
/**
* Function to determine if the DOM needs to update.
*/
MDCTopAppBarFoundation.prototype.checkForUpdate = function () {
var offscreenBoundaryTop = -this.topAppBarHeight;
var hasAnyPixelsOffscreen = this.currentAppBarOffsetTop < 0;
var hasAnyPixelsOnscreen = this.currentAppBarOffsetTop > offscreenBoundaryTop;
var partiallyShowing = hasAnyPixelsOffscreen && hasAnyPixelsOnscreen;
// If it's partially showing, it can't be docked.
if (partiallyShowing) {
this.wasDocked = false;
}
else {
// Not previously docked and not partially showing, it's now docked.
if (!this.wasDocked) {
this.wasDocked = true;
return true;
}
else if (this.isDockedShowing !== hasAnyPixelsOnscreen) {
this.isDockedShowing = hasAnyPixelsOnscreen;
return true;
}
}
return partiallyShowing;
};
/**
* Function to move the top app bar if needed.
*/
MDCTopAppBarFoundation.prototype.moveTopAppBar = function () {
if (this.checkForUpdate()) {
// Once the top app bar is fully hidden we use the max potential top app bar height as our offset
// so the top app bar doesn't show if the window resizes and the new height > the old height.
var offset = this.currentAppBarOffsetTop;
if (Math.abs(offset) >= this.topAppBarHeight) {
offset = -numbers.MAX_TOP_APP_BAR_HEIGHT;
}
this.adapter.setStyle('top', offset + 'px');
}
};
/**
* Throttled function that updates the top app bar scrolled values if the
* top app bar height changes.
*/
MDCTopAppBarFoundation.prototype.throttledResizeHandler = function () {
var currentHeight = this.adapter.getTopAppBarHeight();
if (this.topAppBarHeight !== currentHeight) {
this.wasDocked = false;
// Since the top app bar has a different height depending on the screen width, this
// will ensure that the top app bar remains in the correct location if
// completely hidden and a resize makes the top app bar a different height.
this.currentAppBarOffsetTop -= this.topAppBarHeight - currentHeight;
this.topAppBarHeight = currentHeight;
}
this.handleTargetScroll();
};
return MDCTopAppBarFoundation;
}(MDCTopAppBarBaseFoundation));
export { MDCTopAppBarFoundation };
// tslint:disable-next-line:no-default-export Needed for backward compatibility with MDC Web v0.44.0 and earlier.
export default MDCTopAppBarFoundation;
//# sourceMappingURL=foundation.js.map