UNPKG

carbon-components-angular

Version:
1,035 lines (1,016 loc) 43 kB
import * as i0 from '@angular/core'; import { EventEmitter, Component, Input, Output, HostBinding, NgModule } from '@angular/core'; import { merge } from 'carbon-components-angular/utils'; import * as i1 from 'carbon-components-angular/i18n'; import { I18nModule } from 'carbon-components-angular/i18n'; import * as i2 from 'carbon-components-angular/experimental'; import { ExperimentalModule } from 'carbon-components-angular/experimental'; import * as i3 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i4 from '@angular/forms'; import { FormsModule } from '@angular/forms'; import * as i4$1 from 'carbon-components-angular/icon'; import { IconModule } from 'carbon-components-angular/icon'; import * as i6 from 'carbon-components-angular/forms'; import { ButtonModule } from 'carbon-components-angular/forms'; import { range } from 'carbon-components-angular/common'; class PaginationModel { constructor() { /** * Tracks the current page. */ this.currentPage = 1; /** * Length of page. */ /* tslint:disable-next-line*/ this.pageLength = 10; /** * Absolute total number of items needed to paginate. */ this.totalDataLength = 0; } } /** * Use pagination when you have multiple pages of data to handle. Get started with importing the module: * * ```typescript * import { PaginationModule } from 'carbon-components-angular'; * ``` * * ```html * <cds-pagination [model]="model" (selectPage)="selectPage($event)"></cds-pagination> * ``` * * In your `selectPage()` method set the `model.currentPage` to selected page, _after_ * you load the page. * * ```typescript * selectPage(page) { * // ... your code to load the page goes here * * this.model.currentPage = page; * * // ... anything you want to do after page selection changes goes here * } * ``` * * [See demo](../../?path=/story/components-pagination--basic) */ class Pagination { constructor(i18n, experimental) { this.i18n = i18n; this.experimental = experimental; /** * Set to `true` for a loading pagination component. */ this.skeleton = false; /** * Set to `true` to disable the backward/forward buttons. */ this.disabled = false; /** * Set to `true` to disable the select box that changes the page. */ this.pageInputDisabled = false; /** * Controls wether or not to show the page selects */ this.showPageInput = true; /** * Set to `true` if the total number of items is unknown. */ this.pagesUnknown = false; this.pageSelectThreshold = 1000; /** * Options for items per page select * * A default array of options will be defined: [10, 20, 30, 40, 50] */ this.itemsPerPageOptions = [10, 20, 30, 40, 50]; /** * Emits the new page number. * * You should tie into this and update `model.currentPage` once the fresh * data is finally loaded. */ this.selectPage = new EventEmitter(); this.itemsPerPageSelectId = `pagination-select-items-per-page-${Pagination.paginationCounter}`; this.currentPageSelectId = `pagination-select-current-page-${Pagination.paginationCounter}`; this.itemsPerPageText = this.i18n.getOverridable("PAGINATION.ITEMS_PER_PAGE"); this.optionsListText = this.i18n.getOverridable("PAGINATION.OPEN_LIST_OF_OPTIONS"); this.backwardText = this.i18n.getOverridable("PAGINATION.BACKWARD"); this.forwardText = this.i18n.getOverridable("PAGINATION.FORWARD"); this.totalItemsText = this.i18n.getOverridable("PAGINATION.TOTAL_ITEMS"); this.totalItemText = this.i18n.getOverridable("PAGINATION.TOTAL_ITEM"); this.totalItemsUnknownText = this.i18n.getOverridable("PAGINATION.TOTAL_ITEMS_UNKNOWN"); this.pageText = this.i18n.getOverridable("PAGINATION.PAGE"); this.ofLastPagesText = this.i18n.getOverridable("PAGINATION.OF_LAST_PAGES"); this.ofLastPageText = this.i18n.getOverridable("PAGINATION.OF_LAST_PAGE"); this._pageOptions = []; Pagination.paginationCounter++; } /** * Expects an object that contains some or all of: * ``` * { * "ITEMS_PER_PAGE": "Items per page:", * "OPEN_LIST_OF_OPTIONS": "Open list of options", * "BACKWARD": "Backward", * "FORWARD": "Forward", * "TOTAL_ITEMS_UNKNOWN": "{{start}}-{{end}} items", * "TOTAL_ITEMS": "{{start}}-{{end}} of {{total}} items", * "TOTAL_ITEM": "{{start}}-{{end}} of {{total}} item", * "OF_LAST_PAGES": "of {{last}} pages", * "OF_LAST_PAGE": "of {{last}} page" * } * ``` */ set translations(value) { const valueWithDefaults = merge(this.i18n.getMultiple("PAGINATION"), value); this.itemsPerPageText.override(valueWithDefaults.ITEMS_PER_PAGE); this.optionsListText.override(valueWithDefaults.OPEN_LIST_OF_OPTIONS); this.backwardText.override(valueWithDefaults.BACKWARD); this.forwardText.override(valueWithDefaults.FORWARD); this.totalItemsText.override(valueWithDefaults.TOTAL_ITEMS); this.totalItemText.override(valueWithDefaults.TOTAL_ITEM); this.totalItemsUnknownText.override(valueWithDefaults.TOTAL_ITEMS_UNKNOWN); this.pageText.override(valueWithDefaults.PAGE); this.ofLastPagesText.override(valueWithDefaults.OF_LAST_PAGES); this.ofLastPageText.override(valueWithDefaults.OF_LAST_PAGE); } get itemsPerPage() { return this.model.pageLength; } set itemsPerPage(value) { this.model.pageLength = Number(value); this.currentPage = 1; // reset page } get currentPage() { return this.model.currentPage; } set currentPage(value) { value = Number(value); // emits the value to allow the user to update current page // in the model once the page is loaded this.selectPage.emit(value); } get totalDataLength() { return this.model.totalDataLength; } /** * The last page number to display in the pagination view. */ get lastPage() { const last = Math.ceil(this.totalDataLength / this.itemsPerPage); return last > 0 ? last : 1; } get startItemIndex() { return this.endItemIndex > 0 ? (this.currentPage - 1) * this.itemsPerPage + 1 : 0; } get endItemIndex() { const projectedEndItemIndex = this.currentPage * this.itemsPerPage; return projectedEndItemIndex < this.totalDataLength ? projectedEndItemIndex : this.totalDataLength; } /** * The previous page number to navigate to, from the current page. */ get previousPage() { return this.currentPage <= 1 ? 1 : this.currentPage - 1; } /** * The next page number to navigate to, from the current page. */ get nextPage() { const lastPage = this.lastPage; return this.currentPage >= lastPage ? lastPage : this.currentPage + 1; } get pageOptions() { /** * Calculate number of pages based on totalDataLength and itemsPerPage. * Even if totalDataLength is 0, numberOfPages should be always at least 1. * New array will be constructed only if number of pages changes. */ const numberOfPages = Math.max(Math.ceil(this.totalDataLength / this.itemsPerPage), 1); if (this._pageOptions.length !== numberOfPages) { this._pageOptions = Array(numberOfPages); } return this._pageOptions; } } Pagination.paginationCounter = 0; Pagination.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Pagination, deps: [{ token: i1.I18n }, { token: i2.ExperimentalService }], target: i0.ɵɵFactoryTarget.Component }); Pagination.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Pagination, selector: "cds-pagination, ibm-pagination", inputs: { skeleton: "skeleton", model: "model", disabled: "disabled", pageInputDisabled: "pageInputDisabled", showPageInput: "showPageInput", pagesUnknown: "pagesUnknown", pageSelectThreshold: "pageSelectThreshold", translations: "translations", itemsPerPageOptions: "itemsPerPageOptions" }, outputs: { selectPage: "selectPage" }, ngImport: i0, template: ` <div class="cds--pagination" [ngClass]="{ 'cds--skeleton': skeleton }"> <!-- left skeleton div --> <div *ngIf="skeleton" class="cds--pagination__left"> <p class="cds--skeleton__text" style="width: 70px"></p> <p class="cds--skeleton__text" style="width: 35px"></p> <p class="cds--skeleton__text" style="width: 105px"></p> </div> <div *ngIf="!skeleton" class="cds--pagination__left"> <ng-container *ngIf="showPageInput"> <label class="cds--pagination__text" [for]="itemsPerPageSelectId"> {{itemsPerPageText.subject | async}} </label> <div class="cds--select cds--select--inline cds--select__item-count" [class.cds--select--disabled]="pageInputDisabled"> <select [id]="itemsPerPageSelectId" [(ngModel)]="itemsPerPage" [disabled]="pageInputDisabled" class="cds--select-input"> <option class="cds--select-option" *ngFor="let option of itemsPerPageOptions" [value]="option"> {{ option }} </option> </select> <svg cdsIcon="chevron--down" size="16" style="display: inherit" class="cds--select__arrow" aria-hidden="true" [attr.ariaLabel]="optionsListText.subject | async"> </svg> </div> </ng-container> <span *ngIf="!pagesUnknown && totalDataLength <= 1" class="cds--pagination__text cds--pagination__items-count" [ngStyle]="{'margin-left': showPageInput ? null : 0}"> {{totalItemText.subject | i18nReplace:{start: startItemIndex, end: endItemIndex, total: totalDataLength } | async}} </span> <span *ngIf="!pagesUnknown && totalDataLength > 1" class="cds--pagination__text cds--pagination__items-count" [ngStyle]="{'margin-left': showPageInput ? null : 0}"> {{totalItemsText.subject | i18nReplace:{start: startItemIndex, end: endItemIndex, total: totalDataLength } | async}} </span> <span *ngIf="pagesUnknown" class="cds--pagination__text cds--pagination__items-count" [ngStyle]="{'margin-left': showPageInput ? null : 0}"> {{totalItemsUnknownText.subject | i18nReplace:{start: startItemIndex, end: endItemIndex } | async}} </span> </div> <!-- right skeleton div --> <div *ngIf="skeleton" class="cds--pagination__right"> <p class="cds--skeleton__text" style="width: 70px"></p> </div> <div *ngIf="!skeleton" class="cds--pagination__right"> <span *ngIf="pagesUnknown" class="cds--pagination__text cds--pagination__page-text"> <ng-container *ngIf="!showPageInput">{{currentPage}}</ng-container> {{pageText.subject | async}} </span> <ng-container *ngIf="showPageInput"> <div class="cds--select cds--select--inline cds--select__page-number" [class.cds--select--disabled]="pageInputDisabled"> <label [for]="currentPageSelectId" class="cds--label cds--visually-hidden">{{pageText.subject | async}}</label> <input *ngIf="pageOptions.length > pageSelectThreshold" style="padding-right: 1rem; margin-right: 1rem;" [id]="currentPageSelectId" type="number" min="1" [max]="pageOptions.length" class="cds--select-input" [(ngModel)]="currentPage"> <select *ngIf="pageOptions.length <= pageSelectThreshold" [id]="currentPageSelectId" class="cds--select-input" [disabled]="pageInputDisabled" [(ngModel)]="currentPage"> <option *ngFor="let page of pageOptions; let i = index;" class="cds--select-option" [value]="i + 1">{{i + 1}}</option> </select> <svg *ngIf="pageOptions.length <= pageSelectThreshold" cdsIcon="chevron--down" size="16" style="display: inherit;" class="cds--select__arrow" [attr.ariaLabel]="optionsListText.subject | async"> </svg> </div> </ng-container> <span *ngIf="!pagesUnknown && lastPage <= 1" class="cds--pagination__text"> <ng-container *ngIf="!showPageInput">{{currentPage}}</ng-container> {{ofLastPageText.subject | i18nReplace: {last: lastPage} | async}} </span> <span *ngIf="!pagesUnknown && lastPage > 1" class="cds--pagination__text"> <ng-container *ngIf="!showPageInput">{{currentPage}}</ng-container> {{ofLastPagesText.subject | i18nReplace: {last: lastPage} | async}} </span> <div class="cds--pagination__control-buttons"> <button cdsButton="ghost" iconOnly="true" class="cds--pagination__button cds--pagination__button--backward" [ngClass]="{ 'cds--pagination__button--no-index': currentPage <= 1 || disabled }" tabindex="0" [attr.aria-label]="backwardText.subject | async" (click)="selectPage.emit(previousPage)" [disabled]="(currentPage <= 1 || disabled ? true : null)"> <svg cdsIcon="caret--left" size="16" class="cds--btn__icon"></svg> </button> <button cdsButton="ghost" iconOnly="true" class=" cds--pagination__button cds--pagination__button--forward" [ngClass]="{ 'cds--pagination__button--no-index': currentPage >= lastPage || disabled }" tabindex="0" [attr.aria-label]="forwardText.subject | async" (click)="selectPage.emit(nextPage)" [disabled]="(currentPage >= lastPage || disabled ? true : null)"> <svg cdsIcon="caret--right" size="16" class="cds--btn__icon"></svg> </button> </div> </div> </div> `, isInline: true, 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.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i4.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4$1.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "directive", type: i6.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.ReplacePipe, name: "i18nReplace" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Pagination, decorators: [{ type: Component, args: [{ selector: "cds-pagination, ibm-pagination", template: ` <div class="cds--pagination" [ngClass]="{ 'cds--skeleton': skeleton }"> <!-- left skeleton div --> <div *ngIf="skeleton" class="cds--pagination__left"> <p class="cds--skeleton__text" style="width: 70px"></p> <p class="cds--skeleton__text" style="width: 35px"></p> <p class="cds--skeleton__text" style="width: 105px"></p> </div> <div *ngIf="!skeleton" class="cds--pagination__left"> <ng-container *ngIf="showPageInput"> <label class="cds--pagination__text" [for]="itemsPerPageSelectId"> {{itemsPerPageText.subject | async}} </label> <div class="cds--select cds--select--inline cds--select__item-count" [class.cds--select--disabled]="pageInputDisabled"> <select [id]="itemsPerPageSelectId" [(ngModel)]="itemsPerPage" [disabled]="pageInputDisabled" class="cds--select-input"> <option class="cds--select-option" *ngFor="let option of itemsPerPageOptions" [value]="option"> {{ option }} </option> </select> <svg cdsIcon="chevron--down" size="16" style="display: inherit" class="cds--select__arrow" aria-hidden="true" [attr.ariaLabel]="optionsListText.subject | async"> </svg> </div> </ng-container> <span *ngIf="!pagesUnknown && totalDataLength <= 1" class="cds--pagination__text cds--pagination__items-count" [ngStyle]="{'margin-left': showPageInput ? null : 0}"> {{totalItemText.subject | i18nReplace:{start: startItemIndex, end: endItemIndex, total: totalDataLength } | async}} </span> <span *ngIf="!pagesUnknown && totalDataLength > 1" class="cds--pagination__text cds--pagination__items-count" [ngStyle]="{'margin-left': showPageInput ? null : 0}"> {{totalItemsText.subject | i18nReplace:{start: startItemIndex, end: endItemIndex, total: totalDataLength } | async}} </span> <span *ngIf="pagesUnknown" class="cds--pagination__text cds--pagination__items-count" [ngStyle]="{'margin-left': showPageInput ? null : 0}"> {{totalItemsUnknownText.subject | i18nReplace:{start: startItemIndex, end: endItemIndex } | async}} </span> </div> <!-- right skeleton div --> <div *ngIf="skeleton" class="cds--pagination__right"> <p class="cds--skeleton__text" style="width: 70px"></p> </div> <div *ngIf="!skeleton" class="cds--pagination__right"> <span *ngIf="pagesUnknown" class="cds--pagination__text cds--pagination__page-text"> <ng-container *ngIf="!showPageInput">{{currentPage}}</ng-container> {{pageText.subject | async}} </span> <ng-container *ngIf="showPageInput"> <div class="cds--select cds--select--inline cds--select__page-number" [class.cds--select--disabled]="pageInputDisabled"> <label [for]="currentPageSelectId" class="cds--label cds--visually-hidden">{{pageText.subject | async}}</label> <input *ngIf="pageOptions.length > pageSelectThreshold" style="padding-right: 1rem; margin-right: 1rem;" [id]="currentPageSelectId" type="number" min="1" [max]="pageOptions.length" class="cds--select-input" [(ngModel)]="currentPage"> <select *ngIf="pageOptions.length <= pageSelectThreshold" [id]="currentPageSelectId" class="cds--select-input" [disabled]="pageInputDisabled" [(ngModel)]="currentPage"> <option *ngFor="let page of pageOptions; let i = index;" class="cds--select-option" [value]="i + 1">{{i + 1}}</option> </select> <svg *ngIf="pageOptions.length <= pageSelectThreshold" cdsIcon="chevron--down" size="16" style="display: inherit;" class="cds--select__arrow" [attr.ariaLabel]="optionsListText.subject | async"> </svg> </div> </ng-container> <span *ngIf="!pagesUnknown && lastPage <= 1" class="cds--pagination__text"> <ng-container *ngIf="!showPageInput">{{currentPage}}</ng-container> {{ofLastPageText.subject | i18nReplace: {last: lastPage} | async}} </span> <span *ngIf="!pagesUnknown && lastPage > 1" class="cds--pagination__text"> <ng-container *ngIf="!showPageInput">{{currentPage}}</ng-container> {{ofLastPagesText.subject | i18nReplace: {last: lastPage} | async}} </span> <div class="cds--pagination__control-buttons"> <button cdsButton="ghost" iconOnly="true" class="cds--pagination__button cds--pagination__button--backward" [ngClass]="{ 'cds--pagination__button--no-index': currentPage <= 1 || disabled }" tabindex="0" [attr.aria-label]="backwardText.subject | async" (click)="selectPage.emit(previousPage)" [disabled]="(currentPage <= 1 || disabled ? true : null)"> <svg cdsIcon="caret--left" size="16" class="cds--btn__icon"></svg> </button> <button cdsButton="ghost" iconOnly="true" class=" cds--pagination__button cds--pagination__button--forward" [ngClass]="{ 'cds--pagination__button--no-index': currentPage >= lastPage || disabled }" tabindex="0" [attr.aria-label]="forwardText.subject | async" (click)="selectPage.emit(nextPage)" [disabled]="(currentPage >= lastPage || disabled ? true : null)"> <svg cdsIcon="caret--right" size="16" class="cds--btn__icon"></svg> </button> </div> </div> </div> ` }] }], ctorParameters: function () { return [{ type: i1.I18n }, { type: i2.ExperimentalService }]; }, propDecorators: { skeleton: [{ type: Input }], model: [{ type: Input }], disabled: [{ type: Input }], pageInputDisabled: [{ type: Input }], showPageInput: [{ type: Input }], pagesUnknown: [{ type: Input }], pageSelectThreshold: [{ type: Input }], translations: [{ type: Input }], itemsPerPageOptions: [{ type: Input }], selectPage: [{ type: Output }] } }); /** * Used to present a single navigation item in a pagination list * * * ```html * <cds-pagination-nav-item [page]="5" [isActive]="false" (click)="handleClick(value)"></cds-pagination-nav-item> * ``` */ class PaginationNavItem { constructor() { /** * The page for this component to dipslay */ this.page = 0; /** * The state for this component to dipslay */ this.isActive = false; /** * Emits click event */ this.click = new EventEmitter(); } } PaginationNavItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationNavItem, deps: [], target: i0.ɵɵFactoryTarget.Component }); PaginationNavItem.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PaginationNavItem, selector: "cds-pagination-nav-item, ibm-pagination-nav-item", inputs: { page: "page", isActive: "isActive" }, outputs: { click: "click" }, ngImport: i0, template: ` <li class="cds--pagination-nav__list-item"> <button type="button" class="cds--pagination-nav__page" [ngClass]="{ 'cds--pagination-nav__page--active': isActive }" (click)="click.emit(page)"> <span class="cds--pagination-nav__accessibility-label"> {{page}} </span> {{page}} </button> </li> `, isInline: true, dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationNavItem, decorators: [{ type: Component, args: [{ selector: "cds-pagination-nav-item, ibm-pagination-nav-item", template: ` <li class="cds--pagination-nav__list-item"> <button type="button" class="cds--pagination-nav__page" [ngClass]="{ 'cds--pagination-nav__page--active': isActive }" (click)="click.emit(page)"> <span class="cds--pagination-nav__accessibility-label"> {{page}} </span> {{page}} </button> </li> ` }] }], ctorParameters: function () { return []; }, propDecorators: { page: [{ type: Input }], isActive: [{ type: Input }], click: [{ type: Output }] } }); /** * Used to present a selection of pages when there is an overflow * in the pagination list * * * ```html * <cds-pagination-overflow [fromIndex]="5" [count]="30" (change)="handleChange(value)"></cds-pagination-overflow> * ``` */ class PaginationOverflow { constructor(i18n) { this.i18n = i18n; this.ariaLabel = this.i18n.get().PAGINATION.SELECT_ARIA; /** * Emits click event */ this.change = new EventEmitter(); } get countAsArray() { return [...Array(this.count)]; } handleChange(event) { this.change.emit(+event.target.value); event.target.value = ""; } } PaginationOverflow.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationOverflow, deps: [{ token: i1.I18n }], target: i0.ɵɵFactoryTarget.Component }); PaginationOverflow.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PaginationOverflow, selector: "cds-pagination-overflow, ibm-pagination-overflow", inputs: { fromIndex: "fromIndex", count: "count", ariaLabel: "ariaLabel" }, outputs: { change: "change" }, ngImport: i0, template: ` <li class="cds--pagination-nav__list-item" *ngIf="count > 1"> <div class="cds--pagination-nav__select"> <select [attr.aria-label]="ariaLabel" class="cds--pagination-nav__page cds--pagination-nav__page--select" (change)="handleChange($event)"> <option value="" hidden></option> <option *ngFor="let item of countAsArray; let i = index"> {{fromIndex + i + 1}} </option> </select> <div class="cds--pagination-nav__select-icon-wrapper"> <svg cdsIcon="overflow-menu--horizontal" size="16" style="display: inherit" class="cds--pagination-nav__select-icon"> </svg> </div> </div> </li> <cds-pagination-nav-item *ngIf="count === 1" [page]="fromIndex + 1"></cds-pagination-nav-item> `, isInline: true, dependencies: [{ 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: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4$1.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: PaginationNavItem, selector: "cds-pagination-nav-item, ibm-pagination-nav-item", inputs: ["page", "isActive"], outputs: ["click"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationOverflow, decorators: [{ type: Component, args: [{ selector: "cds-pagination-overflow, ibm-pagination-overflow", template: ` <li class="cds--pagination-nav__list-item" *ngIf="count > 1"> <div class="cds--pagination-nav__select"> <select [attr.aria-label]="ariaLabel" class="cds--pagination-nav__page cds--pagination-nav__page--select" (change)="handleChange($event)"> <option value="" hidden></option> <option *ngFor="let item of countAsArray; let i = index"> {{fromIndex + i + 1}} </option> </select> <div class="cds--pagination-nav__select-icon-wrapper"> <svg cdsIcon="overflow-menu--horizontal" size="16" style="display: inherit" class="cds--pagination-nav__select-icon"> </svg> </div> </div> </li> <cds-pagination-nav-item *ngIf="count === 1" [page]="fromIndex + 1"></cds-pagination-nav-item> ` }] }], ctorParameters: function () { return [{ type: i1.I18n }]; }, propDecorators: { fromIndex: [{ type: Input }], count: [{ type: Input }], ariaLabel: [{ type: Input }], change: [{ type: Output }] } }); /** * Use pagination when you have multiple pages of data to handle. Get started with importing the module: * * ```typescript * import { PaginationModule } from 'carbon-components-angular'; * ``` * * ```html * <cds-pagination-nav [model]="model" (selectPage)="selectPage($event)"></cds-pagination-nav> * ``` * * In your `selectPage()` method set the `model.currentPage` to selected page, _after_ * you load the page. * * ```typescript * selectPage(page) { * // ... your code to load the page goes here * * this.model.currentPage = page; * * // ... anything you want to do after page selection changes goes here * } * ``` * * [See demo](../../?path=/story/components-pagination-nav--basic) */ class PaginationNav { constructor(i18n, experimental) { this.i18n = i18n; this.experimental = experimental; /** * Set to `true` to disable the backward/forward buttons. */ this.disabled = false; /** * Number of items to show in pagination. Minimum is 4. */ this.numOfItemsToShow = 4; /** * Sets the pagination nav size */ this.size = "lg"; /** * Emits the new page number. * * You should tie into this and update `model.currentPage` once the fresh * data is finally loaded. */ this.selectPage = new EventEmitter(); this.nextItemText = this.i18n.getOverridable("PAGINATION.NEXT"); this.previousItemText = this.i18n.getOverridable("PAGINATION.PREVIOUS"); PaginationNav.paginationCounter++; } /** * Expects an object that contains some or all of: * ``` * { * "NEXT": "Next", * "PREVIOUS": "Previous", * } * ``` */ set translations(value) { const valueWithDefaults = merge(this.i18n.getMultiple("PAGINATION"), value); this.nextItemText.override(valueWithDefaults.NEXT); this.previousItemText.override(valueWithDefaults.PREVIOUS); } // Size get smallLayoutSize() { return this.size === "sm"; } get mediumLayoutSize() { return this.size === "md"; } get largeLayoutSize() { return this.size === "lg"; } get totalNumbersArray() { return range(this.totalDataLength + 1, 1); } get currentPage() { return this.model.currentPage; } set currentPage(value) { value = Number(value); // emits the value to allow the user to update current page // in the model once the page is loaded this.selectPage.emit(value); } get totalDataLength() { return this.model.totalDataLength; } get startOffset() { return this.numOfItemsToShow <= 4 && this.currentPage > 1 ? 0 : 1; } get frontCuts() { const cuts = this.getCuts(); return cuts.front; } get backCuts() { const cuts = this.getCuts(); return cuts.back; } get leftArrowDisabled() { return this.disabled || this.currentPage === 1; } get rightArrowDisabled() { return this.disabled || this.currentPage === this.totalDataLength; } handleOverflowSelection(page) { if (typeof page === "number") { this.currentPage = page; } } jumpToNext() { this.currentPage = this.currentPage < this.totalDataLength ? this.currentPage + 1 : this.totalDataLength; } jumpToPrevious() { this.currentPage = this.currentPage > 1 ? this.currentPage - 1 : 1; } getPages() { if (this.totalDataLength <= 1) { return null; } const cuts = this.getCuts(); return this.totalNumbersArray.slice(this.startOffset + cuts.front, (1 + cuts.back) * -1); } getCuts(splitPoint = null) { const page = this.currentPage - 1; const totalItems = this.totalDataLength; const itemsThatFit = this.numOfItemsToShow; if (itemsThatFit >= totalItems) { return { front: 0, back: 0 }; } const split = splitPoint || Math.ceil(itemsThatFit / 2) - 1; let frontHidden = page + 1 - split; let backHidden = totalItems - page - (itemsThatFit - split) + 1; if (frontHidden <= 1) { backHidden -= frontHidden <= 0 ? Math.abs(frontHidden) + 1 : 0; frontHidden = 0; } if (backHidden <= 1) { frontHidden -= backHidden <= 0 ? Math.abs(backHidden) + 1 : 0; backHidden = 0; } return { front: frontHidden, back: backHidden }; } } PaginationNav.paginationCounter = 0; PaginationNav.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationNav, deps: [{ token: i1.I18n }, { token: i2.ExperimentalService }], target: i0.ɵɵFactoryTarget.Component }); PaginationNav.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PaginationNav, selector: "cds-pagination-nav, ibm-pagination-navm", inputs: { model: "model", disabled: "disabled", numOfItemsToShow: "numOfItemsToShow", translations: "translations", size: "size" }, outputs: { selectPage: "selectPage" }, host: { properties: { "class.cds--layout--size-sm": "this.smallLayoutSize", "class.cds--layout--size-md": "this.mediumLayoutSize", "class.cds--layout--size-lg": "this.largeLayoutSize" } }, ngImport: i0, template: ` <div> <div class="cds--pagination-nav"> <ul class="cds--pagination-nav__list"> <li class="cds--pagination-nav__list-item"> <cds-icon-button kind="ghost" [size]="size" (click)="jumpToPrevious()" [disabled]="leftArrowDisabled" [description]="previousItemText.subject | async"> <svg cdsIcon="caret--left" size="16" class="cds--btn__icon"> </svg> </cds-icon-button> </li> <cds-pagination-nav-item *ngIf="this.numOfItemsToShow >= 5 || (this.numOfItemsToShow <= 4 && currentPage <= 1)" page="1" (click)="currentPage = 1" [isActive]="currentPage == 1"> </cds-pagination-nav-item> <cds-pagination-overflow *ngIf="frontCuts" [count]="frontCuts" [fromIndex]="startOffset" (change)="handleOverflowSelection($event)"> </cds-pagination-overflow> <cds-pagination-nav-item *ngFor="let page of getPages();" [page]="page" (click)="currentPage = page" [isActive]="currentPage == page"> </cds-pagination-nav-item> <cds-pagination-overflow *ngIf="backCuts" [count]="backCuts" [fromIndex]="totalNumbersArray.length - backCuts - 1" (change)="handleOverflowSelection($event)"> </cds-pagination-overflow> <cds-pagination-nav-item *ngIf="totalDataLength > 1" [page]="totalNumbersArray.length" (click)="currentPage = totalNumbersArray.length" [isActive]="currentPage == totalNumbersArray.length"> </cds-pagination-nav-item> <li class="cds--pagination-nav__list-item"> <cds-icon-button kind="ghost" [size]="size" (click)="jumpToNext()" [disabled]="rightArrowDisabled" [description]="nextItemText.subject | async"> <svg cdsIcon="caret--right" size="16" class="cds--btn__icon"> </svg> </cds-icon-button> </li> </ul> </div> </div> `, isInline: true, dependencies: [{ 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: i4$1.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: i6.IconButton, selector: "cds-icon-button, ibm-icon-button", inputs: ["buttonNgClass", "buttonAttributes", "buttonId", "kind", "size", "type", "isExpressive", "disabled", "description", "showTooltipWhenDisabled"], outputs: ["click", "focus", "blur", "tooltipClick"] }, { kind: "component", type: PaginationNavItem, selector: "cds-pagination-nav-item, ibm-pagination-nav-item", inputs: ["page", "isActive"], outputs: ["click"] }, { kind: "component", type: PaginationOverflow, selector: "cds-pagination-overflow, ibm-pagination-overflow", inputs: ["fromIndex", "count", "ariaLabel"], outputs: ["change"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationNav, decorators: [{ type: Component, args: [{ selector: "cds-pagination-nav, ibm-pagination-navm", template: ` <div> <div class="cds--pagination-nav"> <ul class="cds--pagination-nav__list"> <li class="cds--pagination-nav__list-item"> <cds-icon-button kind="ghost" [size]="size" (click)="jumpToPrevious()" [disabled]="leftArrowDisabled" [description]="previousItemText.subject | async"> <svg cdsIcon="caret--left" size="16" class="cds--btn__icon"> </svg> </cds-icon-button> </li> <cds-pagination-nav-item *ngIf="this.numOfItemsToShow >= 5 || (this.numOfItemsToShow <= 4 && currentPage <= 1)" page="1" (click)="currentPage = 1" [isActive]="currentPage == 1"> </cds-pagination-nav-item> <cds-pagination-overflow *ngIf="frontCuts" [count]="frontCuts" [fromIndex]="startOffset" (change)="handleOverflowSelection($event)"> </cds-pagination-overflow> <cds-pagination-nav-item *ngFor="let page of getPages();" [page]="page" (click)="currentPage = page" [isActive]="currentPage == page"> </cds-pagination-nav-item> <cds-pagination-overflow *ngIf="backCuts" [count]="backCuts" [fromIndex]="totalNumbersArray.length - backCuts - 1" (change)="handleOverflowSelection($event)"> </cds-pagination-overflow> <cds-pagination-nav-item *ngIf="totalDataLength > 1" [page]="totalNumbersArray.length" (click)="currentPage = totalNumbersArray.length" [isActive]="currentPage == totalNumbersArray.length"> </cds-pagination-nav-item> <li class="cds--pagination-nav__list-item"> <cds-icon-button kind="ghost" [size]="size" (click)="jumpToNext()" [disabled]="rightArrowDisabled" [description]="nextItemText.subject | async"> <svg cdsIcon="caret--right" size="16" class="cds--btn__icon"> </svg> </cds-icon-button> </li> </ul> </div> </div> ` }] }], ctorParameters: function () { return [{ type: i1.I18n }, { type: i2.ExperimentalService }]; }, propDecorators: { model: [{ type: Input }], disabled: [{ type: Input }], numOfItemsToShow: [{ type: Input }], translations: [{ type: Input }], size: [{ type: Input }], smallLayoutSize: [{ type: HostBinding, args: ["class.cds--layout--size-sm"] }], mediumLayoutSize: [{ type: HostBinding, args: ["class.cds--layout--size-md"] }], largeLayoutSize: [{ type: HostBinding, args: ["class.cds--layout--size-lg"] }], selectPage: [{ type: Output }] } }); class PaginationModule { } PaginationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); PaginationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: PaginationModule, declarations: [Pagination, PaginationNav, PaginationNavItem, PaginationOverflow], imports: [CommonModule, FormsModule, I18nModule, ExperimentalModule, IconModule, ButtonModule], exports: [Pagination, PaginationNav, PaginationNavItem, PaginationOverflow] }); PaginationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationModule, imports: [CommonModule, FormsModule, I18nModule, ExperimentalModule, IconModule, ButtonModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationModule, decorators: [{ type: NgModule, args: [{ declarations: [ Pagination, PaginationNav, PaginationNavItem, PaginationOverflow ], exports: [ Pagination, PaginationNav, PaginationNavItem, PaginationOverflow ], imports: [ CommonModule, FormsModule, I18nModule, ExperimentalModule, IconModule, ButtonModule ] }] }] }); /** * Generated bundle index. Do not edit. */ export { Pagination, PaginationModel, PaginationModule, PaginationNav, PaginationNavItem, PaginationOverflow }; //# sourceMappingURL=carbon-components-angular-pagination.mjs.map