Skip to content

Commit

Permalink
fix(material-experimental/mdc-chips): support home/end in chip grid (#…
Browse files Browse the repository at this point in the history
…18052)

Adds support for the "Home" and "End" keys to the `mat-chip-grid`, similarly to the `mat-chip-listbox`.
  • Loading branch information
crisbeto authored and jelbourn committed Jan 27, 2020
1 parent d05c695 commit 847a469
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 6 deletions.
53 changes: 52 additions & 1 deletion src/material-experimental/mdc-chips/chip-grid.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
LEFT_ARROW,
RIGHT_ARROW,
SPACE,
TAB
TAB,
HOME,
END
} from '@angular/cdk/keycodes';
import {
createFakeEvent,
Expand Down Expand Up @@ -443,6 +445,55 @@ describe('MDC-based MatChipGrid', () => {
expect(manager.activeRowIndex).toBe(0);
expect(manager.activeColumnIndex).toBe(0);
});

it('should move focus to the first chip when pressing HOME', () => {
setupStandardGrid();
manager = chipGridInstance._keyManager;

const nativeChips = chipGridNativeElement.querySelectorAll('mat-chip-row');
const lastNativeChip = nativeChips[nativeChips.length - 1] as HTMLElement;

const HOME_EVENT: KeyboardEvent =
createKeyboardEvent('keydown', HOME, undefined, lastNativeChip);
const array = chips.toArray();
const lastItem = array[array.length - 1];

lastItem.focus();
expect(manager.activeRowIndex).toBe(4);
expect(manager.activeColumnIndex).toBe(0);

chipGridInstance._keydown(HOME_EVENT);
fixture.detectChanges();

expect(HOME_EVENT.defaultPrevented).toBe(true);
expect(manager.activeRowIndex).toBe(0);
expect(manager.activeColumnIndex).toBe(0);
});

it('should move focus to the last chip when pressing END', () => {
setupStandardGrid();
manager = chipGridInstance._keyManager;

const nativeChips = chipGridNativeElement.querySelectorAll('mat-chip-row');
const firstNativeChip = nativeChips[0] as HTMLElement;

const END_EVENT: KeyboardEvent =
createKeyboardEvent('keydown', END, undefined, firstNativeChip);
const array = chips.toArray();
const firstItem = array[0];

firstItem.focus();
expect(manager.activeRowIndex).toBe(0);
expect(manager.activeColumnIndex).toBe(0);

chipGridInstance._keydown(END_EVENT);
fixture.detectChanges();

expect(END_EVENT.defaultPrevented).toBe(true);
expect(manager.activeRowIndex).toBe(4);
expect(manager.activeColumnIndex).toBe(0);
});

});
});

Expand Down
20 changes: 15 additions & 5 deletions src/material-experimental/mdc-chips/chip-grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import {Directionality} from '@angular/cdk/bidi';
import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {BACKSPACE, TAB} from '@angular/cdk/keycodes';
import {BACKSPACE, TAB, HOME, END} from '@angular/cdk/keycodes';
import {
AfterContentInit,
AfterViewInit,
Expand Down Expand Up @@ -400,17 +400,27 @@ export class MatChipGrid extends _MatChipGridMixinBase implements AfterContentIn
/** Handles custom keyboard events. */
_keydown(event: KeyboardEvent) {
const target = event.target as HTMLElement;
const keyCode = event.keyCode;
const manager = this._keyManager;

// If they are on an empty input and hit backspace, focus the last chip
if (event.keyCode === BACKSPACE && this._isEmptyInput(target)) {
if (keyCode === BACKSPACE && this._isEmptyInput(target)) {
if (this._chips.length) {
this._keyManager.setLastCellActive();
manager.setLastCellActive();
}
event.preventDefault();
} else if (event.keyCode === TAB && target.id !== this._chipInput!.id ) {
} else if (keyCode === TAB && target.id !== this._chipInput!.id ) {
this._allowFocusEscape();
} else if (this._originatesFromChip(event)) {
this._keyManager.onKeydown(event);
if (keyCode === HOME) {
manager.setFirstCellActive();
event.preventDefault();
} else if (keyCode === END) {
manager.setLastCellActive();
event.preventDefault();
} else {
manager.onKeydown(event);
}
}
this.stateChanges.next();
}
Expand Down

0 comments on commit 847a469

Please sign in to comment.