Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[preact/compat] radix-ui Slider component drag points (Thumbs) not working #3666

Open
1 task done
nikuda opened this issue Aug 12, 2022 · 2 comments
Open
1 task done
Labels

Comments

@nikuda
Copy link

nikuda commented Aug 12, 2022

  • Check if updating to the latest Preact version resolves the issue

Describe the bug
Thumb (drag points) are not receiving any updates past the initial css applied.

To Reproduce

https://stackblitz.com/edit/nextjs-preact-webpack5-pjoxwh

Steps to reproduce the behaviour:

Load the stackblitz example above and drag the edges of the white lines:

Screen Shot 2022-08-08 at 12 43 56 pm

While the line itself is adjustable, the Thumb components are not shown. If the nested span's css is modified from display: none to display: block the Thumb element is rendered on left edge with 0, 0 coords.

Screen Shot 2022-08-08 at 12 49 37 pm

Expected behavior

For slider thumbs to be attached to end of white line and to move along with them.

Screen Shot 2022-08-08 at 12 54 02 pm

Additional context

Slider component used to hang the app as did the Dialog in this bug report #3297. Since version 10.10.1 and this #3645 fix specifically the Slider component now no longer hangs the app but it's not 100% working either with Thumb component being broken.

Same Issue reported in radix-ui repo radix-ui/primitives#1601

@JoviDeCroock
Copy link
Member

So far I have been able to narrow it down to this useCollection, this getItems is not returning the thumbs

@marvinhagemeister
Copy link
Member

Took a stab at this too. From what I can tell so far is that this is caused by a combination of re-renders and abusing refs as state updaters. So what the radix-ui team is doing akin to this:

function Foo() {
  const [thumb, setThumb = useState(null);
  // Ref is abused as a state setter.
  return <button ref={(el) => setThumb(el)} />
}

In the real code base there are a few abstractions in-between like the composedRefs thing, but that's essentially the pattern they are doing. But why does that lead to a different rendering result in Preact vs React?

That can be answered by looking into how both frameworks deal with state updates during a commit is being batched. In Preact we just re-queue the component and once the queue is components is flushed (meaning all components finished rendering), then we fire all pending effects that that were scheduled via useEffect.

Problem is that during the rendering of the re-queued component which holds the thumb state, the state holds now the DOM reference. But that reference is the only thing guarding the invocation of getItems, which is ultimately responsible for setting the thumb index, which ends up controlling what kind of value (=slider position) the thumb has. But because the index is -1 the value is undefined and when the value is undefined the thumb controller adds a display: none to the thumb.

The whole logic relies on this useEffect being called, by which point getItems returns a valid index and the thumb is shown.

In React this works, because the effects seem to be executed before a re-queued element is rendered, instead of at the end when all components have been rendered.

nikogoli added a commit to nikogoli/testing-shadcn-ui-in-fresh that referenced this issue Nov 2, 2023
SliderPrimitive.Thumb が適切に動作しない
([radix-ui 側の issue](radix-ui/primitives#1601))
([preact 側の issue](preactjs/preact#3666))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants