@wix/design-system
Version:
@wix/design-system
64 lines • 3.79 kB
JavaScript
import React, { useCallback, useRef, useState, useEffect, useMemo, } from 'react';
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';
import { useIcons } from '../WixDesignSystemIconThemeProvider';
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 icons = useIcons('HorizontalScroll', {
ChevronLeftSmall,
ChevronRightSmall,
});
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(icons.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(icons.ChevronRightSmall, null)))))));
};
HorizontalScroll.displayName = 'HorizontalScroll';
export default HorizontalScroll;
//# sourceMappingURL=HorizontalScroll.js.map