@wix/design-system
Version:
@wix/design-system
76 lines • 3.63 kB
JavaScript
import { addResizeObserver } from '../../utils/addResizeObserver';
import throttle from 'lodash/throttle';
const addResizeObserverThrottled = (element, cb) => addResizeObserver(element, throttle(cb, 100));
export class FloatingScrollBarState {
constructor(params) {
this.setFloatingPosition = params.setFloatingPosition;
this.setScrollContentSize = params.setScrollContentSize;
this.setScrollContentPosition = params.setScrollContentPosition;
this.viewportRef = params.viewportRef;
this.scrollableContentRef = params.scrollableContentRef;
this.scrollElementRef = params.scrollElementRef;
}
init() {
const { setFloatingPosition, setScrollContentSize, setScrollContentPosition, viewportRef, scrollableContentRef, scrollElementRef, } = this;
const scrollElement = scrollElementRef?.current;
const viewportElement = viewportRef?.current;
const scrollableContentElement = scrollableContentRef?.current;
const scrollableContentParentElement = scrollableContentElement?.parentElement;
if (!viewportElement ||
!scrollableContentElement ||
!scrollableContentParentElement ||
!scrollElement) {
return;
}
const checkIfTableEndExceedsContainer = () => {
const scrollableContentRect = scrollableContentElement.getBoundingClientRect();
const scrollElementRect = scrollElement.getBoundingClientRect();
const viewportRect = viewportElement.getBoundingClientRect();
// min between the bottom of viewport element and the bottom of the viewport
const viewportVerticalEndRelative = Math.min(scrollElement.clientHeight, viewportElement.clientHeight, window.innerHeight - viewportRect.top);
setFloatingPosition(scrollableContentRect.bottom > scrollElementRect.bottom
? {
top: viewportVerticalEndRelative,
}
: undefined);
};
const syncPosition = () => {
const viewportRect = viewportElement.getBoundingClientRect();
const scrollableContentParentRect = scrollableContentParentElement.getBoundingClientRect();
setScrollContentPosition({
left: scrollableContentParentRect.left - viewportRect.left,
width: scrollableContentParentElement.clientWidth,
});
};
const syncSize = () => {
setScrollContentSize({
width: scrollableContentParentElement.scrollWidth,
});
};
const onScroll = throttle(() => {
checkIfTableEndExceedsContainer();
}, 100);
scrollElement?.addEventListener('scroll', onScroll);
const disposers = [
addResizeObserverThrottled(viewportElement, () => {
checkIfTableEndExceedsContainer();
syncPosition();
}),
addResizeObserverThrottled(scrollableContentElement, () => {
checkIfTableEndExceedsContainer();
}),
addResizeObserverThrottled(scrollElement, () => {
checkIfTableEndExceedsContainer();
}),
addResizeObserverThrottled(scrollableContentParentElement, () => {
syncSize();
syncPosition();
}),
];
return () => {
disposers.forEach(disposer => disposer && disposer());
scrollElement?.removeEventListener('scroll', onScroll);
};
}
}
//# sourceMappingURL=FloatingScrollBarState.js.map