forked from phc/website
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
import { useEffect, useState } from 'preact/hooks'
|
|
|
|
export const trottleDebounce = <T extends any[], R>(
|
|
fn: (...args: T) => R,
|
|
delay: number,
|
|
options: { leading?: boolean; trailing?: boolean } = {},
|
|
): ((...args: T) => R | undefined) => {
|
|
let lastCall = 0
|
|
let lastResult: R | undefined
|
|
let lastArgs: T | undefined
|
|
let timeout: NodeJS.Timeout | undefined
|
|
|
|
const leading = options.leading ?? true
|
|
const trailing = options.trailing ?? true
|
|
|
|
return (...args: T): R | undefined => {
|
|
lastArgs = args
|
|
if (leading && Date.now() - lastCall >= delay) {
|
|
lastCall = Date.now()
|
|
lastResult = fn(...args)
|
|
} else {
|
|
if (timeout) {
|
|
clearTimeout(timeout)
|
|
}
|
|
timeout = setTimeout(() => {
|
|
if (trailing && lastArgs) {
|
|
lastCall = Date.now()
|
|
lastResult = fn(...lastArgs)
|
|
}
|
|
}, delay)
|
|
}
|
|
return lastResult
|
|
}
|
|
}
|
|
|
|
export type ClassValue = string | ClassValue[] | Record<string, boolean> | false | undefined
|
|
|
|
export function clsx(...args: ClassValue[]): string {
|
|
return args
|
|
.flatMap(arg => {
|
|
if (typeof arg === 'string') {
|
|
return arg
|
|
} else if (Array.isArray(arg)) {
|
|
return clsx(...arg)
|
|
} else if (typeof arg === 'boolean') {
|
|
return []
|
|
} else if (typeof arg === 'object') {
|
|
return Object.entries(arg).flatMap(([key, value]) => (value ? key : []))
|
|
} else {
|
|
return []
|
|
}
|
|
})
|
|
.join(' ')
|
|
}
|
|
|
|
export const isMobile = () => {
|
|
const [windowWidth, setWindowWidth] = useState(0)
|
|
|
|
useEffect(() => {
|
|
setWindowWidth(window.innerWidth)
|
|
|
|
const handleResize = () => setWindowWidth(window.innerWidth)
|
|
window.addEventListener('resize', handleResize)
|
|
|
|
return () => window.removeEventListener('resize', handleResize)
|
|
}, [])
|
|
|
|
return windowWidth < 1024
|
|
}
|