Merge branch 'main' into dev
This commit is contained in:
@@ -10,6 +10,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"directus": "^9.22.4",
|
"directus": "^9.22.4",
|
||||||
"pg": "^8.8.0"
|
"pg": "^8.9.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
0
apps/website/.eslintignore
Normal file
0
apps/website/.eslintignore
Normal file
@@ -12,43 +12,43 @@
|
|||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
"lint": "eslint --ignore-path .gitignore ."
|
"lint": "eslint ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@studio-freight/lenis": "^0.2.28",
|
"@studio-freight/lenis": "^0.2.28",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"embla-carousel": "^7.0.5",
|
"embla-carousel": "^7.0.9",
|
||||||
"focus-visible": "^5.2.0",
|
"focus-visible": "^5.2.0",
|
||||||
"motion": "^10.15.5",
|
"motion": "^10.15.5",
|
||||||
"ogl": "^0.0.103",
|
"ogl": "^0.0.104",
|
||||||
"sanitize.css": "^13.0.0",
|
"sanitize.css": "^13.0.0",
|
||||||
"swell-js": "3.19.3",
|
"swell-js": "3.19.5",
|
||||||
"tweakpane": "^3.1.1"
|
"tweakpane": "^3.1.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^1.0.0",
|
"@sveltejs/adapter-auto": "^1.0.2",
|
||||||
"@sveltejs/adapter-cloudflare": "^1.0.0",
|
"@sveltejs/adapter-cloudflare": "^2.0.1",
|
||||||
"@sveltejs/adapter-node": "^1.1.0",
|
"@sveltejs/adapter-node": "^1.1.4",
|
||||||
"@sveltejs/adapter-vercel": "^1.0.1",
|
"@sveltejs/adapter-vercel": "^1.0.6",
|
||||||
"@sveltejs/kit": "^1.0.11",
|
"@sveltejs/kit": "^1.3.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.48.1",
|
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||||
"@typescript-eslint/parser": "^5.48.1",
|
"@typescript-eslint/parser": "^5.50.0",
|
||||||
"base-64": "^1.0.0",
|
"base-64": "^1.0.0",
|
||||||
"browserslist": "^4.21.4",
|
"browserslist": "^4.21.5",
|
||||||
"cssnano": "^5.1.14",
|
"cssnano": "^5.1.14",
|
||||||
"eslint": "^8.31.0",
|
"eslint": "^8.33.0",
|
||||||
"eslint-plugin-svelte3": "^4.0.0",
|
"eslint-plugin-svelte3": "^4.0.0",
|
||||||
"postcss": "^8.4.21",
|
"postcss": "^8.4.21",
|
||||||
"postcss-focus-visible": "^7.1.0",
|
"postcss-focus-visible": "^8.0.1",
|
||||||
"postcss-normalize": "^10.0.1",
|
"postcss-normalize": "^10.0.1",
|
||||||
"postcss-preset-env": "^7.8.3",
|
"postcss-preset-env": "^8.0.1",
|
||||||
"postcss-sort-media-queries": "^4.3.0",
|
"postcss-sort-media-queries": "^4.3.0",
|
||||||
"sass": "^1.57.1",
|
"sass": "^1.58.0",
|
||||||
"svelte": "^3.55.1",
|
"svelte": "^3.55.1",
|
||||||
"svelte-check": "^3.0.2",
|
"svelte-check": "^3.0.3",
|
||||||
"svelte-preprocess": "^5.0.0",
|
"svelte-preprocess": "^5.0.1",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.5.0",
|
||||||
"typescript": "^4.9.4",
|
"typescript": "^4.9.5",
|
||||||
"vite": "^4.0.4"
|
"vite": "^4.0.4"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
6
apps/website/src/app.d.ts
vendored
6
apps/website/src/app.d.ts
vendored
@@ -1,12 +1,14 @@
|
|||||||
// See https://kit.svelte.dev/docs/types#app
|
// See https://kit.svelte.dev/docs/types#app
|
||||||
// for information about these interfaces
|
// for information about these interfaces
|
||||||
// and what to do when importing types
|
// and what to do when importing types
|
||||||
declare namespace App {
|
declare global {
|
||||||
|
namespace App {
|
||||||
// interface Locals {}
|
// interface Locals {}
|
||||||
// interface PageData {}
|
// interface PageData {}
|
||||||
// interface Error {}
|
// interface Error {}
|
||||||
// interface Platform {}
|
// interface Platform {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,7 +57,7 @@ declare interface smoothScrollOptions {
|
|||||||
hash: string
|
hash: string
|
||||||
changeHash?: boolean
|
changeHash?: boolean
|
||||||
event?: MouseEvent
|
event?: MouseEvent
|
||||||
callback?: Function
|
callback?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let domain: string
|
export let domain: string
|
||||||
export let enabled: boolean = !import.meta.env.DEV
|
export let enabled = !import.meta.env.DEV
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
export let description: string = undefined
|
export let description: string = undefined
|
||||||
export let image: string = getAssetUrlKey(settings.seo_image.id, 'share-image')
|
export let image: string = getAssetUrlKey(settings.seo_image.id, 'share-image')
|
||||||
export let url: string = undefined
|
export let url: string = undefined
|
||||||
export let type: string = 'website'
|
export let type = 'website'
|
||||||
export let card: string = 'summary_large_image'
|
export let card = 'summary_large_image'
|
||||||
export let creator: string = undefined
|
export let creator: string = undefined
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
export let text: string
|
export let text: string
|
||||||
export let mode: string = undefined
|
export let mode: string = undefined
|
||||||
export let clone: boolean = false
|
export let clone = false
|
||||||
|
|
||||||
$: split = splitText(text, mode)
|
$: split = splitText(text, mode)
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
export let id: string
|
export let id: string
|
||||||
export let alt: string
|
export let alt: string
|
||||||
export let disabled: boolean = false
|
export let disabled = false
|
||||||
|
|
||||||
let hovering: boolean = false
|
let hovering = false
|
||||||
let timer: ReturnType<typeof setTimeout> | number = null
|
let timer: ReturnType<typeof setTimeout> | number = null
|
||||||
|
|
||||||
$: classes = [
|
$: classes = [
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let text: string
|
export let text: string
|
||||||
export let size: string = 'small'
|
export let size = 'small'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="badge badge--{size}">
|
<div class="badge badge--{size}">
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import SplitText from '$components/SplitText.svelte'
|
import SplitText from '$components/SplitText.svelte'
|
||||||
|
|
||||||
export let tag: string = 'a'
|
export let tag = 'a'
|
||||||
export let text: string
|
export let text: string
|
||||||
export let url: string = undefined
|
export let url: string = undefined
|
||||||
export let color: string = undefined
|
export let color: string = undefined
|
||||||
export let size: string = undefined
|
export let size: string = undefined
|
||||||
export let effect: string = 'link-3d'
|
export let effect = 'link-3d'
|
||||||
export let disabled: boolean = undefined
|
export let disabled: boolean = undefined
|
||||||
export let slotPosition: string = 'before'
|
export let slotPosition = 'before'
|
||||||
|
|
||||||
const className = 'button'
|
const className = 'button'
|
||||||
const classes = [
|
const classes = [
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let tag: string = 'button'
|
export let tag = 'button'
|
||||||
export let url: string = undefined
|
export let url: string = undefined
|
||||||
export let color: string = undefined
|
export let color: string = undefined
|
||||||
export let size: string = undefined
|
export let size: string = undefined
|
||||||
export let type: string = undefined
|
export let type: 'button' | 'reset' | 'submit' = undefined
|
||||||
export let clone: boolean = false
|
export let clone = false
|
||||||
export let disabled: boolean = undefined
|
export let disabled: boolean = undefined
|
||||||
export let label: string = undefined
|
export let label: string = undefined
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let color: string = undefined
|
export let color: string = undefined
|
||||||
export let flip: boolean = false
|
export let flip = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svg width="12" height="14"
|
<svg width="12" height="14"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let animate: boolean = false
|
export let animate = false
|
||||||
|
|
||||||
const classes = ['icon-earth', $$props.class].join(' ').trim()
|
const classes = ['icon-earth', $$props.class].join(' ').trim()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
export let height: number = sizes && sizes.medium && sizes.medium.height
|
export let height: number = sizes && sizes.medium && sizes.medium.height
|
||||||
export let ratio: number = undefined
|
export let ratio: number = undefined
|
||||||
export let alt: string
|
export let alt: string
|
||||||
export let lazy: boolean = true
|
export let lazy = true
|
||||||
export let decoding: "auto" | "sync" | "async" = "auto"
|
export let decoding: "auto" | "sync" | "async" = "auto"
|
||||||
|
|
||||||
interface Sizes {
|
interface Sizes {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
export let parallax: number = undefined
|
export let parallax: number = undefined
|
||||||
export let offsetStart: number = undefined
|
export let offsetStart: number = undefined
|
||||||
export let offsetEnd: number = undefined
|
export let offsetEnd: number = undefined
|
||||||
export let animate: boolean = true
|
export let animate = true
|
||||||
|
|
||||||
let scrollY: number
|
let scrollY: number
|
||||||
let innerWidth: number
|
let innerWidth: number
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
import reveal from '$animations/reveal'
|
import reveal from '$animations/reveal'
|
||||||
import { DURATION } from '$utils/constants'
|
import { DURATION } from '$utils/constants'
|
||||||
|
|
||||||
export let variant: string = 'lines'
|
export let variant = 'lines'
|
||||||
export let tag: string = 'h1'
|
export let tag = 'h1'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if tag === 'h1'}
|
{#if tag === 'h1'}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
import IconArrow from '$components/atoms/IconArrow.svelte'
|
import IconArrow from '$components/atoms/IconArrow.svelte'
|
||||||
import ButtonCircle from '$components/atoms/ButtonCircle.svelte'
|
import ButtonCircle from '$components/atoms/ButtonCircle.svelte'
|
||||||
|
|
||||||
export let past: boolean = false
|
export let past = false
|
||||||
|
|
||||||
let inputInFocus = false
|
let inputInFocus = false
|
||||||
let formStatus: FormStatus = null
|
let formStatus: FormStatus = null
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let ended: boolean = false
|
export let ended = false
|
||||||
export let current: number
|
export let current: number
|
||||||
export let total: number
|
export let total: number
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
export let title: string = undefined
|
export let title: string = undefined
|
||||||
export let location: any = undefined
|
export let location: any = undefined
|
||||||
export let city: string = undefined
|
export let city: string = undefined
|
||||||
export let hovered: boolean = false
|
export let hovered = false
|
||||||
export let lazy: boolean = true
|
export let lazy = true
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const sizes = {
|
const sizes = {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import { shopCurrentProductSlug } from '$utils/stores/shop'
|
import { shopCurrentProductSlug } from '$utils/stores/shop'
|
||||||
import { smoothScroll } from '$utils/stores'
|
import { smoothScroll } from '$utils/stores'
|
||||||
|
|
||||||
export let isOver: boolean = false
|
export let isOver = false
|
||||||
|
|
||||||
const { shopLocations }: any = getContext('shop')
|
const { shopLocations }: any = getContext('shop')
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
// Quick location change
|
// Quick location change
|
||||||
const quickLocationChange = async ({ target: { value }}: any) => {
|
const quickLocationChange = async ({ target: { value }}: any) => {
|
||||||
const pathTo = `/shop/poster-${value}`
|
const pathTo = `/shop/poster-${value}`
|
||||||
goto(pathTo, { replaceState: true, noscroll: true, keepfocus: true })
|
goto(pathTo, { replaceState: true, noScroll: true, keepFocus: true })
|
||||||
|
|
||||||
// Scroll to anchor
|
// Scroll to anchor
|
||||||
await tick()
|
await tick()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
export let title: string
|
export let title: string
|
||||||
export let image: any
|
export let image: any
|
||||||
export let back: boolean = false
|
export let back = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="banner">
|
<section class="banner">
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/** Navigate to specific slide */
|
/** Navigate to specific slide */
|
||||||
const goToSlide = (index: number = 0) => carousel.scrollTo(index)
|
const goToSlide = (index = 0) => carousel.scrollTo(index)
|
||||||
|
|
||||||
/** Move and change arrow direction when moving */
|
/** Move and change arrow direction when moving */
|
||||||
const arrowPosition = writable({ x: 0, y: 0 })
|
const arrowPosition = writable({ x: 0, y: 0 })
|
||||||
@@ -89,6 +89,7 @@
|
|||||||
<div class="carousel__viewport" bind:this={carouselEl}
|
<div class="carousel__viewport" bind:this={carouselEl}
|
||||||
on:mousemove={handleArrowMove}
|
on:mousemove={handleArrowMove}
|
||||||
on:click={handleArrowClick}
|
on:click={handleArrowClick}
|
||||||
|
on:keydown
|
||||||
>
|
>
|
||||||
<div class="carousel__slides">
|
<div class="carousel__slides">
|
||||||
{#each slides as { id, alt }}
|
{#each slides as { id, alt }}
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
const isDev = import.meta.env.DEV
|
const isDev = import.meta.env.DEV
|
||||||
|
|
||||||
export let type: string = undefined
|
export let type: string = undefined
|
||||||
export let autoRotate: boolean = true
|
export let autoRotate = true
|
||||||
export let enableMarkers: boolean = true
|
export let enableMarkers = true
|
||||||
export let enableMarkersLinks: boolean = true
|
export let enableMarkersLinks = true
|
||||||
export let speed: number = 0.1
|
export let speed = 0.1
|
||||||
export let pane: boolean = isDev
|
export let pane: boolean = isDev
|
||||||
export let width: number = undefined
|
export let width: number = undefined
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
// Components
|
// Components
|
||||||
import EmailForm from '$components/molecules/EmailForm.svelte'
|
import EmailForm from '$components/molecules/EmailForm.svelte'
|
||||||
|
|
||||||
export let theme: string = 'default'
|
export let theme = 'default'
|
||||||
|
|
||||||
const { settings: { newsletter_text, newsletter_subtitle }}: any = getContext('global')
|
const { settings: { newsletter_text, newsletter_subtitle }}: any = getContext('global')
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/** Navigate to specific slide */
|
/** Navigate to specific slide */
|
||||||
const goToSlide = (index: number = 0) => {
|
const goToSlide = (index = 0) => {
|
||||||
carousel.scrollTo(index)
|
carousel.scrollTo(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,9 @@
|
|||||||
export let title: string = shop.module_title
|
export let title: string = shop.module_title
|
||||||
export let text: string = shop.module_text
|
export let text: string = shop.module_text
|
||||||
export let textBottom: string = undefined
|
export let textBottom: string = undefined
|
||||||
export let buttonText: string = 'Shop'
|
export let buttonText = 'Shop'
|
||||||
export let url: string = '/shop'
|
export let url = '/shop'
|
||||||
export let enabled: boolean = true
|
export let enabled = true
|
||||||
|
|
||||||
if (textBottom !== null) {
|
if (textBottom !== null) {
|
||||||
textBottom = `Posters available for ${locationsWithPoster.join(', ').replace(/,(?!.*,)/gmi, ' and')}.`
|
textBottom = `Posters available for ${locationsWithPoster.join(', ').replace(/,(?!.*,)/gmi, ' and')}.`
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ export type Marker = {
|
|||||||
*/
|
*/
|
||||||
function WebGLSupport () {
|
function WebGLSupport () {
|
||||||
try {
|
try {
|
||||||
var canvas = document.createElement('canvas')
|
const canvas = document.createElement('canvas')
|
||||||
return !!window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))
|
return !!window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
// Close viewer and go to previous page
|
// Close viewer and go to previous page
|
||||||
const closeViewer = () => {
|
const closeViewer = () => {
|
||||||
goto(previousUrl, { replaceState: false, noscroll: true, keepfocus: true })
|
goto(previousUrl, { replaceState: false, noScroll: true, keepFocus: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable navigation with keyboard
|
// Enable navigation with keyboard
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
let scrollY: number, innerWidth: number, innerHeight: number
|
let scrollY: number, innerWidth: number, innerHeight: number
|
||||||
let photosGridEl: HTMLElement
|
let photosGridEl: HTMLElement
|
||||||
let photosGridOffset: number = photosGridEl && photosGridEl.offsetTop
|
let photosGridOffset: number = photosGridEl && photosGridEl.offsetTop
|
||||||
let currentStep: number = 0
|
let currentStep = 0
|
||||||
let emailCopied: string = null
|
let emailCopied: string = null
|
||||||
let emailCopiedTimeout: ReturnType<typeof setTimeout> | number
|
let emailCopiedTimeout: ReturnType<typeof setTimeout> | number
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
urlFiltersParams.set('sort', filterSort)
|
urlFiltersParams.set('sort', filterSort)
|
||||||
|
|
||||||
let path = `${$page.url.pathname}?${urlFiltersParams.toString()}`
|
let path = `${$page.url.pathname}?${urlFiltersParams.toString()}`
|
||||||
goto(path, { replaceState: true, keepfocus: true, noscroll: true })
|
goto(path, { replaceState: true, keepFocus: true, noScroll: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { navigating, page } from '$app/stores'
|
import { navigating } from '$app/stores'
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
import { getContext, onMount } from 'svelte'
|
import { getContext, onMount } from 'svelte'
|
||||||
import { timeline, stagger } from 'motion'
|
import { timeline, stagger } from 'motion'
|
||||||
|
|||||||
@@ -2,27 +2,32 @@ import { sendEvent } from '$utils/analytics'
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throttle function
|
* Debounce a function with a given amount of time
|
||||||
|
* @description For scrolling or other resource demanding behaviors
|
||||||
*/
|
*/
|
||||||
export const throttle = (func: Function, timeout: number) => {
|
export const debounce = (callback: (...args: any[]) => any, wait: number, immediate = false) => {
|
||||||
let ready: boolean = true
|
let timeout: ReturnType<typeof setTimeout> | number = 0
|
||||||
return (...args: any) => {
|
return (...args: any[]) => {
|
||||||
if (!ready) return
|
const callNow: boolean = immediate && !timeout
|
||||||
ready = false
|
const next = () => callback(...args)
|
||||||
func(...args)
|
clearTimeout(timeout)
|
||||||
setTimeout(() => ready = true, timeout)
|
timeout = setTimeout(next, wait)
|
||||||
|
if (callNow) next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debounce function
|
* Throttle a function by a given amount of time
|
||||||
|
* @description Throttling enforces a maximum number of times a function can be called over time, as in 'execute this function at most once every 100 milliseconds
|
||||||
*/
|
*/
|
||||||
export const debounce = (func: Function, timeout: number) => {
|
export const throttle = (fn: (...args: any[]) => any, delay: number) => {
|
||||||
let timer: NodeJS.Timeout
|
let lastCall = 0
|
||||||
return (...args: any) => {
|
return (...args: unknown[]) => {
|
||||||
clearTimeout(timer)
|
const now = performance.now()
|
||||||
timer = setTimeout(() => func(...args), timeout)
|
if (now - lastCall < delay) return
|
||||||
|
lastCall = now
|
||||||
|
requestAnimationFrame(() => fn(...args))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +37,7 @@ export const debounce = (func: Function, timeout: number) => {
|
|||||||
* @description Split a string into words or characters
|
* @description Split a string into words or characters
|
||||||
* @returns string[]
|
* @returns string[]
|
||||||
*/
|
*/
|
||||||
export const splitText = (text: string, mode: string = 'words'): string[] => {
|
export const splitText = (text: string, mode = 'words'): string[] => {
|
||||||
// Split by words
|
// Split by words
|
||||||
if (mode === 'words') {
|
if (mode === 'words') {
|
||||||
const words = text
|
const words = text
|
||||||
@@ -105,23 +110,27 @@ export const clamp = (num: number, a: number, b: number) => {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a random element from an array
|
* Return random elements from an array
|
||||||
*/
|
*/
|
||||||
export const getRandomItem = <T extends unknown> (array: T[]): T => {
|
export const getRandomItems = <T> (array: T[], amount: number): T[] => {
|
||||||
const randomItemIndex = ~~(array.length * Math.random())
|
const shuffled = array.slice()
|
||||||
return array[randomItemIndex]
|
for (let i = shuffled.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
|
||||||
|
}
|
||||||
|
return shuffled.slice(0, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return random elements from an array
|
* Return a random element from an array
|
||||||
*/
|
*/
|
||||||
export const getRandomItems = <T extends unknown> (array: any[], amount: number): T[] => {
|
export const getRandomItem = <T extends Array<unknown>> (array: T): T[0] => {
|
||||||
const shuffled = Array.from(array).sort(() => 0.5 - Math.random())
|
return getRandomItems(array, 1)[0]
|
||||||
return shuffled.slice(0, amount)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll back to top after page transition
|
* Scroll back to top after page transition
|
||||||
*/
|
*/
|
||||||
@@ -143,7 +152,7 @@ export const mailtoClipboard = (node: HTMLElement) => {
|
|||||||
const links = node.querySelectorAll('a[href^="mailto:"]')
|
const links = node.querySelectorAll('a[href^="mailto:"]')
|
||||||
|
|
||||||
const clickToCopy = (event) => {
|
const clickToCopy = (event) => {
|
||||||
let emailAddress = event.currentTarget.href.split('mailto:')[1].split('?')[0]
|
const emailAddress = event.currentTarget.href.split('mailto:')[1].split('?')[0]
|
||||||
|
|
||||||
// Copy email to clipboard
|
// Copy email to clipboard
|
||||||
navigator.clipboard.writeText(emailAddress)
|
navigator.clipboard.writeText(emailAddress)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const getCart = async () => {
|
|||||||
/**
|
/**
|
||||||
* Add a product to a cart
|
* Add a product to a cart
|
||||||
*/
|
*/
|
||||||
export const addToCart = async (product: any, quantity: number = 1) => {
|
export const addToCart = async (product: any, quantity = 1) => {
|
||||||
const updatedCart = await swell.cart.addItem({
|
const updatedCart = await swell.cart.addItem({
|
||||||
product_id: product.id,
|
product_id: product.id,
|
||||||
quantity,
|
quantity,
|
||||||
|
|||||||
@@ -3,5 +3,13 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"lib": ["WebWorker"],
|
"lib": ["WebWorker"],
|
||||||
},
|
// "allowJs": true,
|
||||||
|
// "checkJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
// "strict": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import type { UserConfig } from 'vite'
|
||||||
import { sveltekit } from '@sveltejs/kit/vite'
|
import { sveltekit } from '@sveltejs/kit/vite'
|
||||||
import { scssImports } from './svelte.config'
|
import { scssImports } from './svelte.config'
|
||||||
|
|
||||||
/** @type {import('vite').UserConfig} */
|
const config: UserConfig = {
|
||||||
const config = {
|
|
||||||
plugins: [
|
plugins: [
|
||||||
sveltekit()
|
sveltekit()
|
||||||
],
|
],
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
"lint": "turbo run lint"
|
"lint": "turbo run lint"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^2.8.2",
|
"prettier": "^2.8.3",
|
||||||
"turbo": "^1.7.0"
|
"turbo": "^1.7.1"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
1486
pnpm-lock.yaml
generated
1486
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user