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);
+ });
+ }
}
}
},