webapp/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx

109 lines
3.8 KiB
TypeScript
Raw Normal View History

import { clsx } from 'clsx'
2024-02-04 11:25:21 +00:00
import { For, Show, onMount } from 'solid-js'
import SwiperCore from 'swiper'
import { Manipulation, Navigation, Pagination } from 'swiper/modules'
import { Shout } from '~/graphql/schema/core.gen'
import { ArticleCard } from '../../Feed/ArticleCard'
import { Icon } from '../Icon'
import { ShowOnlyOnClient } from '../ShowOnlyOnClient'
2023-11-13 15:46:23 +00:00
import { SwiperRef } from './swiper'
2024-05-06 23:32:49 +00:00
import { Row1 } from '../../Feed/Row1'
import { Row2 } from '../../Feed/Row2'
import styles from './Swiper.module.scss'
type Props = {
slides: Shout[]
title?: string
}
export const ArticleCardSwiper = (props: Props) => {
2024-06-24 17:50:27 +00:00
let mainSwipeRef: SwiperRef | null
2023-11-13 15:46:23 +00:00
onMount(async () => {
2024-06-28 07:47:38 +00:00
if (props.slides?.length > 1) {
console.debug(props.slides)
2024-05-06 22:15:57 +00:00
const { register } = await import('swiper/element/bundle')
register()
SwiperCore.use([Pagination, Navigation, Manipulation])
}
2023-11-13 15:35:07 +00:00
})
return (
<ShowOnlyOnClient>
2024-05-06 21:51:07 +00:00
<div
class={clsx({
2024-06-28 07:47:38 +00:00
[styles.Swiper]: props.slides?.length > 1,
2024-05-06 21:51:07 +00:00
[styles.articleMode]: true,
2024-06-28 07:47:38 +00:00
[styles.ArticleCardSwiper]: props.slides?.length > 1
2024-05-06 21:51:07 +00:00
})}
>
<Show when={props.title}>
<h2 class={styles.sliderTitle}>{props.title}</h2>
</Show>
<div class={styles.container}>
2024-06-28 07:47:38 +00:00
<Show when={props.slides?.length > 0}>
2024-05-06 23:32:49 +00:00
<Show when={props.slides.length !== 1} fallback={<Row1 article={props.slides[0]} />}>
<Show when={props.slides.length !== 2} fallback={<Row2 articles={props.slides} />}>
<div class={styles.holder}>
<swiper-container
2024-06-24 17:50:27 +00:00
ref={(el) => (mainSwipeRef = el)}
2024-05-06 23:32:49 +00:00
centered-slides={true}
observer={true}
space-between={10}
breakpoints={{
576: { spaceBetween: 20, slidesPerView: 1.5 },
2024-06-26 08:22:05 +00:00
992: { spaceBetween: 52, slidesPerView: 1.5 }
2024-05-06 23:32:49 +00:00
}}
round-lengths={true}
loop={true}
speed={800}
autoplay={{
disableOnInteraction: false,
delay: 6000,
2024-06-26 08:22:05 +00:00
pauseOnMouseEnter: true
2024-05-06 23:32:49 +00:00
}}
>
<For each={props.slides}>
{(slide, index) => (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
<swiper-slide virtual-index={index()}>
<ArticleCard
article={slide}
settings={{
additionalClass: 'swiper-slide',
isFloorImportant: true,
isWithCover: true,
2024-06-26 08:22:05 +00:00
nodate: true
2024-05-06 23:32:49 +00:00
}}
desktopCoverSize="L"
/>
</swiper-slide>
)}
</For>
</swiper-container>
<div
class={clsx(styles.navigation, styles.prev)}
2024-06-24 17:50:27 +00:00
onClick={() => mainSwipeRef?.swiper.slidePrev()}
2024-05-06 23:32:49 +00:00
>
<Icon name="swiper-l-arr" class={styles.icon} />
</div>
<div
class={clsx(styles.navigation, styles.next)}
2024-06-24 17:50:27 +00:00
onClick={() => mainSwipeRef?.swiper.slideNext()}
2024-05-06 23:32:49 +00:00
>
<Icon name="swiper-r-arr" class={styles.icon} />
</div>
</div>
</Show>
</Show>
</Show>
</div>
</div>
</ShowOnlyOnClient>
)
}