Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 70654c3

Browse files
Splaktarjelbourn
authored andcommitted
fix(slider): enable page up/down and home/end (#11517)
fix up/down/left/right to not be orientation-specific based on https://www.w3.org/TR/wai-aria-practices-1.1/#slider Fixes #11515
1 parent 6e6abe7 commit 70654c3

File tree

2 files changed

+68
-15
lines changed

2 files changed

+68
-15
lines changed

src/components/slider/slider.js

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ angular.module('material.components.slider', [
88
.directive('mdSlider', SliderDirective)
99
.directive('mdSliderContainer', SliderContainerDirective);
1010

11+
/**
12+
* @type {number} the page size used for stepping when page up/down keys are pressed.
13+
*/
14+
var stepPageSize = 10;
15+
/**
16+
* @type {number} the multiplier applied to a step when the arrow key is pressed along with
17+
* alt, meta, or ctrl.
18+
*/
19+
var modifierMultiplier = 4;
20+
1121
/**
1222
* @ngdoc directive
1323
* @name mdSliderContainer
@@ -78,6 +88,9 @@ function SliderContainerDirective() {
7888

7989
var initialMaxWidth;
8090

91+
/**
92+
* @param {number} length of the input's string value
93+
*/
8194
ctrl.fitInputWidthToTextLength = function (length) {
8295
var input = element[0].querySelector('md-input-container');
8396

@@ -109,16 +122,22 @@ function SliderContainerDirective() {
109122
* the slider is in the accent color by default. The primary color palette may be used with
110123
* the `md-primary` class.
111124
*
112-
* It has two modes:
125+
* The slider has two modes:
113126
* - "normal" mode where the user slides between a wide range of values
114127
* - "discrete" mode where the user slides between only a few select values
115128
*
116129
* To enable discrete mode, add the `md-discrete` attribute to a slider
117130
* and use the `step` attribute to change the distance between
118131
* values the user is allowed to pick.
119132
*
120-
* When using the keyboard, holding the Meta, Control, or Alt key while pressing the left
121-
* and right arrow buttons will cause the slider to move 4 steps.
133+
* When using the keyboard:
134+
* - pressing the arrow keys will increase or decrease the slider's value by one step
135+
* - holding the Meta, Control, or Alt key while pressing the arrow keys will
136+
* move the slider four steps at a time
137+
* - pressing the Home key will move the slider to the first allowed value
138+
* - pressing the End key will move the slider to the last allowed value
139+
* - pressing the Page Up key will increase the slider value by ten
140+
* - pressing the Page Down key will decrease the slider value by ten
122141
*
123142
* @usage
124143
* <h4>Normal Mode</h4>
@@ -382,29 +401,63 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
382401

383402
/**
384403
* left/right/up/down arrow listener
404+
* @param {!KeyboardEvent} ev
385405
*/
386406
function keydownListener(ev) {
387407
if (isDisabled()) return;
408+
var keyCodes = $mdConstant.KEY_CODE;
388409

389410
var changeAmount;
390-
if (vertical ? ev.keyCode === $mdConstant.KEY_CODE.DOWN_ARROW : ev.keyCode === $mdConstant.KEY_CODE.LEFT_ARROW) {
391-
changeAmount = -step;
392-
} else if (vertical ? ev.keyCode === $mdConstant.KEY_CODE.UP_ARROW : ev.keyCode === $mdConstant.KEY_CODE.RIGHT_ARROW) {
393-
changeAmount = step;
411+
switch (ev.keyCode) {
412+
case keyCodes.DOWN_ARROW:
413+
case keyCodes.LEFT_ARROW:
414+
ev.preventDefault();
415+
changeAmount = -step;
416+
break;
417+
case keyCodes.UP_ARROW:
418+
case keyCodes.RIGHT_ARROW:
419+
ev.preventDefault();
420+
changeAmount = step;
421+
break;
422+
case keyCodes.PAGE_DOWN:
423+
ev.preventDefault();
424+
changeAmount = -step * stepPageSize;
425+
break;
426+
case keyCodes.PAGE_UP:
427+
ev.preventDefault();
428+
changeAmount = step * stepPageSize;
429+
break;
430+
case keyCodes.HOME:
431+
ev.preventDefault();
432+
ev.stopPropagation();
433+
updateValue(min);
434+
break;
435+
case keyCodes.END:
436+
ev.preventDefault();
437+
ev.stopPropagation();
438+
updateValue(max);
439+
break;
394440
}
395-
changeAmount = invert ? -changeAmount : changeAmount;
396441
if (changeAmount) {
442+
changeAmount = invert ? -changeAmount : changeAmount;
397443
if (ev.metaKey || ev.ctrlKey || ev.altKey) {
398-
changeAmount *= 4;
444+
changeAmount *= modifierMultiplier;
399445
}
400446
ev.preventDefault();
401447
ev.stopPropagation();
402-
scope.$evalAsync(function() {
403-
setModelValue(ngModelCtrl.$viewValue + changeAmount);
404-
});
448+
updateValue(ngModelCtrl.$viewValue + changeAmount);
405449
}
406450
}
407451

452+
/**
453+
* @param value new slider value used for setting the model value
454+
*/
455+
function updateValue(value) {
456+
scope.$evalAsync(function() {
457+
setModelValue(value);
458+
});
459+
}
460+
408461
function mouseDownListener() {
409462
redrawTicks();
410463

@@ -462,7 +515,7 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
462515
var formattedValue = (Math.round((value - min) / step) * step + min);
463516
formattedValue = (Math.round(formattedValue * Math.pow(10, round)) / Math.pow(10, round));
464517

465-
if (containerCtrl && containerCtrl.fitInputWidthToTextLength){
518+
if (containerCtrl && containerCtrl.fitInputWidthToTextLength) {
466519
$mdUtil.debounce(function () {
467520
containerCtrl.fitInputWidthToTextLength(formattedValue.toString().length);
468521
}, 100)();
@@ -473,7 +526,7 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi
473526
}
474527

475528
/**
476-
* @param percent 0-1
529+
* @param {number} percent 0-1
477530
*/
478531
function setSliderPercent(percent) {
479532

src/components/slider/slider.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ md-slider-container {
450450

451451
& > *:first-child,
452452
& > *:last-child {
453-
&:not(md-slider){
453+
&:not(md-slider) {
454454
min-width: $items-width;
455455
max-width: ($items-width * 2) - 8;
456456
height: $items-height;

0 commit comments

Comments
 (0)