Skip to content

Commit 834aecc

Browse files
crisbetotinayuangao
authored andcommitted
fix(stepper): support going to first/last steps via home/end keys (#9632)
Adds support for the user to skip to the first/last step in the stepper using the home and end keys. [Based on the a11y guidelines](https://www.w3.org/TR/wai-aria-practices-1.1/#tabpanel).
1 parent 7fe651b commit 834aecc

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

src/cdk/stepper/stepper.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,16 @@ import {
2727
OnChanges,
2828
OnDestroy
2929
} from '@angular/core';
30-
import {LEFT_ARROW, RIGHT_ARROW, DOWN_ARROW, UP_ARROW, ENTER, SPACE} from '@angular/cdk/keycodes';
30+
import {
31+
LEFT_ARROW,
32+
RIGHT_ARROW,
33+
DOWN_ARROW,
34+
UP_ARROW,
35+
ENTER,
36+
SPACE,
37+
HOME,
38+
END,
39+
} from '@angular/cdk/keycodes';
3140
import {CdkStepLabel} from './step-label';
3241
import {coerceBooleanProperty} from '@angular/cdk/coercion';
3342
import {AbstractControl} from '@angular/forms';
@@ -307,6 +316,16 @@ export class CdkStepper implements OnDestroy {
307316
this.selectedIndex = this._focusIndex;
308317
event.preventDefault();
309318
}
319+
320+
if (keyCode === HOME) {
321+
this._focusStep(0);
322+
event.preventDefault();
323+
}
324+
325+
if (keyCode === END) {
326+
this._focusStep(this._steps.length - 1);
327+
event.preventDefault();
328+
}
310329
}
311330

312331
private _focusNextStep() {

src/lib/stepper/stepper.spec.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import {Directionality} from '@angular/cdk/bidi';
2-
import {ENTER, LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW, SPACE} from '@angular/cdk/keycodes';
2+
import {
3+
ENTER,
4+
LEFT_ARROW,
5+
RIGHT_ARROW,
6+
UP_ARROW,
7+
DOWN_ARROW,
8+
SPACE,
9+
HOME,
10+
END,
11+
} from '@angular/cdk/keycodes';
312
import {dispatchKeyboardEvent} from '@angular/cdk/testing';
413
import {Component, DebugElement} from '@angular/core';
514
import {async, ComponentFixture, TestBed, inject} from '@angular/core/testing';
@@ -725,6 +734,16 @@ function assertCorrectKeyboardInteraction(fixture: ComponentFixture<any>,
725734
expect(stepperComponent.selectedIndex)
726735
.toBe(0,
727736
'Expected index of selected step to change to index of focused step after SPACE event.');
737+
738+
const endEvent = dispatchKeyboardEvent(stepHeaderEl, 'keydown', END);
739+
expect(stepperComponent._focusIndex)
740+
.toBe(stepHeaders.length - 1, 'Expected last step to be focused when pressing END.');
741+
expect(endEvent.defaultPrevented).toBe(true, 'Expected default END action to be prevented.');
742+
743+
const homeEvent = dispatchKeyboardEvent(stepHeaderEl, 'keydown', HOME);
744+
expect(stepperComponent._focusIndex)
745+
.toBe(0, 'Expected first step to be focused when pressing HOME.');
746+
expect(homeEvent.defaultPrevented).toBe(true, 'Expected default HOME action to be prevented.');
728747
}
729748

730749
/** Asserts that step selection change using stepper buttons does not focus step header. */

0 commit comments

Comments
 (0)