mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(pagination): initial pagination component (#5156)
This commit is contained in:
committed by
Jeremy Elbourn
parent
7b2d4ae601
commit
85fb00a151
Generated
+4
-4
@@ -4169,7 +4169,7 @@
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=",
|
||||
"dev": true
|
||||
},
|
||||
"glob-base": {
|
||||
@@ -8070,7 +8070,7 @@
|
||||
"npmlog": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.0.tgz",
|
||||
"integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==",
|
||||
"integrity": "sha1-3Fm+6F9k8A7UJO+yrweD3yXRwLU=",
|
||||
"dev": true
|
||||
},
|
||||
"null-check": {
|
||||
@@ -11254,7 +11254,7 @@
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
|
||||
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
|
||||
"integrity": "sha1-Vx4PGwYEY268DfwhsDObvjE0FxA=",
|
||||
"dev": true
|
||||
},
|
||||
"widest-line": {
|
||||
@@ -11316,7 +11316,7 @@
|
||||
"write-file-atomic": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz",
|
||||
"integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==",
|
||||
"integrity": "sha1-F2n0tVHu3OQZ8FBd6uLiZ2NULTc=",
|
||||
"dev": true
|
||||
},
|
||||
"write-file-stdout": {
|
||||
|
||||
@@ -78,4 +78,11 @@
|
||||
}">
|
||||
</cdk-row>
|
||||
</cdk-table>
|
||||
|
||||
<md-paginator #paginator
|
||||
[length]="_peopleDatabase.data.length"
|
||||
[pageIndex]="0"
|
||||
[pageSize]="10"
|
||||
[pageSizeOptions]="[5, 10, 25, 100]">
|
||||
</md-paginator>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {Component, ViewChild} from '@angular/core';
|
||||
import {PeopleDatabase, UserData} from './people-database';
|
||||
import {PersonDataSource} from './person-data-source';
|
||||
import {MdPaginator} from '@angular/material';
|
||||
|
||||
export type UserProperties = 'userId' | 'userName' | 'progress' | 'color' | undefined;
|
||||
|
||||
@@ -19,13 +20,17 @@ export class DataTableDemo {
|
||||
changeReferences = false;
|
||||
highlights = new Set<string>();
|
||||
|
||||
constructor(public _peopleDatabase: PeopleDatabase) {
|
||||
@ViewChild(MdPaginator) _paginator: MdPaginator;
|
||||
|
||||
constructor(public _peopleDatabase: PeopleDatabase) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.connect();
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.propertiesToDisplay = ['userId', 'userName', 'progress', 'color'];
|
||||
this.dataSource = new PersonDataSource(this._peopleDatabase);
|
||||
this.dataSource = new PersonDataSource(this._peopleDatabase, this._paginator);
|
||||
this._peopleDatabase.initialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +1,58 @@
|
||||
import {CollectionViewer, DataSource} from '@angular/material';
|
||||
import {CollectionViewer, DataSource, MdPaginator} from '@angular/material';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {PeopleDatabase, UserData} from './people-database';
|
||||
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
|
||||
|
||||
export class PersonDataSource extends DataSource<any> {
|
||||
/** Data that should be displayed by the table. */
|
||||
_displayData = new BehaviorSubject<UserData[]>([]);
|
||||
|
||||
/** Cached data provided by the display data. */
|
||||
_renderedData: any[] = [];
|
||||
|
||||
constructor(private _peopleDatabase: PeopleDatabase) {
|
||||
constructor(private _peopleDatabase: PeopleDatabase,
|
||||
private _paginator: MdPaginator) {
|
||||
super();
|
||||
|
||||
// Subscribe to page changes and database changes by clearing the cached data and
|
||||
// determining the updated display data.
|
||||
Observable.merge(this._paginator.page, this._peopleDatabase.dataChange).subscribe(() => {
|
||||
this._renderedData = [];
|
||||
this.updateDisplayData();
|
||||
});
|
||||
}
|
||||
|
||||
connect(collectionViewer: CollectionViewer): Observable<UserData[]> {
|
||||
const changeStreams = Observable.combineLatest(
|
||||
collectionViewer.viewChange,
|
||||
this._peopleDatabase.dataChange);
|
||||
return changeStreams.map((result: any[]) => {
|
||||
const view: {start: number, end: number} = result[0];
|
||||
this.updateDisplayData();
|
||||
|
||||
// Set the rendered rows length to the virtual page size. Fill in the data provided
|
||||
// from the index start until the end index or pagination size, whichever is smaller.
|
||||
this._renderedData.length = this._peopleDatabase.data.length;
|
||||
const streams = [collectionViewer.viewChange, this._displayData];
|
||||
return Observable.combineLatest(streams)
|
||||
.map((results: [{start: number, end: number}, UserData[]]) => {
|
||||
const [view, data] = results;
|
||||
|
||||
const buffer = 20;
|
||||
let rangeStart = Math.max(0, view.start - buffer);
|
||||
let rangeEnd = Math.min(this._peopleDatabase.data.length, view.end + buffer);
|
||||
// Set the rendered rows length to the virtual page size. Fill in the data provided
|
||||
// from the index start until the end index or pagination size, whichever is smaller.
|
||||
this._renderedData.length = data.length;
|
||||
|
||||
for (let i = rangeStart; i < rangeEnd; i++) {
|
||||
this._renderedData[i] = this._peopleDatabase.data[i];
|
||||
}
|
||||
const buffer = 20;
|
||||
let rangeStart = Math.max(0, view.start - buffer);
|
||||
let rangeEnd = Math.min(data.length, view.end + buffer);
|
||||
|
||||
return this._renderedData;
|
||||
});
|
||||
for (let i = rangeStart; i < rangeEnd; i++) {
|
||||
this._renderedData[i] = data[i];
|
||||
}
|
||||
|
||||
return this._renderedData;
|
||||
});
|
||||
}
|
||||
|
||||
updateDisplayData() {
|
||||
const data = this._peopleDatabase.data.slice();
|
||||
|
||||
// Grab the page's slice of data.
|
||||
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
|
||||
const paginatedData = data.splice(startIndex, this._paginator.pageSize);
|
||||
|
||||
this._displayData.next(paginatedData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import {
|
||||
MdListModule,
|
||||
MdMenuModule,
|
||||
MdNativeDateModule,
|
||||
MdPaginatorModule,
|
||||
MdProgressBarModule,
|
||||
MdProgressSpinnerModule,
|
||||
MdRadioModule,
|
||||
@@ -98,6 +99,7 @@ import {TableHeaderDemo} from './data-table/table-header-demo';
|
||||
MdListModule,
|
||||
MdMenuModule,
|
||||
MdCoreModule,
|
||||
MdPaginatorModule,
|
||||
MdProgressBarModule,
|
||||
MdProgressSpinnerModule,
|
||||
MdRadioModule,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
@import '../../input/input-theme';
|
||||
@import '../../list/list-theme';
|
||||
@import '../../menu/menu-theme';
|
||||
@import '../../paginator/paginator-theme';
|
||||
@import '../../progress-bar/progress-bar-theme';
|
||||
@import '../../progress-spinner/progress-spinner-theme';
|
||||
@import '../../radio/radio-theme';
|
||||
@@ -44,6 +45,7 @@
|
||||
@include mat-input-theme($theme);
|
||||
@include mat-list-theme($theme);
|
||||
@include mat-menu-theme($theme);
|
||||
@include mat-paginator-theme($theme);
|
||||
@include mat-progress-bar-theme($theme);
|
||||
@include mat-progress-spinner-theme($theme);
|
||||
@include mat-radio-theme($theme);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
@import '../../input/input-theme';
|
||||
@import '../../list/list-theme';
|
||||
@import '../../menu/menu-theme';
|
||||
@import '../../paginator/paginator-theme';
|
||||
@import '../../progress-bar/progress-bar-theme';
|
||||
@import '../../progress-spinner/progress-spinner-theme';
|
||||
@import '../../radio/radio-theme';
|
||||
@@ -42,6 +43,7 @@
|
||||
@include mat-icon-typography($config);
|
||||
@include mat-input-typography($config);
|
||||
@include mat-menu-typography($config);
|
||||
@include mat-paginator-typography($config);
|
||||
@include mat-progress-bar-typography($config);
|
||||
@include mat-progress-spinner-typography($config);
|
||||
@include mat-radio-typography($config);
|
||||
|
||||
@@ -46,6 +46,7 @@ import {StyleModule} from './core/style/index';
|
||||
import {MdDatepickerModule} from './datepicker/index';
|
||||
import {CdkDataTableModule} from './core/data-table/index';
|
||||
import {MdExpansionModule} from './expansion/index';
|
||||
import {MdPaginatorModule} from './paginator/index';
|
||||
|
||||
const MATERIAL_MODULES = [
|
||||
MdAutocompleteModule,
|
||||
@@ -62,6 +63,7 @@ const MATERIAL_MODULES = [
|
||||
MdInputModule,
|
||||
MdListModule,
|
||||
MdMenuModule,
|
||||
MdPaginatorModule,
|
||||
MdProgressBarModule,
|
||||
MdProgressSpinnerModule,
|
||||
MdRadioModule,
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
@import '../core/theming/palette';
|
||||
@import '../core/theming/theming';
|
||||
@import '../core/typography/typography-utils';
|
||||
|
||||
|
||||
@mixin mat-paginator-theme($theme) {
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
.mat-paginator,
|
||||
.mat-paginator-page-size .mat-select-trigger {
|
||||
color: mat-color($foreground, secondary-text);
|
||||
}
|
||||
|
||||
.mat-paginator-increment,
|
||||
.mat-paginator-decrement {
|
||||
border-top: 2px solid mat-color($foreground, 'icon');
|
||||
border-right: 2px solid mat-color($foreground, 'icon');
|
||||
}
|
||||
|
||||
.mat-icon-button[disabled] {
|
||||
.mat-paginator-increment,
|
||||
.mat-paginator-decrement {
|
||||
border-color: mat-color($foreground, 'disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin mat-paginator-typography($config) {
|
||||
.mat-paginator {
|
||||
font: {
|
||||
family: mat-font-family($config);
|
||||
size: mat-font-size($config, caption);
|
||||
}
|
||||
}
|
||||
|
||||
.mat-paginator-page-size .mat-select-trigger {
|
||||
font: {
|
||||
family: mat-font-family($config);
|
||||
size: mat-font-size($config, caption);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {MdCommonModule, OverlayModule} from '../core';
|
||||
import {MdButtonModule} from '../button/index';
|
||||
import {MdSelectModule} from '../select/index';
|
||||
import {MdPaginator} from './paginator';
|
||||
import {MdPaginatorIntl} from './paginator-intl';
|
||||
import {MdTooltipModule} from '../tooltip/index';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
MdButtonModule,
|
||||
MdSelectModule,
|
||||
MdTooltipModule,
|
||||
],
|
||||
exports: [MdPaginator],
|
||||
declarations: [MdPaginator],
|
||||
providers: [MdPaginatorIntl],
|
||||
})
|
||||
export class MdPaginatorModule {}
|
||||
|
||||
|
||||
export * from './paginator';
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
/**
|
||||
* To modify the labels and text displayed, create a new instance of MdPaginatorIntl and
|
||||
* include it in a custom provider
|
||||
*/
|
||||
@Injectable()
|
||||
export class MdPaginatorIntl {
|
||||
/** A label for the page size selector. */
|
||||
itemsPerPageLabel = 'Items per page:';
|
||||
|
||||
/** A label for the button that increments the current page. */
|
||||
nextPageLabel = 'Next page';
|
||||
|
||||
/** A label for the button that decrements the current page. */
|
||||
previousPageLabel = 'Previous page';
|
||||
|
||||
/** A label for the range of items within the current page and the length of the whole list. */
|
||||
getRangeLabel = (page: number, pageSize: number, length: number) => {
|
||||
if (length == 0 || pageSize == 0) { return `0 of ${length}`; }
|
||||
|
||||
length = Math.max(length, 0);
|
||||
|
||||
const startIndex = page * pageSize;
|
||||
|
||||
// If the start index exceeds the list length, do not try and fix the end index to the end.
|
||||
const endIndex = startIndex < length ?
|
||||
Math.min(startIndex + pageSize, length) :
|
||||
startIndex + pageSize;
|
||||
|
||||
return `${startIndex + 1} - ${endIndex} of ${length}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<div class="mat-paginator-page-size">
|
||||
<div class="mat-paginator-page-size-label">
|
||||
{{_intl.itemsPerPageLabel}}
|
||||
</div>
|
||||
|
||||
<md-select *ngIf="_displayedPageSizeOptions.length > 1"
|
||||
class="mat-paginator-page-size-select"
|
||||
[ngModel]="pageSize"
|
||||
[aria-label]="_intl.itemsPerPageLabel"
|
||||
(change)="_changePageSize($event.value)">
|
||||
<md-option *ngFor="let pageSizeOption of _displayedPageSizeOptions" [value]="pageSizeOption">
|
||||
{{pageSizeOption}}
|
||||
</md-option>
|
||||
</md-select>
|
||||
|
||||
<div *ngIf="_displayedPageSizeOptions.length <= 1">{{pageSize}}</div>
|
||||
</div>
|
||||
|
||||
<div class="mat-paginator-range-label">
|
||||
{{_intl.getRangeLabel(pageIndex, pageSize, length)}}
|
||||
</div>
|
||||
|
||||
<button md-icon-button
|
||||
class="mat-paginator-navigation-previous"
|
||||
(click)="previousPage()"
|
||||
[attr.aria-label]="_intl.previousPageLabel"
|
||||
[mdTooltip]="_intl.previousPageLabel"
|
||||
[mdTooltipPosition]="'above'"
|
||||
[disabled]="!hasPreviousPage()">
|
||||
<div class="mat-paginator-increment"></div>
|
||||
</button>
|
||||
<button md-icon-button
|
||||
class="mat-paginator-navigation-next"
|
||||
(click)="nextPage()"
|
||||
[attr.aria-label]="_intl.nextPageLabel"
|
||||
[mdTooltip]="_intl.nextPageLabel"
|
||||
[mdTooltipPosition]="'above'"
|
||||
[disabled]="!hasNextPage()">
|
||||
<div class="mat-paginator-decrement"></div>
|
||||
</button>
|
||||
@@ -0,0 +1,26 @@
|
||||
`<md-paginator>` is a navigation for pages information, typically used with a data-table.
|
||||
|
||||
<!-- example(pagination-overview) -->
|
||||
|
||||
### Basic use
|
||||
Each paginator instance requires:
|
||||
* The number of items per page (default set to 50)
|
||||
* The total number of items being paged
|
||||
|
||||
The current page index defaults to 0, but can be explicitly set via pageIndex.
|
||||
|
||||
When the user interacts with the paginator, a `PageEvent` will be fired that can be used to update
|
||||
any associated data view.
|
||||
|
||||
### Page size options
|
||||
The paginator displays a dropdown of page sizes for the user to choose from. The options for this
|
||||
dropdown can be set via `pageSizeOptions`
|
||||
|
||||
The current pageSize will always appear in the dropdown, even if it is not included in pageSizeOptions.
|
||||
|
||||
### Internationalization
|
||||
The labels for the paginator can be customized by providing your own instance of `MdPaginatorIntl`.
|
||||
This will allow you to change the following:
|
||||
1. The label for the length of each page.
|
||||
2. The range text displayed to the user.
|
||||
3. The tooltip messages on the navigation buttons.
|
||||
@@ -0,0 +1,81 @@
|
||||
$mat-paginator-height: 56px;
|
||||
$mat-paginator-padding: 0 8px;
|
||||
|
||||
$mat-paginator-items-per-page-label-margin: 0 4px;
|
||||
$mat-paginator-selector-margin: 0 4px;
|
||||
$mat-paginator-selector-trigger-min-width: 56px;
|
||||
|
||||
$mat-paginator-range-label-margin: 0 32px;
|
||||
|
||||
$mat-paginator-button-margin: 8px;
|
||||
$mat-paginator-button-icon-height: 8px;
|
||||
$mat-paginator-button-icon-width: 8px;
|
||||
|
||||
$mat-paginator-button-decrement-icon-margin: 12px;
|
||||
$mat-paginator-button-increment-icon-margin: 16px;
|
||||
|
||||
.mat-paginator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
min-height: $mat-paginator-height;
|
||||
padding: $mat-paginator-padding;
|
||||
}
|
||||
|
||||
.mat-paginator-page-size {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mat-paginator-page-size-label {
|
||||
margin: $mat-paginator-items-per-page-label-margin;
|
||||
}
|
||||
|
||||
.mat-paginator-page-size-select {
|
||||
margin: $mat-paginator-selector-margin;
|
||||
|
||||
.mat-select-trigger {
|
||||
min-width: $mat-paginator-selector-trigger-min-width;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-paginator-range-label {
|
||||
margin: $mat-paginator-range-label-margin;
|
||||
}
|
||||
|
||||
.mat-paginator-increment-button + .mat-paginator-increment-button {
|
||||
margin: 0 0 0 $mat-paginator-button-margin;
|
||||
|
||||
[dir='rtl'] & {
|
||||
margin: 0 $mat-paginator-button-margin 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-paginator-increment,
|
||||
.mat-paginator-decrement {
|
||||
width: $mat-paginator-button-icon-width;
|
||||
height: $mat-paginator-button-icon-height;
|
||||
}
|
||||
|
||||
.mat-paginator-decrement,
|
||||
[dir='rtl'] .mat-paginator-increment {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.mat-paginator-increment,
|
||||
[dir='rtl'] .mat-paginator-decrement {
|
||||
transform: rotate(225deg);
|
||||
}
|
||||
|
||||
.mat-paginator-decrement {
|
||||
margin-left: $mat-paginator-button-decrement-icon-margin;
|
||||
[dir='rtl'] & {
|
||||
margin-right: $mat-paginator-button-decrement-icon-margin;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-paginator-increment {
|
||||
margin-left: $mat-paginator-button-increment-icon-margin;
|
||||
[dir='rtl'] & {
|
||||
margin-right: $mat-paginator-button-increment-icon-margin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import {MdPaginatorModule} from './index';
|
||||
import {MdPaginator, PageEvent} from './paginator';
|
||||
import {Component, ElementRef, ViewChild} from '@angular/core';
|
||||
import {MdPaginatorIntl} from './paginator-intl';
|
||||
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {customMatchers} from '../core/testing/jasmine-matchers';
|
||||
import {dispatchMouseEvent} from '../core/testing/dispatch-events';
|
||||
|
||||
|
||||
describe('MdPaginator', () => {
|
||||
let fixture: ComponentFixture<MdPaginatorApp>;
|
||||
let component: MdPaginatorApp;
|
||||
let paginator: MdPaginator;
|
||||
|
||||
beforeEach(async(() => {
|
||||
jasmine.addMatchers(customMatchers);
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
MdPaginatorModule,
|
||||
NoopAnimationsModule,
|
||||
],
|
||||
declarations: [
|
||||
MdPaginatorApp,
|
||||
MdPaginatorWithoutPageSizeApp,
|
||||
MdPaginatorWithoutOptionsApp,
|
||||
],
|
||||
providers: [MdPaginatorIntl]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(MdPaginatorApp);
|
||||
component = fixture.componentInstance;
|
||||
paginator = component.mdPaginator;
|
||||
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
describe('with the default internationalization provider', () => {
|
||||
it('should show the right range text', () => {
|
||||
const rangeElement = fixture.nativeElement.querySelector('.mat-paginator-range-label');
|
||||
|
||||
// View second page of list of 100, each page contains 10 items.
|
||||
component.length = 100;
|
||||
component.pageSize = 10;
|
||||
component.pageIndex = 1;
|
||||
fixture.detectChanges();
|
||||
expect(rangeElement.innerText).toBe('11 - 20 of 100');
|
||||
|
||||
// View third page of list of 200, each page contains 20 items.
|
||||
component.length = 200;
|
||||
component.pageSize = 20;
|
||||
component.pageIndex = 2;
|
||||
fixture.detectChanges();
|
||||
expect(rangeElement.innerText).toBe('41 - 60 of 200');
|
||||
|
||||
// View first page of list of 0, each page contains 5 items.
|
||||
component.length = 0;
|
||||
component.pageSize = 5;
|
||||
component.pageIndex = 2;
|
||||
fixture.detectChanges();
|
||||
expect(rangeElement.innerText).toBe('0 of 0');
|
||||
|
||||
// View third page of list of 12, each page contains 5 items.
|
||||
component.length = 12;
|
||||
component.pageSize = 5;
|
||||
component.pageIndex = 2;
|
||||
fixture.detectChanges();
|
||||
expect(rangeElement.innerText).toBe('11 - 12 of 12');
|
||||
|
||||
// View third page of list of 10, each page contains 5 items.
|
||||
component.length = 10;
|
||||
component.pageSize = 5;
|
||||
component.pageIndex = 2;
|
||||
fixture.detectChanges();
|
||||
expect(rangeElement.innerText).toBe('11 - 15 of 10');
|
||||
|
||||
// View third page of list of -5, each page contains 5 items.
|
||||
component.length = -5;
|
||||
component.pageSize = 5;
|
||||
component.pageIndex = 2;
|
||||
fixture.detectChanges();
|
||||
expect(rangeElement.innerText).toBe('11 - 15 of 0');
|
||||
});
|
||||
|
||||
it('should show right aria-labels for select and buttons', () => {
|
||||
const select = fixture.nativeElement.querySelector('.mat-select');
|
||||
expect(select.getAttribute('aria-label')).toBe('Items per page:');
|
||||
|
||||
const prevButton = fixture.nativeElement.querySelector('.mat-paginator-navigation-previous');
|
||||
expect(prevButton.getAttribute('aria-label')).toBe('Previous page');
|
||||
|
||||
const nextButton = fixture.nativeElement.querySelector('.mat-paginator-navigation-next');
|
||||
expect(nextButton.getAttribute('aria-label')).toBe('Next page');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when navigating with the navigation buttons', () => {
|
||||
it('should be able to go to the next page', () => {
|
||||
expect(paginator.pageIndex).toBe(0);
|
||||
|
||||
component.clickNextButton();
|
||||
|
||||
expect(paginator.pageIndex).toBe(1);
|
||||
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(1);
|
||||
});
|
||||
|
||||
it('should be able to go to the previous page', () => {
|
||||
paginator.pageIndex = 1;
|
||||
fixture.detectChanges();
|
||||
expect(paginator.pageIndex).toBe(1);
|
||||
|
||||
component.clickPreviousButton();
|
||||
|
||||
expect(paginator.pageIndex).toBe(0);
|
||||
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(0);
|
||||
});
|
||||
|
||||
it('should disable navigating to the next page if at first page', () => {
|
||||
component.goToLastPage();
|
||||
fixture.detectChanges();
|
||||
expect(paginator.pageIndex).toBe(10);
|
||||
expect(paginator.hasNextPage()).toBe(false);
|
||||
|
||||
component.latestPageEvent = null;
|
||||
component.clickNextButton();
|
||||
|
||||
expect(component.latestPageEvent).toBe(null);
|
||||
expect(paginator.pageIndex).toBe(10);
|
||||
});
|
||||
|
||||
it('should disable navigating to the previous page if at first page', () => {
|
||||
expect(paginator.pageIndex).toBe(0);
|
||||
expect(paginator.hasPreviousPage()).toBe(false);
|
||||
|
||||
component.latestPageEvent = null;
|
||||
component.clickPreviousButton();
|
||||
|
||||
expect(component.latestPageEvent).toBe(null);
|
||||
expect(paginator.pageIndex).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should default the page size options to the page size if no options provided', () => {
|
||||
const withoutOptionsAppFixture = TestBed.createComponent(MdPaginatorWithoutOptionsApp);
|
||||
withoutOptionsAppFixture.detectChanges();
|
||||
|
||||
expect(withoutOptionsAppFixture.componentInstance.mdPaginator._displayedPageSizeOptions)
|
||||
.toEqual([10]);
|
||||
});
|
||||
|
||||
it('should show a sorted list of page size options including the current page size', () => {
|
||||
expect(paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 100]);
|
||||
|
||||
component.pageSize = 30;
|
||||
fixture.detectChanges();
|
||||
expect(paginator.pageSizeOptions).toEqual([5, 10, 25, 100]);
|
||||
expect(paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 30, 100]);
|
||||
|
||||
component.pageSizeOptions = [100, 25, 10, 5];
|
||||
fixture.detectChanges();
|
||||
expect(paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 30, 100]);
|
||||
});
|
||||
|
||||
it('should be able to change the page size while keeping the first item present', () => {
|
||||
// Start on the third page of a list of 100 with a page size of 10.
|
||||
component.pageIndex = 4;
|
||||
component.pageSize = 10;
|
||||
component.length = 100;
|
||||
fixture.detectChanges();
|
||||
|
||||
// The first item of the page should be item with index 40
|
||||
let firstPageItemIndex: number | null = paginator.pageIndex * paginator.pageSize;
|
||||
expect(firstPageItemIndex).toBe(40);
|
||||
|
||||
// The first item on the page is now 25. Change the page size to 25 so that we should now be
|
||||
// on the second page where the top item is index 25.
|
||||
paginator._changePageSize(25);
|
||||
let paginationEvent = component.latestPageEvent;
|
||||
firstPageItemIndex = paginationEvent ?
|
||||
paginationEvent.pageIndex * paginationEvent.pageSize : null;
|
||||
expect(firstPageItemIndex).toBe(25);
|
||||
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(1);
|
||||
|
||||
// The first item on the page is still 25. Change the page size to 8 so that we should now be
|
||||
// on the fourth page where the top item is index 24.
|
||||
paginator._changePageSize(8);
|
||||
paginationEvent = component.latestPageEvent;
|
||||
firstPageItemIndex = paginationEvent ?
|
||||
paginationEvent.pageIndex * paginationEvent.pageSize : null;
|
||||
expect(firstPageItemIndex).toBe(24);
|
||||
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(3);
|
||||
|
||||
// The first item on the page is 24. Change the page size to 16 so that we should now be
|
||||
// on the first page where the top item is index 0.
|
||||
paginator._changePageSize(25);
|
||||
paginationEvent = component.latestPageEvent;
|
||||
firstPageItemIndex = paginationEvent ?
|
||||
paginationEvent.pageIndex * paginationEvent.pageSize : null;
|
||||
expect(firstPageItemIndex).toBe(0);
|
||||
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(0);
|
||||
});
|
||||
|
||||
it('should show a select only if there are multiple options', () => {
|
||||
expect(paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 100]);
|
||||
expect(fixture.nativeElement.querySelector('.mat-select')).not.toBeNull();
|
||||
|
||||
// Remove options so that the paginator only uses the current page size (10) as an option.
|
||||
// Should no longer show the select component since there is only one option.
|
||||
component.pageSizeOptions = [];
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement.querySelector('.mat-select')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<md-paginator [pageIndex]="pageIndex"
|
||||
[pageSize]="pageSize"
|
||||
[pageSizeOptions]="pageSizeOptions"
|
||||
[length]="length"
|
||||
(page)="latestPageEvent = $event">
|
||||
</md-paginator>
|
||||
`,
|
||||
})
|
||||
class MdPaginatorApp {
|
||||
pageIndex = 0;
|
||||
pageSize = 10;
|
||||
pageSizeOptions = [5, 10, 25, 100];
|
||||
length = 100;
|
||||
|
||||
latestPageEvent: PageEvent | null;
|
||||
|
||||
@ViewChild(MdPaginator) mdPaginator: MdPaginator;
|
||||
|
||||
constructor(private _elementRef: ElementRef) { }
|
||||
|
||||
clickPreviousButton() {
|
||||
const previousButton =
|
||||
this._elementRef.nativeElement.querySelector('.mat-paginator-navigation-previous');
|
||||
dispatchMouseEvent(previousButton, 'click');
|
||||
}
|
||||
|
||||
clickNextButton() {
|
||||
const nextButton =
|
||||
this._elementRef.nativeElement.querySelector('.mat-paginator-navigation-next');
|
||||
dispatchMouseEvent(nextButton, 'click'); }
|
||||
|
||||
goToLastPage() {
|
||||
this.pageIndex = Math.ceil(this.length / this.pageSize);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<md-paginator [length]="100"></md-paginator>
|
||||
`,
|
||||
})
|
||||
class MdPaginatorWithoutPageSizeOrOptionsApp {
|
||||
@ViewChild(MdPaginator) mdPaginator: MdPaginator;
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<md-paginator [pageSizeOptions]="[10, 20, 30]"></md-paginator>
|
||||
`,
|
||||
})
|
||||
class MdPaginatorWithoutPageSizeApp {
|
||||
@ViewChild(MdPaginator) mdPaginator: MdPaginator;
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<md-paginator [pageSize]="10"></md-paginator>
|
||||
`,
|
||||
})
|
||||
class MdPaginatorWithoutOptionsApp {
|
||||
@ViewChild(MdPaginator) mdPaginator: MdPaginator;
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import {MdPaginatorIntl} from './paginator-intl';
|
||||
import {MATERIAL_COMPATIBILITY_MODE} from '../core';
|
||||
|
||||
/**
|
||||
* Change event object that is emitted when the user selects a
|
||||
* different page size or navigates to another page.
|
||||
*/
|
||||
export class PageEvent {
|
||||
pageIndex: number;
|
||||
pageSize: number;
|
||||
length: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to provide navigation between paged information. Displays the size of the current
|
||||
* page, user-selectable options to change that size, what items are being shown, and
|
||||
* navigational button to go to the previous or next page.
|
||||
*/
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'md-paginator, mat-paginator',
|
||||
templateUrl: 'paginator.html',
|
||||
styleUrls: ['paginator.css'],
|
||||
host: {
|
||||
'class': 'mat-paginator',
|
||||
},
|
||||
providers: [
|
||||
{provide: MATERIAL_COMPATIBILITY_MODE, useValue: false}
|
||||
],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
export class MdPaginator implements OnInit {
|
||||
private _initialized: boolean;
|
||||
|
||||
/** The zero-based page index of the displayed list of items. Defaulted to 0. */
|
||||
@Input() pageIndex: number = 0;
|
||||
|
||||
/** The length of the total number of items that are being paginated. Defaulted to 0. */
|
||||
@Input() length: number = 0;
|
||||
|
||||
/** Number of items to display on a page. By default set to 50. */
|
||||
@Input()
|
||||
get pageSize(): number { return this._pageSize; }
|
||||
set pageSize(pageSize: number) {
|
||||
this._pageSize = pageSize;
|
||||
this._updateDisplayedPageSizeOptions();
|
||||
}
|
||||
private _pageSize: number = 50;
|
||||
|
||||
/** The set of provided page size options to display to the user. */
|
||||
@Input()
|
||||
get pageSizeOptions(): number[] { return this._pageSizeOptions; }
|
||||
set pageSizeOptions(pageSizeOptions: number[]) {
|
||||
this._pageSizeOptions = pageSizeOptions;
|
||||
this._updateDisplayedPageSizeOptions();
|
||||
}
|
||||
private _pageSizeOptions: number[] = [];
|
||||
|
||||
/** Event emitted when the paginator changes the page size or page index. */
|
||||
@Output() page = new EventEmitter<PageEvent>();
|
||||
|
||||
/** Displayed set of page size options. Will be sorted and include current page size. */
|
||||
_displayedPageSizeOptions: number[];
|
||||
|
||||
constructor(public _intl: MdPaginatorIntl) { }
|
||||
|
||||
ngOnInit() {
|
||||
this._initialized = true;
|
||||
this._updateDisplayedPageSizeOptions();
|
||||
}
|
||||
|
||||
/** Increments the page index to the next page index if a next page exists. */
|
||||
nextPage() {
|
||||
if (!this.hasNextPage()) { return; }
|
||||
this.pageIndex++;
|
||||
this._emitPageEvent();
|
||||
}
|
||||
|
||||
/** Decrements the page index to the previous page index if a next page exists. */
|
||||
previousPage() {
|
||||
if (!this.hasPreviousPage()) { return; }
|
||||
this.pageIndex--;
|
||||
this._emitPageEvent();
|
||||
}
|
||||
|
||||
/** Returns true if the user can go to the next page. */
|
||||
hasPreviousPage() {
|
||||
return this.pageIndex >= 1 && this.pageSize != 0;
|
||||
}
|
||||
|
||||
/** Returns true if the user can go to the next page. */
|
||||
hasNextPage() {
|
||||
const numberOfPages = Math.ceil(this.length / this.pageSize) - 1;
|
||||
return this.pageIndex < numberOfPages && this.pageSize != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the page size so that the first item displayed on the page will still be
|
||||
* displayed using the new page size.
|
||||
*
|
||||
* For example, if the page size is 10 and on the second page (items indexed 10-19) then
|
||||
* switching so that the page size is 5 will set the third page as the current page so
|
||||
* that the 10th item will still be displayed.
|
||||
*/
|
||||
_changePageSize(pageSize: number) {
|
||||
// Current page needs to be updated to reflect the new page size. Navigate to the page
|
||||
// containing the previous page's first item.
|
||||
const startIndex = this.pageIndex * this.pageSize;
|
||||
this.pageIndex = Math.floor(startIndex / pageSize) || 0;
|
||||
|
||||
this.pageSize = pageSize;
|
||||
this._emitPageEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the list of page size options to display to the user. Includes making sure that
|
||||
* the page size is an option and that the list is sorted.
|
||||
*/
|
||||
private _updateDisplayedPageSizeOptions() {
|
||||
if (!this._initialized) { return; }
|
||||
|
||||
this._displayedPageSizeOptions = this.pageSizeOptions.slice();
|
||||
if (this._displayedPageSizeOptions.indexOf(this.pageSize) == -1) {
|
||||
this._displayedPageSizeOptions.push(this.pageSize);
|
||||
}
|
||||
|
||||
// Sort the numbers using a number-specific sort function.
|
||||
this._displayedPageSizeOptions.sort((a, b) => a - b);
|
||||
}
|
||||
|
||||
/** Emits an event notifying that a change of the paginator's properties has been triggered. */
|
||||
private _emitPageEvent() {
|
||||
this.page.next({
|
||||
pageIndex: this.pageIndex,
|
||||
pageSize: this.pageSize,
|
||||
length: this.length
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ export * from './icon/index';
|
||||
export * from './input/index';
|
||||
export * from './list/index';
|
||||
export * from './menu/index';
|
||||
export * from './paginator/index';
|
||||
export * from './progress-bar/index';
|
||||
export * from './progress-spinner/index';
|
||||
export * from './radio/index';
|
||||
|
||||
@@ -15,8 +15,8 @@ import {
|
||||
ProgressBarConfigurableExample
|
||||
} from './progress-bar-configurable/progress-bar-configurable-example';
|
||||
import {
|
||||
DialogOverviewExampleDialog,
|
||||
DialogOverviewExample
|
||||
DialogOverviewExample,
|
||||
DialogOverviewExampleDialog
|
||||
} from './dialog-overview/dialog-overview-example';
|
||||
import {RadioNgModelExample} from './radio-ng-model/radio-ng-model-example';
|
||||
import {CardFancyExample} from './card-fancy/card-fancy-example';
|
||||
@@ -36,12 +36,12 @@ import {
|
||||
import {ListSectionsExample} from './list-sections/list-sections-example';
|
||||
import {SnackBarOverviewExample} from './snack-bar-overview/snack-bar-overview-example';
|
||||
import {
|
||||
DialogResultExampleDialog,
|
||||
DialogResultExample
|
||||
DialogResultExample,
|
||||
DialogResultExampleDialog
|
||||
} from './dialog-result/dialog-result-example';
|
||||
import {
|
||||
DialogElementsExampleDialog,
|
||||
DialogElementsExample
|
||||
DialogElementsExample,
|
||||
DialogElementsExampleDialog
|
||||
} from './dialog-elements/dialog-elements-example';
|
||||
import {TooltipOverviewExample} from './tooltip-overview/tooltip-overview-example';
|
||||
import {ButtonToggleOverviewExample} from './button-toggle-overview/button-toggle-overview-example';
|
||||
@@ -68,20 +68,22 @@ import {SelectOverviewExample} from './select-overview/select-overview-example';
|
||||
import {ChipsOverviewExample} from './chips-overview/chips-overview-example';
|
||||
import {ChipsStackedExample} from './chips-stacked/chips-stacked-example';
|
||||
import {SelectFormExample} from './select-form/select-form-example';
|
||||
import {PaginatorOverviewExample} from './paginator-overview/paginator-overview-example';
|
||||
import {DatepickerOverviewExample} from './datepicker-overview/datepicker-overview-example';
|
||||
import {
|
||||
PaginatorConfigurableExample
|
||||
} from './paginator-configurable/paginator-configurable-example';
|
||||
import {InputOverviewExample} from './input-overview/input-overview-example';
|
||||
import {InputErrorsExample} from './input-errors/input-errors-example';
|
||||
import {InputFormExample} from './input-form/input-form-example';
|
||||
import {InputPrefixSuffixExample} from './input-prefix-suffix/input-prefix-suffix-example';
|
||||
import {InputHintExample} from './input-hint/input-hint-example';
|
||||
|
||||
import {
|
||||
MdAutocompleteModule, MdButtonModule, MdButtonToggleModule, MdCardModule, MdCheckboxModule,
|
||||
MdChipsModule, MdDatepickerModule, MdDialogModule, MdGridListModule, MdIconModule, MdInputModule,
|
||||
MdListModule, MdMenuModule, MdProgressBarModule, MdProgressSpinnerModule, MdRadioModule,
|
||||
MdSelectModule, MdSidenavModule, MdSliderModule, MdSlideToggleModule, MdSnackBarModule,
|
||||
MdTabsModule,
|
||||
MdToolbarModule, MdTooltipModule
|
||||
MdListModule, MdMenuModule, MdPaginatorModule, MdProgressBarModule, MdProgressSpinnerModule,
|
||||
MdRadioModule, MdSelectModule, MdSidenavModule, MdSliderModule, MdSlideToggleModule,
|
||||
MdSnackBarModule, MdTabsModule, MdToolbarModule, MdTooltipModule
|
||||
} from '@angular/material';
|
||||
|
||||
export interface LiveExample {
|
||||
@@ -143,6 +145,11 @@ export const EXAMPLE_COMPONENTS = {
|
||||
'list-sections': {title: 'List with sections', component: ListSectionsExample},
|
||||
'menu-icons': {title: 'Menu with icons', component: MenuIconsExample},
|
||||
'menu-overview': {title: 'Basic menu', component: MenuOverviewExample},
|
||||
'paginator-overview': {title: 'Paginator', component: PaginatorOverviewExample},
|
||||
'paginator-configurable': {
|
||||
title: 'Configurable paginator',
|
||||
component: PaginatorConfigurableExample
|
||||
},
|
||||
'progress-bar-configurable': {
|
||||
title: 'Configurable progress-bar',
|
||||
component: ProgressBarConfigurableExample
|
||||
@@ -201,6 +208,7 @@ export const EXAMPLE_COMPONENTS = {
|
||||
MdInputModule,
|
||||
MdListModule,
|
||||
MdMenuModule,
|
||||
MdPaginatorModule,
|
||||
MdProgressBarModule,
|
||||
MdProgressSpinnerModule,
|
||||
MdRadioModule,
|
||||
@@ -252,6 +260,7 @@ export const EXAMPLE_LIST = [
|
||||
ListSectionsExample,
|
||||
MenuIconsExample,
|
||||
MenuOverviewExample,
|
||||
PaginatorOverviewExample,
|
||||
ProgressBarConfigurableExample,
|
||||
ProgressBarOverviewExample,
|
||||
ProgressSpinnerConfigurableExample,
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/** No CSS for this example */
|
||||
@@ -0,0 +1,28 @@
|
||||
<md-input-container>
|
||||
List length:
|
||||
<input mdInput [(ngModel)]="length">
|
||||
</md-input-container>
|
||||
|
||||
<md-input-container>
|
||||
Page size:
|
||||
<input mdInput [(ngModel)]="pageSize">
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
Page size options:
|
||||
<input mdInput
|
||||
[ngModel]="pageSizeOptions"
|
||||
(ngModelChange)="setPageSizeOptions($event)">
|
||||
</md-input-container>
|
||||
|
||||
<md-paginator [length]="length"
|
||||
[pageSize]="pageSize"
|
||||
[pageSizeOptions]="pageSizeOptions"
|
||||
(page)="pageEvent = $event">
|
||||
</md-paginator>
|
||||
|
||||
<div *ngIf="pageEvent">
|
||||
<h2>Page Change Event Properties</h2>
|
||||
<div>List length: {{pageEvent.length}}</div>
|
||||
<div>Page size: {{pageEvent.pageSize}}</div>
|
||||
<div>Page index: {{pageEvent.pageIndex}}</div>
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {PageEvent} from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector: 'paginator-configurable-example',
|
||||
templateUrl: 'paginator-configurable-example.html',
|
||||
})
|
||||
export class PaginatorConfigurableExample {
|
||||
// MdPaginator Inputs
|
||||
length = 100;
|
||||
pageSize = 10;
|
||||
pageSizeOptions = [5, 10, 25, 100];
|
||||
|
||||
// MdPaginator Output
|
||||
pageEvent: PageEvent;
|
||||
|
||||
setPageSizeOptions(setPageSizeOptionsInput: string) {
|
||||
this.pageSizeOptions = setPageSizeOptionsInput.split(',').map(str => +str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
/** No CSS for this example */
|
||||
@@ -0,0 +1,4 @@
|
||||
<md-paginator [length]="100"
|
||||
[pageSize]="10"
|
||||
[pageSizeOptions]="[5, 10, 25, 100]" ]>
|
||||
</md-paginator>
|
||||
@@ -0,0 +1,8 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'paginator-overview-example',
|
||||
templateUrl: 'paginator-overview-example.html',
|
||||
})
|
||||
export class PaginatorOverviewExample {}
|
||||
@@ -97,6 +97,7 @@ let apiDocsPackage = new DgeniPackage('material2-api-docs', dgeniPackageDeps)
|
||||
'input/index.ts',
|
||||
'list/index.ts',
|
||||
'menu/index.ts',
|
||||
'paginator/index.ts',
|
||||
'progress-bar/index.ts',
|
||||
'progress-spinner/index.ts',
|
||||
'radio/index.ts',
|
||||
|
||||
Reference in New Issue
Block a user