Skip to content

Commit 3723191

Browse files
crisbetojelbourn
authored andcommitted
fix(chips): support focusing first/last item using home/end (#11892)
Based on the accessibility guidelines, grid cells should support moving focus to the first/last items via the Home and End keys.
1 parent 82b35d0 commit 3723191

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

Diff for: src/lib/chips/chip-list.spec.ts

+41-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import {FocusKeyManager} from '@angular/cdk/a11y';
22
import {Directionality, Direction} from '@angular/cdk/bidi';
3-
import {BACKSPACE, DELETE, ENTER, LEFT_ARROW, RIGHT_ARROW, SPACE, TAB} from '@angular/cdk/keycodes';
3+
import {
4+
BACKSPACE,
5+
DELETE,
6+
ENTER,
7+
LEFT_ARROW,
8+
RIGHT_ARROW,
9+
SPACE,
10+
TAB,
11+
HOME,
12+
END,
13+
} from '@angular/cdk/keycodes';
414
import {
515
createKeyboardEvent,
616
dispatchFakeEvent,
@@ -296,6 +306,36 @@ describe('MatChipList', () => {
296306
.toBe(initialActiveIndex, 'Expected focused item not to have changed.');
297307
});
298308

309+
it('should focus the first item when pressing HOME', () => {
310+
const nativeChips = chipListNativeElement.querySelectorAll('mat-chip');
311+
const lastNativeChip = nativeChips[nativeChips.length - 1] as HTMLElement;
312+
const HOME_EVENT = createKeyboardEvent('keydown', HOME, lastNativeChip);
313+
const array = chips.toArray();
314+
const lastItem = array[array.length - 1];
315+
316+
lastItem.focus();
317+
expect(manager.activeItemIndex).toBe(array.length - 1);
318+
319+
chipListInstance._keydown(HOME_EVENT);
320+
fixture.detectChanges();
321+
322+
expect(manager.activeItemIndex).toBe(0);
323+
expect(HOME_EVENT.defaultPrevented).toBe(true);
324+
});
325+
326+
it('should focus the last item when pressing END', () => {
327+
const nativeChips = chipListNativeElement.querySelectorAll('mat-chip');
328+
const END_EVENT = createKeyboardEvent('keydown', END, nativeChips[0]);
329+
330+
expect(manager.activeItemIndex).toBe(-1);
331+
332+
chipListInstance._keydown(END_EVENT);
333+
fixture.detectChanges();
334+
335+
expect(manager.activeItemIndex).toBe(chips.length - 1);
336+
expect(END_EVENT.defaultPrevented).toBe(true);
337+
});
338+
299339
});
300340

301341
describe('RTL', () => {

Diff for: src/lib/chips/chip-list.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {FocusKeyManager} from '@angular/cdk/a11y';
1010
import {Directionality} from '@angular/cdk/bidi';
1111
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1212
import {SelectionModel} from '@angular/cdk/collections';
13-
import {BACKSPACE} from '@angular/cdk/keycodes';
13+
import {BACKSPACE, HOME, END} from '@angular/cdk/keycodes';
1414
import {
1515
AfterContentInit,
1616
ChangeDetectionStrategy,
@@ -483,7 +483,16 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo
483483
this._keyManager.setLastItemActive();
484484
event.preventDefault();
485485
} else if (target && target.classList.contains('mat-chip')) {
486-
this._keyManager.onKeydown(event);
486+
if (event.keyCode === HOME) {
487+
this._keyManager.setFirstItemActive();
488+
event.preventDefault();
489+
} else if (event.keyCode === END) {
490+
this._keyManager.setLastItemActive();
491+
event.preventDefault();
492+
} else {
493+
this._keyManager.onKeydown(event);
494+
}
495+
487496
this.stateChanges.next();
488497
}
489498
}

0 commit comments

Comments
 (0)