import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid' import clsx from 'clsx' import { throttle } from 'lodash' import { ReactNode, useRef, useState, useEffect } from 'react' import { Row } from './layout/row' import { VisibilityObserver } from 'web/components/visibility-observer' export function Carousel(props: { children: ReactNode loadMore?: () => void className?: string }) { const { children, loadMore, className } = props const ref = useRef(null) const th = (f: () => any) => throttle(f, 500, { trailing: false }) const scrollLeft = th(() => ref.current?.scrollBy({ left: -ref.current.clientWidth }) ) const scrollRight = th(() => ref.current?.scrollBy({ left: ref.current.clientWidth }) ) const [atFront, setAtFront] = useState(true) const [atBack, setAtBack] = useState(false) const onScroll = throttle(() => { if (ref.current) { const { scrollLeft, clientWidth, scrollWidth } = ref.current setAtFront(scrollLeft < 80) setAtBack(scrollWidth - (clientWidth + scrollLeft) < 80) } }, 500) // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(onScroll, [children]) return (
{children} {loadMore && ( visible && loadMore()} /> )} {!atFront && (
)} {!atBack && (
)}
) }