diff --git a/packages/react/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.test.tsx b/packages/react/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.test.tsx index dc20401c3b..f50a120d31 100644 --- a/packages/react/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.test.tsx +++ b/packages/react/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.test.tsx @@ -54,6 +54,7 @@ describe.skipIf(isWebKit)('', () => { const { user } = await render( + @@ -129,4 +130,44 @@ describe.skipIf(isWebKit)('', () => { Element.prototype.requestPointerLock = originalRequestPointerLock; } }); + + it('does not render after a quick tap when pointer lock resolves later', async () => { + const originalRequestPointerLock = Element.prototype.requestPointerLock; + + try { + // Simulate pointer lock resolving after the user already released the pointer (tap) + Element.prototype.requestPointerLock = sinon.stub().returns( + new Promise((resolve) => { + setTimeout(resolve, 30); + }), + ); + + const { user } = await render( + + + + + + , + ); + + const scrubArea = screen.getByTestId('scrub-area'); + + await act(async () => { + // Quick press and release (tap) + await user.pointer({ target: scrubArea, keys: '[MouseLeft>]', pointerName: 'mouse' }); + await user.pointer({ target: scrubArea, keys: '[/MouseLeft]', pointerName: 'mouse' }); + window.dispatchEvent(new Event('pointerup')); + // Wait longer than the delayed pointer lock resolution + await new Promise((resolve) => { + setTimeout(resolve, 50); + }); + }); + + // After a tap, the scrub cursor should not remain rendered + expect(screen.queryByTestId('scrub-area-cursor')).to.equal(null); + } finally { + Element.prototype.requestPointerLock = originalRequestPointerLock; + } + }); }); diff --git a/packages/react/src/number-field/scrub-area/NumberFieldScrubArea.tsx b/packages/react/src/number-field/scrub-area/NumberFieldScrubArea.tsx index ffdf791427..fd532115ce 100644 --- a/packages/react/src/number-field/scrub-area/NumberFieldScrubArea.tsx +++ b/packages/react/src/number-field/scrub-area/NumberFieldScrubArea.tsx @@ -258,9 +258,11 @@ export const NumberFieldScrubArea = React.forwardRef(function NumberFieldScrubAr } catch (error) { setIsPointerLockDenied(true); } finally { - ReactDOM.flushSync(() => { - onScrubbingChange(true, event.nativeEvent); - }); + if (isScrubbingRef.current) { + ReactDOM.flushSync(() => { + onScrubbingChange(true, event.nativeEvent); + }); + } } } },