UNPKG

carbon-components-angular

Version:
199 lines (196 loc) 8.23 kB
/*! * * Neutrino v0.0.0 | scrollable-list.directive.js * * Copyright 2014, 2018 IBM * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Input, Directive, ElementRef, HostListener } from "@angular/core"; var ScrollableList = /** @class */ (function () { function ScrollableList(elementRef) { this.elementRef = elementRef; /** * Optional target list to scroll */ this.nScrollableList = null; /** * Enables or disables scrolling for the whole directive */ this.scrollEnabled = true; /** * How many lines to scroll by each time `wheel` fires * Defaults to 10 - based on testing this isn't too fast or slow on any platform */ this.scrollBy = 10; this.canScrollUp = false; this.canScrollDown = false; this.list = this.elementRef.nativeElement; } ScrollableList.prototype.ngOnChanges = function (changes) { var _this = this; if (changes.scrollEnabled) { if (changes.scrollEnabled.currentValue) { this.list.style.overflow = "hidden"; this.scrollUpTarget.style.display = "flex"; this.scrollDownTarget.style.display = "flex"; this.canScrollUp = true; this.canScrollDown = true; this.updateScrollHeight(); this.checkScrollArrows(); setTimeout(function () { _this.checkScrollArrows(); }); } else { this.scrollUpTarget.style.display = "none"; this.scrollDownTarget.style.display = "none"; this.canScrollUp = false; this.canScrollDown = false; this.list.style.height = null; this.list.style.overflow = null; clearInterval(this.hoverScrollInterval); } } }; ScrollableList.prototype.ngAfterViewInit = function () { var _this = this; if (this.nScrollableList) { this.list = this.elementRef.nativeElement.querySelector(this.nScrollableList); } this.scrollUpTarget.addEventListener("mouseover", function () { return _this.onHoverUp(true); }); this.scrollUpTarget.addEventListener("mouseout", function () { return _this.onHoverUp(false); }); this.scrollDownTarget.addEventListener("mouseover", function () { return _this.onHoverDown(true); }); this.scrollDownTarget.addEventListener("mouseout", function () { return _this.onHoverDown(false); }); }; ScrollableList.prototype.updateScrollHeight = function () { if (this.scrollEnabled) { var container = this.elementRef.nativeElement.parentElement; var containerRect = container.getBoundingClientRect(); var innerHeightDiff = this.list.getBoundingClientRect().top - containerRect.top; var outerHeightDiff = containerRect.height - (containerRect.bottom - window.innerHeight); // 40 gives us some padding between the bottom of the list, // the bottom of the window, and the scroll down button var height = outerHeightDiff - innerHeightDiff - 40; this.list.style.height = height + "px"; } }; ScrollableList.prototype.checkScrollArrows = function () { var scrollUpHeight = this.scrollUpTarget.offsetHeight; var scrollDownHeight = this.scrollDownTarget.offsetHeight; if (this.list.scrollTop === 0) { if (this.canScrollUp) { this.list.style.height = parseInt(this.list.style.height, 10) + scrollUpHeight + "px"; } this.scrollUpTarget.style.display = "none"; this.canScrollUp = false; } else if (this.list.scrollTop === this.list.scrollTopMax) { if (this.canScrollDown) { this.list.style.height = parseInt(this.list.style.height, 10) + scrollDownHeight + "px"; } this.scrollDownTarget.style.display = "none"; this.canScrollDown = false; } else { if (!this.canScrollUp) { this.list.style.height = parseInt(this.list.style.height, 10) - scrollUpHeight + "px"; } if (!this.canScrollDown) { this.list.style.height = parseInt(this.list.style.height, 10) - scrollDownHeight + "px"; } this.scrollUpTarget.style.display = "flex"; this.scrollDownTarget.style.display = "flex"; this.canScrollUp = true; this.canScrollDown = true; } }; ScrollableList.prototype.onWheel = function (event) { if (event.deltaY < 0) { this.list.scrollTop -= this.scrollBy; } else { this.list.scrollTop += this.scrollBy; } // only prevent the parent/window from scrolling if we can scroll if (!(this.list.scrollTop === this.list.scrollTopMax || this.list.scrollTop === 0)) { event.preventDefault(); event.stopPropagation(); } this.checkScrollArrows(); }; ScrollableList.prototype.onTouchStart = function (event) { if (event.touches[0]) { this.lastTouch = event.touches[0].clientY; } }; ScrollableList.prototype.onTouchMove = function (event) { event.preventDefault(); event.stopPropagation(); if (event.touches[0]) { var touch = event.touches[0]; this.list.scrollTop += this.lastTouch - touch.clientY; this.lastTouch = touch.clientY; this.checkScrollArrows(); } }; ScrollableList.prototype.hoverScrollBy = function (hovering, amount) { var _this = this; if (hovering) { this.hoverScrollInterval = setInterval(function () { _this.list.scrollTop += amount; _this.checkScrollArrows(); }, 1); } else { clearInterval(this.hoverScrollInterval); } }; ScrollableList.prototype.onHoverUp = function (hovering) { // how many px/lines to scroll by on hover // 3 is just a random number that felt good // 1 and 2 are too slow, 4 works but it might be a tad fast this.hoverScrollBy(hovering, -3); }; ScrollableList.prototype.onHoverDown = function (hovering) { this.hoverScrollBy(hovering, 3); }; ScrollableList.prototype.onKeyDown = function (event) { if (event.key === "ArrowDown" || event.key === "ArrowUp") { this.checkScrollArrows(); } }; ScrollableList.decorators = [ { type: Directive, args: [{ selector: "[ibmScrollableList]", exportAs: "scrollable-list" },] }, ]; /** @nocollapse */ ScrollableList.ctorParameters = function () { return [ { type: ElementRef } ]; }; ScrollableList.propDecorators = { nScrollableList: [{ type: Input }], scrollEnabled: [{ type: Input }], scrollUpTarget: [{ type: Input }], scrollDownTarget: [{ type: Input }], scrollBy: [{ type: Input }], onWheel: [{ type: HostListener, args: ["wheel", ["$event"],] }], onTouchStart: [{ type: HostListener, args: ["touchstart", ["$event"],] }], onTouchMove: [{ type: HostListener, args: ["touchmove", ["$event"],] }], onKeyDown: [{ type: HostListener, args: ["keydown", ["$event"],] }] }; return ScrollableList; }()); export { ScrollableList }; //# sourceMappingURL=scrollable-list.directive.js.map