import React, { useState, useEffect } from "react"; import "./Carousel.css"; import { IconButton, Button } from "../../index"; import { IconLeftArrow } from "../../svg_icons/IconLeftArrow"; import { IconRightArrow } from "../../svg_icons/IconRightArrow"; import { getCN, isMasive, getClassName } from "../utils"; function Carousel({ children, pagination = false, autoPlay = true, counter = true, // Вклчюает счетчик counterVisible = 4000, //таймер пропадания счётчика, false - выключает пропадание size = 200, autoPlayTime = 5000, playClickTime = 10000, //false - Выключает автоматическое продолжение карусели switches = true, switchesVisible = 3000, //false - выключает пропадание ripple = false, type = `defailt`, ...props }: { [x: string]: any; switchesVisible?: false | number; counterVisible?: false | number; type?: "defailt" | "mushroom"; size?: number; }) { const [currentIndex, setCurrentIndex] = useState(0); const [length, setLength] = useState(children.length); const [touchPosition, setTouchPosition] = useState(null); const [visible_counter, setVisibleCounter] = useState(false); const [visible_switches, setVisibleSwitches] = useState(true); const [is_autoplay, setAutoPlay] = useState(true); const [is_click, setIs_click] = useState(false); const [is_hover, setIs_hover] = useState(false); useEffect(() => { setLength(children.length); if (!children[0]) { autoPlay = false; } return; }, [children]); useEffect(() => { if (currentIndex < 0) { setCurrentIndex(0); } else if (currentIndex >= length - 1) { setCurrentIndex(length - 1); } return; }, [currentIndex]); useEffect(() => { if (counterVisible) { if (!is_autoplay) { //counter setVisibleCounter(true); var timer = setTimeout(() => setVisibleCounter(false), counterVisible); return () => { clearTimeout(timer); }; } } return; }, [currentIndex, is_hover]); useEffect(() => { if (switchesVisible) { if (!is_autoplay) { //switches setVisibleSwitches(true); var timer = setTimeout( () => setVisibleSwitches(false), switchesVisible ); return () => { clearTimeout(timer); }; } } return; }, [currentIndex, is_hover]); const next = async (id = 1, auto = false) => { await setAutoPlay(auto); if (currentIndex < length - 1) await setCurrentIndex((prevState) => prevState + id); }; const prev = async (id = 1, auto = false) => { await setAutoPlay(auto); if (currentIndex > 0) await setCurrentIndex((prevState) => prevState - id); }; const onTouchStart = (e: any) => setTouchPosition(e.touches[0].clientX); const onTouchMove = (e: any) => { if (touchPosition === null) return; const currentPosition = e.touches[0].clientX; var direction = touchPosition - currentPosition; if (direction > 7) { if (currentIndex < length - 1) next(1); } if (direction < -7) { if (currentIndex > 0) prev(1); } setIs_click(true); setTouchPosition(null); }; useEffect(() => { if (!playClickTime) return; const onsetIs_click = () => { setIs_click(false); }; const interval = setInterval(() => { onsetIs_click(); }, playClickTime); return () => { clearInterval(interval); }; }, [is_click]); useEffect(() => { if (!playClickTime) return; var currentIndex_time = currentIndex; var children_length = length - 1; var playStatus = currentIndex_time < children_length ? true : false; if (children_length == undefined) { setCurrentIndex(0); autoPlay = false; return; } const reloadStatick = () => { if (currentIndex_time > children_length) { currentIndex_time = currentIndex_time - children_length; if (currentIndex_time < 0) currentIndex_time = 0; playStatus = true; return setCurrentIndex(currentIndex_time); } }; reloadStatick(); if (is_click) return; if (!autoPlay) return; const interval = setInterval(async () => { reloadStatick(); if (playStatus) { currentIndex_time++; if (currentIndex_time >= children_length) playStatus = false; next(1, true); } else { currentIndex_time--; if (currentIndex_time <= 0) playStatus = true; prev(1, true); } }, autoPlayTime); return () => { clearInterval(interval); }; }, [length, is_click]); const transformInfo = () => { if (type === "mushroom") { if (currentIndex == 0) return `translateX(calc(-${currentIndex * 100 }% + var(--padding_content) * 7))`; if (currentIndex + 1 == length) return `translateX(calc(-${currentIndex * 100 }% + (var(--padding_content) * 19.5 + var(--padding_content)) * ${currentIndex} )`; return `translateX(calc(-${currentIndex * 100 }% + var(--padding_content) * 25))`; } if (currentIndex == 0) return `translateX(0px)`; if (currentIndex + 1 == length) return `translateX(calc(-${currentIndex * 100 }% + (var(--padding_content) * 2 + var(--padding_content)) * ${currentIndex} )`; return `translateX(calc(-${currentIndex * 100 }% + var(--padding_content) * 2.5))`; }; return (
{ setAutoPlay(false); setIs_hover(true); }} onMouseLeave={() => { setAutoPlay(false); setIs_hover(false); }} data-type={type} data-pagination={pagination} className={getCN(["MYUI-Carousel"], props.className)} >
{counter && (
{currentIndex + 1}/{length}
)}
{isMasive(children) ? children.map((a: any, index: any) => (
{a}
)) : children}
{switches && (
{ setIs_click(true); await prev(); }} className="MYUI-Carousel__in--before" > 0} aria-label="before arrow" ripple={ripple} onClick={async () => { setIs_click(true); await prev(); }} className="MYUI-Carousel__in--before__in" >
{ setIs_click(true); await next(); }} className="MYUI-Carousel__in--after" > { setIs_click(true); await next(); }} className="MYUI-Carousel__in--after__in" >
)}
{pagination && (
{isMasive(children) && children.map((a: any, index: number) => ( <> {index == 0 && ( )} {index != 0 && ( )} ))}
)}
); } function getTransformActive(currentIndex: any, length: any) { if (currentIndex == 0) return `translateX(calc(0px))`; return `translateX(calc((var(--padding_default) + var(--paggination-size)) * ${currentIndex}))`; } function getTransform(currentIndex: any, length: any, index: any) { if (currentIndex == 0) return `translateX(calc(0px))`; var send: any; for (var i = 1; i < length - 1; i++) { if (currentIndex + i == index) send = `translateX(calc(0px))`; } if (send) return send; return `translateX(calc( (var(--padding_default) - var(--padding_default) * 2) - var(--paggination-size)))`; } export default Carousel;