@wix/design-system
Version:
@wix/design-system
56 lines • 2.84 kB
JavaScript
import React, { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
// @ts-ignore
import { ScrollSyncPane } from 'react-scroll-sync';
import { classes, st } from './FloatingScrollBar.st.css.js';
import { useFloatingScrollBarContext } from './FloatingScrollBarContext';
import { useFloatingScrollBarState } from './useFloatingScrollBarState';
import { usePageScrollContext } from '../../Page/PageScrollContext';
function FloatingScrollBarInner(props) {
const { dataHook, viewportElement, scrollBarRef, zIndex, scrollContentSize, floatingPosition, scrollContentPosition, } = props;
const [height, setHeight] = useState(0);
useEffect(() => {
const scrollBarElement = scrollBarRef.current;
if (!scrollBarElement) {
return;
}
setHeight(scrollBarElement.getBoundingClientRect().height);
}, [scrollBarRef]);
return createPortal(React.createElement("div", { "data-hook": dataHook, className: st(classes.root), ref: scrollBarRef, style: {
...scrollContentPosition,
zIndex,
...(floatingPosition
? { top: floatingPosition.top - height }
: { visibility: 'hidden' }),
} },
React.createElement("div", { "data-hook": "floating-scroll-bar-content", className: st(classes.content), style: scrollContentSize })), viewportElement);
}
export function FloatingScrollBar(props) {
const { viewportRef } = useFloatingScrollBarContext();
const { scrollableContentRef: pageScrollableContentRef } = usePageScrollContext();
const [viewportElement, setViewportElement] = useState(null);
const scrollBarRef = useRef(null);
const { floatingScrollBarStateRef } = useFloatingScrollBarContext();
const { scrollContentPosition, scrollContentSize, floatingPosition, state } = useFloatingScrollBarState();
useEffect(() => {
floatingScrollBarStateRef.current = state;
return () => {
floatingScrollBarStateRef.current = null;
};
}, [floatingScrollBarStateRef, state]);
useEffect(() => {
const pageElement = pageScrollableContentRef?.current?.parentElement;
if (pageElement) {
setViewportElement(pageElement);
}
else {
setViewportElement(viewportRef?.current ?? null);
}
}, [viewportRef, pageScrollableContentRef]);
if (!viewportElement) {
return null;
}
return (React.createElement(ScrollSyncPane, { attachTo: scrollBarRef },
React.createElement(FloatingScrollBarInner, { ...props, viewportElement: viewportElement, scrollBarRef: scrollBarRef, scrollContentPosition: scrollContentPosition, scrollContentSize: scrollContentSize, floatingPosition: floatingPosition, state: state })));
}
//# sourceMappingURL=FloatingScrollBar.js.map