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

Select component is not scrollable in shadow dom #1980

Closed
sandro768 opened this issue Feb 22, 2023 · 15 comments
Closed

Select component is not scrollable in shadow dom #1980

sandro768 opened this issue Feb 22, 2023 · 15 comments

Comments

@sandro768
Copy link

Bug report

Select component is not scrollable in shadow dom due to a bug of react-remove-scroll

Here is a link of that bug - theKashey/react-remove-scroll#45

Reproducible example

CodeSandbox Template

@colmanhumphrey
Copy link

I think I'm having the same issue. This is Select in the "popper" position. I have the same set of items twice: once where the origin gives enough space for the full menu, and one in the middle of the screen where it doesn't:

CleanShot.2023-03-22.at.10.38.05.mp4

Is there a workaround (other than using "item-aligned")?

@focux
Copy link

focux commented Apr 25, 2023

I'm also experiencing this when using position popper. Did you find any workaround @colmanhumphrey?

@colmanhumphrey
Copy link

I'm also experiencing this when using position popper. Did you find any workaround @colmanhumphrey?

Hey @focux — I think we ended up setting a max height. It's not ideal because in theory you have to set it to be less than half the screen (for when the trigger is in the middle), and that looks bad when the trigger is up top. But sure that's life.

@joaom00
Copy link
Contributor

joaom00 commented Apr 25, 2023

Have you tried using --radix-select-content-available-height?

https://www.radix-ui.com/docs/primitives/components/select#constrain-the-content-size

@focux
Copy link

focux commented Apr 25, 2023

Just tried and it didn't work.

@joaom00
Copy link
Contributor

joaom00 commented Apr 26, 2023

It should work 🤔. Is your select in a shadow dom too?

@bennik88
Copy link

Is there a reason why there is no scrollbar visible with --radix-select-content-available-height?

@kyrylolvov
Copy link

kyrylolvov commented Aug 8, 2023

I was able to fix the issue by adding a data-scrollable to part of the dropdown content which should be scrollable and then adding this event listeners.

useEffect(() => {
    const handleWheel = (e: WheelEvent) => {
        if ((e.target as Element).closest('[data-scrollable]')) return;
        e.stopPropagation();
    };

    const handleTouchMove = (e: TouchEvent) => {
        if ((e.target as Element).closest('[data-scrollable]')) return;
        e.stopPropagation();
    };

    document.addEventListener('wheel', handleWheel, true);
    document.addEventListener('touchmove', handleTouchMove, true);

    return () => {
        document.removeEventListener('wheel', handleWheel, true);
        document.removeEventListener('touchmove', handleTouchMove, true);
    };
}, []);

@f3sa
Copy link

f3sa commented Sep 16, 2023

I was able to fix the issue by adding a data-scrollable to part of the dropdown content which should be scrollable and then adding this event listeners.

useEffect(() => {
    const handleWheel = (e: WheelEvent) => {
        if ((e.target as Element).closest('[data-scrollable]')) return;
        e.stopPropagation();
    };

    const handleTouchMove = (e: TouchEvent) => {
        if ((e.target as Element).closest('[data-scrollable]')) return;
        e.stopPropagation();
    };

    document.addEventListener('wheel', handleWheel, true);
    document.addEventListener('touchmove', handleTouchMove, true);

    return () => {
        document.removeEventListener('wheel', handleWheel, true);
        document.removeEventListener('touchmove', handleTouchMove, true);
    };
}, []);

Could you be kind to share your code on where you pasted the data-scrollable and where you inserted the useEffect?

@kyrylolvov
Copy link

I was able to fix the issue by adding a data-scrollable to part of the dropdown content which should be scrollable and then adding this event listeners.

useEffect(() => {
    const handleWheel = (e: WheelEvent) => {
        if ((e.target as Element).closest('[data-scrollable]')) return;
        e.stopPropagation();
    };

    const handleTouchMove = (e: TouchEvent) => {
        if ((e.target as Element).closest('[data-scrollable]')) return;
        e.stopPropagation();
    };

    document.addEventListener('wheel', handleWheel, true);
    document.addEventListener('touchmove', handleTouchMove, true);

    return () => {
        document.removeEventListener('wheel', handleWheel, true);
        document.removeEventListener('touchmove', handleTouchMove, true);
    };
}, []);

Could you be kind to share your code on where you pasted the data-scrollable and where you inserted the useEffect?

Hello! So the useEffect I put in App.tsx (I'm using React.js), basically it should run on app mount. And as for the data-scrollable, I just passed it as prop to element inside DropdownContent which should be scrollable.

<div className="max-h-[210px] overflow-y-scroll" data-scrollable>
...
</div

@f3sa
Copy link

f3sa commented Sep 18, 2023

I was able to fix the issue by adding a data-scrollable to part of the dropdown content which should be scrollable and then adding this event listeners.

useEffect(() => {
    const handleWheel = (e: WheelEvent) => {
        if ((e.target as Element).closest('[data-scrollable]')) return;
        e.stopPropagation();
    };

    const handleTouchMove = (e: TouchEvent) => {
        if ((e.target as Element).closest('[data-scrollable]')) return;
        e.stopPropagation();
    };

    document.addEventListener('wheel', handleWheel, true);
    document.addEventListener('touchmove', handleTouchMove, true);

    return () => {
        document.removeEventListener('wheel', handleWheel, true);
        document.removeEventListener('touchmove', handleTouchMove, true);
    };
}, []);

Could you be kind to share your code on where you pasted the data-scrollable and where you inserted the useEffect?

Hello! So the useEffect I put in App.tsx (I'm using React.js), basically it should run on app mount. And as for the data-scrollable, I just passed it as prop to element inside DropdownContent which should be scrollable.

<div className="max-h-[210px] overflow-y-scroll" data-scrollable>
...
</div

Thank you, it works flawlessly!

@alexgshaw
Copy link

For reference adding this class worked for me.

max-h-[var(--radix-select-content-available-height)]

@fgatti675
Copy link

Hi, thank you for the workarounds.
But shouldn't this be fixed in the library?

@jwm0
Copy link

jwm0 commented Jan 15, 2024

The fix was released in react-remove-scroll dependency version 2.5.7. There's a PR waiting to be merged: #2489

Until this gets merged, you can either update the lockfile manually to enforce the dependency's version (not recommended) or wrap the scrollable element in this component:

function ScrollableContainer({ children, ...props }: React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>) {
  const ref = useRef<HTMLDivElement>(null);
  useEffect(() => {
    const element = ref.current!;
    const handleWheel = (e: WheelEvent) => {
      e.stopPropagation();
    };
    const handleTouchMove = (e: TouchEvent) => {
      e.stopPropagation();
    };

    element.addEventListener('wheel', handleWheel, true);
    element.addEventListener('touchmove', handleTouchMove, true);

    return () => {
      element.removeEventListener('wheel', handleWheel, true);
      element.removeEventListener('touchmove', handleTouchMove, true);
    };
  }, []);

  return (
    <div {...props} ref={ref}>
      {children}
    </div>
  );
}

@benoitgrelard
Copy link
Collaborator

Fixed by #2765

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

No branches or pull requests