@wix/design-system
Version:
@wix/design-system
69 lines • 3.91 kB
JavaScript
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