chore: move utils to package
This commit is contained in:
@@ -23,7 +23,8 @@
|
|||||||
"ogl": "^0.0.110",
|
"ogl": "^0.0.110",
|
||||||
"sanitize.css": "^13.0.0",
|
"sanitize.css": "^13.0.0",
|
||||||
"swell-js": "3.19.8",
|
"swell-js": "3.19.8",
|
||||||
"tweakpane": "^3.1.4"
|
"tweakpane": "^3.1.4",
|
||||||
|
"utils": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^2.0.0",
|
"@sveltejs/adapter-auto": "^2.0.0",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { page } from '$app/stores'
|
import { page } from '$app/stores'
|
||||||
import { afterUpdate } from 'svelte'
|
import { afterUpdate } from 'svelte'
|
||||||
import { fade } from 'svelte/transition'
|
import { fade } from 'svelte/transition'
|
||||||
import { scrollToTop } from '$utils/functions'
|
import { scrollToTop } from 'utils/scroll'
|
||||||
import { pageLoading } from '$utils/stores'
|
import { pageLoading } from '$utils/stores'
|
||||||
import { DELAY, DURATION } from '$utils/constants'
|
import { DELAY, DURATION } from '$utils/constants'
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { splitText } from '$utils/functions'
|
import { splitText } from 'utils/text'
|
||||||
|
|
||||||
export let text: string
|
export let text: string
|
||||||
export let mode: string = undefined
|
export let mode: string = undefined
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { map } from '$utils/functions'
|
import { map } from 'utils/math'
|
||||||
import reveal from '$animations/reveal'
|
import reveal from '$animations/reveal'
|
||||||
|
|
||||||
export let tag: string
|
export let tag: string
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { addToCart } from '$utils/functions/shop'
|
import { addToCart } from '$utils/functions/shop'
|
||||||
import { capitalizeFirstLetter } from '$utils/functions'
|
import { capitalizeFirstLetter } from 'utils/string'
|
||||||
// Components
|
// Components
|
||||||
import SplitText from '$components/SplitText.svelte'
|
import SplitText from '$components/SplitText.svelte'
|
||||||
import Button from '$components/atoms/Button.svelte'
|
import Button from '$components/atoms/Button.svelte'
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { getContext } from 'svelte'
|
import { getContext } from 'svelte'
|
||||||
import { spring } from 'svelte/motion'
|
import { spring } from 'svelte/motion'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { lerp } from '$utils/functions'
|
import { lerp } from 'utils/math'
|
||||||
import { PUBLIC_PREVIEW_COUNT } from '$env/static/public'
|
import { PUBLIC_PREVIEW_COUNT } from '$env/static/public'
|
||||||
import { seenLocations } from '$utils/stores'
|
import { seenLocations } from '$utils/stores'
|
||||||
// Components
|
// Components
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
import { fade, fly as flySvelte } from 'svelte/transition'
|
import { fade, fly as flySvelte } from 'svelte/transition'
|
||||||
import { quartOut } from 'svelte/easing'
|
import { quartOut } from 'svelte/easing'
|
||||||
import { Globe, type Marker } from '$modules/globe'
|
import { Globe, type Marker } from '$modules/globe'
|
||||||
import { getRandomItem, debounce } from '$utils/functions'
|
import { getRandomItem } from 'utils/array'
|
||||||
|
import { debounce } from 'utils/actions'
|
||||||
import { revealSplit } from '$animations/transitions'
|
import { revealSplit } from '$animations/transitions'
|
||||||
// Components
|
// Components
|
||||||
import SplitText from '$components/SplitText.svelte'
|
import SplitText from '$components/SplitText.svelte'
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import { quartOut } from 'svelte/easing'
|
import { quartOut } from 'svelte/easing'
|
||||||
import reveal from '$animations/reveal'
|
import reveal from '$animations/reveal'
|
||||||
import { send, receive } from '$animations/crossfade'
|
import { send, receive } from '$animations/crossfade'
|
||||||
import { throttle } from '$utils/functions'
|
import { throttle } from 'utils/actions'
|
||||||
import { sendEvent } from '$utils/analytics'
|
import { sendEvent } from '$utils/analytics'
|
||||||
// Components
|
// Components
|
||||||
import Button from '$components/atoms/Button.svelte'
|
import Button from '$components/atoms/Button.svelte'
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import EmblaCarousel, { type EmblaCarouselType } from 'embla-carousel'
|
import EmblaCarousel, { type EmblaCarouselType } from 'embla-carousel'
|
||||||
// Components
|
// Components
|
||||||
import Poster from '$components/molecules/Poster.svelte'
|
import Poster from '$components/molecules/Poster.svelte'
|
||||||
import { debounce } from '$utils/functions'
|
import { debounce } from 'utils/actions'
|
||||||
|
|
||||||
export let posters: any = []
|
export let posters: any = []
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { error } from '@sveltejs/kit'
|
import { error } from '@sveltejs/kit'
|
||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { getRandomItem } from '$utils/functions'
|
import { getRandomItem } from 'utils/array'
|
||||||
import { fetchSwell } from '$utils/functions/shopServer'
|
import { fetchSwell } from '$utils/functions/shopServer'
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { getContext } from 'svelte'
|
import { getContext } from 'svelte'
|
||||||
import { getAssetUrlKey } from '$utils/api'
|
import { getAssetUrlKey } from '$utils/api'
|
||||||
import { shopCurrentProductSlug } from '$utils/stores/shop'
|
import { shopCurrentProductSlug } from '$utils/stores/shop'
|
||||||
import { capitalizeFirstLetter } from '$utils/functions'
|
import { capitalizeFirstLetter } from 'utils/string'
|
||||||
// Components
|
// Components
|
||||||
import PageTransition from '$components/PageTransition.svelte'
|
import PageTransition from '$components/PageTransition.svelte'
|
||||||
import Metas from '$components/Metas.svelte'
|
import Metas from '$components/Metas.svelte'
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
import { getAssetUrlKey } from '$utils/api'
|
import { getAssetUrlKey } from '$utils/api'
|
||||||
import { previousPage } from '$utils/stores'
|
import { previousPage } from '$utils/stores'
|
||||||
import { DELAY } from '$utils/constants'
|
import { DELAY } from '$utils/constants'
|
||||||
import { throttle } from '$utils/functions'
|
import { throttle } from 'utils/actions'
|
||||||
import { swipe } from '$utils/interactions/swipe'
|
import { swipe } from '$utils/interactions/swipe'
|
||||||
// Components
|
// Components
|
||||||
import Metas from '$components/Metas.svelte'
|
import Metas from '$components/Metas.svelte'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { error } from '@sveltejs/kit'
|
import { error } from '@sveltejs/kit'
|
||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { getRandomItems } from '$utils/functions'
|
import { getRandomItems } from 'utils/array'
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -9,9 +9,10 @@
|
|||||||
import { fade, fly } from 'svelte/transition'
|
import { fade, fly } from 'svelte/transition'
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
import { animate, inView, stagger, timeline } from 'motion'
|
import { animate, inView, stagger, timeline } from 'motion'
|
||||||
import { mailtoClipboard, map } from '$utils/functions'
|
import { mailtoClipboard } from '$utils/functions'
|
||||||
import { getAssetUrlKey } from '$utils/api'
|
import { getAssetUrlKey } from '$utils/api'
|
||||||
import { DELAY } from '$utils/constants'
|
import { DELAY } from '$utils/constants'
|
||||||
|
import { map } from 'utils/math'
|
||||||
import { sendEvent } from '$utils/analytics'
|
import { sendEvent } from '$utils/analytics'
|
||||||
import { quartOut } from '$animations/easings'
|
import { quartOut } from '$animations/easings'
|
||||||
// Components
|
// Components
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||||
import { stagger, timeline } from 'motion'
|
import { stagger, timeline } from 'motion'
|
||||||
import { DELAY } from '$utils/constants'
|
import { DELAY } from '$utils/constants'
|
||||||
import { map, lerp, throttle } from '$utils/functions'
|
import { map, lerp } from 'utils/math'
|
||||||
|
import { throttle } from 'utils/actions'
|
||||||
import { getAssetUrlKey } from '$utils/api'
|
import { getAssetUrlKey } from '$utils/api'
|
||||||
import { quartOut } from '$animations/easings'
|
import { quartOut } from '$animations/easings'
|
||||||
import { PUBLIC_FILTERS_DEFAULT_COUNTRY, PUBLIC_FILTERS_DEFAULT_SORT, PUBLIC_GRID_INCREMENT } from '$env/static/public'
|
import { PUBLIC_FILTERS_DEFAULT_COUNTRY, PUBLIC_FILTERS_DEFAULT_SORT, PUBLIC_GRID_INCREMENT } from '$env/static/public'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { error } from '@sveltejs/kit'
|
import { error } from '@sveltejs/kit'
|
||||||
import type { PageServerLoad } from './$types'
|
import type { PageServerLoad } from './$types'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
import { getRandomItems } from '$utils/functions'
|
import { getRandomItems } from 'utils/array'
|
||||||
|
|
||||||
|
|
||||||
export const load = (async ({ setHeaders }) => {
|
export const load = (async ({ setHeaders }) => {
|
||||||
|
|||||||
@@ -1,150 +1,6 @@
|
|||||||
import { sendEvent } from '$utils/analytics'
|
import { sendEvent } from '$utils/analytics'
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debounce a function with a given amount of time
|
|
||||||
* @description For scrolling or other resource demanding behaviors
|
|
||||||
*/
|
|
||||||
export const debounce = (callback: (...args: any[]) => any, wait: number, immediate = false) => {
|
|
||||||
let timeout: ReturnType<typeof setTimeout> | number = 0
|
|
||||||
return (...args: any[]) => {
|
|
||||||
const callNow: boolean = immediate && !timeout
|
|
||||||
const next = () => callback(...args)
|
|
||||||
clearTimeout(timeout)
|
|
||||||
timeout = setTimeout(next, wait)
|
|
||||||
if (callNow) next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 throttle = (fn: (...args: any[]) => any, delay: number) => {
|
|
||||||
let lastCall = 0
|
|
||||||
return (...args: unknown[]) => {
|
|
||||||
const now = performance.now()
|
|
||||||
if (now - lastCall < delay) return
|
|
||||||
lastCall = now
|
|
||||||
requestAnimationFrame(() => fn(...args))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Split text
|
|
||||||
* @description Split a string into words or characters
|
|
||||||
* @returns string[]
|
|
||||||
*/
|
|
||||||
export const splitText = (text: string, mode = 'words'): string[] => {
|
|
||||||
// Split by words
|
|
||||||
if (mode === 'words') {
|
|
||||||
const words = text
|
|
||||||
.replace(/\\n/g, '\n')
|
|
||||||
.replace(/\s+/g, m => m.includes('\n') ? '\n ' : ' ')
|
|
||||||
.trim()
|
|
||||||
.split(' ')
|
|
||||||
|
|
||||||
return words
|
|
||||||
}
|
|
||||||
// Split by chars
|
|
||||||
else if (mode === 'chars') {
|
|
||||||
const chars = Array.from(text).map(char => char === ' ' ? '\xa0' : char)
|
|
||||||
return chars
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Capitalize first letter
|
|
||||||
*/
|
|
||||||
export const capitalizeFirstLetter = (string: string) => {
|
|
||||||
return string[0].toUpperCase() + string.slice(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a delay
|
|
||||||
*/
|
|
||||||
export const sleep = (milliseconds: number) => {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, milliseconds))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Linear Interpolation
|
|
||||||
*/
|
|
||||||
export const lerp = (start: number, end: number, amount: number): number => {
|
|
||||||
return (1 - amount) * start + amount * end
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-maps a number from one range to another
|
|
||||||
* @param value the incoming value to be converted
|
|
||||||
* @param start1 lower bound of the value's current range
|
|
||||||
* @param stop1 upper bound of the value's current range
|
|
||||||
* @param start2 lower bound of the value's target range
|
|
||||||
* @param stop2 upper bound of the value's target range
|
|
||||||
* @param [withinBounds] constrain the value to the newly mapped range
|
|
||||||
* @return remapped number
|
|
||||||
*/
|
|
||||||
export const map = (n: number, start1: number, stop1: number, start2: number, stop2: number, withinBounds: boolean): number => {
|
|
||||||
const value = (n - start1) / (stop1 - start1) * (stop2 - start2) + start2
|
|
||||||
if (!withinBounds) return value
|
|
||||||
if (start2 < stop2) {
|
|
||||||
return clamp(value, start2, stop2)
|
|
||||||
} else {
|
|
||||||
return clamp(value, stop2, start2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clamp a number
|
|
||||||
*/
|
|
||||||
export const clamp = (num: number, a: number, b: number) => {
|
|
||||||
return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return random elements from an array
|
|
||||||
*/
|
|
||||||
export const getRandomItems = <T> (array: T[], amount: number): T[] => {
|
|
||||||
const shuffled = array.slice()
|
|
||||||
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 a random element from an array
|
|
||||||
*/
|
|
||||||
export const getRandomItem = <T extends Array<unknown>> (array: T): T[0] => {
|
|
||||||
return getRandomItems(array, 1)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll back to top after page transition
|
|
||||||
*/
|
|
||||||
export const scrollToTop = (delay?: number) => {
|
|
||||||
const scroll = () => window.scrollTo(0,0)
|
|
||||||
|
|
||||||
if (delay && delay > 0) {
|
|
||||||
setTimeout(scroll, delay)
|
|
||||||
} else {
|
|
||||||
return scroll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy mailto links to clipboard and show message
|
* Copy mailto links to clipboard and show message
|
||||||
*/
|
*/
|
||||||
|
|||||||
29
packages/utils/actions.ts
Normal file
29
packages/utils/actions.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Debounce a function with a given amount of time
|
||||||
|
* @description For scrolling or other resource demanding behaviors
|
||||||
|
*/
|
||||||
|
export const debounce = (callback: (...args: any[]) => any, wait: number, immediate = false) => {
|
||||||
|
let timeout: ReturnType<typeof setTimeout> | number = 0
|
||||||
|
return (...args: any[]) => {
|
||||||
|
const callNow: boolean = immediate && !timeout
|
||||||
|
const next = () => callback(...args)
|
||||||
|
clearTimeout(timeout)
|
||||||
|
timeout = setTimeout(next, wait)
|
||||||
|
if (callNow) next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 throttle = (fn: (...args: any[]) => any, delay: number) => {
|
||||||
|
let lastCall = 0
|
||||||
|
return (...args: unknown[]) => {
|
||||||
|
const now = performance.now()
|
||||||
|
if (now - lastCall < delay) return
|
||||||
|
lastCall = now
|
||||||
|
requestAnimationFrame(() => fn(...args))
|
||||||
|
}
|
||||||
|
}
|
||||||
19
packages/utils/array.ts
Normal file
19
packages/utils/array.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Return random elements from an array
|
||||||
|
*/
|
||||||
|
export const getRandomItems = <T> (array: T[], amount: number): T[] => {
|
||||||
|
const shuffled = array.slice()
|
||||||
|
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 a random element from an array
|
||||||
|
*/
|
||||||
|
export const getRandomItem = <T extends Array<unknown>> (array: T): T[0] => {
|
||||||
|
return getRandomItems(array, 1)[0]
|
||||||
|
}
|
||||||
17
packages/utils/index.ts
Normal file
17
packages/utils/index.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Create a delay
|
||||||
|
*/
|
||||||
|
export const sleep = (milliseconds: number) => {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, milliseconds))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an object is empty
|
||||||
|
*/
|
||||||
|
export const isEmpty = (obj: Object) => {
|
||||||
|
if (obj === null || obj === undefined) {
|
||||||
|
throw new Error('Error: Given object is not an object')
|
||||||
|
}
|
||||||
|
return Object.keys(obj).length === 0 && obj.constructor === Object
|
||||||
|
}
|
||||||
35
packages/utils/math.ts
Normal file
35
packages/utils/math.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Linear Interpolation
|
||||||
|
*/
|
||||||
|
export const lerp = (start: number, end: number, amount: number): number => {
|
||||||
|
return (1 - amount) * start + amount * end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamp a number
|
||||||
|
*/
|
||||||
|
export const clamp = (num: number, a: number, b: number) => {
|
||||||
|
return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-maps a number from one range to another
|
||||||
|
* @param value the incoming value to be converted
|
||||||
|
* @param start1 lower bound of the value's current range
|
||||||
|
* @param stop1 upper bound of the value's current range
|
||||||
|
* @param start2 lower bound of the value's target range
|
||||||
|
* @param stop2 upper bound of the value's target range
|
||||||
|
* @param [withinBounds] constrain the value to the newly mapped range
|
||||||
|
* @return remapped number
|
||||||
|
*/
|
||||||
|
export const map = (n: number, start1: number, stop1: number, start2: number, stop2: number, withinBounds: boolean): number => {
|
||||||
|
const value = (n - start1) / (stop1 - start1) * (stop2 - start2) + start2
|
||||||
|
if (!withinBounds) return value
|
||||||
|
if (start2 < stop2) {
|
||||||
|
return clamp(value, start2, stop2)
|
||||||
|
} else {
|
||||||
|
return clamp(value, stop2, start2)
|
||||||
|
}
|
||||||
|
}
|
||||||
6
packages/utils/package.json
Normal file
6
packages/utils/package.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "utils",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"module": "index.ts"
|
||||||
|
}
|
||||||
12
packages/utils/scroll.ts
Normal file
12
packages/utils/scroll.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Scroll back to top after page transition
|
||||||
|
*/
|
||||||
|
export const scrollToTop = (delay?: number) => {
|
||||||
|
const scroll = () => window.scrollTo(0,0)
|
||||||
|
|
||||||
|
if (delay && delay > 0) {
|
||||||
|
return setTimeout(scroll, delay)
|
||||||
|
} else {
|
||||||
|
return scroll()
|
||||||
|
}
|
||||||
|
}
|
||||||
6
packages/utils/string.ts
Normal file
6
packages/utils/string.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Capitalize first letter
|
||||||
|
*/
|
||||||
|
export const capitalizeFirstLetter = (string: string) => {
|
||||||
|
return string[0].toUpperCase() + string.slice(1)
|
||||||
|
}
|
||||||
24
packages/utils/text.ts
Normal file
24
packages/utils/text.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Split text
|
||||||
|
* @description Split a string into words or characters
|
||||||
|
* @returns string[]
|
||||||
|
*/
|
||||||
|
export const splitText = (text: string, mode = 'words'): string[] => {
|
||||||
|
// Split by words
|
||||||
|
if (mode === 'words') {
|
||||||
|
const words = text
|
||||||
|
.replace(/\\n/g, '\n')
|
||||||
|
.replace(/\s+/g, m => m.includes('\n') ? '\n ' : ' ')
|
||||||
|
.trim()
|
||||||
|
.split(' ')
|
||||||
|
|
||||||
|
return words
|
||||||
|
}
|
||||||
|
// Split by chars
|
||||||
|
else if (mode === 'chars') {
|
||||||
|
const chars = Array.from(text).map(char => char === ' ' ? '\xa0' : char)
|
||||||
|
return chars
|
||||||
|
}
|
||||||
|
|
||||||
|
return []
|
||||||
|
}
|
||||||
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
@@ -53,6 +53,7 @@ importers:
|
|||||||
tslib: ^2.5.0
|
tslib: ^2.5.0
|
||||||
tweakpane: ^3.1.4
|
tweakpane: ^3.1.4
|
||||||
typescript: ^4.9.5
|
typescript: ^4.9.5
|
||||||
|
utils: workspace:*
|
||||||
vite: ^4.1.1
|
vite: ^4.1.1
|
||||||
dependencies:
|
dependencies:
|
||||||
'@studio-freight/lenis': 0.2.28
|
'@studio-freight/lenis': 0.2.28
|
||||||
@@ -64,6 +65,7 @@ importers:
|
|||||||
sanitize.css: 13.0.0
|
sanitize.css: 13.0.0
|
||||||
swell-js: 3.19.8
|
swell-js: 3.19.8
|
||||||
tweakpane: 3.1.4
|
tweakpane: 3.1.4
|
||||||
|
utils: link:../../packages/utils
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@sveltejs/adapter-auto': 2.0.0_@sveltejs+kit@1.5.3
|
'@sveltejs/adapter-auto': 2.0.0_@sveltejs+kit@1.5.3
|
||||||
'@sveltejs/adapter-cloudflare': 2.0.1_@sveltejs+kit@1.5.3
|
'@sveltejs/adapter-cloudflare': 2.0.1_@sveltejs+kit@1.5.3
|
||||||
|
|||||||
Reference in New Issue
Block a user