Files
landscape-template/src/Components/Slider/Slider.tsx
MTG2000 923e28282d fix: fixed carousels ux
- made categories badges a carousel
- added custom arrows to apps carousel on non-tocuh devices
- fixed invalid items offset on mobile sometimes
2022-02-03 18:54:38 +02:00

46 lines
1.6 KiB
TypeScript

import React, { useRef, useState, useEffect, useCallback, PropsWithChildren } from 'react';
import { useDrag } from '@use-gesture/react'
import { useSpring, animated } from '@react-spring/web'
import { useResizeListener } from 'src/utils/hooks';
interface Props {
gap?: number
}
export default function Slider({
gap = 12,
children
}: PropsWithChildren<Props>) {
const [{ x, y }, api] = useSpring(() => ({ x: 0, y: 0 }))
const containerRef = useRef<HTMLDivElement>(null!);
const sliderRef = useRef<HTMLDivElement>(null!);
const [sliderWidth, setSliderWidth] = useState(-1);
const bind = useDrag(({ down, offset: [ox, oy] }) => api.start({ x: ox, y: oy, immediate: down }), {
bounds: () => ({ left: -sliderWidth, right: 0, top: 0, bottom: 0 }),
rubberband: [.15, 0],
filterTaps: true
})
const resizeListener = useCallback(() => {
setSliderWidth(Math.max(sliderRef.current?.scrollWidth - containerRef.current?.clientWidth, 0));
}, [setSliderWidth]);
useResizeListener(resizeListener)
useEffect(() => {
setSliderWidth(Math.max(sliderRef.current?.scrollWidth - containerRef.current?.clientWidth, 0));
}, [setSliderWidth]);
return <>
<div className='w-full relative ' ref={containerRef} style={{ height: sliderRef.current?.scrollHeight + 'px' }}>
<animated.div {...bind()} style={{ x, y, touchAction: 'none', gap: `${gap}px` }} className={`absolute top-0 left-0 flex w-max select-none`} ref={sliderRef} >
{children}
</animated.div>
</div>
</>;
}