parent
f1e68f219c
commit
891b9ec5f7
|
@ -20,7 +20,7 @@ import { AudioHeader } from './AudioHeader'
|
|||
import { Popover } from '../_shared/Popover'
|
||||
import { VideoPlayer } from '../_shared/VideoPlayer'
|
||||
import { Icon } from '../_shared/Icon'
|
||||
import { SolidSwiper } from '../_shared/SolidSwiper'
|
||||
import { ImageSwiper } from '../_shared/SolidSwiper'
|
||||
import styles from './Article.module.scss'
|
||||
import { CardTopic } from '../Feed/CardTopic'
|
||||
import { createPopper } from '@popperjs/core'
|
||||
|
@ -331,7 +331,7 @@ export const FullArticle = (props: Props) => {
|
|||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<div class="col-md-20 offset-md-2">
|
||||
<SolidSwiper images={media()} />
|
||||
<ImageSwiper images={media()} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,7 +12,7 @@ import { GrowingTextarea } from '../_shared/GrowingTextarea'
|
|||
import { VideoUploader } from '../Editor/VideoUploader'
|
||||
import { AudioUploader } from '../Editor/AudioUploader'
|
||||
import { slugify } from '../../utils/slugify'
|
||||
import { SolidSwiper } from '../_shared/SolidSwiper'
|
||||
import { ImageSwiper } from '../_shared/SolidSwiper'
|
||||
import { DropArea } from '../_shared/DropArea'
|
||||
import { LayoutType, MediaItem } from '../../pages/types'
|
||||
import { clone } from '../../utils/clone'
|
||||
|
@ -384,7 +384,7 @@ export const EditView = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<Show when={props.shout.layout === 'image'}>
|
||||
<SolidSwiper
|
||||
<ImageSwiper
|
||||
editorMode={true}
|
||||
images={mediaItems()}
|
||||
onImageChange={handleMediaChange}
|
||||
|
|
|
@ -8,10 +8,8 @@ import { Row1 } from '../Feed/Row1'
|
|||
import Hero from '../Discours/Hero'
|
||||
import { Beside } from '../Feed/Beside'
|
||||
import RowShort from '../Feed/RowShort'
|
||||
import { Slider } from '../_shared/Slider'
|
||||
import Group from '../Feed/Group'
|
||||
import type { Shout } from '../../graphql/types.gen'
|
||||
|
||||
import { useTopicsStore } from '../../stores/zine/topics'
|
||||
import {
|
||||
loadShouts,
|
||||
|
@ -22,8 +20,8 @@ import {
|
|||
import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
|
||||
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
||||
import { splitToPages } from '../../utils/splitToPages'
|
||||
import { ArticleCard } from '../Feed/ArticleCard'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper'
|
||||
|
||||
type Props = {
|
||||
shouts: Shout[]
|
||||
|
@ -130,21 +128,7 @@ export const HomeView = (props: Props) => {
|
|||
/>
|
||||
|
||||
<Show when={topMonthArticles()}>
|
||||
<Slider title={t('Top month articles')}>
|
||||
<For each={topMonthArticles()}>
|
||||
{(a) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: true,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
<ArticleCardSwiper title={t('Top month articles')} slides={topMonthArticles()} />
|
||||
</Show>
|
||||
|
||||
<Row2 articles={sortedArticles().slice(10, 12)} nodate={true} />
|
||||
|
@ -162,21 +146,7 @@ export const HomeView = (props: Props) => {
|
|||
{randomLayout()}
|
||||
|
||||
<Show when={topArticles()}>
|
||||
<Slider title={t('Favorite')}>
|
||||
<For each={topArticles()}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: true,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
<ArticleCardSwiper title={t('Favorite')} slides={topArticles()} />
|
||||
</Show>
|
||||
|
||||
<Beside
|
||||
|
|
0
src/components/Views/Topic.module.scss
Normal file
0
src/components/Views/Topic.module.scss
Normal file
|
@ -13,10 +13,10 @@ import { useAuthorsStore } from '../../stores/zine/authors'
|
|||
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
||||
import { splitToPages } from '../../utils/splitToPages'
|
||||
import { clsx } from 'clsx'
|
||||
import { Slider } from '../_shared/Slider'
|
||||
import { Row1 } from '../Feed/Row1'
|
||||
import { ArticleCard } from '../Feed/ArticleCard'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper'
|
||||
|
||||
type TopicsPageSearchParams = {
|
||||
by: 'comments' | '' | 'recent' | 'viewed' | 'rating' | 'commented'
|
||||
|
@ -136,21 +136,7 @@ export const TopicView = (props: TopicProps) => {
|
|||
wrapper={'author'}
|
||||
/>
|
||||
|
||||
<Slider title={title()}>
|
||||
<For each={sortedArticles().slice(5, 11)}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: true,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
<ArticleCardSwiper title={title()} slides={sortedArticles().slice(5, 11)} />
|
||||
|
||||
<Beside
|
||||
beside={sortedArticles()[12]}
|
||||
|
@ -163,22 +149,7 @@ export const TopicView = (props: TopicProps) => {
|
|||
<Row1 article={sortedArticles()[15]} />
|
||||
|
||||
<Show when={sortedArticles().length > 15}>
|
||||
<Slider slidesPerView={3}>
|
||||
<For each={sortedArticles().slice(16, 22)}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: false,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
|
||||
<ArticleCardSwiper slides={sortedArticles().slice(16, 22)} />
|
||||
<Row3 articles={sortedArticles().slice(23, 26)} />
|
||||
<Row2 articles={sortedArticles().slice(26, 28)} />
|
||||
</Show>
|
||||
|
|
|
@ -1,253 +0,0 @@
|
|||
.swiper-slide {
|
||||
min-height: 0 !important;
|
||||
|
||||
.cards-with-cover & {
|
||||
height: 0 !important;
|
||||
padding-top: 100%;
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
padding-top: 56.2% !important;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
padding-top: 35% !important;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slider-arrow-prev,
|
||||
.slider-arrow-next {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
outline: none;
|
||||
border: 0;
|
||||
transform: translate(0);
|
||||
top: 0;
|
||||
width: 21%;
|
||||
z-index: 1;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
width: 8%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.icon {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
height: 36px;
|
||||
opacity: 1;
|
||||
transition: opacity 0.2s;
|
||||
width: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.slider-arrow-prev {
|
||||
background: linear-gradient(to left, rgb(0 0 0 / 0%) 0%, rgb(0 0 0 / 90%) 100%);
|
||||
justify-content: flex-start;
|
||||
left: 0;
|
||||
|
||||
&::after {
|
||||
margin-left: 5rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-left: 5rem;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
margin-left: 25%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slider-arrow-next {
|
||||
background: linear-gradient(to left, rgb(0 0 0 / 90%) 0%, rgb(0 0 0 / 0%) 100%);
|
||||
justify-content: flex-end;
|
||||
right: 0;
|
||||
|
||||
&::after {
|
||||
margin-right: 5rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-right: 5rem;
|
||||
transform: rotate(180deg);
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
margin-right: 25%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.swiper--page-gallery {
|
||||
padding-bottom: 4rem;
|
||||
|
||||
.swiper-wrapper {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.swiper-slide__inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
max-height: 80vh;
|
||||
width: auto;
|
||||
position: relative;
|
||||
z-index: 11;
|
||||
}
|
||||
}
|
||||
|
||||
.slider-arrow-prev,
|
||||
.slider-arrow-next {
|
||||
background: rgb(0 0 0 / 20%);
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
.slider-arrow-next .icon {
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
.slider-arrow-prev .icon {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
.swiper-slide-active {
|
||||
.swiper-lazy-preloader {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.thumbs-container {
|
||||
@include media-breakpoint-up(md) {
|
||||
padding-left: 3.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper--thumbs {
|
||||
@include media-breakpoint-up(md) {
|
||||
max-height: 80vh;
|
||||
min-width: 100px;
|
||||
padding: 0 !important;
|
||||
width: 100px !important;
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
cursor: pointer;
|
||||
height: 80px;
|
||||
opacity: 0.5;
|
||||
width: 100px;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
height: 52px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper-slide-thumb-active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.swiper-slide__inner {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.swiper-lazy-preloader,
|
||||
.image-description {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sliders-container {
|
||||
@include media-breakpoint-up(md) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper-pagination {
|
||||
background: #141414;
|
||||
bottom: 0;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
left: auto;
|
||||
right: 0;
|
||||
padding: 1rem;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.uploadPreview {
|
||||
background: unset;
|
||||
position: relative;
|
||||
padding: 0 40px;
|
||||
|
||||
.sliders-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
background: unset;
|
||||
|
||||
.swiper-wrapper {
|
||||
min-height: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
.slider-arrow-next,
|
||||
.slider-arrow-prev {
|
||||
background: none;
|
||||
filter: invert(1);
|
||||
width: 40px;
|
||||
max-height: 540px;
|
||||
|
||||
.icon {
|
||||
margin: auto;
|
||||
width: 12px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//.slider-arrow-prev {
|
||||
// margin-left: -40px;
|
||||
//}
|
||||
//.slider-arrow-next {
|
||||
// margin-right: -40px;
|
||||
//}
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
//TODO: Replace with SolidSwiper.tsx
|
||||
|
||||
import { Swiper, Navigation, Pagination, Thumbs } from 'swiper'
|
||||
import type { SwiperOptions } from 'swiper'
|
||||
import 'swiper/scss'
|
||||
import 'swiper/scss/navigation'
|
||||
import 'swiper/scss/pagination'
|
||||
import 'swiper/scss/thumbs'
|
||||
import './Slider.scss'
|
||||
import { createEffect, createSignal, JSX, on, Show } from 'solid-js'
|
||||
import { Icon } from '../Icon'
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
interface Props {
|
||||
title?: string
|
||||
slidesPerView?: number
|
||||
isCardsWithCover?: boolean
|
||||
children?: JSX.Element
|
||||
isPageGallery?: boolean
|
||||
hasThumbs?: boolean
|
||||
variant?: 'uploadPreview'
|
||||
slideIndex?: (value: number) => void
|
||||
}
|
||||
|
||||
export const Slider = (props: Props) => {
|
||||
let el: HTMLDivElement | undefined
|
||||
let thumbsEl: HTMLDivElement | undefined
|
||||
let nextEl: HTMLDivElement | undefined
|
||||
let prevEl: HTMLDivElement | undefined
|
||||
|
||||
const isCardsWithCover = typeof props.isCardsWithCover === 'boolean' ? props.isCardsWithCover : true
|
||||
|
||||
const [swiper, setSwiper] = createSignal<Swiper>()
|
||||
const [swiperThumbs, setSwiperThumbs] = createSignal<Swiper>()
|
||||
const opts: SwiperOptions = {
|
||||
observer: true,
|
||||
observeParents: true,
|
||||
roundLengths: true,
|
||||
loop: true,
|
||||
centeredSlides: true,
|
||||
slidesPerView: 1,
|
||||
modules: [Navigation, Pagination, Thumbs],
|
||||
speed: 500,
|
||||
on: {
|
||||
slideChange: () => {
|
||||
if (swiper()) {
|
||||
props.slideIndex(swiper().realIndex || 0)
|
||||
}
|
||||
}
|
||||
},
|
||||
navigation: { nextEl, prevEl },
|
||||
breakpoints: {
|
||||
768: {
|
||||
slidesPerView: props.slidesPerView > 0 ? props.slidesPerView : 1.66666,
|
||||
spaceBetween: isCardsWithCover ? 8 : 26
|
||||
},
|
||||
992: {
|
||||
slidesPerView: props.slidesPerView > 0 ? props.slidesPerView : 1.66666,
|
||||
spaceBetween: isCardsWithCover ? 8 : 52
|
||||
}
|
||||
},
|
||||
thumbs: {
|
||||
swiper: swiperThumbs()
|
||||
}
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
if (props.hasThumbs && !!thumbsEl) {
|
||||
setSwiperThumbs(
|
||||
new Swiper(thumbsEl, {
|
||||
slidesPerView: 'auto',
|
||||
modules: [Thumbs],
|
||||
roundLengths: true,
|
||||
spaceBetween: 20,
|
||||
freeMode: true,
|
||||
breakpoints: {
|
||||
768: {
|
||||
direction: 'vertical'
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (!swiper() && !!el) {
|
||||
if (swiperThumbs()) {
|
||||
opts.thumbs = {
|
||||
swiper: swiperThumbs()
|
||||
}
|
||||
|
||||
opts.pagination = {
|
||||
el: '.swiper-pagination',
|
||||
type: 'fraction'
|
||||
}
|
||||
}
|
||||
|
||||
setSwiper(new Swiper(el, opts))
|
||||
swiper().update()
|
||||
}
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
swiper().update()
|
||||
})
|
||||
|
||||
return (
|
||||
<div class={clsx('floor', 'floor--important', props.variant)}>
|
||||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<Show when={props.title}>
|
||||
<h2 class="col-24">{props.title}</h2>
|
||||
</Show>
|
||||
|
||||
<div class="sliders-container">
|
||||
<div
|
||||
class={clsx('swiper')}
|
||||
classList={{
|
||||
'cards-with-cover': isCardsWithCover,
|
||||
'swiper--page-gallery': props.isPageGallery
|
||||
}}
|
||||
ref={el}
|
||||
>
|
||||
<div class="swiper-wrapper">{props.children}</div>
|
||||
<Show when={!(props.variant === 'uploadPreview')}>
|
||||
<div class="slider-arrow-next" ref={nextEl} onClick={() => swiper()?.slideNext()}>
|
||||
<Icon name="slider-arrow" class={'icon'} />
|
||||
</div>
|
||||
<div class="slider-arrow-prev" ref={prevEl} onClick={() => swiper()?.slidePrev()}>
|
||||
<Icon name="slider-arrow" class={'icon'} />
|
||||
</div>
|
||||
</Show>
|
||||
{/*<div class="swiper-pagination" ref={pagEl} />*/}
|
||||
</div>
|
||||
|
||||
<Show when={props.hasThumbs}>
|
||||
<div class="thumbs-container">
|
||||
<div class="swiper swiper--thumbs" ref={thumbsEl}>
|
||||
<div class="swiper-wrapper">{props.children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Show when={props.variant === 'uploadPreview'}>
|
||||
<div class="slider-arrow-next" ref={nextEl} onClick={() => swiper()?.slideNext()}>
|
||||
<Icon name="slider-arrow" class={'icon'} />
|
||||
</div>
|
||||
<div class="slider-arrow-prev" ref={prevEl} onClick={() => swiper()?.slidePrev()}>
|
||||
<Icon name="slider-arrow" class={'icon'} />
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export { Slider } from './Slider'
|
97
src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx
Normal file
97
src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx
Normal file
|
@ -0,0 +1,97 @@
|
|||
import { createSignal, For, Show } from 'solid-js'
|
||||
import { Icon } from '../Icon'
|
||||
import { register } from 'swiper/element/bundle'
|
||||
import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper'
|
||||
import { SwiperRef } from './swiper'
|
||||
import { clsx } from 'clsx'
|
||||
import styles from './Swiper.module.scss'
|
||||
import { Shout } from '../../../graphql/types.gen'
|
||||
import { ArticleCard } from '../../Feed/ArticleCard'
|
||||
|
||||
type Props = {
|
||||
slides: Shout[]
|
||||
slidesPerView?: number
|
||||
title?: string
|
||||
}
|
||||
|
||||
register()
|
||||
|
||||
SwiperCore.use([Pagination, Navigation, Manipulation])
|
||||
|
||||
export const ArticleCardSwiper = (props: Props) => {
|
||||
const [slideIndex, setSlideIndex] = createSignal(0)
|
||||
|
||||
const mainSwipeRef: { current: SwiperRef } = { current: null }
|
||||
|
||||
const handleSlideChange = () => {
|
||||
setSlideIndex(mainSwipeRef.current.swiper.activeIndex)
|
||||
}
|
||||
|
||||
return (
|
||||
<div class={clsx(styles.Swiper, styles.articleMode, styles.ArticleCardSwiper)}>
|
||||
<Show when={props.title}>
|
||||
<h2 class={styles.sliderTitle}>{props.title}</h2>
|
||||
</Show>
|
||||
<div class={styles.container}>
|
||||
<Show when={props.slides.length > 0}>
|
||||
<div class={styles.holder}>
|
||||
<swiper-container
|
||||
ref={(el) => (mainSwipeRef.current = el)}
|
||||
centered-slides={true}
|
||||
thumbs-swiper={'.thumbSwiper'}
|
||||
observer={true}
|
||||
onSlideChange={handleSlideChange}
|
||||
slides-per-view={props.slidesPerView ?? 1.5}
|
||||
space-between={52}
|
||||
breakpoints={{ 768: { spaceBetween: 26 }, 992: { spaceBetween: 52 } }}
|
||||
loop={true}
|
||||
speed={800}
|
||||
autoplay={{
|
||||
disableOnInteraction: false,
|
||||
delay: 3000,
|
||||
pauseOnMouseEnter: true
|
||||
}}
|
||||
>
|
||||
<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,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
</swiper-slide>
|
||||
)}
|
||||
</For>
|
||||
</swiper-container>
|
||||
<div
|
||||
class={clsx(styles.navigation, styles.prev, {
|
||||
[styles.disabled]: slideIndex() === 0
|
||||
})}
|
||||
onClick={() => mainSwipeRef.current.swiper.slidePrev()}
|
||||
>
|
||||
<Icon name="swiper-l-arr" class={styles.icon} />
|
||||
</div>
|
||||
<div
|
||||
class={clsx(styles.navigation, styles.next, {
|
||||
[styles.disabled]: slideIndex() + 1 === props.slides.length
|
||||
})}
|
||||
onClick={() => mainSwipeRef.current.swiper.slideNext()}
|
||||
>
|
||||
<Icon name="swiper-r-arr" class={styles.icon} />
|
||||
</div>
|
||||
<div class={styles.counter}>
|
||||
{slideIndex() + 1} / {props.slides.length}
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { createEffect, createSignal, For, Show, on } from 'solid-js'
|
||||
import { createEffect, createSignal, For, Show, on, JSXElement } from 'solid-js'
|
||||
import { MediaItem, UploadedFile } from '../../../pages/types'
|
||||
import { Icon } from '../Icon'
|
||||
import { Popover } from '../Popover'
|
||||
|
@ -32,7 +32,7 @@ register()
|
|||
|
||||
SwiperCore.use([Pagination, Navigation, Manipulation])
|
||||
|
||||
export const SolidSwiper = (props: Props) => {
|
||||
export const ImageSwiper = (props: Props) => {
|
||||
const { t } = useLocalize()
|
||||
const [loading, setLoading] = createSignal(false)
|
||||
const [slideIndex, setSlideIndex] = createSignal(0)
|
||||
|
@ -68,7 +68,6 @@ export const SolidSwiper = (props: Props) => {
|
|||
{ defer: true }
|
||||
)
|
||||
)
|
||||
|
||||
const handleDropAreaUpload = (value: UploadedFile[]) => {
|
||||
props.onImagesAdd(composeMediaItems(value))
|
||||
swipeToUploaded()
|
|
@ -13,6 +13,17 @@ $navigation-reserve: 32px;
|
|||
margin: 2rem 0;
|
||||
flex-direction: column;
|
||||
|
||||
&.ArticleCardSwiper {
|
||||
margin-bottom: 6rem;
|
||||
}
|
||||
|
||||
.sliderTitle {
|
||||
@include font-size(4.5rem);
|
||||
|
||||
text-align: center;
|
||||
padding: 4rem 0 0;
|
||||
}
|
||||
|
||||
&.articleMode {
|
||||
background: var(--background-color-invert);
|
||||
color: var(--default-color-invert);
|
||||
|
@ -114,6 +125,10 @@ $navigation-reserve: 32px;
|
|||
overflow: hidden;
|
||||
width: calc(100% - 130px);
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.counter {
|
||||
@include font-size(1.2rem);
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
export { SolidSwiper } from './SolidSwiper'
|
||||
export { ImageSwiper } from './ImageSwiper'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'solid-js'
|
||||
import { SwiperOptions } from 'swiper'
|
||||
import { SwiperOptions, AutoplayOptions } from 'swiper'
|
||||
import { SwiperSlideProps } from 'swiper/react'
|
||||
|
||||
type Kebab<T extends string, A extends string = ''> = T extends `${infer F}${infer R}`
|
||||
|
@ -37,6 +37,11 @@ declare module 'solid-js' {
|
|||
onSlideChange?: () => void
|
||||
onBeforeSlideChangeStart?: () => void
|
||||
class?: string
|
||||
breakpoints?: {
|
||||
[width: number]: SwiperOptions
|
||||
[ratio: string]: SwiperOptions
|
||||
}
|
||||
autoplay?: AutoplayOptions | boolean
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
interface SwiperSlideAttributes extends KebabObjectKeys<SwiperSlideProps> {
|
||||
|
|
Loading…
Reference in New Issue
Block a user