UNPKG

@wix/design-system

Version:

@wix/design-system

63 lines 3.1 kB
import React, { useRef, forwardRef, useCallback, useEffect } from 'react'; import throttle from 'lodash/throttle'; import { getScrollAreaY } from './scrollAreaLogic'; import { extractDataAttributes } from '../../utils/extractAttributes'; const ScrollableContainer = forwardRef(function ScrollableContainer({ dataHook, className, style, children, onScrollAreaChanged, onScrollChanged, scrollThrottleWait = 100, ...restProps }, ref) { const elementRef = useRef(null); // In case a ref was passed from outside we should use it so allow the parent access to the dom node as well. const scrollContainerElement = ref || elementRef; const scrollAreaY = useRef(''); // TODO: fix ESLint error // eslint-disable-next-line react-hooks/exhaustive-deps const handleScrollAreaChanged = useCallback(throttle(({ target }) => { const newScrollAreaY = getScrollAreaY(target); if (scrollAreaY.current !== newScrollAreaY) { scrollAreaY.current = newScrollAreaY; onScrollAreaChanged({ target, area: { y: newScrollAreaY }, }); } }, scrollThrottleWait, { trailing: true }), [onScrollAreaChanged, scrollThrottleWait]); // TODO: fix ESLint error // eslint-disable-next-line react-hooks/exhaustive-deps const handleScrollChanged = useCallback(throttle(e => onScrollChanged(e), scrollThrottleWait, { trailing: true }), [onScrollChanged, scrollThrottleWait]); useEffect(() => { // Registering to the scroll event only if the relevant handlers were provided const scrollableElement = scrollContainerElement.current; if (onScrollAreaChanged) { scrollableElement.addEventListener('scroll', handleScrollAreaChanged); // We trigger a call to this handler to expose the initial scroll area to registering consumers handleScrollAreaChanged({ target: scrollableElement }); } if (onScrollChanged) { scrollableElement.addEventListener('scroll', handleScrollChanged); } return () => { // Unregistering from relevant events on component unmount if (onScrollAreaChanged) { handleScrollAreaChanged.cancel(); scrollableElement.removeEventListener('scroll', handleScrollAreaChanged); } if (onScrollChanged) { handleScrollChanged.cancel(); scrollableElement.removeEventListener('scroll', handleScrollChanged); } }; }, [ handleScrollChanged, handleScrollAreaChanged, onScrollChanged, onScrollAreaChanged, scrollContainerElement, ]); const stl = { height: 'inherit', width: 'inherit', overflowY: 'auto', ...style, }; return (React.createElement("div", { "data-hook": dataHook, className: className, style: stl, ref: scrollContainerElement, ...extractDataAttributes(restProps) }, children)); }); export default ScrollableContainer; //# sourceMappingURL=ScrollableContainer.js.map