UNPKG

@wix/design-system

Version:

@wix/design-system

69 lines 3.91 kB
import React, { useCallback, useRef, useState, useEffect, useMemo, } from 'react'; import PropTypes from 'prop-types'; import { ChevronLeftSmall, ChevronRightSmall } from '@wix/wix-ui-icons-common'; import { classes, vars } from './HorizontalScroll.st.css.js'; import IconButton from '../IconButton'; import { SIZES, SKINS } from '../IconButton/IconButton.constants'; import { dataHooks } from './HorizontalScroll.constants'; import debounce from 'lodash/debounce'; const DEFAULT_DEBOUNCE_TIMEOUT_MS = 20; const DEFAULT_SCROLL_DISTANCE_PX = 150; const HorizontalScroll = ({ children, scrollDistance = DEFAULT_SCROLL_DISTANCE_PX, scrollDebounce = DEFAULT_DEBOUNCE_TIMEOUT_MS, scrollButtonSkin = SKINS.standard, scrollButtonSize = SIZES.tiny, gradientColor, gradientWidth, dataHook, }) => { const scrollContainerRef = useRef(null); const [canScrollLeft, setCanScrollLeft] = useState(false); const [canScrollRight, setCanScrollRight] = useState(false); const handleScrollByStep = useCallback((scrollValue) => { const container = scrollContainerRef.current; if (!container) return; container.scrollLeft += scrollValue; }, []); const checkOverflow = useCallback(() => { const container = scrollContainerRef.current; if (!container) return; const { scrollLeft, scrollWidth, clientWidth } = container; setCanScrollLeft(scrollLeft > 0); setCanScrollRight(Math.round(scrollLeft) < scrollWidth - clientWidth); }, []); const debouncedCheckOverflow = useMemo(() => debounce(checkOverflow, scrollDebounce), [checkOverflow, scrollDebounce]); useEffect(() => { const container = scrollContainerRef.current; if (!container) return; const observer = new ResizeObserver(checkOverflow); observer.observe(container); return () => observer.disconnect(); }, [checkOverflow]); useEffect(() => { checkOverflow(); return () => { debouncedCheckOverflow.cancel(); }; }, [children, checkOverflow, debouncedCheckOverflow]); return (React.createElement("div", { className: classes.root, "data-hook": dataHook, style: { [vars['wds-horizontal-scroll-gradient-color']]: gradientColor, [vars['wds-horizontal-scroll-gradient-width']]: gradientWidth, } }, canScrollLeft && (React.createElement("div", { className: classes.startScroll }, React.createElement("div", { className: classes.startScrollButton }, React.createElement(IconButton, { "aria-hidden": true, size: scrollButtonSize, priority: "secondary", skin: scrollButtonSkin, onClick: () => handleScrollByStep(-scrollDistance), dataHook: dataHooks.leftButton }, React.createElement(ChevronLeftSmall, null))))), React.createElement("div", { className: classes.scrollContainer, ref: scrollContainerRef, onScroll: debouncedCheckOverflow, "data-hook": dataHooks.scrollContainer, tabIndex: -1 }, children), canScrollRight && (React.createElement("div", { className: classes.endScroll }, React.createElement("div", { className: classes.endScrollButton }, React.createElement(IconButton, { "aria-hidden": true, size: scrollButtonSize, priority: "secondary", skin: scrollButtonSkin, onClick: () => handleScrollByStep(scrollDistance), dataHook: dataHooks.rightButton }, React.createElement(ChevronRightSmall, null))))))); }; HorizontalScroll.displayName = 'HorizontalScroll'; HorizontalScroll.propTypes = { children: PropTypes.any, scrollDistance: PropTypes.any, scrollDebounce: PropTypes.any, gradientColor: PropTypes.any, gradientWidth: PropTypes.any, scrollButtonSkin: PropTypes.any, dataHook: PropTypes.any, }; export default HorizontalScroll; //# sourceMappingURL=HorizontalScroll.js.map