Skip to content

Commit 2727cd6

Browse files
committed
fix(sort): add aria-sort to host when sorted
1 parent 5c6e3df commit 2727cd6

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

src/lib/sort/sort-header-intl.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import {Injectable} from '@angular/core';
1010
import {Subject} from 'rxjs/Subject';
11-
import {SortDirection} from './sort-direction';
1211

1312
/**
1413
* To modify the labels and text displayed, create a new instance of MatSortHeaderIntl and
@@ -26,9 +25,4 @@ export class MatSortHeaderIntl {
2625
sortButtonLabel = (id: string) => {
2726
return `Change sorting for ${id}`;
2827
}
29-
30-
/** A label to describe the current sort (visible only to screenreaders). */
31-
sortDescriptionLabel = (id: string, direction: SortDirection) => {
32-
return `Sorted by ${id} ${direction == 'asc' ? 'ascending' : 'descending'}`;
33-
}
3428
}

src/lib/sort/sort-header.html

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,3 @@
1414
</div>
1515
</div>
1616
</div>
17-
18-
<span class="cdk-visually-hidden" *ngIf="_isSorted()">
19-
&nbsp;{{_intl.sortDescriptionLabel(id, _sort.direction)}}
20-
</span>

src/lib/sort/sort-header.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
ViewEncapsulation
1616
} from '@angular/core';
1717
import {coerceBooleanProperty} from '@angular/cdk/coercion';
18+
<<<<<<< HEAD
1819
import {
1920
trigger,
2021
state,
@@ -23,6 +24,9 @@ import {
2324
transition,
2425
keyframes,
2526
} from '@angular/animations';
27+
=======
28+
import {animate, state, style, transition, trigger} from '@angular/animations';
29+
>>>>>>> fix(sort): add aria-sort to host when sorted
2630
import {CdkColumnDef} from '@angular/cdk/table';
2731
import {Subscription} from 'rxjs/Subscription';
2832
import {merge} from 'rxjs/observable/merge';
@@ -51,6 +55,7 @@ const SORT_ANIMATION_TRANSITION =
5155
styleUrls: ['sort-header.css'],
5256
host: {
5357
'(click)': '_sort.sort(this)',
58+
'[attr.aria-sort]': '_getAriaSortAttribute()',
5459
'[class.mat-sort-header-sorted]': '_isSorted()',
5560
},
5661
encapsulation: ViewEncapsulation.None,
@@ -145,4 +150,16 @@ export class MatSortHeader implements MatSortable {
145150
return this._sort.active == this.id &&
146151
(this._sort.direction === 'asc' || this._sort.direction === 'desc');
147152
}
153+
154+
/**
155+
* Gets the aria-sort attribute that should be applied to this sort header. If this header
156+
* is not sorted, returns null so that the attribute is removed from the host element. Aria spec
157+
* says that the aria-sort property should only be present on one header at a time, so removing
158+
* ensures this is true.
159+
*/
160+
_getAriaSortAttribute() {
161+
if (!this._isSorted()) { return null; }
162+
163+
return this._sort.direction == 'asc' ? 'ascending' : 'descending';
164+
}
148165
}

src/lib/sort/sort.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,23 @@ describe('MatSort', () => {
159159
expect(button.getAttribute('aria-label')).toBe('Change sorting for defaultSortHeaderA');
160160
});
161161

162+
it('should apply the aria-sort label to the header when sorted', () => {
163+
const sortHeaderElement = fixture.nativeElement.querySelector('#defaultSortHeaderA');
164+
expect(sortHeaderElement.getAttribute('aria-sort')).toBe(null);
165+
166+
component.sort('defaultSortHeaderA');
167+
fixture.detectChanges();
168+
expect(sortHeaderElement.getAttribute('aria-sort')).toBe('ascending');
169+
170+
component.sort('defaultSortHeaderA');
171+
fixture.detectChanges();
172+
expect(sortHeaderElement.getAttribute('aria-sort')).toBe('descending');
173+
174+
component.sort('defaultSortHeaderA');
175+
fixture.detectChanges();
176+
expect(sortHeaderElement.getAttribute('aria-sort')).toBe(null);
177+
});
178+
162179
it('should re-render when the i18n labels have changed',
163180
inject([MatSortHeaderIntl], (intl: MatSortHeaderIntl) => {
164181
const header = fixture.debugElement.query(By.directive(MatSortHeader)).nativeElement;

0 commit comments

Comments
 (0)