import { clsx } from 'clsx' import { createEffect, createSignal, For, Show, on, onMount, lazy, onCleanup } from 'solid-js' import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' import { throttle } from 'throttle-debounce' import { MediaItem } from '../../../pages/types' import { getImageUrl } from '../../../utils/getImageUrl' import { Icon } from '../Icon' import { Image } from '../Image' import { SwiperRef } from './swiper' import styles from './Swiper.module.scss' type Props = { images: MediaItem[] onImagesAdd?: (value: MediaItem[]) => void onImagesSorted?: (value: MediaItem[]) => void onImageDelete?: (mediaItemIndex: number) => void onImageChange?: (index: number, value: MediaItem) => void } const MIN_WIDTH = 540 export const ImageSwiper = (props: Props) => { const [slideIndex, setSlideIndex] = createSignal(0) const [isMobileView, setIsMobileView] = createSignal(false) const mainSwipeRef: { current: SwiperRef } = { current: null } const thumbSwipeRef: { current: SwiperRef } = { current: null } const swiperMainContainer: { current: HTMLDivElement } = { current: null } const handleSlideChange = () => { thumbSwipeRef.current.swiper.slideTo(mainSwipeRef.current.swiper.activeIndex) setSlideIndex(mainSwipeRef.current.swiper.activeIndex) } createEffect( on( () => props.images.length, () => { mainSwipeRef.current?.swiper.update() thumbSwipeRef.current?.swiper.update() }, { defer: true }, ), ) onMount(async () => { const { register } = await import('swiper/element/bundle') register() SwiperCore.use([Pagination, Navigation, Manipulation]) }) onMount(() => { const updateDirection = () => { const width = window.innerWidth const direction = width > MIN_WIDTH ? 'vertical' : 'horizontal' if (direction === 'horizontal') { setIsMobileView(true) } else { setIsMobileView(false) } thumbSwipeRef.current?.swiper?.changeDirection(direction) } updateDirection() const handleResize = throttle(100, () => { updateDirection() }) window.addEventListener('resize', handleResize) onCleanup(() => { window.removeEventListener('resize', handleResize) }) }) return (
(swiperMainContainer.current = el)}> 0}>
(mainSwipeRef.current = el)} slides-per-view={1} thumbs-swiper={'.thumbSwiper'} observer={true} onSlideChange={handleSlideChange} space-between={isMobileView() ? 20 : 10} > {(slide, index) => ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore
{slide.title}
)}
mainSwipeRef.current.swiper.slidePrev()} >
mainSwipeRef.current.swiper.slideNext()} >
{slideIndex() + 1} / {props.images.length}
(thumbSwipeRef.current = el)} slides-per-view={'auto'} space-between={isMobileView() ? 20 : 10} auto-scroll-offset={1} watch-overflow={true} watch-slides-visibility={true} > {(slide, index) => ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore
)}
thumbSwipeRef.current.swiper.slidePrev()} >
thumbSwipeRef.current.swiper.slideNext()} >
{props.images[slideIndex()].title}
{props.images[slideIndex()].source}
) }