@wix/design-system
Version:
@wix/design-system
75 lines • 4.53 kB
JavaScript
import React, { useCallback, useRef, useState, useEffect, useMemo, } from 'react';
import { ChevronLeftSmall, ChevronRightSmall } from '@wix/wix-ui-icons-common';
import { st, 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';
import deprecationLog from '../utils/deprecationLog';
const DEFAULT_DEBOUNCE_TIMEOUT_MS = 20;
const DEFAULT_SCROLL_DISTANCE_PX = 150;
const EDGE_BLUR_LAYER_COUNT = 7;
const HorizontalScroll = ({ children, scrollDistance = DEFAULT_SCROLL_DISTANCE_PX, scrollDebounce = DEFAULT_DEBOUNCE_TIMEOUT_MS, scrollButtonSkin = SKINS.standard, scrollButtonSize = SIZES.tiny, edgeStyle = 'blur', edgeWidth, 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]);
useEffect(() => {
if (gradientWidth !== undefined) {
deprecationLog('<HorizontalScroll/> prop "gradientWidth" is deprecated and will be removed in the next major release, please use "edgeWidth" instead.');
}
}, [gradientWidth]);
const edgeBlurLayers = edgeStyle === 'blur' &&
Array.from({ length: EDGE_BLUR_LAYER_COUNT }, (_, index) => (React.createElement("div", { key: index, className: classes.blurLayer })));
return (React.createElement("div", { className: st(classes.root, { edge: edgeStyle }), "data-hook": dataHook, style: {
[vars['wds-horizontal-scroll-gradient-color']]: gradientColor,
[vars['wds-horizontal-scroll-edge-width']]: edgeWidth ?? gradientWidth,
} },
canScrollLeft && (React.createElement("div", { className: classes.startScroll },
edgeBlurLayers,
React.createElement("div", { className: classes.startScrollButton },
React.createElement(IconButton, { "aria-hidden": true, className: classes.scrollButton, 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 },
edgeBlurLayers,
React.createElement("div", { className: classes.endScrollButton },
React.createElement(IconButton, { "aria-hidden": true, className: classes.scrollButton, 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