-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat(sort): add ability to manage and display sorting #5307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 15 commits
12ec1fb
4eea9a6
c5244b3
af0df28
29ef808
45a06af
1644763
06adfc7
9cee02b
efe57aa
d3ff9f8
cf272ce
1684996
9240dd3
7b32a05
3341fee
6e11c41
25b4fd6
ec18696
cdeba41
eb3556e
ea51206
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import {CollectionViewer, DataSource, MdPaginator} from '@angular/material'; | ||
import {CollectionViewer, DataSource, MdPaginator, MdSort} from '@angular/material'; | ||
import {Observable} from 'rxjs/Observable'; | ||
import {PeopleDatabase, UserData} from './people-database'; | ||
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; | ||
import 'rxjs/add/observable/combineLatest'; | ||
import 'rxjs/add/observable/merge'; | ||
import 'rxjs/add/operator/map'; | ||
|
||
export class PersonDataSource extends DataSource<any> { | ||
|
@@ -12,12 +14,15 @@ export class PersonDataSource extends DataSource<any> { | |
_renderedData: any[] = []; | ||
|
||
constructor(private _peopleDatabase: PeopleDatabase, | ||
private _paginator: MdPaginator) { | ||
private _paginator: MdPaginator, | ||
private _sort: MdSort) { | ||
super(); | ||
|
||
// Subscribe to page changes and database changes by clearing the cached data and | ||
// Subscribe to paging, sorting, and database changes by clearing the cached data and | ||
// determining the updated display data. | ||
Observable.merge(this._paginator.page, this._peopleDatabase.dataChange).subscribe(() => { | ||
Observable.merge(this._paginator.page, | ||
this._peopleDatabase.dataChange, | ||
this._sort.mdSortChange).subscribe(() => { | ||
this._renderedData = []; | ||
this.updateDisplayData(); | ||
}); | ||
|
@@ -48,12 +53,35 @@ export class PersonDataSource extends DataSource<any> { | |
} | ||
|
||
updateDisplayData() { | ||
const data = this._peopleDatabase.data.slice(); | ||
const data = this.getSortedData(); | ||
|
||
// 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); | ||
} | ||
|
||
/** Returns a sorted copy of the database data. */ | ||
getSortedData(): UserData[] { | ||
const data = this._peopleDatabase.data.slice(); | ||
if (!this._sort.active || this._sort.direction == '') { return data; } | ||
|
||
return data.sort((a, b) => { | ||
let propertyA: number|string = ''; | ||
let propertyB: number|string = ''; | ||
|
||
switch (this._sort.active) { | ||
case 'userId': [propertyA, propertyB] = [a.id, b.id]; break; | ||
case 'userName': [propertyA, propertyB] = [a.name, b.name]; break; | ||
case 'progress': [propertyA, propertyB] = [a.progress, b.progress]; break; | ||
case 'color': [propertyA, propertyB] = [a.color, b.color]; break; | ||
} | ||
|
||
let valueA = isNaN(+propertyA) ? propertyA : +propertyA; | ||
let valueB = isNaN(+propertyB) ? propertyB : +propertyB; | ||
|
||
return (valueA < valueB ? -1 : 1) * (this._sort.direction == 'ascending' ? 1 : -1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missed a spot |
||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* @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 {MdSortHeader} from './sort-header'; | ||
import {MdSort} from './sort'; | ||
import {MdSortIntl} from './sort-intl'; | ||
import {CommonModule} from '@angular/common'; | ||
|
||
export * from './sort-direction'; | ||
export * from './sort-header'; | ||
export * from './sort-intl'; | ||
export * from './sort'; | ||
|
||
@NgModule({ | ||
imports: [CommonModule], | ||
exports: [MdSort, MdSortHeader], | ||
declarations: [MdSort, MdSortHeader], | ||
providers: [MdSortIntl] | ||
}) | ||
export class MdSortModule {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* @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 | ||
*/ | ||
|
||
export type SortDirection = 'ascending' | 'descending' | ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe just |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* @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 | ||
*/ | ||
|
||
/** @docs-private */ | ||
export function getMdSortDuplicateMdSortableIdError(id: string): Error { | ||
return Error(`Cannot have two MdSortables with the same id (${id}).`); | ||
} | ||
|
||
/** @docs-private */ | ||
export function getMdSortHeaderNotContainedWithinMdSortError(): Error { | ||
return Error(`MdSortHeader must be placed within a parent element with the MdSort directive.`); | ||
} | ||
|
||
/** @docs-private */ | ||
export function getMdSortHeaderMissingIdError(): Error { | ||
return Error(`MdSortHeader must be provided with a unique id.`); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<div class="mat-sort-header-container" type="button" | ||
[class.mat-sort-header-position-before]="arrowPosition == 'before'"> | ||
<button class="mat-sort-header-button" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still needs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah misunderstood, thought this was an accessibility thing, putting type on the wrong element. Good now |
||
[attr.aria-label]="_intl.sortButtonLabel(id)"> | ||
<ng-content></ng-content> | ||
</button> | ||
|
||
<div *ngIf="_isSorted()" | ||
class="mat-sort-header-arrow" | ||
[class.mat-sort-header-ascending]="_sort.direction == 'ascending'" | ||
[class.mat-sort-header-descending]="_sort.direction == 'descending'"> | ||
<div class="mat-sort-header-stem"></div> | ||
<div class="mat-sort-header-pointer-left"></div> | ||
<div class="mat-sort-header-pointer-right"></div> | ||
</div> | ||
</div> | ||
|
||
<span class="cdk-visually-hidden" *ngIf="_isSorted()"> | ||
{{_intl.sortDescriptionLabel(id, _sort.direction)}} | ||
</span> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
$mat-sort-header-arrow-margin: 6px; | ||
$mat-sort-header-arrow-container-size: 10px; | ||
$mat-sort-header-arrow-pointer-length: 8px; | ||
$mat-sort-header-arrow-thickness: 2px; | ||
|
||
.mat-sort-header-container { | ||
display: flex; | ||
cursor: pointer; | ||
} | ||
|
||
.mat-sort-header-position-before { | ||
flex-direction: row-reverse; | ||
} | ||
|
||
.mat-sort-header-button { | ||
border: none; | ||
background: 0 0; | ||
display: flex; | ||
align-items: center; | ||
padding: 0; | ||
cursor: pointer; | ||
outline: 0; | ||
font: inherit; | ||
color: currentColor; | ||
} | ||
|
||
.mat-sort-header-arrow { | ||
display: none; | ||
height: $mat-sort-header-arrow-container-size; | ||
width: $mat-sort-header-arrow-container-size; | ||
position: relative; | ||
margin: 0 0 0 $mat-sort-header-arrow-margin; | ||
|
||
.mat-sort-header-position-before & { | ||
margin: 0 $mat-sort-header-arrow-margin 0 0; | ||
} | ||
} | ||
|
||
.mat-sort-header-ascending { | ||
display: block; | ||
transform: rotate(45deg); | ||
} | ||
|
||
.mat-sort-header-descending { | ||
display: block; | ||
transform: rotate(225deg); | ||
top: $mat-sort-header-arrow-thickness; | ||
} | ||
|
||
.mat-sort-header-stem { | ||
background: currentColor; | ||
transform: rotate(135deg); | ||
height: $mat-sort-header-arrow-container-size; | ||
width: $mat-sort-header-arrow-thickness; | ||
margin: auto; | ||
} | ||
|
||
.mat-sort-header-pointer-left { | ||
background: currentColor; | ||
width: $mat-sort-header-arrow-thickness; | ||
height: $mat-sort-header-arrow-pointer-length; | ||
position: absolute; | ||
bottom: 0; | ||
right: 0; | ||
} | ||
|
||
.mat-sort-header-pointer-right { | ||
background: currentColor; | ||
width: $mat-sort-header-arrow-pointer-length; | ||
height: $mat-sort-header-arrow-thickness; | ||
position: absolute; | ||
bottom: 0; | ||
right: 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too