@take-out/helpers 0.0.39 → 0.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/clipboard/clipboard.cjs +32 -0
- package/dist/cjs/clipboard/clipboard.js +27 -0
- package/dist/cjs/clipboard/clipboard.js.map +6 -0
- package/dist/cjs/clipboard/clipboard.native.js +41 -0
- package/dist/cjs/clipboard/clipboard.native.js.map +6 -0
- package/dist/cjs/clipboard/index.cjs +18 -0
- package/dist/cjs/clipboard/index.js +15 -0
- package/dist/cjs/clipboard/index.js.map +6 -0
- package/dist/cjs/clipboard/index.native.js +20 -0
- package/dist/cjs/clipboard/index.native.js.map +6 -0
- package/dist/cjs/color/extractOpacityFromColor.cjs +34 -0
- package/dist/cjs/color/extractOpacityFromColor.js +29 -0
- package/dist/cjs/color/extractOpacityFromColor.js.map +6 -0
- package/dist/cjs/color/extractOpacityFromColor.native.js +38 -0
- package/dist/cjs/color/extractOpacityFromColor.native.js.map +6 -0
- package/dist/cjs/color/generateColors.cjs +77 -0
- package/dist/cjs/color/generateColors.js +64 -0
- package/dist/cjs/color/generateColors.js.map +6 -0
- package/dist/cjs/color/generateColors.native.js +88 -0
- package/dist/cjs/color/generateColors.native.js.map +6 -0
- package/dist/cjs/color/index.cjs +21 -0
- package/dist/cjs/color/index.js +18 -0
- package/dist/cjs/color/index.js.map +6 -0
- package/dist/cjs/color/index.native.js +26 -0
- package/dist/cjs/color/index.native.js.map +6 -0
- package/dist/cjs/color/lum.cjs +75 -0
- package/dist/cjs/color/lum.js +61 -0
- package/dist/cjs/color/lum.js.map +6 -0
- package/dist/cjs/color/lum.native.js +70 -0
- package/dist/cjs/color/lum.native.js.map +6 -0
- package/dist/cjs/color/toHex.cjs +32 -0
- package/dist/cjs/color/toHex.js +27 -0
- package/dist/cjs/color/toHex.js.map +6 -0
- package/dist/cjs/color/toHex.native.js +33 -0
- package/dist/cjs/color/toHex.native.js.map +6 -0
- package/dist/cjs/index.cjs +4 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.native.js +8 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/number/formatNumber.cjs +9 -1
- package/dist/cjs/number/formatNumber.js +9 -1
- package/dist/cjs/number/formatNumber.js.map +1 -1
- package/dist/cjs/number/formatNumber.native.js +12 -2
- package/dist/cjs/number/formatNumber.native.js.map +1 -1
- package/dist/cjs/time/formatDistanceToNow.cjs +32 -0
- package/dist/cjs/time/formatDistanceToNow.js +24 -0
- package/dist/cjs/time/formatDistanceToNow.js.map +6 -0
- package/dist/cjs/time/formatDistanceToNow.native.js +29 -0
- package/dist/cjs/time/formatDistanceToNow.native.js.map +6 -0
- package/dist/cjs/time/useTimer.cjs +55 -0
- package/dist/cjs/time/useTimer.js +51 -0
- package/dist/cjs/time/useTimer.js.map +6 -0
- package/dist/cjs/time/useTimer.native.js +67 -0
- package/dist/cjs/time/useTimer.native.js.map +6 -0
- package/dist/esm/clipboard/clipboard.js +11 -0
- package/dist/esm/clipboard/clipboard.js.map +6 -0
- package/dist/esm/clipboard/clipboard.mjs +9 -0
- package/dist/esm/clipboard/clipboard.mjs.map +1 -0
- package/dist/esm/clipboard/clipboard.native.js +11 -0
- package/dist/esm/clipboard/clipboard.native.js.map +1 -0
- package/dist/esm/clipboard/index.js +2 -0
- package/dist/esm/clipboard/index.js.map +6 -0
- package/dist/esm/clipboard/index.mjs +2 -0
- package/dist/esm/clipboard/index.mjs.map +1 -0
- package/dist/esm/clipboard/index.native.js +2 -0
- package/dist/esm/clipboard/index.native.js.map +1 -0
- package/dist/esm/color/extractOpacityFromColor.js +13 -0
- package/dist/esm/color/extractOpacityFromColor.js.map +6 -0
- package/dist/esm/color/extractOpacityFromColor.mjs +11 -0
- package/dist/esm/color/extractOpacityFromColor.mjs.map +1 -0
- package/dist/esm/color/extractOpacityFromColor.native.js +15 -0
- package/dist/esm/color/extractOpacityFromColor.native.js.map +1 -0
- package/dist/esm/color/generateColors.js +48 -0
- package/dist/esm/color/generateColors.js.map +6 -0
- package/dist/esm/color/generateColors.mjs +54 -0
- package/dist/esm/color/generateColors.mjs.map +1 -0
- package/dist/esm/color/generateColors.native.js +52 -0
- package/dist/esm/color/generateColors.native.js.map +1 -0
- package/dist/esm/color/index.js +5 -0
- package/dist/esm/color/index.js.map +6 -0
- package/dist/esm/color/index.mjs +5 -0
- package/dist/esm/color/index.mjs.map +1 -0
- package/dist/esm/color/index.native.js +5 -0
- package/dist/esm/color/index.native.js.map +1 -0
- package/dist/esm/color/lum.js +45 -0
- package/dist/esm/color/lum.js.map +6 -0
- package/dist/esm/color/lum.mjs +52 -0
- package/dist/esm/color/lum.mjs.map +1 -0
- package/dist/esm/color/lum.native.js +57 -0
- package/dist/esm/color/lum.native.js.map +1 -0
- package/dist/esm/color/toHex.js +11 -0
- package/dist/esm/color/toHex.js.map +6 -0
- package/dist/esm/color/toHex.mjs +8 -0
- package/dist/esm/color/toHex.mjs.map +1 -0
- package/dist/esm/color/toHex.native.js +8 -0
- package/dist/esm/color/toHex.native.js.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +4 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +4 -0
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/number/formatNumber.js +9 -1
- package/dist/esm/number/formatNumber.js.map +1 -1
- package/dist/esm/number/formatNumber.mjs +7 -1
- package/dist/esm/number/formatNumber.mjs.map +1 -1
- package/dist/esm/number/formatNumber.native.js +7 -1
- package/dist/esm/number/formatNumber.native.js.map +1 -1
- package/dist/esm/time/formatDistanceToNow.js +8 -0
- package/dist/esm/time/formatDistanceToNow.js.map +6 -0
- package/dist/esm/time/formatDistanceToNow.mjs +9 -0
- package/dist/esm/time/formatDistanceToNow.mjs.map +1 -0
- package/dist/esm/time/formatDistanceToNow.native.js +10 -0
- package/dist/esm/time/formatDistanceToNow.native.js.map +1 -0
- package/dist/esm/time/useTimer.js +35 -0
- package/dist/esm/time/useTimer.js.map +6 -0
- package/dist/esm/time/useTimer.mjs +32 -0
- package/dist/esm/time/useTimer.mjs.map +1 -0
- package/dist/esm/time/useTimer.native.js +40 -0
- package/dist/esm/time/useTimer.native.js.map +1 -0
- package/package.json +2 -1
- package/src/clipboard/clipboard.native.ts +10 -0
- package/src/clipboard/clipboard.ts +8 -0
- package/src/clipboard/index.ts +1 -0
- package/src/color/extractOpacityFromColor.ts +18 -0
- package/src/color/generateColors.ts +72 -0
- package/src/color/index.ts +4 -0
- package/src/color/lum.ts +78 -0
- package/src/color/toHex.ts +10 -0
- package/src/index.ts +8 -0
- package/src/number/formatNumber.ts +15 -0
- package/src/time/formatDistanceToNow.ts +17 -0
- package/src/time/useTimer.ts +80 -0
- package/types/clipboard/clipboard.d.ts +3 -0
- package/types/clipboard/clipboard.d.ts.map +11 -0
- package/types/clipboard/clipboard.native.d.ts +3 -0
- package/types/clipboard/clipboard.native.d.ts.map +11 -0
- package/types/clipboard/index.d.ts +3 -0
- package/types/clipboard/index.d.ts.map +11 -0
- package/types/color/extractOpacityFromColor.d.ts +3 -0
- package/types/color/extractOpacityFromColor.d.ts.map +13 -0
- package/types/color/generateColors.d.ts +11 -0
- package/types/color/generateColors.d.ts.map +11 -0
- package/types/color/index.d.ts +6 -0
- package/types/color/index.d.ts.map +11 -0
- package/types/color/lum.d.ts +3 -0
- package/types/color/lum.d.ts.map +13 -0
- package/types/color/toHex.d.ts +6 -0
- package/types/color/toHex.d.ts.map +13 -0
- package/types/index.d.ts +6 -0
- package/types/index.d.ts.map +2 -2
- package/types/number/formatNumber.d.ts +2 -0
- package/types/number/formatNumber.d.ts.map +5 -3
- package/types/time/formatDistanceToNow.d.ts +3 -0
- package/types/time/formatDistanceToNow.d.ts.map +13 -0
- package/types/time/useTimer.d.ts +11 -0
- package/types/time/useTimer.d.ts.map +14 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { toHex } from './toHex'
|
|
2
|
+
|
|
3
|
+
type ColorGenOptions = {
|
|
4
|
+
numColors?: number
|
|
5
|
+
minSaturation?: number
|
|
6
|
+
maxSaturation?: number
|
|
7
|
+
minLightness?: number
|
|
8
|
+
maxLightness?: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// convert HSL to hex
|
|
12
|
+
function hslToHex(h: number, s: number, l: number): string {
|
|
13
|
+
// normalize values
|
|
14
|
+
h = h / 360
|
|
15
|
+
s = s / 100
|
|
16
|
+
l = l / 100
|
|
17
|
+
|
|
18
|
+
const a = s * Math.min(l, 1 - l)
|
|
19
|
+
const f = (n: number) => {
|
|
20
|
+
const k = (n + h * 12) % 12
|
|
21
|
+
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)
|
|
22
|
+
return Math.round(255 * color)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const r = f(0)
|
|
26
|
+
const g = f(8)
|
|
27
|
+
const b = f(4)
|
|
28
|
+
|
|
29
|
+
return toHex((r << 16) | (g << 8) | b)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const generateColors = ({
|
|
33
|
+
numColors = 32,
|
|
34
|
+
minSaturation = 45,
|
|
35
|
+
maxSaturation = 85,
|
|
36
|
+
minLightness = 45,
|
|
37
|
+
maxLightness = 65,
|
|
38
|
+
}: ColorGenOptions = {}): string[] => {
|
|
39
|
+
const colors: string[] = []
|
|
40
|
+
|
|
41
|
+
// Define hue ranges for color groups
|
|
42
|
+
const hueRanges = [
|
|
43
|
+
[0, 30], // reds
|
|
44
|
+
[30, 60], // oranges
|
|
45
|
+
[60, 90], // yellows
|
|
46
|
+
[90, 150], // greens
|
|
47
|
+
[150, 180], // teals
|
|
48
|
+
[180, 240], // blues
|
|
49
|
+
[240, 270], // purples
|
|
50
|
+
[270, 330], // magentas
|
|
51
|
+
[330, 360], // pink-reds
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
// Calculate colors per group
|
|
55
|
+
const colorsPerGroup = Math.ceil(numColors / hueRanges.length)
|
|
56
|
+
|
|
57
|
+
hueRanges.forEach(([start, end]) => {
|
|
58
|
+
const hueStep = (end! - start!) / colorsPerGroup
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < colorsPerGroup; i++) {
|
|
61
|
+
if (colors.length >= numColors) break
|
|
62
|
+
|
|
63
|
+
const hue = start! + hueStep * i
|
|
64
|
+
const saturation = minSaturation + Math.random() * (maxSaturation - minSaturation)
|
|
65
|
+
const lightness = minLightness + Math.random() * (maxLightness - minLightness)
|
|
66
|
+
|
|
67
|
+
colors.push(hslToHex(hue, saturation, lightness))
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
return colors
|
|
72
|
+
}
|
package/src/color/lum.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Helper to ensure color string is valid (simple fallback implementation)
|
|
2
|
+
const validColor = (color: string) => color
|
|
3
|
+
|
|
4
|
+
export function lum(color: string, luminance = 0.5): string {
|
|
5
|
+
// handle hsl/hsla
|
|
6
|
+
if (color.startsWith('hsl')) {
|
|
7
|
+
const match = color.match(/hsla?\((\d+),\s*(\d+)%,\s*(\d+)%(?:,\s*([\d.]+))?\)/)
|
|
8
|
+
if (match) {
|
|
9
|
+
const [, h, s, , a] = match
|
|
10
|
+
const newL = Math.round(luminance * 100)
|
|
11
|
+
if (a) {
|
|
12
|
+
return validColor(`hsla(${h}, ${s}%, ${newL}%, ${a})`)
|
|
13
|
+
}
|
|
14
|
+
return validColor(`hsl(${h}, ${s}%, ${newL}%)`)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// handle hex - convert to hsl and adjust
|
|
19
|
+
if (color.startsWith('#')) {
|
|
20
|
+
let hex = color.slice(1)
|
|
21
|
+
|
|
22
|
+
// expand shorthand hex
|
|
23
|
+
if (hex.length === 3) {
|
|
24
|
+
hex = hex
|
|
25
|
+
.split('')
|
|
26
|
+
.map((c) => c + c)
|
|
27
|
+
.join('')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// convert hex to rgb
|
|
31
|
+
const r = parseInt(hex.slice(0, 2), 16) / 255
|
|
32
|
+
const g = parseInt(hex.slice(2, 4), 16) / 255
|
|
33
|
+
const b = parseInt(hex.slice(4, 6), 16) / 255
|
|
34
|
+
|
|
35
|
+
// convert rgb to hsl
|
|
36
|
+
const max = Math.max(r, g, b)
|
|
37
|
+
const min = Math.min(r, g, b)
|
|
38
|
+
const l = (max + min) / 2
|
|
39
|
+
|
|
40
|
+
if (max === min) {
|
|
41
|
+
// achromatic
|
|
42
|
+
const newL = Math.round(luminance * 100)
|
|
43
|
+
return validColor(`hsl(0, 0%, ${newL}%)`)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const d = max - min
|
|
47
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
|
|
48
|
+
|
|
49
|
+
let h: number
|
|
50
|
+
switch (max) {
|
|
51
|
+
case r:
|
|
52
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6
|
|
53
|
+
break
|
|
54
|
+
case g:
|
|
55
|
+
h = ((b - r) / d + 2) / 6
|
|
56
|
+
break
|
|
57
|
+
case b:
|
|
58
|
+
h = ((r - g) / d + 4) / 6
|
|
59
|
+
break
|
|
60
|
+
default:
|
|
61
|
+
h = 0
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const newH = Math.round(h * 360)
|
|
65
|
+
const newS = Math.round(s * 100)
|
|
66
|
+
const newL = Math.round(luminance * 100)
|
|
67
|
+
|
|
68
|
+
// preserve alpha if present
|
|
69
|
+
if (hex.length === 8) {
|
|
70
|
+
const alpha = parseInt(hex.slice(6, 8), 16) / 255
|
|
71
|
+
return validColor(`hsla(${newH}, ${newS}%, ${newL}%, ${alpha.toFixed(2)})`)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return validColor(`hsl(${newH}, ${newS}%, ${newL}%)`)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return validColor(color)
|
|
78
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// simple helper to ensure we always get a valid 6-digit hex color from a number
|
|
2
|
+
export function toHex(value: number): string {
|
|
3
|
+
// ensure we get a 6-digit hex string with leading zeros if needed
|
|
4
|
+
return '#' + value.toString(16).padStart(6, '0')
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// generate a random hex color
|
|
8
|
+
export function randomHex(): string {
|
|
9
|
+
return toHex(Math.floor(Math.random() * 0xffffff))
|
|
10
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,12 @@ export * from './async/useLazyValue'
|
|
|
23
23
|
|
|
24
24
|
// browser
|
|
25
25
|
export * from './browser/clearIndexedDB'
|
|
26
|
+
|
|
27
|
+
// clipboard
|
|
28
|
+
export * from './clipboard'
|
|
29
|
+
|
|
30
|
+
// color
|
|
31
|
+
export * from './color'
|
|
26
32
|
export * from './browser/isActiveElementFormField'
|
|
27
33
|
export * from './browser/openPopup'
|
|
28
34
|
|
|
@@ -92,7 +98,9 @@ export * from './string/truncateList'
|
|
|
92
98
|
// time
|
|
93
99
|
export * from './time/formatDate'
|
|
94
100
|
export * from './time/formatDateRelative'
|
|
101
|
+
export * from './time/formatDistanceToNow'
|
|
95
102
|
export * from './time/time'
|
|
103
|
+
export * from './time/useTimer'
|
|
96
104
|
|
|
97
105
|
// types
|
|
98
106
|
export type * from './types/NullToOptional'
|
|
@@ -38,3 +38,18 @@ export function formatCount(value: number): string {
|
|
|
38
38
|
forceCompact: value >= 1000,
|
|
39
39
|
})
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
export function formatReactionCount(value: number | string): string {
|
|
43
|
+
if (typeof value === 'string') return value
|
|
44
|
+
if (value >= 1000000) {
|
|
45
|
+
return `${(value / 1000000).toFixed(1)}M`
|
|
46
|
+
}
|
|
47
|
+
if (value >= 1000) {
|
|
48
|
+
return `${(value / 1000).toFixed(1)}K`
|
|
49
|
+
}
|
|
50
|
+
return value.toString()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function formatPhoneNumber(value: string): string {
|
|
54
|
+
return value
|
|
55
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function formatDistanceToNow(timestamp: number): string {
|
|
2
|
+
const now = Date.now()
|
|
3
|
+
const diff = now - timestamp
|
|
4
|
+
|
|
5
|
+
const minutes = Math.floor(diff / 60000)
|
|
6
|
+
const hours = Math.floor(diff / 3600000)
|
|
7
|
+
const days = Math.floor(diff / 86400000)
|
|
8
|
+
|
|
9
|
+
if (minutes < 1) return 'just now'
|
|
10
|
+
if (minutes < 60) return `${minutes}m`
|
|
11
|
+
if (hours < 24) return `${hours}h`
|
|
12
|
+
if (days < 7) return `${days}d`
|
|
13
|
+
if (days < 30) return `${Math.floor(days / 7)}w`
|
|
14
|
+
if (days < 365) return `${Math.floor(days / 30)}mo`
|
|
15
|
+
|
|
16
|
+
return `${Math.floor(days / 365)}y`
|
|
17
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
|
|
2
|
+
|
|
3
|
+
type UseTimerReturn = {
|
|
4
|
+
count: number
|
|
5
|
+
start: (time: number, start: boolean) => void
|
|
6
|
+
pause: () => void
|
|
7
|
+
resume: () => void
|
|
8
|
+
clear: () => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const useTimer = (): UseTimerReturn => {
|
|
12
|
+
const [timerCount, setTimer] = useState<number>(30)
|
|
13
|
+
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)
|
|
14
|
+
|
|
15
|
+
const clearTimer = useCallback(() => {
|
|
16
|
+
if (intervalRef.current) {
|
|
17
|
+
clearInterval(intervalRef.current)
|
|
18
|
+
intervalRef.current = null
|
|
19
|
+
}
|
|
20
|
+
}, [])
|
|
21
|
+
|
|
22
|
+
const resetTimer = useCallback(
|
|
23
|
+
(time: number, start: boolean) => {
|
|
24
|
+
setTimer(time)
|
|
25
|
+
clearTimer()
|
|
26
|
+
if (start) {
|
|
27
|
+
intervalRef.current = setInterval(() => {
|
|
28
|
+
setTimer((lastTimerCount) => {
|
|
29
|
+
if (lastTimerCount <= 1) {
|
|
30
|
+
clearInterval(intervalRef.current!)
|
|
31
|
+
intervalRef.current = null
|
|
32
|
+
return 0
|
|
33
|
+
}
|
|
34
|
+
return lastTimerCount - 1
|
|
35
|
+
})
|
|
36
|
+
}, 1000)
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
[clearTimer]
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const pauseTimer = useCallback(() => {
|
|
43
|
+
clearTimer()
|
|
44
|
+
}, [clearTimer])
|
|
45
|
+
|
|
46
|
+
const resumeTimer = useCallback(() => {
|
|
47
|
+
if (!intervalRef.current) {
|
|
48
|
+
intervalRef.current = setInterval(() => {
|
|
49
|
+
setTimer((lastTimerCount) => {
|
|
50
|
+
if (lastTimerCount <= 1) {
|
|
51
|
+
clearInterval(intervalRef.current!)
|
|
52
|
+
intervalRef.current = null
|
|
53
|
+
return 0
|
|
54
|
+
}
|
|
55
|
+
return lastTimerCount - 1
|
|
56
|
+
})
|
|
57
|
+
}, 1000)
|
|
58
|
+
}
|
|
59
|
+
}, [])
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
return () => {
|
|
63
|
+
if (intervalRef.current) {
|
|
64
|
+
clearInterval(intervalRef.current)
|
|
65
|
+
intervalRef.current = null
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}, [])
|
|
69
|
+
|
|
70
|
+
return useMemo(
|
|
71
|
+
() => ({
|
|
72
|
+
count: timerCount,
|
|
73
|
+
start: resetTimer,
|
|
74
|
+
pause: pauseTimer,
|
|
75
|
+
resume: resumeTimer,
|
|
76
|
+
clear: clearTimer,
|
|
77
|
+
}),
|
|
78
|
+
[timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer]
|
|
79
|
+
)
|
|
80
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": "AAAA,OAAO,cAAM,wBAA6B",
|
|
3
|
+
"names": [],
|
|
4
|
+
"sources": [
|
|
5
|
+
"src/clipboard/clipboard.ts"
|
|
6
|
+
],
|
|
7
|
+
"sourcesContent": [
|
|
8
|
+
"export const getClipboardText = async (): Promise<string | null> => {\n try {\n const text = await navigator.clipboard.readText()\n return text\n } catch {\n return null\n }\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"version": 3
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": "AAEA,OAAO,cAAM,wBAA6B",
|
|
3
|
+
"names": [],
|
|
4
|
+
"sources": [
|
|
5
|
+
"src/clipboard/clipboard.native.ts"
|
|
6
|
+
],
|
|
7
|
+
"sourcesContent": [
|
|
8
|
+
"import * as Clipboard from 'expo-clipboard'\n\nexport const getClipboardText = async (): Promise<string | null> => {\n try {\n const text = await Clipboard.getStringAsync()\n return text\n } catch {\n return null\n }\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"version": 3
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": "AAAA,OAAO,iBAAS,wBAAwBA",
|
|
3
|
+
"names": [
|
|
4
|
+
"color: string"
|
|
5
|
+
],
|
|
6
|
+
"sources": [
|
|
7
|
+
"src/color/extractOpacityFromColor.ts"
|
|
8
|
+
],
|
|
9
|
+
"sourcesContent": [
|
|
10
|
+
"export function extractOpacityFromColor(color: string): number {\n if (color === 'transparent') return 0\n\n // Match hex codes like #RRGGBBAA or #RRGGBB\n const hexMatch = color.match(/^#([0-9a-fA-F]{6})([0-9a-fA-F]{2})?$/)\n if (hexMatch) {\n const [, _rgb, alphaHex] = hexMatch\n if (alphaHex) {\n const alpha = parseInt(alphaHex, 16)\n return alpha / 255\n }\n return 1 // No alpha specified → fully opaque\n }\n\n // Could expand this to support rgba(), hsl(), etc. if needed\n console.warn(`Unsupported color format: ${color}`)\n return 1\n}\n"
|
|
11
|
+
],
|
|
12
|
+
"version": 3
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type ColorGenOptions = {
|
|
2
|
+
numColors?: number;
|
|
3
|
+
minSaturation?: number;
|
|
4
|
+
maxSaturation?: number;
|
|
5
|
+
minLightness?: number;
|
|
6
|
+
maxLightness?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const generateColors: ({ numColors, minSaturation, maxSaturation, minLightness, maxLightness }?: ColorGenOptions) => string[];
|
|
9
|
+
export {};
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=generateColors.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": "KAEK,kBAAkB;CACrB;CACA;CACA;CACA;CACA;AACD;AAuBD,OAAO,cAAM,iBAAkB,EAC7B,WACA,eACA,eACA,cACA,cACgB,GAAf",
|
|
3
|
+
"names": [],
|
|
4
|
+
"sources": [
|
|
5
|
+
"src/color/generateColors.ts"
|
|
6
|
+
],
|
|
7
|
+
"sourcesContent": [
|
|
8
|
+
"import { toHex } from './toHex'\n\ntype ColorGenOptions = {\n numColors?: number\n minSaturation?: number\n maxSaturation?: number\n minLightness?: number\n maxLightness?: number\n}\n\n// convert HSL to hex\nfunction hslToHex(h: number, s: number, l: number): string {\n // normalize values\n h = h / 360\n s = s / 100\n l = l / 100\n\n const a = s * Math.min(l, 1 - l)\n const f = (n: number) => {\n const k = (n + h * 12) % 12\n const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\n return Math.round(255 * color)\n }\n\n const r = f(0)\n const g = f(8)\n const b = f(4)\n\n return toHex((r << 16) | (g << 8) | b)\n}\n\nexport const generateColors = ({\n numColors = 32,\n minSaturation = 45,\n maxSaturation = 85,\n minLightness = 45,\n maxLightness = 65,\n}: ColorGenOptions = {}): string[] => {\n const colors: string[] = []\n\n // Define hue ranges for color groups\n const hueRanges = [\n [0, 30], // reds\n [30, 60], // oranges\n [60, 90], // yellows\n [90, 150], // greens\n [150, 180], // teals\n [180, 240], // blues\n [240, 270], // purples\n [270, 330], // magentas\n [330, 360], // pink-reds\n ]\n\n // Calculate colors per group\n const colorsPerGroup = Math.ceil(numColors / hueRanges.length)\n\n hueRanges.forEach(([start, end]) => {\n const hueStep = (end! - start!) / colorsPerGroup\n\n for (let i = 0; i < colorsPerGroup; i++) {\n if (colors.length >= numColors) break\n\n const hue = start! + hueStep * i\n const saturation = minSaturation + Math.random() * (maxSaturation - minSaturation)\n const lightness = minLightness + Math.random() * (maxLightness - minLightness)\n\n colors.push(hslToHex(hue, saturation, lightness))\n }\n })\n\n return colors\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"version": 3
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc",
|
|
3
|
+
"names": [],
|
|
4
|
+
"sources": [
|
|
5
|
+
"src/color/index.ts"
|
|
6
|
+
],
|
|
7
|
+
"sourcesContent": [
|
|
8
|
+
"export * from './toHex'\nexport * from './generateColors'\nexport * from './lum'\nexport * from './extractOpacityFromColor'\n"
|
|
9
|
+
],
|
|
10
|
+
"version": 3
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": "AAGA,OAAO,iBAAS,IAAIA,eAAe",
|
|
3
|
+
"names": [
|
|
4
|
+
"color: string"
|
|
5
|
+
],
|
|
6
|
+
"sources": [
|
|
7
|
+
"src/color/lum.ts"
|
|
8
|
+
],
|
|
9
|
+
"sourcesContent": [
|
|
10
|
+
"// Helper to ensure color string is valid (simple fallback implementation)\nconst validColor = (color: string) => color\n\nexport function lum(color: string, luminance = 0.5): string {\n // handle hsl/hsla\n if (color.startsWith('hsl')) {\n const match = color.match(/hsla?\\((\\d+),\\s*(\\d+)%,\\s*(\\d+)%(?:,\\s*([\\d.]+))?\\)/)\n if (match) {\n const [, h, s, , a] = match\n const newL = Math.round(luminance * 100)\n if (a) {\n return validColor(`hsla(${h}, ${s}%, ${newL}%, ${a})`)\n }\n return validColor(`hsl(${h}, ${s}%, ${newL}%)`)\n }\n }\n\n // handle hex - convert to hsl and adjust\n if (color.startsWith('#')) {\n let hex = color.slice(1)\n\n // expand shorthand hex\n if (hex.length === 3) {\n hex = hex\n .split('')\n .map((c) => c + c)\n .join('')\n }\n\n // convert hex to rgb\n const r = parseInt(hex.slice(0, 2), 16) / 255\n const g = parseInt(hex.slice(2, 4), 16) / 255\n const b = parseInt(hex.slice(4, 6), 16) / 255\n\n // convert rgb to hsl\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n const l = (max + min) / 2\n\n if (max === min) {\n // achromatic\n const newL = Math.round(luminance * 100)\n return validColor(`hsl(0, 0%, ${newL}%)`)\n }\n\n const d = max - min\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)\n\n let h: number\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n break\n case g:\n h = ((b - r) / d + 2) / 6\n break\n case b:\n h = ((r - g) / d + 4) / 6\n break\n default:\n h = 0\n }\n\n const newH = Math.round(h * 360)\n const newS = Math.round(s * 100)\n const newL = Math.round(luminance * 100)\n\n // preserve alpha if present\n if (hex.length === 8) {\n const alpha = parseInt(hex.slice(6, 8), 16) / 255\n return validColor(`hsla(${newH}, ${newS}%, ${newL}%, ${alpha.toFixed(2)})`)\n }\n\n return validColor(`hsl(${newH}, ${newS}%, ${newL}%)`)\n }\n\n return validColor(color)\n}\n"
|
|
11
|
+
],
|
|
12
|
+
"version": 3
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": ";AACA,OAAO,iBAAS,MAAMA;;AAMtB,OAAO,iBAAS",
|
|
3
|
+
"names": [
|
|
4
|
+
"value: number"
|
|
5
|
+
],
|
|
6
|
+
"sources": [
|
|
7
|
+
"src/color/toHex.ts"
|
|
8
|
+
],
|
|
9
|
+
"sourcesContent": [
|
|
10
|
+
"// simple helper to ensure we always get a valid 6-digit hex color from a number\nexport function toHex(value: number): string {\n // ensure we get a 6-digit hex string with leading zeros if needed\n return '#' + value.toString(16).padStart(6, '0')\n}\n\n// generate a random hex color\nexport function randomHex(): string {\n return toHex(Math.floor(Math.random() * 0xffffff))\n}\n"
|
|
11
|
+
],
|
|
12
|
+
"version": 3
|
|
13
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export * from "./async/useLazyMount";
|
|
|
19
19
|
export * from "./async/useLazyValue";
|
|
20
20
|
// browser
|
|
21
21
|
export * from "./browser/clearIndexedDB";
|
|
22
|
+
// clipboard
|
|
23
|
+
export * from "./clipboard";
|
|
24
|
+
// color
|
|
25
|
+
export * from "./color";
|
|
22
26
|
export * from "./browser/isActiveElementFormField";
|
|
23
27
|
export * from "./browser/openPopup";
|
|
24
28
|
// debug
|
|
@@ -75,7 +79,9 @@ export * from "./string/truncateList";
|
|
|
75
79
|
// time
|
|
76
80
|
export * from "./time/formatDate";
|
|
77
81
|
export * from "./time/formatDateRelative";
|
|
82
|
+
export * from "./time/formatDistanceToNow";
|
|
78
83
|
export * from "./time/time";
|
|
84
|
+
export * from "./time/useTimer";
|
|
79
85
|
// types
|
|
80
86
|
export type * from "./types/NullToOptional";
|
|
81
87
|
export type * from "./types/object";
|
package/types/index.d.ts.map
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"mappings": "AAAA,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;;AAGd,cAAc;;;AAKd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;;AAGd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,SAAS,uBAAuB;AAChC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc,qBAAqB;;AAGnC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,mBAAmB;AACnB,mBAAmB;AACnB,mBAAmB;AACnB,mBAAmB;AACnB,mBAAmB;;AAGnB,cAAc;AACd,cAAc",
|
|
2
|
+
"mappings": "AAAA,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;;AAGd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;;AAGd,cAAc;;;AAKd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;;AAGd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,SAAS,uBAAuB;AAChC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc,qBAAqB;;AAGnC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;;AAGd,mBAAmB;AACnB,mBAAmB;AACnB,mBAAmB;AACnB,mBAAmB;AACnB,mBAAmB;;AAGnB,cAAc;AACd,cAAc",
|
|
3
3
|
"names": [],
|
|
4
4
|
"sources": [
|
|
5
5
|
"src/index.ts"
|
|
6
6
|
],
|
|
7
7
|
"sourcesContent": [
|
|
8
|
-
"export * from './constants'\nexport * from './emitter'\n\n// array\nexport * from './array/getRandomItem'\nexport * from './array/takeLast'\nexport * from './array/uniqBy'\n\n// assert\nexport * from './assert'\n\n// async\nexport * from './async/abortable'\nexport * from './async/asyncContext'\nexport * from './async/idle'\nexport * from './async/interval'\nexport * from './async/isAborted'\nexport * from './async/sleep'\nexport * from './async/useAsync'\nexport * from './async/useAsyncEffect'\nexport * from './async/useLazyMount'\nexport * from './async/useLazyValue'\n\n// browser\nexport * from './browser/clearIndexedDB'\nexport * from './browser/isActiveElementFormField'\nexport * from './browser/openPopup'\n\n// debug\nexport * from './debug/debugLog'\nexport * from './debug/debugUseState'\n\n// ensure\nexport * from './ensure/ensure'\nexport * from './ensure/ensureOne'\n\n// error\nexport * from './error/errors'\n\n// files\n\n// function\nexport * from './function/emptyFn'\nexport * from './function/identityFn'\nexport * from './function/throttle'\n\n// global\nexport * from './global/globalEffect'\nexport * from './global/globalValue'\n\n// number\nexport * from './number/formatNumber'\n\n// object\nexport * from './object/decorateObject'\nexport * from './object/isEqualDeep'\nexport { isEqualDeepLite } from './object/isEqualDeep'\nexport * from './object/isEqualIdentity'\nexport * from './object/isEqualJSON'\nexport * from './object/isEqualNever'\nexport * from './object/mapObject'\nexport * from './object/object'\nexport * from './object/objectUniqueKey'\n\n// react\nexport * from './react/createGlobalContext'\nexport * from './react/getCurrentComponentStack'\n\n// storage\nexport * from './storage/createStorage'\nexport * from './storage/driver'\nexport type { StorageDriver } from './storage/types'\n\n// server\nexport * from './server/ensureEnv'\nexport * from './server/getHeaders'\nexport * from './server/prettyPrintRequest'\nexport * from './server/prettyPrintResponse'\nexport * from './server/streamToString'\n\n// string\nexport * from './string/dedent'\nexport * from './string/ellipsis'\nexport * from './string/hash'\nexport * from './string/insertAtIndex'\nexport * from './string/pickLast'\nexport * from './string/pluralize'\nexport * from './string/randomId'\nexport * from './string/slugify'\nexport * from './string/truncateList'\n\n// time\nexport * from './time/formatDate'\nexport * from './time/formatDateRelative'\nexport * from './time/time'\n\n// types\nexport type * from './types/NullToOptional'\nexport type * from './types/object'\nexport type * from './types/react'\nexport type * from './types/timer'\nexport type * from './types/tuple'\n\n// url\nexport * from './url/urlSanitize'\nexport * from './url/urlValidate'\n"
|
|
8
|
+
"export * from './constants'\nexport * from './emitter'\n\n// array\nexport * from './array/getRandomItem'\nexport * from './array/takeLast'\nexport * from './array/uniqBy'\n\n// assert\nexport * from './assert'\n\n// async\nexport * from './async/abortable'\nexport * from './async/asyncContext'\nexport * from './async/idle'\nexport * from './async/interval'\nexport * from './async/isAborted'\nexport * from './async/sleep'\nexport * from './async/useAsync'\nexport * from './async/useAsyncEffect'\nexport * from './async/useLazyMount'\nexport * from './async/useLazyValue'\n\n// browser\nexport * from './browser/clearIndexedDB'\n\n// clipboard\nexport * from './clipboard'\n\n// color\nexport * from './color'\nexport * from './browser/isActiveElementFormField'\nexport * from './browser/openPopup'\n\n// debug\nexport * from './debug/debugLog'\nexport * from './debug/debugUseState'\n\n// ensure\nexport * from './ensure/ensure'\nexport * from './ensure/ensureOne'\n\n// error\nexport * from './error/errors'\n\n// files\n\n// function\nexport * from './function/emptyFn'\nexport * from './function/identityFn'\nexport * from './function/throttle'\n\n// global\nexport * from './global/globalEffect'\nexport * from './global/globalValue'\n\n// number\nexport * from './number/formatNumber'\n\n// object\nexport * from './object/decorateObject'\nexport * from './object/isEqualDeep'\nexport { isEqualDeepLite } from './object/isEqualDeep'\nexport * from './object/isEqualIdentity'\nexport * from './object/isEqualJSON'\nexport * from './object/isEqualNever'\nexport * from './object/mapObject'\nexport * from './object/object'\nexport * from './object/objectUniqueKey'\n\n// react\nexport * from './react/createGlobalContext'\nexport * from './react/getCurrentComponentStack'\n\n// storage\nexport * from './storage/createStorage'\nexport * from './storage/driver'\nexport type { StorageDriver } from './storage/types'\n\n// server\nexport * from './server/ensureEnv'\nexport * from './server/getHeaders'\nexport * from './server/prettyPrintRequest'\nexport * from './server/prettyPrintResponse'\nexport * from './server/streamToString'\n\n// string\nexport * from './string/dedent'\nexport * from './string/ellipsis'\nexport * from './string/hash'\nexport * from './string/insertAtIndex'\nexport * from './string/pickLast'\nexport * from './string/pluralize'\nexport * from './string/randomId'\nexport * from './string/slugify'\nexport * from './string/truncateList'\n\n// time\nexport * from './time/formatDate'\nexport * from './time/formatDateRelative'\nexport * from './time/formatDistanceToNow'\nexport * from './time/time'\nexport * from './time/useTimer'\n\n// types\nexport type * from './types/NullToOptional'\nexport type * from './types/object'\nexport type * from './types/react'\nexport type * from './types/timer'\nexport type * from './types/tuple'\n\n// url\nexport * from './url/urlSanitize'\nexport * from './url/urlValidate'\n"
|
|
9
9
|
],
|
|
10
10
|
"version": 3
|
|
11
11
|
}
|
|
@@ -7,5 +7,7 @@ export interface FormatNumberOptions {
|
|
|
7
7
|
export declare function formatNumber(value: number, options?: FormatNumberOptions): string;
|
|
8
8
|
export declare function abbreviateNumber(value: number): string;
|
|
9
9
|
export declare function formatCount(value: number): string;
|
|
10
|
+
export declare function formatReactionCount(value: number | string): string;
|
|
11
|
+
export declare function formatPhoneNumber(value: string): string;
|
|
10
12
|
|
|
11
13
|
//# sourceMappingURL=formatNumber.d.ts.map
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
"mappings": "AAAA,iBAAiB,oBAAoB;CACnC;CACA;CACA;CACA;AACD;AAED,OAAO,iBAAS,aAAaA,eAAeC,UAAS;AAuBrD,OAAO,iBAAS,iBAAiBD;AAIjC,OAAO,iBAAS,YAAYA",
|
|
2
|
+
"mappings": "AAAA,iBAAiB,oBAAoB;CACnC;CACA;CACA;CACA;AACD;AAED,OAAO,iBAAS,aAAaA,eAAeC,UAAS;AAuBrD,OAAO,iBAAS,iBAAiBD;AAIjC,OAAO,iBAAS,YAAYA;AAO5B,OAAO,iBAAS,oBAAoBE;AAWpC,OAAO,iBAAS,kBAAkBC",
|
|
3
3
|
"names": [
|
|
4
4
|
"value: number",
|
|
5
|
-
"options: FormatNumberOptions"
|
|
5
|
+
"options: FormatNumberOptions",
|
|
6
|
+
"value: number | string",
|
|
7
|
+
"value: string"
|
|
6
8
|
],
|
|
7
9
|
"sources": [
|
|
8
10
|
"src/number/formatNumber.ts"
|
|
9
11
|
],
|
|
10
12
|
"sourcesContent": [
|
|
11
|
-
"export interface FormatNumberOptions {\n locale?: string\n maximumFractionDigits?: number\n minimumFractionDigits?: number\n forceCompact?: boolean\n}\n\nexport function formatNumber(value: number, options: FormatNumberOptions = {}): string {\n const {\n locale = 'en-US',\n maximumFractionDigits = 1,\n minimumFractionDigits = 0,\n forceCompact = false,\n } = options\n\n if (!forceCompact && Math.abs(value) < 1000) {\n return new Intl.NumberFormat(locale, {\n maximumFractionDigits,\n minimumFractionDigits,\n }).format(value)\n }\n\n return new Intl.NumberFormat(locale, {\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits,\n minimumFractionDigits,\n }).format(value)\n}\n\nexport function abbreviateNumber(value: number): string {\n return formatNumber(value, { maximumFractionDigits: 1 })\n}\n\nexport function formatCount(value: number): string {\n return formatNumber(value, {\n maximumFractionDigits: 0,\n forceCompact: value >= 1000,\n })\n}\n"
|
|
13
|
+
"export interface FormatNumberOptions {\n locale?: string\n maximumFractionDigits?: number\n minimumFractionDigits?: number\n forceCompact?: boolean\n}\n\nexport function formatNumber(value: number, options: FormatNumberOptions = {}): string {\n const {\n locale = 'en-US',\n maximumFractionDigits = 1,\n minimumFractionDigits = 0,\n forceCompact = false,\n } = options\n\n if (!forceCompact && Math.abs(value) < 1000) {\n return new Intl.NumberFormat(locale, {\n maximumFractionDigits,\n minimumFractionDigits,\n }).format(value)\n }\n\n return new Intl.NumberFormat(locale, {\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits,\n minimumFractionDigits,\n }).format(value)\n}\n\nexport function abbreviateNumber(value: number): string {\n return formatNumber(value, { maximumFractionDigits: 1 })\n}\n\nexport function formatCount(value: number): string {\n return formatNumber(value, {\n maximumFractionDigits: 0,\n forceCompact: value >= 1000,\n })\n}\n\nexport function formatReactionCount(value: number | string): string {\n if (typeof value === 'string') return value\n if (value >= 1000000) {\n return `${(value / 1000000).toFixed(1)}M`\n }\n if (value >= 1000) {\n return `${(value / 1000).toFixed(1)}K`\n }\n return value.toString()\n}\n\nexport function formatPhoneNumber(value: string): string {\n return value\n}\n"
|
|
12
14
|
],
|
|
13
15
|
"version": 3
|
|
14
16
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": "AAAA,OAAO,iBAAS,oBAAoBA",
|
|
3
|
+
"names": [
|
|
4
|
+
"timestamp: number"
|
|
5
|
+
],
|
|
6
|
+
"sources": [
|
|
7
|
+
"src/time/formatDistanceToNow.ts"
|
|
8
|
+
],
|
|
9
|
+
"sourcesContent": [
|
|
10
|
+
"export function formatDistanceToNow(timestamp: number): string {\n const now = Date.now()\n const diff = now - timestamp\n\n const minutes = Math.floor(diff / 60000)\n const hours = Math.floor(diff / 3600000)\n const days = Math.floor(diff / 86400000)\n\n if (minutes < 1) return 'just now'\n if (minutes < 60) return `${minutes}m`\n if (hours < 24) return `${hours}h`\n if (days < 7) return `${days}d`\n if (days < 30) return `${Math.floor(days / 7)}w`\n if (days < 365) return `${Math.floor(days / 30)}mo`\n\n return `${Math.floor(days / 365)}y`\n}\n"
|
|
11
|
+
],
|
|
12
|
+
"version": 3
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type UseTimerReturn = {
|
|
2
|
+
count: number;
|
|
3
|
+
start: (time: number, start: boolean) => void;
|
|
4
|
+
pause: () => void;
|
|
5
|
+
resume: () => void;
|
|
6
|
+
clear: () => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const useTimer: () => UseTimerReturn;
|
|
9
|
+
export {};
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=useTimer.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": "KAEK,iBAAiB;CACpB;CACA,QAAQA,cAAcC;CACtB;CACA;CACA;AACD;AAED,OAAO,cAAM,gBAAe",
|
|
3
|
+
"names": [
|
|
4
|
+
"time: number",
|
|
5
|
+
"start: boolean"
|
|
6
|
+
],
|
|
7
|
+
"sources": [
|
|
8
|
+
"src/time/useTimer.ts"
|
|
9
|
+
],
|
|
10
|
+
"sourcesContent": [
|
|
11
|
+
"import { useState, useEffect, useRef, useMemo, useCallback } from 'react'\n\ntype UseTimerReturn = {\n count: number\n start: (time: number, start: boolean) => void\n pause: () => void\n resume: () => void\n clear: () => void\n}\n\nexport const useTimer = (): UseTimerReturn => {\n const [timerCount, setTimer] = useState<number>(30)\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n const clearTimer = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current)\n intervalRef.current = null\n }\n }, [])\n\n const resetTimer = useCallback(\n (time: number, start: boolean) => {\n setTimer(time)\n clearTimer()\n if (start) {\n intervalRef.current = setInterval(() => {\n setTimer((lastTimerCount) => {\n if (lastTimerCount <= 1) {\n clearInterval(intervalRef.current!)\n intervalRef.current = null\n return 0\n }\n return lastTimerCount - 1\n })\n }, 1000)\n }\n },\n [clearTimer]\n )\n\n const pauseTimer = useCallback(() => {\n clearTimer()\n }, [clearTimer])\n\n const resumeTimer = useCallback(() => {\n if (!intervalRef.current) {\n intervalRef.current = setInterval(() => {\n setTimer((lastTimerCount) => {\n if (lastTimerCount <= 1) {\n clearInterval(intervalRef.current!)\n intervalRef.current = null\n return 0\n }\n return lastTimerCount - 1\n })\n }, 1000)\n }\n }, [])\n\n useEffect(() => {\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current)\n intervalRef.current = null\n }\n }\n }, [])\n\n return useMemo(\n () => ({\n count: timerCount,\n start: resetTimer,\n pause: pauseTimer,\n resume: resumeTimer,\n clear: clearTimer,\n }),\n [timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer]\n )\n}\n"
|
|
12
|
+
],
|
|
13
|
+
"version": 3
|
|
14
|
+
}
|