@wix/design-system
Version:
@wix/design-system
73 lines • 4.55 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';
import { ProgressiveBlur } from '../common/ProgressiveBlur';
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, 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]);
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 },
edgeStyle === 'blur' && (React.createElement(ProgressiveBlur, { side: "left", className: classes.blur })),
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 },
edgeStyle === 'blur' && (React.createElement(ProgressiveBlur, { side: "right", className: classes.blur })),
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 { HorizontalScroll };
//# sourceMappingURL=HorizontalScroll.js.map