/**
* EventsCarousel Component
* Карусель событий с использованием Swiper
* Отображает список исторических событий в виде слайдера
*/
import classNames from 'classnames'
import { gsap } from 'gsap'
import { memo, useEffect, useRef, useState } from 'react'
import { Swiper, SwiperSlide } from 'swiper/react'
import 'swiper/css'
import 'swiper/css/navigation'
import 'swiper/css/pagination'
import ChevronSvg from '@/shared/assets/chevron--left.svg'
import { Button } from '@/shared/ui/Button'
import { Card } from '@/shared/ui/Card'
import {
EVENT_CAROUSEL_CONFIG,
HIDE_DURATION,
SHOW_DELAY,
SHOW_DURATION,
SHOW_Y_OFFSET,
} from './constants'
import styles from './EventsCarousel.module.scss'
import type { HistoricalEvent } from '@/entities/TimePeriod'
import type { Swiper as SwiperType } from 'swiper'
export interface EventsCarouselProps {
/**
* Массив исторических событий для отображения
*/
readonly events: readonly HistoricalEvent[]
/**
* Флаг видимости карусели (управляет анимацией появления/исчезновения)
*/
readonly visible: boolean
}
/**
* Компонент карусели исторических событий
*
* Использует Swiper для создания слайдера с кастомной навигацией.
* Поддерживает адаптивное количество слайдов на разных размерах экрана.
* Анимирует появление/исчезновение с помощью GSAP.
*
* @example
* ```tsx
*
* ```
*/
export const EventsCarousel = memo(
({ events, visible }: EventsCarouselProps) => {
const containerRef = useRef(null)
const [isBeginning, setIsBeginning] = useState(true)
const [isEnd, setIsEnd] = useState(false)
/**
* Эффект для анимации появления/исчезновения карусели
* Использует GSAP для плавной анимации opacity и y-позиции
*/
useEffect(() => {
if (!containerRef.current) return
const ctx = gsap.context(() => {
if (visible) {
gsap.fromTo(
containerRef.current,
{ opacity: 0, y: SHOW_Y_OFFSET },
{
opacity: 1,
y: 0,
duration: SHOW_DURATION,
delay: SHOW_DELAY,
}
)
} else {
gsap.to(containerRef.current, {
opacity: 0,
duration: HIDE_DURATION,
})
}
}, containerRef)
return () => ctx.revert()
}, [visible, events])
/**
* Обработчик инициализации Swiper
* Устанавливает начальное состояние кнопок навигации
*/
const handleSwiperInit = (swiper: SwiperType) => {
setIsBeginning(swiper.isBeginning)
setIsEnd(swiper.isEnd)
}
/**
* Обработчик изменения состояния Swiper
* Обновляет состояние кнопок навигации
*/
const handleSlideChange = (swiper: SwiperType) => {
setIsBeginning(swiper.isBeginning)
setIsEnd(swiper.isEnd)
}
return (
{events.map((event) => (
))}
)
}
)
EventsCarousel.displayName = 'EventsCarousel'