@nova-ui/bits
Version:
SolarWinds Nova Framework
458 lines • 78.6 kB
JavaScript
// © 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