Merge remote-tracking branch 'gitlab/dev' into minor-fixes
This commit is contained in:
commit
20ecc28ad9
|
@ -89,11 +89,15 @@ export const FullArticle = (props: ArticleProps) => {
|
|||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="shout wide-container">
|
||||
<article class="col-md-6 shift-content">
|
||||
<div class={styles.shoutHeader}>
|
||||
<div class={styles.shoutTopic}>
|
||||
<a href={`/topic/${props.article.mainTopic}`} class={styles.mainTopicLink}>
|
||||
<a
|
||||
href={getPagePath(router, 'topic', { slug: props.article.mainTopic })}
|
||||
class={styles.mainTopicLink}
|
||||
>
|
||||
{mainTopic().title}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -113,24 +117,13 @@ export const FullArticle = (props: ArticleProps) => {
|
|||
)}
|
||||
</For>
|
||||
</div>
|
||||
<div class={styles.shoutCover} style={{ 'background-image': `url('${props.article.cover}')` }} />
|
||||
<div
|
||||
class={styles.shoutCover}
|
||||
style={{ 'background-image': `url('${props.article.cover}')` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Show
|
||||
when={media() && props.article.layout !== 'image'}
|
||||
fallback={
|
||||
<Slider>
|
||||
<For each={media() || []}>
|
||||
{(m: MediaItem) => (
|
||||
<>
|
||||
<img src={m.url || m.pic} alt={m.title} />
|
||||
<div innerHTML={m.body} />
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
}
|
||||
>
|
||||
<Show when={media() && props.article.layout !== 'image'}>
|
||||
<div class="media-items">
|
||||
<For each={media() || []}>
|
||||
{(m: MediaItem) => (
|
||||
|
@ -152,7 +145,25 @@ export const FullArticle = (props: ArticleProps) => {
|
|||
</div>
|
||||
</Show>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<Show when={media() && props.article.layout === 'image'}>
|
||||
<Slider slidesPerView={1} isPageGallery={true} isCardsWithCover={true} hasThumbs={true}>
|
||||
<For each={media() || []}>
|
||||
{(m: MediaItem) => (
|
||||
<div class="swiper-slide">
|
||||
<div class="swiper-slide__inner">
|
||||
<img src={m.url || m.pic} alt={m.title} loading="lazy" />
|
||||
<div class="swiper-lazy-preloader swiper-lazy-preloader-white" />
|
||||
<div class="image-description" innerHTML={m.title} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
</Show>
|
||||
|
||||
<div class="shout wide-container">
|
||||
<div class="col-md-8 shift-content">
|
||||
<div class={styles.shoutStats}>
|
||||
<div class={styles.shoutStatsItem}>
|
||||
|
@ -237,5 +248,6 @@ export const FullArticle = (props: ArticleProps) => {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
.swiper-slide {
|
||||
min-height: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
.cards-with-cover & {
|
||||
height: 0 !important;
|
||||
|
@ -13,6 +12,16 @@
|
|||
@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%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,3 +97,117 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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 / 0.2);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,40 +1,46 @@
|
|||
import { Swiper, Navigation, Pagination } from 'swiper'
|
||||
import { Swiper, Navigation, Pagination, Lazy, Thumbs } from 'swiper'
|
||||
import type { SwiperOptions } from 'swiper'
|
||||
import 'swiper/scss'
|
||||
import 'swiper/scss/navigation'
|
||||
import 'swiper/scss/pagination'
|
||||
import 'swiper/scss/lazy'
|
||||
import 'swiper/scss/thumbs'
|
||||
import './Slider.scss'
|
||||
import { createEffect, createSignal, JSX } from 'solid-js'
|
||||
import { createEffect, createSignal, JSX, Show } from 'solid-js'
|
||||
import { Icon } from './Icon'
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
interface SliderProps {
|
||||
title?: string
|
||||
slidesPerView?: number
|
||||
isCardsWithCover?: boolean
|
||||
children?: JSX.Element
|
||||
class?: string
|
||||
isPageGallery?: boolean
|
||||
hasThumbs?: boolean
|
||||
}
|
||||
|
||||
export default (props: SliderProps) => {
|
||||
let el: HTMLDivElement | undefined
|
||||
let thumbsEl: HTMLDivElement | undefined
|
||||
let pagEl: 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 = {
|
||||
lazy: true,
|
||||
roundLengths: true,
|
||||
loop: true,
|
||||
centeredSlides: true,
|
||||
slidesPerView: 1,
|
||||
modules: [Navigation, Pagination],
|
||||
modules: [Navigation, Pagination, Lazy, Thumbs],
|
||||
speed: 500,
|
||||
navigation: { nextEl, prevEl },
|
||||
pagination: {
|
||||
el: pagEl,
|
||||
type: 'bullets',
|
||||
clickable: true
|
||||
},
|
||||
breakpoints: {
|
||||
768: {
|
||||
slidesPerView: props.slidesPerView > 0 ? props.slidesPerView : 1.66666,
|
||||
|
@ -44,13 +50,48 @@ export default (props: SliderProps) => {
|
|||
slidesPerView: props.slidesPerView > 0 ? props.slidesPerView : 1.66666,
|
||||
spaceBetween: isCardsWithCover ? 8 : 52
|
||||
}
|
||||
},
|
||||
thumbs: {
|
||||
swiper: swiperThumbs()
|
||||
}
|
||||
}
|
||||
|
||||
const [swiper, setSwiper] = createSignal<Swiper>()
|
||||
createEffect(() => {
|
||||
if (props.hasThumbs && !!thumbsEl) {
|
||||
setTimeout(() => {
|
||||
setSwiperThumbs(
|
||||
new Swiper(thumbsEl, {
|
||||
slidesPerView: 'auto',
|
||||
modules: [Lazy, Thumbs],
|
||||
lazy: true,
|
||||
roundLengths: true,
|
||||
spaceBetween: 20,
|
||||
freeMode: true,
|
||||
breakpoints: {
|
||||
768: {
|
||||
direction: 'vertical'
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (!swiper() && !!el) {
|
||||
setTimeout(() => {
|
||||
if (swiperThumbs()) {
|
||||
opts.thumbs = {
|
||||
swiper: swiperThumbs()
|
||||
}
|
||||
|
||||
opts.pagination = {
|
||||
el: '.swiper-pagination',
|
||||
type: 'fraction'
|
||||
}
|
||||
}
|
||||
|
||||
setSwiper(new Swiper(el, opts))
|
||||
}, 500)
|
||||
}
|
||||
|
@ -61,7 +102,16 @@ export default (props: SliderProps) => {
|
|||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<h2 class="col-12">{props.title}</h2>
|
||||
<div class="swiper" classList={{ 'cards-with-cover': isCardsWithCover }} ref={el}>
|
||||
|
||||
<div class="sliders-container">
|
||||
<div
|
||||
class={clsx('swiper', props.class)}
|
||||
classList={{
|
||||
'cards-with-cover': isCardsWithCover,
|
||||
'swiper--page-gallery': props.isPageGallery
|
||||
}}
|
||||
ref={el}
|
||||
>
|
||||
<div class="swiper-wrapper">{props.children}</div>
|
||||
<div class="slider-arrow-next" ref={nextEl} onClick={() => swiper()?.slideNext()}>
|
||||
<Icon name="slider-arrow" class={'icon'} />
|
||||
|
@ -69,7 +119,16 @@ export default (props: SliderProps) => {
|
|||
<div class="slider-arrow-prev" ref={prevEl} onClick={() => swiper()?.slidePrev()}>
|
||||
<Icon name="slider-arrow" class={'icon'} />
|
||||
</div>
|
||||
<div class="slider-pagination" ref={pagEl} />
|
||||
<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>
|
||||
|
|
Loading…
Reference in New Issue
Block a user