From 48c4b1297d5c504ab93078c0305dc630e7e549a3 Mon Sep 17 00:00:00 2001 From: Josh Kelley Date: Fri, 17 Jan 2025 14:15:33 -0500 Subject: [PATCH] Fix arrow keys past the end for Slider with custom marks Fixes #45049 --- .../mui-material/src/Slider/Slider.test.js | 48 +++++++++++++++++++ packages/mui-material/src/Slider/useSlider.ts | 4 +- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/mui-material/src/Slider/Slider.test.js b/packages/mui-material/src/Slider/Slider.test.js index 8f1b0af1dfc19b..ec3dcd18beabb0 100644 --- a/packages/mui-material/src/Slider/Slider.test.js +++ b/packages/mui-material/src/Slider/Slider.test.js @@ -1195,6 +1195,54 @@ describe('', () => { }); }); }); + + it(`stops at the max value with custom marks`, () => { + const handleChange = stub().callsFake((_event, value) => value); + const { getByRole } = render( + ({ value }))} + step={null} + value={30} + onChange={handleChange} + />, + ); + + const slider = getByRole('slider'); + expect(slider).to.have.attribute('aria-valuenow', '30'); + + act(() => { + slider.focus(); + }); + + fireEvent.keyDown(slider, { key: 'ArrowRight' }); + + expect(handleChange.callCount).to.equal(0); + expect(slider).to.have.attribute('aria-valuenow', '30'); + }); + + it(`stops at the min value with custom marks`, () => { + const handleChange = stub().callsFake((_event, value) => value); + const { getByRole } = render( + ({ value }))} + step={null} + value={10} + onChange={handleChange} + />, + ); + + const slider = getByRole('slider'); + expect(slider).to.have.attribute('aria-valuenow', '10'); + + act(() => { + slider.focus(); + }); + + fireEvent.keyDown(slider, { key: 'ArrowLeft' }); + + expect(handleChange.callCount).to.equal(0); + expect(slider).to.have.attribute('aria-valuenow', '10'); + }); }); describe('warnings', () => { diff --git a/packages/mui-material/src/Slider/useSlider.ts b/packages/mui-material/src/Slider/useSlider.ts index 71fef5b75129bb..a5d455b2315426 100644 --- a/packages/mui-material/src/Slider/useSlider.ts +++ b/packages/mui-material/src/Slider/useSlider.ts @@ -311,9 +311,9 @@ export function useSlider(parameters: UseSliderParameters): UseSliderReturnValue let newValue: number | number[] = valueInput; if (marks && step == null) { const maxMarksValue = marksValues[marksValues.length - 1]; - if (newValue > maxMarksValue) { + if (newValue >= maxMarksValue) { newValue = maxMarksValue; - } else if (newValue < marksValues[0]) { + } else if (newValue <= marksValues[0]) { newValue = marksValues[0]; } else { newValue = newValue < value ? marksValues[marksIndex - 1] : marksValues[marksIndex + 1];