diff --git a/src/components/carousel/index.tsx b/src/components/carousel/index.tsx index 1c8b40a..b0610a5 100644 --- a/src/components/carousel/index.tsx +++ b/src/components/carousel/index.tsx @@ -51,7 +51,9 @@ export const Carousel: FunctionComponent = (userProps: CarouselPr isSliding: true, }); setCurrent(next); - setShowArrow(getShowArrow(props.children.length, props.show, props.infinite, next)); + setShowArrow( + getShowArrow(props.children.length, props.show, props.infinite, next), + ); setTimeout(() => { if (props.infinite) { setItems(cleanItems(rotated, slide, direction)); diff --git a/src/components/slider/index.tsx b/src/components/scrolling-carousel/index.tsx similarity index 69% rename from src/components/slider/index.tsx rename to src/components/scrolling-carousel/index.tsx index d742cc4..3eb819f 100644 --- a/src/components/slider/index.tsx +++ b/src/components/scrolling-carousel/index.tsx @@ -7,8 +7,9 @@ import React, { } from 'react'; import { Item, SlideDirection } from '../../types/carousel'; import styles from '../../styles/slider/styles.module.css'; +import { getOuterWidth } from '../../helpers'; -export const Slider: FunctionComponent = ({ +export const ScrollingCarousel: FunctionComponent = ({ children, className, }: SliderProps) => { @@ -31,11 +32,16 @@ export const Slider: FunctionComponent = ({ }; const [showArrow, setShowArrow] = useState(showArrows()); + const onScroll = (_: Event) => { + setShowArrow(showArrows()); + }; + const ref = useCallback( (node) => { if (node !== null) { Object.defineProperty(slider, 'current', { value: node }); setShowArrow(showArrows()); + node.addEventListener('scroll', onScroll); } }, [slider], @@ -64,11 +70,36 @@ export const Slider: FunctionComponent = ({ slider.current!.scrollLeft = position.scrollLeft - slide; }; + const calculateSlideAmount = (direction: SlideDirection): number => { + const _slider = slider.current!; + const currentView = + direction === SlideDirection.Left + ? _slider.scrollLeft + _slider.offsetWidth + : _slider.scrollLeft; + + const childNodes = Array.from(_slider.children) as HTMLElement[]; + let nodeWidthSum = 0; + for (const node of childNodes) { + const nodeWidth = getOuterWidth(node); + nodeWidthSum += nodeWidth; + + if (nodeWidthSum >= currentView) { + const showingPart = + direction === SlideDirection.Left + ? nodeWidthSum - currentView + : nodeWidth; + + return (_slider.offsetWidth - showingPart) * direction; + } + } + + return _slider.offsetWidth; + }; + const slide = (direction: SlideDirection) => { - const slideAmount = -1 * direction * slider.current!.offsetWidth * 0.9; + const slideAmount = calculateSlideAmount(direction); const start = slider.current!.scrollLeft; smoothHorizontalScroll(500, slideAmount, start); - setShowArrow(showArrows()); }; const smoothHorizontalScroll = (time: number, amount: number, start: number) => { @@ -85,16 +116,19 @@ export const Slider: FunctionComponent = ({ const smoothHorizontalScrollBehavior = (amount: number) => { slider.current!.scrollLeft = amount; - setShowArrow(showArrows()); }; return (
{showArrow.left && ( - +
+
)} {showArrow.right && ( - +
+
)}