Skip to content

Commit b20a59d

Browse files
crisbetotinayuangao
authored andcommitted
fix(selection-list): allow jumping to first/last item using home/end (#9062)
Allows users to jump focus to the first and last items in a selection list using the home and end keys.
1 parent 1eaec1e commit b20a59d

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

src/lib/list/selection-list.spec.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import {DOWN_ARROW, SPACE, ENTER, UP_ARROW} from '@angular/cdk/keycodes';
1+
import {DOWN_ARROW, SPACE, ENTER, UP_ARROW, HOME, END} from '@angular/cdk/keycodes';
22
import {Platform} from '@angular/cdk/platform';
3-
import {createKeyboardEvent, dispatchFakeEvent} from '@angular/cdk/testing';
3+
import {createKeyboardEvent, dispatchFakeEvent, dispatchKeyboardEvent} from '@angular/cdk/testing';
44
import {Component, DebugElement} from '@angular/core';
55
import {async, ComponentFixture, fakeAsync, inject, TestBed, tick} from '@angular/core/testing';
66
import {By} from '@angular/platform-browser';
@@ -264,6 +264,29 @@ describe('MatSelectionList without forms', () => {
264264
expect(manager.activeItemIndex).toEqual(3);
265265
});
266266

267+
it('should focus the first non-disabled item when pressing HOME', () => {
268+
const manager = selectionList.componentInstance._keyManager;
269+
expect(manager.activeItemIndex).toBe(-1);
270+
271+
const event = dispatchKeyboardEvent(selectionList.nativeElement, 'keydown', HOME);
272+
fixture.detectChanges();
273+
274+
// Note that the first item is disabled so we expect the second one to be focused.
275+
expect(manager.activeItemIndex).toBe(1);
276+
expect(event.defaultPrevented).toBe(true);
277+
});
278+
279+
it('should focus the last item when pressing END', () => {
280+
const manager = selectionList.componentInstance._keyManager;
281+
expect(manager.activeItemIndex).toBe(-1);
282+
283+
const event = dispatchKeyboardEvent(selectionList.nativeElement, 'keydown', END);
284+
fixture.detectChanges();
285+
286+
expect(manager.activeItemIndex).toBe(3);
287+
expect(event.defaultPrevented).toBe(true);
288+
});
289+
267290
it('should be able to select all options', () => {
268291
const list: MatSelectionList = selectionList.componentInstance;
269292

src/lib/list/selection-list.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {FocusableOption, FocusKeyManager} from '@angular/cdk/a11y';
1010
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1111
import {SelectionModel} from '@angular/cdk/collections';
12-
import {SPACE, ENTER} from '@angular/cdk/keycodes';
12+
import {SPACE, ENTER, HOME, END} from '@angular/cdk/keycodes';
1313
import {
1414
AfterContentInit,
1515
Attribute,
@@ -356,6 +356,12 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu
356356
// Always prevent space from scrolling the page since the list has focus
357357
event.preventDefault();
358358
break;
359+
case HOME:
360+
case END:
361+
event.keyCode === HOME ? this._keyManager.setFirstItemActive() :
362+
this._keyManager.setLastItemActive();
363+
event.preventDefault();
364+
break;
359365
default:
360366
this._keyManager.onKeydown(event);
361367
}

0 commit comments

Comments
 (0)