-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
feat(sort): add ability to manage and display sorting #5307
Conversation
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
src/lib/sort/sort-header.ts
Outdated
|
||
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
src/lib/sort/sort.spec.ts
Outdated
], | ||
}).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
<cdk-cell *cdkCellDef="let row"> {{row.id}} </cdk-cell> | ||
</ng-container> | ||
|
||
<!-- Column Definition: Progress --> | ||
<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 |
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 |
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
MdSort
which containsMdSortable
elements. TheMdSort
manages the active sort and direction while eachMdSortable
element changes and displays the sorting for its field.MdSortHeader
is the firstMdSortable
to be introduced, to be easily used within CdkTable.