Skip to content

Commit 52ba9fd

Browse files
authored
[slider] Fix range slider onValueCommitted not called (#3600)
1 parent 6fb3bc2 commit 52ba9fd

File tree

2 files changed

+95
-1
lines changed

2 files changed

+95
-1
lines changed

packages/react/src/slider/control/SliderControl.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,6 @@ export const SliderControl = React.forwardRef(function SliderControl(
322322

323323
pressedInputRef.current = null;
324324
pressedThumbCenterOffsetRef.current = null;
325-
pressedThumbIndexRef.current = -1;
326325

327326
const fingerCoords = getFingerCoords(nativeEvent, touchIdRef);
328327
const finger = fingerCoords != null ? getFingerState(fingerCoords) : null;
@@ -343,6 +342,7 @@ export const SliderControl = React.forwardRef(function SliderControl(
343342
controlRef.current?.releasePointerCapture(nativeEvent.pointerId);
344343
}
345344

345+
pressedThumbIndexRef.current = -1;
346346
touchIdRef.current = null;
347347
pressedValuesRef.current = null;
348348
// eslint-disable-next-line @typescript-eslint/no-use-before-define

packages/react/src/slider/root/SliderRoot.test.tsx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,100 @@ describe.skipIf(typeof Touch === 'undefined')('<Slider.Root />', () => {
594594
});
595595
});
596596

597+
describe('prop: onValueCommitted', () => {
598+
it('single value', async () => {
599+
const handleValueCommitted = spy((newValue: number, eventDetails) => ({
600+
newValue,
601+
reason: eventDetails.reason,
602+
}));
603+
604+
await render(
605+
<Slider.Root onValueCommitted={handleValueCommitted} defaultValue={0}>
606+
<Slider.Control data-testid="control">
607+
<Slider.Thumb />
608+
</Slider.Control>
609+
</Slider.Root>,
610+
);
611+
612+
const sliderControl = screen.getByTestId('control');
613+
614+
stub(sliderControl, 'getBoundingClientRect').callsFake(getHorizontalSliderRect);
615+
616+
const slider = screen.getByRole('slider');
617+
618+
fireEvent.pointerDown(sliderControl, {
619+
buttons: 1,
620+
clientX: 10,
621+
});
622+
fireEvent.pointerUp(sliderControl, {
623+
buttons: 1,
624+
clientX: 10,
625+
});
626+
627+
expect(handleValueCommitted.callCount).to.equal(1);
628+
expect(handleValueCommitted.lastCall.returnValue.newValue).to.equal(10);
629+
expect(handleValueCommitted.lastCall.returnValue.reason).to.equal(REASONS.trackPress);
630+
631+
await act(async () => {
632+
slider.focus();
633+
});
634+
635+
fireEvent.change(slider, { target: { value: 23 } });
636+
expect(handleValueCommitted.callCount).to.equal(2);
637+
expect(handleValueCommitted.lastCall.returnValue.reason).to.equal(REASONS.inputChange);
638+
});
639+
640+
it('array value', async () => {
641+
const handleValueCommitted = spy((newValue: number[], eventDetails) => ({
642+
newValue,
643+
reason: eventDetails.reason,
644+
}));
645+
646+
await render(
647+
<Slider.Root onValueCommitted={handleValueCommitted} defaultValue={[10, 20]}>
648+
<Slider.Control data-testid="control">
649+
<Slider.Thumb index={0} />
650+
<Slider.Thumb index={1} />
651+
</Slider.Control>
652+
</Slider.Root>,
653+
);
654+
655+
const sliderControl = screen.getByTestId('control');
656+
657+
stub(sliderControl, 'getBoundingClientRect').callsFake(getHorizontalSliderRect);
658+
659+
const [thumb1, thumb2] = screen.getAllByRole('slider');
660+
661+
fireEvent.pointerDown(thumb2, {
662+
buttons: 1,
663+
clientX: 20,
664+
});
665+
666+
fireEvent.pointerMove(thumb2, {
667+
buttons: 1,
668+
clientX: 30,
669+
});
670+
671+
expect(handleValueCommitted.callCount).to.equal(0);
672+
673+
fireEvent.pointerUp(thumb2, {
674+
buttons: 1,
675+
clientX: 30,
676+
});
677+
678+
expect(handleValueCommitted.callCount).to.equal(1);
679+
expect(handleValueCommitted.lastCall.returnValue.reason).to.equal(REASONS.drag);
680+
681+
await act(async () => {
682+
thumb1.focus();
683+
});
684+
685+
fireEvent.change(thumb1, { target: { value: 23 } });
686+
expect(handleValueCommitted.callCount).to.equal(2);
687+
expect(handleValueCommitted.lastCall.returnValue.reason).to.equal(REASONS.inputChange);
688+
});
689+
});
690+
597691
describe('events', () => {
598692
it.skipIf(isJSDOM)('should call handlers', async () => {
599693
const handleValueChange = spy();

0 commit comments

Comments
 (0)