primitives icon indicating copy to clipboard operation
primitives copied to clipboard

[Slider] onValueCommit not being called properly

Open vctormb opened this issue 2 years ago • 42 comments

Bug report

Sometimes the onValueCommit prop is not being called properly when moving the thumb.

Current Behavior

When moving the thumb sometimes the onValueCommit prop is not called.

Expected behavior

To always call the onValueCommit prop when the user stops sliding

Reproducible example

I'm using the same example from the documentation.

https://user-images.githubusercontent.com/13953703/200179160-12c1437c-1a3f-4c91-bcc7-6ef191ca45d7.mov

Your environment

Software Name(s) Version
Radix Package(s) slider 1.1.0
React n/a 18.2
Browser chrome 107.0.5304.87 (Official Build) (arm64)
Assistive tech
Node n/a
npm/yarn
Operating System macOS Version 13.0

vctormb avatar Nov 06 '22 15:11 vctormb

Hey @vctormb,

I am unable to reproduce this on my side, what browser/OS are you using and how do your replicate it?

benoitgrelard avatar Nov 07 '22 09:11 benoitgrelard

Hey @vctormb,

I am unable to reproduce this on my side, what browser/OS are you using and how do your replicate it?

Hey @benoitgrelard! chrome v107 / macOS v13 ventura.

I just opened up the slider docs and moved the thumb really fast. Keep sliding until you notice that the onValueCommit wasn't called

vctormb avatar Nov 07 '22 13:11 vctormb

I'm not yet on Ventura, but I cannot reproduce the issue with the same chrome v107.

I notice in the video that when it happens if when you released outside the codesandbox iframe. Although, this doesn't break things for me, could you try to do this but slowly and see if it still breaks for you? Perhaps it could be a pointer capture bug in Ventura?

benoitgrelard avatar Nov 07 '22 13:11 benoitgrelard

I'm not yet on Ventura, but I cannot reproduce the issue with the same chrome v107.

I notice in the video that when it happens if when you released outside the codesandbox iframe. Although, this doesn't break things for me, could you try to do this but slowly and see if it still breaks for you? Perhaps it could be a pointer capture bug in Ventura?

Oh, right! Here it is another video doing it slowly

https://user-images.githubusercontent.com/13953703/200327627-0f9cc19d-9070-414d-b621-165b103ea6fa.mov

vctormb avatar Nov 07 '22 13:11 vctormb

Sorry, I meant trying to reproduce what you did in the first video.

Notice how when it started failing, you dragged but went so fast that you released above the code part of codesandbox, rather than the iframe where the demo is rendered?

Could you try to do this but slowly to see if it's due to pointer capture, rather than some weird speed thing?

Thanks 🙏

benoitgrelard avatar Nov 07 '22 14:11 benoitgrelard

Sure! Is this a valid example? If not, please let me know so I can record another one 😅

https://user-images.githubusercontent.com/13953703/200330560-b7829fe5-4aee-48c5-8545-d9d9338182c1.mov

vctormb avatar Nov 07 '22 14:11 vctormb

Ok, well that shows it has nothing to do with the iframe, thanks. However, I'm still struggling to reproduce it or understand how you are doing it 😀

One thing to note is that onValueCommit will only trigger is the value has actually changed, but from what I can see (although tricky with just watching a video) it looks like you are changing it.

Could you try logging the value you receive in onValueCommit and also logging the value in onValueChange and reproduce?

benoitgrelard avatar Nov 07 '22 14:11 benoitgrelard

here it is

https://user-images.githubusercontent.com/13953703/200359911-99380390-0bea-4983-84f9-ecb0f2ba2cec.mov

vctormb avatar Nov 07 '22 16:11 vctormb

It looks like that in Firefox it's working properly 🤔

vctormb avatar Nov 07 '22 16:11 vctormb

How about Safari? Wondering if it's a Webkit/Chromium based bug in Ventura only…

benoitgrelard avatar Nov 07 '22 16:11 benoitgrelard

Safari is working good too

vctormb avatar Nov 07 '22 16:11 vctormb

This is definitely odd, but I was able to reproduce after a couple of tries.

  • Ventura 13
  • Chrome 107.0.5304.87 (Official Build) (x86_64)

https://user-images.githubusercontent.com/6929565/200378479-11b5671d-1808-4a3e-8337-ca24295cc1b6.mp4

bukinoshita avatar Nov 07 '22 17:11 bukinoshita

It's 100% reproducible if you drag the thumb, then move the cursor outside the slider, and then release the mouse.

latin-1 avatar Feb 28 '23 08:02 latin-1

~~More accurately, the bug will occur if you start dragging on the thumb and then stop dragging outside the thumb region.~~

latin-1 avatar Feb 28 '23 09:02 latin-1

It's weird. It seems that the bug only happens if you slide quickly enough.

latin-1 avatar Feb 28 '23 09:02 latin-1

We are experiencing this issue as well. Does anyone have a fix/workaround?

FlorisdeG avatar Mar 27 '23 11:03 FlorisdeG

Same here, my temporary workaround for a single thumb slider is to listen on onPointerLeave. Might be nicer ways to solve it though, let me know if you have ideas.


const Workaround = () => {
  const [isActive, setIsActive] = useState(false)

  return (
    <Slider.Root
      onValueCommit={() => {
        /* Commit value here */
      }}
      onPointerDown={() => setIsActive(true)}
      onPointerUp={() => setIsActive(false)}
      onPointerLeave={() => {
        if (isActive) {
          /* Also commit value here */
          setIsActive(false)
        }
      }}
    >
      [...]
    </Slider.Root>
  )
}

annavik avatar Apr 04 '23 09:04 annavik

Able to reproduce this, although still inconsistently. It's hard to identify what's happening. Using a combination of change & commit to have a song playing, and allow scrubbing through with the slider. Scrubbing will update the value prop (as a controlled element) and then the commit function will tell the audio player to skip to that position.

alii avatar May 07 '23 02:05 alii

Experiencing the same issue on latest Chrome / MacOS. I am using a similar approach to @annavik for now.

riccardolardi avatar May 12 '23 08:05 riccardolardi

I am still struggling to reproduce this (even though on latest Chrome / MacOS):

https://github.com/radix-ui/primitives/assets/1539897/0611b103-7991-4924-b859-2964f3ac5871

How are you all doing it???! 😀

benoitgrelard avatar May 22 '23 11:05 benoitgrelard

Also having this issue on OSX Chrome. Haven't really looked in to why it's happening but I suspect it's something to do with the mouseup event registration or a condition in the event? It doesn't seem like a race condition.

out.webm

jamsch avatar May 28 '23 01:05 jamsch

Had a chance to look in to this further. It seems like the onPointerUp event often isn't getting called when the user drags their mouse off the the element and let's go of their mouse. For what it's worth, the onPointerOut/onPointerLeave events are still emitted. And registering a document.mouseup event listener when the onPointerDown event gets fired works too (although even this would need to be cancelled if the onPointerUp event correctly fires).

Screenshot 2023-05-28 at 6 39 30 PM

jamsch avatar May 28 '23 06:05 jamsch

My problem is that I still can't reproduce it… So without being able to reproduce it there isn't much I can do unfortunately. Is there a definite sandbox/way to reproduce the issue?

I am using our storybook in latest Chrome CleanShot 2023-05-30 at 15 47 25@2x and latest macOS CleanShot 2023-05-30 at 15 47 36@2x

benoitgrelard avatar May 30 '23 14:05 benoitgrelard

Same issue with the storybook. For what it's worth, I'm on an M1, latest OSX & Chrome, and using the trackpad.

out.webm

Having a look at the mui slider implementation it works quite differently:

  • It only registers the touchmove & touchend on the document when the touchstart event is triggered on the root element
  • and it only registers mousemove & mouseup events on the document when the mousedown event is triggered on the root element.

So it doesn't seem to be using any pointer events like this implementation.

jamsch avatar May 31 '23 00:05 jamsch

Same issue with the storybook. For what it's worth, I'm on an M1, latest OSX & Chrome, and using the trackpad.

I'm on an M1, latest OSX & Chrome, so the only diff would be trackpad?

I just tried on the trackpad rather than using my mouse and I can reproduce it! That's very strange that trackpad vs. mouse would make a difference…

At least now I know how to reproduce it now, so I can look into it 🙂

Thanks!

benoitgrelard avatar May 31 '23 09:05 benoitgrelard

Hey everyone, we are also having this issue with onValueCommit not being called properly. In our case, we are using two thumbs and a minStepsBetweenThumbs of 0. The onValueCommit function is not called when the right thumb gets dragged all the way to the left. It works the other way around though. This is easily reproducible and a reproduction is available here in this sandbox.

florianloechle avatar Jun 02 '23 08:06 florianloechle

It would seem that I had encoutered the same problem. I used a state to track and sync a input element value and the slider value. When i moved the slide very fast,it produced this error

Application error: a client-side exception has occurred (see the browser console for more information).

The code can be found here After I removed the slider component,the problem no longer appears.

I am still learning React, please forgive me if I make any mistakes.

ngalioth avatar Jul 13 '23 18:07 ngalioth

Upon further investigation, I discovered that the onPointerUp event fails to trigger when rapidly moving the slider outside of the document. Consequently, the onValueCommit props is not invoked since they rely on the onPointerUp event.

My temporary workaround made:

const Slider = () => {
  const [value, setValue] = useState();
  const [commitedValue, setCommitedValue] = useState();

  const handleValueCommit = (vals) => {
     setCommitedValue(vals);

     // Make Commit
  };
}

<ReactSlider.Root
  value={value}
  onValueChange={setValue}
  onValueCommit={handleValueCommit}

  onPointerLeave={() => {
    // `onPointerLeave` always fired
    // Avoid redundant commits
    if (commitValue[0] !== value[0] || commitValue[1] !== value[1]) {
setCommitedValue(vals);
      // Make Commit
    }
  }}
>

Hope it helps! @benoitgrelard @vctormb

maoxiaoke avatar Aug 29 '23 09:08 maoxiaoke

Arc Version 1.8.1 (41651) / Chromium Engine Version 116.0.5845.187

https://github.com/radix-ui/primitives/assets/6929565/46c6f850-0055-4dd3-b7ae-51b259fa4ece

Chrome Version 116.0.5845.187 (Official Build) (arm64)

https://github.com/radix-ui/primitives/assets/6929565/c973dc71-1ae9-4547-9283-eba3a8539b86

The bug still happens sometimes, I don't actually know the pattern to make it work/not work here. In the video above you can see that sometimes it works and sometimes it just doesn't.

Tested on Chrome, Arc, Firefox and Safari. I could only reproduce on Chrome and Arc. Firefox and Safari seems to be working fine.

Codesandbox: https://codesandbox.io/p/sandbox/polished-currying-svyn38?file=/App.jsx:12,47

bukinoshita avatar Sep 21 '23 01:09 bukinoshita

Hi.

In my environment, workaround of onPointerLeave was not enough. I add onMouseUp. (sometimes only onMouseUp is called)

keisukekomeda avatar Oct 01 '23 14:10 keisukekomeda