emilkowalski / vaul

An unstyled drawer component for React.
https://vaul.emilkowal.ski
MIT License
6k stars 201 forks source link

`preventScrollRestoration` setting is not properly working. #316

Closed tomjas1997 closed 2 weeks ago

tomjas1997 commented 6 months ago

as can be seen in , this code block exists and it checks for preventScrollRestoration, but afterward it still scrolls.

Should be an easy fix to not call scrollTo when preventScrollRestoration is true

const restorePositionSetting = React.useCallback(() => {
    if (previousBodyPosition !== null) {
      // Convert the position from "px" to Int
      const y = -parseInt(document.body.style.top, 10);
      const x = -parseInt(document.body.style.left, 10);

      // Restore styles
      document.body.style.position = previousBodyPosition.position;
      document.body.style.top = previousBodyPosition.top;
      document.body.style.left = previousBodyPosition.left;
      document.body.style.height = previousBodyPosition.height;
      document.body.style.right = 'unset';

      requestAnimationFrame(() => {
        if (preventScrollRestoration && activeUrl !== window.location.href) {
          setActiveUrl(window.location.href);
          return;
        }

        window.scrollTo(x, y);
      });

      previousBodyPosition = null;
    }
  }, [activeUrl]);

This was undercover when I allowed body to be scrollable with the drawer open.

Maybe someone else is having the same problem so a workaround for this:

    const [offset, setOffset] = useState(0);

    useEffect(() => {
        const onScroll = () => setOffset(window.scrollY);

        window.addEventListener('scroll', onScroll);

        return () => window.removeEventListener('scroll', onScroll);
    }, []);

    <Drawer
        open={isOpen}
        dismissible={false}
        onClose={() => {
            document.body.style.top = `-${offset}px`;
        }}
    >

onClose is called and it runs before scroll restoration so we set the offset value.

emilkowalski commented 2 weeks ago

This has been refactored and should be working correctly now.