[wip] Rework Shop
- Change strategy for content fetching - Add a route per page instead of using __layout for all - Change the behaviors of the posters section (add a carousel on small screens) - Change Poster buttons styling and make interactions only for desktop
This commit is contained in:
115
src/components/organisms/PostersGrid.svelte
Normal file
115
src/components/organisms/PostersGrid.svelte
Normal file
@@ -0,0 +1,115 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import EmblaCarousel, { EmblaCarouselType } from 'embla-carousel'
|
||||
// Components
|
||||
import Poster from '$components/molecules/Poster.svelte'
|
||||
import EmailForm from '$components/molecules/EmailForm.svelte'
|
||||
import { debounce } from '$utils/functions'
|
||||
|
||||
export let posters: any = []
|
||||
|
||||
let innerWidth: number
|
||||
let carouselEl: HTMLElement
|
||||
let carousel: EmblaCarouselType
|
||||
let currentSlide = 0
|
||||
let carouselDots = []
|
||||
|
||||
const { shopProducts } = getContext('shop')
|
||||
|
||||
|
||||
/** Navigate to specific slide */
|
||||
const goToSlide = (index: number = 0) => {
|
||||
carousel.scrollTo(index)
|
||||
}
|
||||
|
||||
/** Init Carousel */
|
||||
const initCarousel = () => {
|
||||
if (innerWidth < 992) {
|
||||
if (!carousel) {
|
||||
carousel = EmblaCarousel(carouselEl, {
|
||||
slidesToScroll: innerWidth < 550 ? 1 : 2,
|
||||
})
|
||||
|
||||
// On init
|
||||
carousel.on('init', () => {
|
||||
// Define amounts of dots
|
||||
carouselDots = carousel.scrollSnapList()
|
||||
})
|
||||
// On slide change
|
||||
carousel.on('select', () => {
|
||||
// Define current slide
|
||||
currentSlide = carousel.selectedScrollSnap()
|
||||
})
|
||||
// On resize
|
||||
carousel.on('resize', () => {
|
||||
// Redefine options
|
||||
carousel.reInit({
|
||||
slidesToScroll: innerWidth < 550 ? 1 : 2
|
||||
})
|
||||
// Define amounts of dots
|
||||
carouselDots = carousel.scrollSnapList()
|
||||
// Define current slide
|
||||
currentSlide = carousel.selectedScrollSnap()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (carousel) {
|
||||
carousel.destroy()
|
||||
carousel = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Destroy carousel for larger screens */
|
||||
const handleResize = debounce(initCarousel, 200)
|
||||
|
||||
|
||||
onMount(() => {
|
||||
initCarousel()
|
||||
|
||||
// Destroy
|
||||
return () => {
|
||||
if (carousel) {
|
||||
carousel.destroy()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:window
|
||||
bind:innerWidth
|
||||
on:resize={handleResize}
|
||||
/>
|
||||
|
||||
{#if posters}
|
||||
<section class="shop-page__posters grid">
|
||||
<h3>View all of our available posters</h3>
|
||||
|
||||
<div class="set" bind:this={carouselEl}>
|
||||
<div class="set__content">
|
||||
{#each posters as { location, photos_product }}
|
||||
<Poster
|
||||
location={location}
|
||||
image={photos_product.length && photos_product[1].directus_files_id}
|
||||
product={shopProducts.find(item => item.slug.includes(location.slug))}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if carousel}
|
||||
<ul class="set__dots">
|
||||
{#each carouselDots as _, index}
|
||||
<li class:is-active={index === currentSlide}>
|
||||
<button on:click={() => goToSlide(index)} aria-label="Go to slide #{index + 1}" />
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="subscribe">
|
||||
<label class="subscribe__text" for="SUB_EMAIL">Subscribe to be notified when new posters become available</label>
|
||||
<EmailForm />
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user