143 lines
3.9 KiB
Svelte
143 lines
3.9 KiB
Svelte
<style lang="scss">
|
|
// Toast
|
|
:global(.toast--global) {
|
|
position: fixed;
|
|
z-index: 20;
|
|
max-width: 420px;
|
|
bottom: var(--offset-sides);
|
|
right: var(--offset-sides);
|
|
left: calc(var(--offset-sides) + 44px + 24px);
|
|
|
|
@include bp (mob-lg) {
|
|
left: auto;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script lang="ts">
|
|
import 'sanitize.css'
|
|
import '../style/global.scss'
|
|
|
|
import { PUBLIC_ANALYTICS_DOMAIN } from '$env/static/public'
|
|
import { browser } from '$app/environment'
|
|
import { page } from '$app/stores'
|
|
import { beforeNavigate, afterNavigate } from '$app/navigation'
|
|
import { setContext } from 'svelte'
|
|
import { fade } from 'svelte/transition'
|
|
import { DELAY, DURATION } from '$utils/constants'
|
|
import { pageLoading, previousPage } from '$utils/stores'
|
|
import { scrollToTop } from 'utils/scroll'
|
|
import '$utils/polyfills'
|
|
// Components
|
|
import SVGSprite from '$components/SVGSprite.svelte'
|
|
import SmoothScroll from '$components/SmoothScroll.svelte'
|
|
import Analytics from '$components/Analytics.svelte'
|
|
import Switcher from '$components/molecules/Switcher/Switcher.svelte'
|
|
import Toast from '$components/molecules/Toast/Toast.svelte'
|
|
import Footer from '$components/organisms/Footer/Footer.svelte'
|
|
|
|
let { data, children } = $props()
|
|
|
|
let innerHeight = $state<number>()
|
|
|
|
// Fonts to preload
|
|
const fonts = [
|
|
'G-Light',
|
|
'G-Regular',
|
|
'G-Medium',
|
|
'G-Semibold',
|
|
'J-Extralight',
|
|
'J-Light',
|
|
]
|
|
|
|
// Set global data
|
|
setContext('global', data)
|
|
|
|
|
|
/**
|
|
* On page change
|
|
*/
|
|
beforeNavigate(({ from, to }) => {
|
|
// Store previous page (for photo Viewer close button)
|
|
$previousPage = from.url.pathname
|
|
|
|
// Enable page loading state if URL changed
|
|
if (from?.route.id !== to?.route.id) {
|
|
$pageLoading = true
|
|
}
|
|
})
|
|
|
|
afterNavigate(({ from }) => {
|
|
// Remove page loading state
|
|
setTimeout(() => $pageLoading = false, DELAY.PAGE_LOADING)
|
|
|
|
// Scroll back to top when new page is ready (excepted certain pages)
|
|
if (from?.url?.pathname && (!$page.url.searchParams.get('country') && !$page.url.pathname.includes('/shop/'))) {
|
|
setTimeout(scrollToTop, DELAY.PAGE_IN)
|
|
}
|
|
})
|
|
|
|
|
|
$effect(() => {
|
|
// Set viewport height
|
|
innerHeight && document.body.style.setProperty('--vh', `${innerHeight}px`)
|
|
|
|
// Avoid FOUC
|
|
document.body.style.opacity = '1'
|
|
|
|
// Define page loading
|
|
document.body.classList.toggle('is-loading', $pageLoading)
|
|
// Block scroll on certain conditions
|
|
// document.body.classList.toggle('block-scroll', condition)
|
|
})
|
|
</script>
|
|
|
|
<svelte:window bind:innerHeight />
|
|
|
|
<svelte:head>
|
|
<link rel="canonical" href={$page.url.href.split('#')[0]} />
|
|
|
|
{#each fonts as font}
|
|
<link rel="preload" href="/fonts/{font}.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
{/each}
|
|
</svelte:head>
|
|
|
|
|
|
<Switcher />
|
|
|
|
{#key data.currentPath}
|
|
<div
|
|
in:fade={{ duration: DURATION.PAGE_IN, delay: DELAY.PAGE_LOADING }}
|
|
out:fade={{ duration: DURATION.PAGE_OUT }}
|
|
>
|
|
{@render children()}
|
|
|
|
{#if !$page.params.photo}
|
|
<Footer />
|
|
{/if}
|
|
</div>
|
|
{/key}
|
|
|
|
|
|
{#if !['/[photo]'].some(sub => $page.route.id.includes(sub))}
|
|
<Toast
|
|
type="global"
|
|
id="posters-promo"
|
|
text="Upgrade your walls! Our graphic posters are <strong>10% off</strong> in cart with free shipping."
|
|
cta={{
|
|
label: 'View posters',
|
|
url: '/shop',
|
|
color: 'pink',
|
|
}}
|
|
images={data.shop.module_images.map(({ directus_files_id: { id, title } }) => ({ id, title }))}
|
|
class="toast-home"
|
|
/>
|
|
{/if}
|
|
|
|
<SVGSprite />
|
|
<SmoothScroll />
|
|
|
|
{#if browser}
|
|
<Analytics domain={PUBLIC_ANALYTICS_DOMAIN} />
|
|
{/if}
|