diff --git a/src/material-experimental/mdc-slider/slider.spec.ts b/src/material-experimental/mdc-slider/slider.spec.ts
index e7821e37c4ff..0a504b4b686f 100644
--- a/src/material-experimental/mdc-slider/slider.spec.ts
+++ b/src/material-experimental/mdc-slider/slider.spec.ts
@@ -6,8 +6,10 @@
* found in the LICENSE file at https://angular.io/license
*/
+import {LEFT_ARROW, RIGHT_ARROW} from '@angular/cdk/keycodes';
import {Platform} from '@angular/cdk/platform';
import {
+ dispatchEvent,
dispatchMouseEvent,
dispatchPointerEvent,
dispatchTouchEvent,
@@ -392,7 +394,6 @@ describe('MDC-based MatSlider' , () => {
it('should be able to set the min and max values when they are more precise ' +
'than the step', () => {
sliderInstance.step = 10;
- fixture.detectChanges();
slideToValue(sliderInstance, 25, Thumb.END, platform.IOS);
expect(inputInstance.value).toBe(25);
slideToValue(sliderInstance, 75, Thumb.END, platform.IOS);
@@ -521,6 +522,130 @@ describe('MDC-based MatSlider' , () => {
expect(endInputInstance.value).toBe(99);
});
});
+
+ describe('slider with set step', () => {
+ let sliderInstance: MatSlider;
+ let inputInstance: MatSliderThumb;
+
+ beforeEach(waitForAsync(() => {
+ const fixture = createComponent(SliderWithStep);
+ fixture.detectChanges();
+ const sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider));
+ sliderInstance = sliderDebugElement.componentInstance;
+ inputInstance = sliderInstance._getInput(Thumb.END);
+ }));
+
+ it('should set the correct step value on mousedown', () => {
+ expect(inputInstance.value).toBe(0);
+ setValueByClick(sliderInstance, 13, platform.IOS);
+ expect(inputInstance.value).toBe(25);
+ });
+
+ it('should set the correct step value on slide', () => {
+ slideToValue(sliderInstance, 12, Thumb.END, platform.IOS);
+ expect(inputInstance.value).toBe(0);
+ });
+
+ it('should not add decimals to the value if it is a whole number', () => {
+ sliderInstance.step = 0.1;
+ slideToValue(sliderInstance, 100, Thumb.END, platform.IOS);
+ expect(inputInstance.value).toBe(100);
+ });
+
+ it('should truncate long decimal values when using a decimal step', () => {
+ // TODO(wagnermaciel): Uncomment this test once b/182504575 is resolved.
+ // sliderInstance.step = 0.1;
+ // slideToValue(sliderInstance, 33.3333, Thumb.END, platform.IOS);
+ // expect(inputInstance.value).toBe(33);
+ });
+
+ it('should truncate long decimal values when using a decimal step and the arrow keys', () => {
+ sliderInstance.step = 0.1;
+ changeValueUsingArrowKeys(sliderInstance, RIGHT_ARROW, Thumb.END);
+ changeValueUsingArrowKeys(sliderInstance, RIGHT_ARROW, Thumb.END);
+ changeValueUsingArrowKeys(sliderInstance, RIGHT_ARROW, Thumb.END);
+ expect(inputInstance.value).toBe(0.3);
+ });
+ });
+
+ describe('range slider with set step', () => {
+ let sliderInstance: MatSlider;
+ let startInputInstance: MatSliderThumb;
+ let endInputInstance: MatSliderThumb;
+
+ beforeEach(waitForAsync(() => {
+ const fixture = createComponent(RangeSliderWithStep);
+ fixture.detectChanges();
+ const sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider));
+ sliderInstance = sliderDebugElement.componentInstance;
+ startInputInstance = sliderInstance._getInput(Thumb.START);
+ endInputInstance = sliderInstance._getInput(Thumb.END);
+ }));
+
+ it('should set the correct step value on mousedown behind the start thumb', () => {
+ sliderInstance._setValue(50, Thumb.START);
+ setValueByClick(sliderInstance, 13, platform.IOS);
+ expect(startInputInstance.value).toBe(25);
+ });
+
+ it('should set the correct step value on mousedown in front of the end thumb', () => {
+ sliderInstance._setValue(50, Thumb.END);
+ setValueByClick(sliderInstance, 63, platform.IOS);
+ expect(endInputInstance.value).toBe(75);
+ });
+
+ it('should set the correct start thumb step value on slide', () => {
+ slideToValue(sliderInstance, 26, Thumb.START, platform.IOS);
+ expect(startInputInstance.value).toBe(25);
+ });
+
+ it('should set the correct end thumb step value on slide', () => {
+ slideToValue(sliderInstance, 45, Thumb.END, platform.IOS);
+ expect(endInputInstance.value).toBe(50);
+ });
+
+ it('should not add decimals to the end value if it is a whole number', () => {
+ sliderInstance.step = 0.1;
+ slideToValue(sliderInstance, 100, Thumb.END, platform.IOS);
+ expect(endInputInstance.value).toBe(100);
+ });
+
+ it('should not add decimals to the start value if it is a whole number', () => {
+ sliderInstance.step = 0.1;
+ slideToValue(sliderInstance, 100, Thumb.END, platform.IOS);
+ expect(endInputInstance.value).toBe(100);
+ });
+
+ it('should truncate long decimal start values when using a decimal step', () => {
+ // TODO(wagnermaciel): Uncomment this test once b/182504575 is resolved.
+ // sliderInstance.step = 0.1;
+ // slideToValue(sliderInstance, 33.3333, Thumb.START, platform.IOS);
+ // expect(startInputInstance.value).toBe(33);
+ });
+
+ it('should truncate long decimal end values when using a decimal step', () => {
+ // TODO(wagnermaciel): Uncomment this test once b/182504575 is resolved.
+ // sliderInstance.step = 0.1;
+ // slideToValue(sliderInstance, 66.6666, Thumb.END, platform.IOS);
+ // expect(endInputInstance.value).toBe(66);
+ });
+
+ it('should truncate long decimal start values when using a decimal step arrow keys', () => {
+ sliderInstance.step = 0.1;
+ changeValueUsingArrowKeys(sliderInstance, RIGHT_ARROW, Thumb.START);
+ changeValueUsingArrowKeys(sliderInstance, RIGHT_ARROW, Thumb.START);
+ changeValueUsingArrowKeys(sliderInstance, RIGHT_ARROW, Thumb.START);
+ expect(startInputInstance.value).toBe(0.3);
+ });
+
+ it('should truncate long decimal end values when using a decimal step arrow keys', () => {
+ sliderInstance.step = 0.1;
+ changeValueUsingArrowKeys(sliderInstance, LEFT_ARROW, Thumb.END);
+ changeValueUsingArrowKeys(sliderInstance, LEFT_ARROW, Thumb.END);
+ changeValueUsingArrowKeys(sliderInstance, LEFT_ARROW, Thumb.END);
+ expect(endInputInstance.value).toBe(99.7);
+ });
+ });
});
@@ -600,6 +725,25 @@ class SliderWithValue {}
})
class RangeSliderWithValue {}
+@Component({
+ template: `
+
+
+
+ `,
+})
+class SliderWithStep {}
+
+@Component({
+ template: `
+
+
+
+
+ `,
+})
+class RangeSliderWithStep {}
+
/** The pointer event types used by the MDC Slider. */
const enum PointerEventType {
POINTER_DOWN = 'pointerdown',
@@ -650,6 +794,22 @@ function slideToValue(slider: MatSlider, value: number, thumbPosition: Thumb, is
dispatchPointerOrTouchEvent(sliderElement, PointerEventType.POINTER_UP, endX, endY, isIOS);
}
+/**
+ * Mimics changing the slider value using arrow keys.
+ *
+ * Dispatching keydown events on inputs do not trigger value changes. Thus, to mimic this behavior,
+ * we manually change the slider inputs value and then dispatch a change event (which is what the
+ * MDC Foundation is listening for & how it handles these updates).
+ */
+function changeValueUsingArrowKeys(slider: MatSlider, arrow: number, thumbPosition: Thumb) {
+ const input = slider._getInput(thumbPosition);
+ const value = arrow === RIGHT_ARROW
+ ? input.value + slider.step
+ : input.value - slider.step;
+ input._hostElement.value = value.toString();
+ dispatchEvent(input._hostElement, new Event('change'));
+}
+
/** Dispatch a pointerdown or pointerup event if supported, otherwise dispatch the touch event. */
function dispatchPointerOrTouchEvent(
node: Node, type: PointerEventType, x: number, y: number, isIOS: boolean) {