-
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
Conversation
jelbourn
left a comment
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.
Got some strict null errors
src/lib/sort/sort-header.ts
Outdated
|
|
||
| /** Overrides the reverse order value of the containing MdSort for this MdSortable. */ | ||
| @Input() | ||
| get reverseOrder() { return this._reverseOrder; } |
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.
I don't follow what this does
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.
For setting the sort order as
descending -> ascending -> [none] -> descending -> ...
as opposed to
ascending -> descending' -> [none] -> descending -> ...
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.
Isn't that what start already does?
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.
Not quite - start determines where in the cycle the user is placed when first clicked. reverseOrder will reverse the cycle.
Sounds like I misunderstood your intentions on start, which would reverse the order.
We could remove one or the other and we'd lose a minor and probably unnecessary cycle. I prefer keeping reverseOrder over start though
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.
Yeah, my intent was that:
Default: asc -> desc -> none
Start = desc: desc -> asc -> none
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.
I think having both of these is more confusing than helpful. The problem with "reverse" is that you have to know what the default is. Saying start or startWith, in my mind, better captures the developer's intent
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.
SGTM - removed the reverse. Agreed that just start is enough
src/lib/sort/sort-header.html
Outdated
| @@ -0,0 +1,20 @@ | |||
| <div class="mat-sort-header-container" | |||
| [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 comment
The reason will be displayed to describe this comment to others. Learn more.
Add type="button"
src/lib/sort/sort-header.ts
Outdated
| host: { | ||
| '(click)': '_sort.sort(this)', | ||
| '[class.mat-sort-header-sorted]': '_isSorted()', | ||
| } |
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.
Add ViewEncapsulation.None and ChangeDetectionStrategy.OnPush
src/lib/sort/sort-header.scss
Outdated
| } | ||
|
|
||
| .mat-sort-header-stem { | ||
| background: black; |
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.
Color should be part of the theme (or maybe just currentColor?)
| this.id = this._cdkColumnDef.name; | ||
| } | ||
|
|
||
| this._sort.register(this); |
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.
Should be able to do this in the constructor
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.
Cannot do this since the MdSort creates a mapping of id to MdSortable and this is the earlier lifecycle hook where we have the id available
|
|
||
| constructor(@Optional() public _sort: MdSort, | ||
| public _intl: MdSortIntl, | ||
| @Optional() public _cdkColumnDef: CdkColumnDef) { |
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.
Put the @Optional args next to each other?
src/lib/sort/sort-header.ts
Outdated
|
|
||
| /** Whether this MdSortHeader is currently sorted in either ascending or descending order. */ | ||
| _isSorted() { | ||
| return this._sort.active == this.id && this._sort.direction != ''; |
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.
Just this._sort.active == this.id && this._sort.direction?
src/lib/sort/sort.ts
Outdated
| /** | ||
| * Register function to be used by the contained MdSortables. Adds the MdSortable to the | ||
| * collection of MdSortables. | ||
| * @docs-private |
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.
Why @docs-private here?
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.
Hmm I wasn't thinking others needed it but people implementing their own MdSortable certainly would. Removed
src/lib/sort/sort-header.html
Outdated
| @@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
Still needs type="button"
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.
Ah misunderstood, thought this was an accessibility thing, putting type on the wrong element. Good now
| host: { | ||
| '(click)': '_sort.sort(this)', | ||
| '[class.mat-sort-header-sorted]': '_isSorted()', | ||
| }, |
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.
Still missing view encapsulation none and onpush
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.
Whoops, got removed in testing. It's back in
|
Good for another review round |
src/lib/sort/sort-direction.ts
Outdated
| * 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 comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just asc and desc?
src/lib/sort/sort.ts
Outdated
| if (!sortable) { return ''; } | ||
|
|
||
| // Get the sort direction cycle with the potential sortable overrides. | ||
| const disableClear = sortable.disableClear != undefined ? |
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.
Prefer doing == null or != null (it captures both null and undefined and is shorter)
src/lib/sort/sort-header.ts
Outdated
| throw getMdSortHeaderNotContainedWithinMdSortError(); | ||
| } | ||
|
|
||
| _sort.mdSortChange.subscribe(() => _changeDetectorRef.markForCheck()); |
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.
Need to unsubscribe to this on destroy
src/lib/sort/sort-header.ts
Outdated
| } | ||
|
|
||
| ngOnDestroy() { | ||
| this._sort.unregister(this); |
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.
nit: deregister
| ], | ||
| }).compileComponents(); | ||
|
|
||
| fixture = TestBed.createComponent(SimpleMdSortApp); |
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.
createComponent has to go in a separate beforeEach block because compileComponents() is asynchronous
|
Made the changes, thanks |
| 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 comment
The reason will be displayed to describe this comment to others. Learn more.
Missed a spot
| <ng-container cdkColumnDef="progress"> | ||
| <cdk-header-cell *cdkHeaderCellDef> Progress </cdk-header-cell> | ||
| <cdk-header-cell *cdkHeaderCellDef | ||
| md-sort-header start="descending"> |
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
|
D'oh, forgot to export my last fixes - should be good to go |
jelbourn
left a comment
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.
LGTM
|
Caretaker note: this will need a new build rule |
ErinCoughlan
left a comment
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.
LGTM
src/lib/sort/sort-header-intl.ts
Outdated
|
|
||
| /** A label to describe the current sort (visible only to screenreaders). */ | ||
| sortDescriptionLabel = (id: string, direction: SortDirection) => { | ||
| return `Sorted by ${id} ${direction}`; |
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.
If direction is 'asc' | 'desc', won't that sound strange with a screenreader? I wonder if you want to override it to be a real word, but I'm not super familiar with what the standards are here.
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.
Good catch, I'll add a check for this
* feat(sort): add sortable * checkin * checkin * feat(sort): add sort header * overrides, tests * format demo html * add ngif to screenready label * add new line to scss * fix tests * fix types * fix types * shorten coerce import * comments * comments * rebase * specialize intl to header; make public * remove reverse * button type and onpush * rename sort directions (shorten) * small changes * remove consolelog * screenreader
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Introduces the
MdSortwhich containsMdSortableelements. TheMdSortmanages the active sort and direction while eachMdSortableelement changes and displays the sorting for its field.MdSortHeaderis the firstMdSortableto be introduced, to be easily used within CdkTable.