-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(pagination): initial pagination component (#5156)
- Loading branch information
1 parent
7b2d4ae
commit 85fb00a
Showing
25 changed files
with
854 additions
and
36 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> |
Oops, something went wrong.