UNPKG

test-iki-mini-app

Version:

ứng dựng bán hàng trên mini app z a l o

105 lines (91 loc) 3.04 kB
import { useSwipeable } from "react-swipeable"; import React, { useState, useEffect } from "react"; import "../../style/carousel.css"; import { useAppStore } from "../../store/appStore"; const NEXT = "next"; const PREV = "prev"; const getOrder = (index, pos, numItems) => { return index - pos < 0 ? numItems - Math.abs(index - pos) : index - pos; }; export const Carousel = ({ children }) => { const numItems = React.Children.count(children); const [sliding, setSliding] = useState(false); const [direction, setDirection] = useState(""); const [pos, setPos] = useState(0); const { appTheme } = useAppStore((state) => state); const { color_main_1 } = appTheme; const slideNext = () => { setSliding(true); setDirection(NEXT); setPos(pos === numItems - 1 ? 0 : pos + 1); setTimeout(stopSliding, 50); }; useEffect(() => { const interval = setInterval(slideNext, 3000); return () => clearInterval(interval); }, [pos]); const slidePrev = () => { setSliding(true); setDirection(PREV); setPos(pos === 0 ? numItems - 1 : pos - 1); setTimeout(stopSliding, 50); }; const stopSliding = () => setSliding(false); const slide = (direction) => { if (direction === NEXT) { slideNext(); } else { slidePrev(); } }; const handlePageClick = (pageIndex) => { setSliding(true); setDirection(pageIndex > pos ? NEXT : PREV); setPos(pageIndex); setTimeout(stopSliding, 50); }; const pages = Array.from({ length: numItems }, (_, index) => ({ index, active: index === pos, })); const handlers = useSwipeable({ onSwipedLeft: () => slide(NEXT), onSwipedRight: () => slide(PREV), swipeDuration: 1000, preventScrollOnSwipe: true, trackMouse: true, // onSwiped: (eventData) => console.log("User Swiped!", eventData), // onSwiping: () => console.log("swiping"), // onSwipedUp: () => console.log("up"), touchEventOptions: { passive: false }, }); return ( <div {...handlers} style={{ touchAction: "pan-y" }} className="relative"> <div className="wrapper w-full overflow-hidden pr-[16px]"> <div className={`carousel-container ${direction} ${sliding && "sliding"} flex gap-[16px]`} > {React.Children.map(children, (child, index) => ( <div className="carousel-slot" style={{ order: getOrder(index, pos, numItems) }} key={index} > {child} </div> ))} </div> </div> <div className="pagination flex justify-center w-fit absolute bottom-[10px] right-[50%] translate-x-[50%]"> {pages.map((page) => ( <span key={page.index} className={`w-[6px] h-[6px] rounded-full bg-[#fff] mx-[5px] cursor-pointer`} onClick={() => handlePageClick(page.index)} style={{backgroundColor: page.active ? color_main_1 : "#fff"}} /> ))} </div> </div> ); };