diff --git a/packages/dnb-eufemia/src/components/slider/SliderProvider.tsx b/packages/dnb-eufemia/src/components/slider/SliderProvider.tsx index 73af9ac3e65..52094c6ee4d 100644 --- a/packages/dnb-eufemia/src/components/slider/SliderProvider.tsx +++ b/packages/dnb-eufemia/src/components/slider/SliderProvider.tsx @@ -184,6 +184,12 @@ export function SliderProvider(localProps: SliderProps) { multiValues[currentIndex + 1] = numberValue } } + + if (numberValue === realtimeValue.current[currentIndex]) { + return // stop here + } + } else if (numberValue === realtimeValue.current) { + return // stop here } if (typeof onChange === 'function') { diff --git a/packages/dnb-eufemia/src/components/slider/__tests__/Slider.test.tsx b/packages/dnb-eufemia/src/components/slider/__tests__/Slider.test.tsx index e0b4aa9ffda..e47f6b9d86b 100644 --- a/packages/dnb-eufemia/src/components/slider/__tests__/Slider.test.tsx +++ b/packages/dnb-eufemia/src/components/slider/__tests__/Slider.test.tsx @@ -21,6 +21,10 @@ const props: SliderProps = { labelDirection: 'horizontal', } +const resetMouseSimulation = () => { + fireEvent.mouseUp(document.querySelector('.dnb-slider__track')) +} + describe('Slider component', () => { it('supports snake_case props', () => { const props: SliderProps = { @@ -215,6 +219,20 @@ describe('Slider component', () => { ).toBe('80,0 norske kroner') }) + it('will not emit onChange with same value twice', () => { + const onChange = jest.fn() + + render() + + simulateMouseMove({ pageX: 80, width: 100, height: 10 }) + simulateMouseMove({ pageX: 80, width: 100, height: 10 }) + + expect(onChange).toBeCalledTimes(1) + expect(onChange.mock.calls[0][0].value).toBe(80) + + resetMouseSimulation() + }) + describe('multi thumb', () => { const SliderWithStateUpdate = (props: SliderProps) => { const [value, setValue] = React.useState(props.value) @@ -227,9 +245,26 @@ describe('Slider component', () => { return } - const resetMouseSimulation = () => { - fireEvent.mouseUp(document.querySelector('.dnb-slider__track')) - } + const getRangeElement = (index: number) => + document.querySelectorAll('[type="range"]')[ + index + ] as HTMLInputElement + + it('will not emit onChange with same value twice', () => { + const onChange = jest.fn() + + props.value = [20, 30, 90] + render() + + fireEvent.mouseDown(getRangeElement(1)) + simulateMouseMove({ pageX: 80, width: 100, height: 10 }) + simulateMouseMove({ pageX: 80, width: 100, height: 10 }) + + expect(onChange).toBeCalledTimes(1) + expect(onChange.mock.calls[0][0].value).toEqual([20, 30, 80]) + + resetMouseSimulation() + }) it('tracks mousemove on track', () => { const onChange = jest.fn() @@ -243,14 +278,9 @@ describe('Slider component', () => { /> ) - const getRangeElements = (index: number) => - document.querySelectorAll('[type="range"]')[ - index - ] as HTMLInputElement - simulateMouseMove({ pageX: 80, width: 100, height: 10 }) - expect(parseFloat(getRangeElements(2).value)).toBe(80) + expect(parseFloat(getRangeElement(2).value)).toBe(80) expect(onChange).toBeCalledWith({ event: { @@ -284,7 +314,7 @@ describe('Slider component', () => { width: 100, }) - fireEvent.mouseDown(getRangeElements(1)) + fireEvent.mouseDown(getRangeElement(1)) simulateMouseMove({ pageX: 40, width: 100, height: 10 })