Skip to content

Commit

Permalink
fix(selection-list): allow users to jump focus to a particular item b…
Browse files Browse the repository at this point in the history
…y typing (#9026)

Similarly to our other listbox-based components, this allows people to move focus to a particular item by typing the first letters of its label.
  • Loading branch information
crisbeto authored and jelbourn committed Jan 8, 2018
1 parent b8ff582 commit af44b9d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/lib/list/list-option.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
[matRippleTrigger]="_getHostElement()"
[matRippleDisabled]="_isRippleDisabled()"></div>

<mat-pseudo-checkbox #autocheckbox
<mat-pseudo-checkbox
[state]="selected ? 'checked' : 'unchecked'"
[disabled]="disabled"></mat-pseudo-checkbox>

<div class="mat-list-text"><ng-content></ng-content></div>
<div class="mat-list-text" #text><ng-content></ng-content></div>

</div>
26 changes: 25 additions & 1 deletion src/lib/list/selection-list.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {DOWN_ARROW, SPACE, ENTER, UP_ARROW, HOME, END} from '@angular/cdk/keycodes';
import {Platform} from '@angular/cdk/platform';
import {createKeyboardEvent, dispatchFakeEvent, dispatchKeyboardEvent} from '@angular/cdk/testing';
import {
createKeyboardEvent,
dispatchFakeEvent,
dispatchEvent,
dispatchKeyboardEvent,
} from '@angular/cdk/testing';
import {Component, DebugElement} from '@angular/core';
import {async, ComponentFixture, fakeAsync, inject, TestBed, tick} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
Expand Down Expand Up @@ -287,6 +292,25 @@ describe('MatSelectionList without forms', () => {
expect(event.defaultPrevented).toBe(true);
});

it('should be able to jump focus down to an item by typing', fakeAsync(() => {
const listEl = selectionList.nativeElement;
const manager = selectionList.componentInstance._keyManager;

expect(manager.activeItemIndex).toBe(-1);

dispatchEvent(listEl, createKeyboardEvent('keydown', 83, undefined, 's'));
fixture.detectChanges();
tick(200);

expect(manager.activeItemIndex).toBe(1);

dispatchEvent(listEl, createKeyboardEvent('keydown', 68, undefined, 'd'));
fixture.detectChanges();
tick(200);

expect(manager.activeItemIndex).toBe(3);
}));

it('should be able to select all options', () => {
const list: MatSelectionList = selectionList.componentInstance;

Expand Down
14 changes: 13 additions & 1 deletion src/lib/list/selection-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
Optional,
Output,
QueryList,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import {
Expand Down Expand Up @@ -118,6 +119,9 @@ export class MatListOption extends _MatListOptionMixinBase

@ContentChildren(MatLine) _lines: QueryList<MatLine>;

/** DOM element containing the item's text. */
@ViewChild('text') _text: ElementRef;

/** Whether the label should appear before or after the checkbox. Defaults to 'after' */
@Input() checkboxPosition: 'before' | 'after' = 'after';

Expand Down Expand Up @@ -197,6 +201,14 @@ export class MatListOption extends _MatListOptionMixinBase
this._element.nativeElement.focus();
}

/**
* Returns the list item's text label. Implemented as a part of the FocusKeyManager.
* @docs-private
*/
getLabel() {
return this._text ? this._text.nativeElement.textContent : '';
}

/** Whether this list item should show a ripple effect when clicked. */
_isRippleDisabled() {
return this.disabled || this.disableRipple || this.selectionList.disableRipple;
Expand Down Expand Up @@ -309,7 +321,7 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu
}

ngAfterContentInit(): void {
this._keyManager = new FocusKeyManager<MatListOption>(this.options).withWrap();
this._keyManager = new FocusKeyManager<MatListOption>(this.options).withWrap().withTypeAhead();

if (this._tempValues) {
this._setOptionsFromValues(this._tempValues);
Expand Down

0 comments on commit af44b9d

Please sign in to comment.