primitives
primitives copied to clipboard
[Slider] onValueCommit not being called properly
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 |
Hey @vctormb,
I am unable to reproduce this on my side, what browser/OS are you using and how do your replicate it?
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
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?
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
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 🙏
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
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?
here it is
https://user-images.githubusercontent.com/13953703/200359911-99380390-0bea-4983-84f9-ecb0f2ba2cec.mov
It looks like that in Firefox it's working properly 🤔
How about Safari? Wondering if it's a Webkit/Chromium based bug in Ventura only…
Safari is working good too
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
It's 100% reproducible if you drag the thumb, then move the cursor outside the slider, and then release the mouse.
~~More accurately, the bug will occur if you start dragging on the thumb and then stop dragging outside the thumb region.~~
It's weird. It seems that the bug only happens if you slide quickly enough.
We are experiencing this issue as well. Does anyone have a fix/workaround?
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>
)
}
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.
Experiencing the same issue on latest Chrome / MacOS. I am using a similar approach to @annavik for now.
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???! 😀
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.
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).
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
and latest macOS
Same issue with the storybook. For what it's worth, I'm on an M1, latest OSX & Chrome, and using the trackpad.
Having a look at the mui slider implementation it works quite differently:
- It only registers the
touchmove
&touchend
on the document when thetouchstart
event is triggered on the root element - and it only registers
mousemove
&mouseup
events on the document when themousedown
event is triggered on the root element.
So it doesn't seem to be using any pointer events like this implementation.
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!
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.
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.
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
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
Hi.
In my environment, workaround of onPointerLeave
was not enough. I add onMouseUp
.
(sometimes only onMouseUp
is called)