Skip to content

Conversation

@chirokas
Copy link
Contributor

Closes #9406

Fixes regressions introduced in #9012

// If triggered from a screen reader or by using element.click(),
// trigger as if it were a keyboard click.
if (!state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || isVirtualClick(e.nativeEvent))) {
let stopPressStart = triggerPressStart(e, 'virtual');
let stopPressUp = triggerPressUp(e, 'virtual');
let stopPressEnd = triggerPressEnd(e, 'virtual');

Since onPressStart and onPressUp are triggered synchronously, setIsIncrementPressed(null) immediately overwrites the previous state, so onIncrement is not triggered.

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

🧢 Your Project:

@chirokas chirokas marked this pull request as ready for review December 27, 2025 15:47
@snowystinger
Copy link
Member

Hope you don't mind, pushed some updates while I was testing. I think there was an extraneous onIncrement/decrement, though it didn't seem to affect anything. Do you know where it came from? If needed, I was going to see about merging it with the onPressStart behaviour which already had that for non-touch, but removing it seemed more correct given the code comments.

@chirokas
Copy link
Contributor Author

chirokas commented Jan 4, 2026

If I understand correctly, for touch users, we need to wait 600ms before triggering onIncrement/decrement, then start spinning.

Following this logic, the code should look like this:

_async.current = window.setTimeout(() => {
  onIncrement?.();
  setIsIncrementPressed('touch');
}, 600);

However, to ensure we always access the latest onIncrement/decrement from props (avoiding stale closure issues in setTimeout), I moved the call into useEffect.

useEffect(() => {
  if (isIncrementPressed === 'touch') {
    onIncrement?.();
    onIncrementPressStart(60);
  }

If we remove the onIncrement/decrement call from useEffect, the first trigger would occur at 600ms + 60ms = 660ms.

@snowystinger
Copy link
Member

Ah, thanks, I see, this only affects the amount of time to start a spin. Not for a tap. And it's 60ms, so would be hard to notice manually.
However, I think we can simplify to help the two branches match each other a little more closely. I'll push the change. Thanks for explaining that, I'd missed that little detail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NumberField: userEvent.click on increment/decrement in storybook does not work anymore

2 participants