import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid' import useDrag from 'hooks/useDrag' import { useTranslation } from 'next-i18next' import React, { useContext, useEffect, useState } from 'react' import { ScrollMenu, VisibilityContext, getItemsPos, slidingWindow, } from 'react-horizontal-scrolling-menu' type scrollVisibilityApiType = React.ContextType function SwipeableTabs({ items, onChange, tabIndex, width, }: { items: any[] onChange: (x) => void tabIndex: number width?: string }) { const { dragStart, dragStop, dragMove, dragging } = useDrag() const handleDrag = ({ scrollContainer }: scrollVisibilityApiType) => (ev: React.MouseEvent) => dragMove(ev, (posDiff) => { if (scrollContainer.current) { scrollContainer.current.scrollLeft += posDiff } }) const handleItemClick = (itemId: string) => ({ getItemById, scrollToItem }: scrollVisibilityApiType) => { if (dragging) { return false } onChange(parseInt(itemId)) scrollToItem(getItemById(itemId), 'smooth', 'center', 'nearest') } return (
dragStart} onMouseUp={({ getItemById, scrollToItem, visibleItems, }: scrollVisibilityApiType) => () => { dragStop() const { center } = getItemsPos(visibleItems) scrollToItem(getItemById(center), 'smooth', 'center') }} options={{ throttle: 0 }} onMouseMove={handleDrag} onUpdate={({ getItemById, scrollToItem, visibleItems, }: scrollVisibilityApiType) => () => { dragStop() const { center } = getItemsPos(visibleItems) scrollToItem(getItemById(center), 'smooth', 'center') }} > {items.map((item, i) => ( ))}
) } export default SwipeableTabs function onWheel( { getItemById, items, visibleItems, scrollToItem }: scrollVisibilityApiType, ev: React.WheelEvent ): void { const isThouchpad = Math.abs(ev.deltaX) !== 0 || Math.abs(ev.deltaY) < 15 if (isThouchpad) { ev.stopPropagation() return } if (ev.deltaY < 0) { const nextGroupItems = slidingWindow( items.toItemsKeys(), visibleItems ).next() const { center } = getItemsPos(nextGroupItems) scrollToItem(getItemById(center), 'smooth', 'center') } else if (ev.deltaY > 0) { const prevGroupItems = slidingWindow( items.toItemsKeys(), visibleItems ).prev() const { center } = getItemsPos(prevGroupItems) scrollToItem(getItemById(center), 'smooth', 'center') } } function Tab({ selected, onClick, title, width, }: { itemId: string selected: boolean onClick: (x) => void title: string width?: string }) { const { t } = useTranslation('common') const visibility = React.useContext(VisibilityContext) useEffect(() => { if (selected) { onClick(visibility) } }, [selected]) return (
onClick(visibility)} role="button" tabIndex={0} className={`relative flex h-10 ${ width ? width : 'w-28' } items-center justify-center font-bold focus:text-th-primary focus:outline-none ${ selected ? 'border-b-2 border-th-primary text-th-primary' : 'border-b border-th-bkg-4 text-th-fgd-3' }`} > {t(title.toLowerCase().replace(/\s/g, '-'))}
) } function Arrow({ children, disabled, onClick, className, }: { children: React.ReactNode disabled: boolean onClick: VoidFunction className?: string }) { return ( ) } function LeftArrow() { const { isFirstItemVisible, scrollPrev, visibleItemsWithoutSeparators, initComplete, } = useContext(VisibilityContext) const [disabled, setDisabled] = useState( !initComplete || (initComplete && isFirstItemVisible) ) useEffect(() => { if (visibleItemsWithoutSeparators.length) { setDisabled(isFirstItemVisible) } }, [isFirstItemVisible, visibleItemsWithoutSeparators]) return ( scrollPrev()} className="-left-3 z-10 flex h-10 w-12 items-center justify-start bg-gradient-to-r from-th-bkg-1 to-transparent" > ) } function RightArrow() { const { isLastItemVisible, scrollNext, visibleItemsWithoutSeparators } = useContext(VisibilityContext) const [disabled, setDisabled] = useState( !visibleItemsWithoutSeparators.length && isLastItemVisible ) useEffect(() => { if (visibleItemsWithoutSeparators.length) { setDisabled(isLastItemVisible) } }, [isLastItemVisible, visibleItemsWithoutSeparators]) return ( scrollNext()} className="-right-3 z-10 flex h-10 w-12 items-center justify-end bg-gradient-to-l from-th-bkg-1 to-transparent" > ) }