UNPKG

@nova-ui/bits

Version:

SolarWinds Nova Framework

458 lines 78.6 kB
// © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // 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 { CdkVirtualScrollViewport } from "@angular/cdk/scrolling"; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from "@angular/core"; import _chunk from "lodash/chunk"; import _clone from "lodash/clone"; import _get from "lodash/get"; import _includes from "lodash/includes"; import _min from "lodash/min"; import _range from "lodash/range"; import { Subject } from "rxjs"; import { LoggerService } from "../../services/log-service"; import { PopupContainerService } from "../popup/popup-container.service"; import { SelectComponent } from "../select"; import * as i0 from "@angular/core"; import * as i1 from "../../services/log-service"; import * as i2 from "../popup/popup-container.service"; import * as i3 from "@angular/common"; import * as i4 from "../popup/popup-toggle.directive"; import * as i5 from "../popup-adapter/popup-adapter.component"; import * as i6 from "../button/button.component"; import * as i7 from "@angular/cdk/scrolling"; import * as i8 from "../select-v2/select/select-v2.component"; import * as i9 from "../select-v2/option/select-v2-option.component"; export const defaultPageSizeSet = [10, 25, 50, 100]; const singleSymbolWidth = 8; const singleCellPaddings = 12; const containerPaddingsWithScroll = 37; /** * Component used for pagination of data * <example-url>./../examples/index.html#/paginator</example-url> */ export class PaginatorComponent { get dotsPagesPerRow() { return this._dotsPagesPerRow; } constructor(logger, popupContainer, cd) { this.logger = logger; this.popupContainer = popupContainer; this.cd = cd; this.itemsList = []; /** * Current page number */ this.page = 1; /** * Array of page numbers */ this.pageSizeSet = []; /** * Total number of items */ this.total = 0; /** * Paginator separator symbol. */ this.dots = "..."; /** * Hide paginator if all items of data can be displayed on one page */ this.hideIfEmpty = false; /** * Paginator active item class */ this.activeClass = "active"; /** * Paginator disabled item class */ this.disabledClass = "disabled"; /** * Number of items displayed before separator */ this.adjacent = 1; /** * Maximum number of items in paginator */ this.maxElements = this.adjacent * 2 + 5; /** * Show previous and next buttons */ this.showPrevNext = true; /** * Display popup above paginator if equals to 'true' */ this.popupDirectionTop = false; /** * Action occurs on page change */ this.pagerAction = new EventEmitter(); this.pageChange = new EventEmitter(); this.onDestroy$ = new Subject(); this._dotsPagesPerRow = 5; this.popupContainer.parent = this; } /** * Component initialization */ ngOnInit() { this.initPageSizeSet(); const pageCount = this.getPageCount(); if (this.page > pageCount) { this.page = pageCount; this.pageChange.emit(this.page); } if (this.page <= 0) { this.page = 1; this.pageChange.emit(this.page); } } /** * Redraw component when 'total' or 'page' propery was changed * @param changes Changed properties */ ngOnChanges(changes) { if (changes["total"] || changes["page"] || changes["adjacent"] || changes["pageSize"]) { this.assemble(); } } /** * Initialize set of pages */ initPageSizeSet() { if (!_get(this.pageSizeSet, "length")) { this.pageSizeSet = _clone(defaultPageSizeSet); } if (!this.pageSize || this.pageSize <= 0) { this.pageSize = this.pageSizeSet[0]; } if (!_includes(this.pageSizeSet, this.pageSize)) { this.logger .warn(`pageSize ${this.pageSize} not found in the current pageSizeSet ${this.pageSizeSet}. pageSize will be set to ${this.pageSizeSet[0]}. To set the desired initial page size, include it as part of the paginator's pageSizeSet input.`); this.pageSize = this.pageSizeSet[0]; } } getFilters() { return { type: "range", value: { start: (this.page - 1) * this.pageSize, end: this.page * this.pageSize, }, }; } resetFilter() { this.page = 1; this.pageChange.emit(this.page); } /** * Change page number * @param page Page number */ goToPage(page) { this.page = page; this.pageChange.emit(this.page); if (this.pagerAction) { const result = { page: this.page, pageSize: this.pageSize, total: this.total, pageSizeSet: this.pageSizeSet, }; this.pagerAction.emit(result); } this.assemble(); } // TODO: remove in vNext. Needs only for backward compatibility /** * @deprecated - remove in v12. Needs only for backward compatibility - Removal: NUI-5837 */ onPageSizeChange(value) { this.setItemsPerPage({ oldValue: 0, newValue: value, }); } // TODO: refactor in vNext. Replace ISelectChangedEvent to InputValueTypes - NUI-5837 /** * Set items per page that should displayed * @param changedEvent select change event */ setItemsPerPage(changedEvent) { if (changedEvent?.newValue === changedEvent?.oldValue) { return; } const newValue = changedEvent?.newValue; if (newValue) { if (newValue < 1) { this.logger.warn("paginator-controller.setItemsPerPage - invalid newValue: " + newValue); return; } this.pageSize = newValue; } this.goToPage(1); } /** * Get number of pages */ getPageCount() { if (this.total <= 0) { return 1; } return Math.ceil(this.total / this.pageSize); } /** * Display paginator component */ showPaginator() { const count = this.getPageCount(); return isFinite(count) && (this.hideIfEmpty === false || count > 1); } /** * Get sequence number of first item of currently displayed paginated list */ getFirstItemOnPage() { return this.pageSize * (this.page - 1) + 1; } /** * Get sequence number of last item of currently displayed paginated repeat */ getLastItemOnPage() { return _min([this.pageSize * this.page, this.total]); } /** * Return range for info section */ getRange(total) { return total > 0 ? `${this.getFirstItemOnPage()}-${this.getLastItemOnPage()}` : "0"; } /** * Re-renders the virtual scroll viewport to properly display items within the virtual scroll viewport */ handleDotsClick() { if (this.virtualScrollViewport) { this.virtualScrollViewport.checkViewportSize(); } } /** * Add items to paginator component */ assemble() { this.itemsList = []; if (this.getPageCount() <= 0) { return; } const pageCount = this.getPageCount(); this.prepareSeparators(); this.addPrev(); if (this.mainRangeStart !== 1) { // add starting separator and the first page this.add(1); this.addSeparator(2, this.mainRangeStart - 1); } this.addRange(this.mainRangeStart, this.mainRangeEnd); if (this.mainRangeEnd !== pageCount) { // add ending separator and the last page this.addSeparator(this.mainRangeEnd + 1, pageCount - 1); this.add(pageCount); } this.addNext(); this.cd.detectChanges(); } /** * Fills mainRangeStart and mainRangeEnd properties with proper values. Those properties * are used for displaying of page numbers between 'dots' separators. */ prepareSeparators() { // the only 2 variables that are needed to display everything are: // mainRangeStart mainRangeEnd // | | // < 1 ... 100 101 102 103 104 > const pageCount = this.getPageCount(); const page = +this.page; const adjacent = +this.adjacent; // case when there are few items if (pageCount <= this.maxElements) { this.mainRangeStart = 1; this.mainRangeEnd = pageCount; return; } // set main range to this.mainRangeStart = page - adjacent < 1 ? 1 : page - adjacent; this.mainRangeEnd = page + adjacent > pageCount ? pageCount : page + adjacent; // case where starting separator is not shown if (this.mainRangeStart - 1 - // end of possible starting separator 2 < // start of possible starting separator 1) { this.mainRangeStart = 1; } // case where ending separator is not shown if (pageCount - 1 - // end of possible ending separator (this.mainRangeEnd + 1) < // start of possible ending separator 1) { this.mainRangeEnd = pageCount; } // case where we have one of the first pages selected and the ending separator if (this.mainRangeEnd !== pageCount && page < this.maxElements - 2 - adjacent) { this.mainRangeStart = 1; this.mainRangeEnd = this.mainRangeStart + this.maxElements - 3; } // case where we have one of the last pages selected and the starting separator if (this.mainRangeStart !== 1 && page > pageCount - this.maxElements + 2 + adjacent) { this.mainRangeEnd = pageCount; this.mainRangeStart = this.mainRangeEnd - this.maxElements + 3; } } addSeparator(from, to) { const pageRows = _chunk(_range(from, to + 1), this._dotsPagesPerRow); this.itemsList.push({ title: $localize `Pages ${from} - ${to}`, value: this.dots, pageRows: pageRows, popupWidth: (to.toString().length * singleSymbolWidth + singleCellPaddings) * this._dotsPagesPerRow + containerPaddingsWithScroll, useVirtualScroll: pageRows.length * this._dotsPagesPerRow >= 1000, }); } addPrev() { const pageCount = this.getPageCount(); if (!this.showPrevNext || pageCount < 1) { return; } const prevBtn = { iconName: "caret-left", title: $localize `Previous Page`, page: this.page - 1 <= 0 ? 1 : this.page - 1, }; const isDisabled = this.page - 1 <= 0; this.addItem(prevBtn, isDisabled); } addNext() { const pageCount = this.getPageCount(); if (!this.showPrevNext || pageCount < 1) { return; } const nextBtn = { iconName: "caret-right", title: $localize `Next Page`, page: this.page + 1 >= pageCount ? pageCount : this.page + 1, }; const isDisabled = this.page + 1 > pageCount; this.addItem(nextBtn, isDisabled); } addItem(item, isDisabled) { this.itemsList.push({ iconName: item.iconName, value: item.value, title: item.title, style: isDisabled ? this.disabledClass : "", action: () => { if (item.page) { this.goToPage(item.page); } return false; }, }); } add(page) { const inst = this; this.itemsList.push({ value: page, title: $localize `Page ${page}`, style: this.page === page ? this.activeClass : "", action: function () { inst.goToPage(this.value); return false; }, }); } addRange(start, finish) { for (let index = start; index <= finish; index++) { this.add(index); } } ngOnDestroy() { this.onDestroy$.next(); this.onDestroy$.complete(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PaginatorComponent, deps: [{ token: i1.LoggerService }, { token: i2.PopupContainerService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PaginatorComponent, selector: "nui-paginator", inputs: { itemsList: "itemsList", page: "page", pageSize: "pageSize", pageSizeSet: "pageSizeSet", total: "total", dots: "dots", hideIfEmpty: "hideIfEmpty", hide: "hide", activeClass: "activeClass", disabledClass: "disabledClass", adjacent: "adjacent", maxElements: "maxElements", showPrevNext: "showPrevNext", popupDirectionTop: "popupDirectionTop", popupBaseElementSelector: "popupBaseElementSelector", appendToBody: "appendToBody" }, outputs: { pagerAction: "pagerAction", pageChange: "pageChange" }, host: { attributes: { "role": "navigation" } }, providers: [PopupContainerService], viewQueries: [{ propertyName: "selectComponent", first: true, predicate: ["select"], descendants: true }, { propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"nui-paginator\" *ngIf=\"showPaginator()\">\n <div class=\"nui-paginator__items\">\n <ul\n class=\"nui-paginator__list\"\n role=\"listbox\"\n aria-label=\"List of pages\"\n >\n <li\n role=\"option\"\n title=\"{{ item.title }}\"\n [ngClass]=\"item.style\"\n *ngFor=\"let item of itemsList\"\n value=\"{{ item.value }}\"\n >\n <button\n nui-button\n type=\"button\"\n displayStyle=\"action\"\n [disabled]=\"item.style\"\n *ngIf=\"item.iconName\"\n class=\"move-icon\"\n [icon]=\"item.iconName\"\n (click)=\"item.action($event)\"\n ></button>\n <button\n nui-button\n type=\"button\"\n *ngIf=\"item.value !== dots && !item.iconName\"\n displayStyle=\"action\"\n (click)=\"item.action($event)\"\n [isEmpty]=\"false\"\n >\n {{ item.value }}\n </button>\n <nui-popup\n *ngIf=\"item.value === dots\"\n [appendToBody]=\"appendToBody\"\n [baseElementSelector]=\"popupBaseElementSelector\"\n >\n <button\n nui-button\n type=\"button\"\n nuiPopupToggle\n displayStyle=\"action\"\n [ngClass]=\"item.imageClass\"\n [isEmpty]=\"false\"\n aria-haspopup=\"true\"\n (click)=\"handleDotsClick()\"\n class=\"nui-paginator__dots\"\n >\n {{ item.value }}\n </button>\n\n <ul popupAreaContent class=\"nui-paginator__elipsis-pages\">\n <li>\n <table\n class=\"nui-paginator__page-table\"\n [ngClass]=\"{\n 'native-scroll': !item.useVirtualScroll\n }\"\n >\n <cdk-virtual-scroll-viewport\n *ngIf=\"item.useVirtualScroll\"\n [style.width.px]=\"item.popupWidth\"\n [style.height.px]=\"130\"\n [itemSize]=\"40\"\n [maxBufferPx]=\"130\"\n [minBufferPx]=\"130\"\n >\n <ng-container\n *cdkVirtualFor=\"\n let pages of item.pageRows\n \"\n >\n <div\n [ngTemplateOutlet]=\"tableRow\"\n [ngTemplateOutletContext]=\"{\n pages: pages\n }\"\n ></div>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n <tbody *ngIf=\"!item.useVirtualScroll\">\n <ng-container\n *ngFor=\"let pages of item.pageRows\"\n [ngTemplateOutlet]=\"tableRow\"\n [ngTemplateOutletContext]=\"{\n pages: pages\n }\"\n >\n </ng-container>\n </tbody>\n </table>\n </li>\n </ul>\n </nui-popup>\n </li>\n </ul>\n </div>\n <div class=\"nui-paginator__options\">\n <div class=\"nui-paginator__info\" i18n>\n {{ getRange(total) }} of\n <span class=\"nui-paginator__total\">{{ total }}</span>\n </div>\n\n <nui-select-v2\n ariaLabel=\"Items per page\"\n [value]=\"pageSize\"\n (valueSelected)=\"onPageSizeChange($event)\"\n >\n <nui-select-v2-option\n *ngFor=\"let item of pageSizeSet\"\n [value]=\"item\"\n >{{ item }}</nui-select-v2-option\n >\n </nui-select-v2>\n </div>\n</div>\n<ng-template #tableRow let-pages=\"pages\">\n <tr [ngClass]=\"{ 'stretch-row': pages.length === dotsPagesPerRow }\">\n <td *ngFor=\"let value of pages\" class=\"nui-paginator__page-cell\">\n <button\n nui-button\n type=\"button\"\n displayStyle=\"action\"\n (click)=\"goToPage(value)\"\n >\n <!-- This tag span was added to display value properly on Safari brouser inside a button in ngFor directive -->\n <span>{{ value }}</span>\n </button>\n </td>\n </tr>\n</ng-template>\n", styles: [".nui .nui-paginator{height:30px;display:flex;align-items:center;justify-content:space-between}.nui .nui-paginator .nui-select-v2{min-width:60px}.nui .nui-paginator__info{font-size:13px;margin-right:10px;color:var(--nui-color-text-default,#111)}.nui .nui-paginator__icon{position:relative}.nui .nui-paginator__icon:hover{cursor:pointer;opacity:.7}.nui .nui-paginator__dots{font-size:13px}.nui .nui-paginator__dots:hover{cursor:pointer;background-color:var(--nui-color-bg-light-hover,#f2f2f2)}.nui .nui-paginator__elipsis-pages[popupAreaContent]{padding:0;max-height:130px;overflow-y:auto;overflow-x:hidden}.nui .nui-paginator__list{border-radius:0;display:flex;border-collapse:collapse;padding-left:3px;font-size:13px;margin-right:15px;margin-bottom:0}.nui .nui-paginator__list:before,.nui .nui-paginator__list:after{content:\" \";display:table;width:0px}.nui .nui-paginator__list:after{clear:both}.nui .nui-paginator__list>li>button.move-icon{padding:5px}.nui .nui-paginator__list>li{position:relative;padding:0;display:inline}.nui .nui-paginator__list>.active>button,.nui .nui-paginator__list>.active>button:hover,.nui .nui-paginator__list>.active>button:focus{background-color:transparent;border-color:transparent;color:var(--nui-color-text-default,#111);font-weight:600;cursor:default;z-index:2}.nui .nui-paginator__page-table{background-color:var(--nui-color-bg-transparent,transparent)}.nui .nui-paginator__page-table.native-scroll{margin:10px}.nui .nui-paginator__page-table:not(.native-scroll) tr{display:inline-table}.nui .nui-paginator__page-table:not(.native-scroll) tr.stretch-row{width:100%}.nui .nui-paginator__page-table tr:not(:last-child) .nui-paginator__page-cell{padding-bottom:10px}.nui .nui-paginator__page-table .cdk-virtual-scroll-content-wrapper{padding:10px}.nui .nui-paginator__page-cell>.btn{min-width:30px;padding:5px}.nui .nui-paginator__options{display:flex;align-items:center}.nui .nui-paginator__options .nui-select .nui-popup .nui-popup__area,.nui .nui-paginator__options .nui-select .nui-popup .nui-popup__area .nui-select__menu,.popup-adapter-overlay .nui-overlay.nui-select-popup-host{min-width:0}nui-popup-container[parent=PaginatorComponent] .nui-popup__area{min-width:0}nui-popup-container[parent=PaginatorComponent] .nui-popup__area .nui-select__menu{min-width:0}@-moz-document url-prefix(){.nui-paginator__page-table tr:nth-child(4) td:last-child{padding-right:15px}}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.PopupToggleDirective, selector: "[nuiPopupToggle]", inputs: ["isDisabled", "disabled"], outputs: ["toggle"] }, { kind: "component", type: i5.PopupComponent, selector: "nui-popup", inputs: ["width", "overlayConfig", "contextClass", "directionTop", "directionRight", "manualOpenControl", "appendToBody", "baseElementSelector", "isHostToggleRef", "ariaLabel", "isOpen", "visible"], outputs: ["opened"] }, { kind: "component", type: i6.ButtonComponent, selector: "[nui-button]", inputs: ["displayStyle", "icon", "iconColor", "iconRight", "isBusy", "isEmpty", "ariaLabel", "isRepeat", "size"] }, { kind: "directive", type: i7.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i7.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i7.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: i8.SelectV2Component, selector: "nui-select-v2", inputs: ["displayValueTemplate"] }, { kind: "component", type: i9.SelectV2OptionComponent, selector: "nui-select-v2-option", inputs: ["value", "index", "displayValueContext", "outfiltered"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PaginatorComponent, decorators: [{ type: Component, args: [{ selector: "nui-paginator", changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [PopupContainerService], host: { role: "navigation" }, template: "<div class=\"nui-paginator\" *ngIf=\"showPaginator()\">\n <div class=\"nui-paginator__items\">\n <ul\n class=\"nui-paginator__list\"\n role=\"listbox\"\n aria-label=\"List of pages\"\n >\n <li\n role=\"option\"\n title=\"{{ item.title }}\"\n [ngClass]=\"item.style\"\n *ngFor=\"let item of itemsList\"\n value=\"{{ item.value }}\"\n >\n <button\n nui-button\n type=\"button\"\n displayStyle=\"action\"\n [disabled]=\"item.style\"\n *ngIf=\"item.iconName\"\n class=\"move-icon\"\n [icon]=\"item.iconName\"\n (click)=\"item.action($event)\"\n ></button>\n <button\n nui-button\n type=\"button\"\n *ngIf=\"item.value !== dots && !item.iconName\"\n displayStyle=\"action\"\n (click)=\"item.action($event)\"\n [isEmpty]=\"false\"\n >\n {{ item.value }}\n </button>\n <nui-popup\n *ngIf=\"item.value === dots\"\n [appendToBody]=\"appendToBody\"\n [baseElementSelector]=\"popupBaseElementSelector\"\n >\n <button\n nui-button\n type=\"button\"\n nuiPopupToggle\n displayStyle=\"action\"\n [ngClass]=\"item.imageClass\"\n [isEmpty]=\"false\"\n aria-haspopup=\"true\"\n (click)=\"handleDotsClick()\"\n class=\"nui-paginator__dots\"\n >\n {{ item.value }}\n </button>\n\n <ul popupAreaContent class=\"nui-paginator__elipsis-pages\">\n <li>\n <table\n class=\"nui-paginator__page-table\"\n [ngClass]=\"{\n 'native-scroll': !item.useVirtualScroll\n }\"\n >\n <cdk-virtual-scroll-viewport\n *ngIf=\"item.useVirtualScroll\"\n [style.width.px]=\"item.popupWidth\"\n [style.height.px]=\"130\"\n [itemSize]=\"40\"\n [maxBufferPx]=\"130\"\n [minBufferPx]=\"130\"\n >\n <ng-container\n *cdkVirtualFor=\"\n let pages of item.pageRows\n \"\n >\n <div\n [ngTemplateOutlet]=\"tableRow\"\n [ngTemplateOutletContext]=\"{\n pages: pages\n }\"\n ></div>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n <tbody *ngIf=\"!item.useVirtualScroll\">\n <ng-container\n *ngFor=\"let pages of item.pageRows\"\n [ngTemplateOutlet]=\"tableRow\"\n [ngTemplateOutletContext]=\"{\n pages: pages\n }\"\n >\n </ng-container>\n </tbody>\n </table>\n </li>\n </ul>\n </nui-popup>\n </li>\n </ul>\n </div>\n <div class=\"nui-paginator__options\">\n <div class=\"nui-paginator__info\" i18n>\n {{ getRange(total) }} of\n <span class=\"nui-paginator__total\">{{ total }}</span>\n </div>\n\n <nui-select-v2\n ariaLabel=\"Items per page\"\n [value]=\"pageSize\"\n (valueSelected)=\"onPageSizeChange($event)\"\n >\n <nui-select-v2-option\n *ngFor=\"let item of pageSizeSet\"\n [value]=\"item\"\n >{{ item }}</nui-select-v2-option\n >\n </nui-select-v2>\n </div>\n</div>\n<ng-template #tableRow let-pages=\"pages\">\n <tr [ngClass]=\"{ 'stretch-row': pages.length === dotsPagesPerRow }\">\n <td *ngFor=\"let value of pages\" class=\"nui-paginator__page-cell\">\n <button\n nui-button\n type=\"button\"\n displayStyle=\"action\"\n (click)=\"goToPage(value)\"\n >\n <!-- This tag span was added to display value properly on Safari brouser inside a button in ngFor directive -->\n <span>{{ value }}</span>\n </button>\n </td>\n </tr>\n</ng-template>\n", styles: [".nui .nui-paginator{height:30px;display:flex;align-items:center;justify-content:space-between}.nui .nui-paginator .nui-select-v2{min-width:60px}.nui .nui-paginator__info{font-size:13px;margin-right:10px;color:var(--nui-color-text-default,#111)}.nui .nui-paginator__icon{position:relative}.nui .nui-paginator__icon:hover{cursor:pointer;opacity:.7}.nui .nui-paginator__dots{font-size:13px}.nui .nui-paginator__dots:hover{cursor:pointer;background-color:var(--nui-color-bg-light-hover,#f2f2f2)}.nui .nui-paginator__elipsis-pages[popupAreaContent]{padding:0;max-height:130px;overflow-y:auto;overflow-x:hidden}.nui .nui-paginator__list{border-radius:0;display:flex;border-collapse:collapse;padding-left:3px;font-size:13px;margin-right:15px;margin-bottom:0}.nui .nui-paginator__list:before,.nui .nui-paginator__list:after{content:\" \";display:table;width:0px}.nui .nui-paginator__list:after{clear:both}.nui .nui-paginator__list>li>button.move-icon{padding:5px}.nui .nui-paginator__list>li{position:relative;padding:0;display:inline}.nui .nui-paginator__list>.active>button,.nui .nui-paginator__list>.active>button:hover,.nui .nui-paginator__list>.active>button:focus{background-color:transparent;border-color:transparent;color:var(--nui-color-text-default,#111);font-weight:600;cursor:default;z-index:2}.nui .nui-paginator__page-table{background-color:var(--nui-color-bg-transparent,transparent)}.nui .nui-paginator__page-table.native-scroll{margin:10px}.nui .nui-paginator__page-table:not(.native-scroll) tr{display:inline-table}.nui .nui-paginator__page-table:not(.native-scroll) tr.stretch-row{width:100%}.nui .nui-paginator__page-table tr:not(:last-child) .nui-paginator__page-cell{padding-bottom:10px}.nui .nui-paginator__page-table .cdk-virtual-scroll-content-wrapper{padding:10px}.nui .nui-paginator__page-cell>.btn{min-width:30px;padding:5px}.nui .nui-paginator__options{display:flex;align-items:center}.nui .nui-paginator__options .nui-select .nui-popup .nui-popup__area,.nui .nui-paginator__options .nui-select .nui-popup .nui-popup__area .nui-select__menu,.popup-adapter-overlay .nui-overlay.nui-select-popup-host{min-width:0}nui-popup-container[parent=PaginatorComponent] .nui-popup__area{min-width:0}nui-popup-container[parent=PaginatorComponent] .nui-popup__area .nui-select__menu{min-width:0}@-moz-document url-prefix(){.nui-paginator__page-table tr:nth-child(4) td:last-child{padding-right:15px}}\n"] }] }], ctorParameters: () => [{ type: i1.LoggerService }, { type: i2.PopupContainerService }, { type: i0.ChangeDetectorRef }], propDecorators: { itemsList: [{ type: Input }], page: [{ type: Input }], pageSize: [{ type: Input }], pageSizeSet: [{ type: Input }], total: [{ type: Input }], dots: [{ type: Input }], hideIfEmpty: [{ type: Input }], hide: [{ type: Input }], activeClass: [{ type: Input }], disabledClass: [{ type: Input }], adjacent: [{ type: Input }], maxElements: [{ type: Input }], showPrevNext: [{ type: Input }], popupDirectionTop: [{ type: Input }], popupBaseElementSelector: [{ type: Input }], appendToBody: [{ type: Input }], pagerAction: [{ type: Output }], pageChange: [{ type: Output }], selectComponent: [{ type: ViewChild, args: ["select"] }], virtualScrollViewport: [{ type: ViewChild, args: [CdkVirtualScrollViewport] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcGFnaW5hdG9yL3BhZ2luYXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3BhZ2luYXRvci9wYWdpbmF0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xFLE9BQU8sRUFDSCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sRUFFTixTQUFTLEVBQ1QsaUJBQWlCLEdBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sTUFBTSxNQUFNLGNBQWMsQ0FBQztBQUNsQyxPQUFPLE1BQU0sTUFBTSxjQUFjLENBQUM7QUFDbEMsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQzlCLE9BQU8sU0FBUyxNQUFNLGlCQUFpQixDQUFDO0FBQ3hDLE9BQU8sSUFBSSxNQUFNLFlBQVksQ0FBQztBQUM5QixPQUFPLE1BQU0sTUFBTSxjQUFjLENBQUM7QUFDbEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQVEvQixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFFLHFC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OytCQUNJLGVBQWUsbUJBRVIsdUJBQXVCLENBQUMsTUFBTSxpQkFFaEMsaUJBQWlCLENBQUMsSUFBSSxhQUMxQixDQUFDLHFCQUFxQixDQUFDLFFBQzVCLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRTtzSkFLWixTQUFTO3NCQUF4QixLQUFLO2dCQUlVLElBQUk7c0JBQW5CLEtBQUs7Z0JBSVUsUUFBUTtzQkFBdkIsS0FBSztnQkFJVSxXQUFXO3NCQUExQixLQUFLO2dCQUlVLEtBQUs7c0JBQXBCLEtBQUs7Z0JBSVUsSUFBSTtzQkFBbkIsS0FBSztnQkFJVSxXQUFXO3NCQUExQixLQUFLO2dCQUlVLElBQUk7c0JBQW5CLEtBQUs7Z0JBSVUsV0FBVztzQkFBMUIsS0FBSztnQkFJVSxhQUFhO3NCQUE1QixLQUFLO2dCQUlVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBSVUsV0FBVztzQkFBMUIsS0FBSztnQkFJVSxZQUFZO3NCQUEzQixLQUFLO2dCQUlVLGlCQUFpQjtzQkFBaEMsS0FBSztnQkFJVSx3QkFBd0I7c0JBQXZDLEtBQUs7Z0JBSVUsWUFBWTtzQkFBM0IsS0FBSztnQkFJVyxXQUFXO3NCQUEzQixNQUFNO2dCQUVHLFVBQVU7c0JBQW5CLE1BQU07Z0JBS0MsZUFBZTtzQkFEdEIsU0FBUzt1QkFBQyxRQUFRO2dCQUlYLHFCQUFxQjtzQkFENUIsU0FBUzt1QkFBQyx3QkFBd0IiLCJzb3VyY2VzQ29udGVudCI6WyIvLyDCqSAyMDIyIFNvbGFyV2luZHMgV29ybGR3aWRlLCBMTEMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4vLyAgZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vICByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1