@cleen/ui-core 0.1.1 → 0.1.2
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/index.js +1 -758
- package/dist/styles.css +15 -4560
- package/package.json +1 -1
- package/tailwind-entry.css +5 -0
package/dist/index.js
CHANGED
|
@@ -1,758 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
3
|
-
var easeOutQuad = (progress) => {
|
|
4
|
-
return 1 - (1 - progress) * (1 - progress);
|
|
5
|
-
};
|
|
6
|
-
var useAnimateNumber = ({
|
|
7
|
-
targetNumber,
|
|
8
|
-
defaultNumber = 0,
|
|
9
|
-
duration = 1e3,
|
|
10
|
-
disabled = false,
|
|
11
|
-
easeOut = true
|
|
12
|
-
}) => {
|
|
13
|
-
const [animatedNumber, setAnimatedNumber] = useState(defaultNumber);
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (disabled) {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
let start = null;
|
|
19
|
-
const animate = (timestamp) => {
|
|
20
|
-
if (!start) start = timestamp;
|
|
21
|
-
const progressTime = timestamp - start;
|
|
22
|
-
let progress = Math.min(progressTime / duration, 1);
|
|
23
|
-
if (easeOut) {
|
|
24
|
-
progress = easeOutQuad(progress);
|
|
25
|
-
}
|
|
26
|
-
const progressValue = progress * targetNumber;
|
|
27
|
-
setAnimatedNumber(progressValue);
|
|
28
|
-
if (progressValue < targetNumber) {
|
|
29
|
-
requestAnimationFrame(animate);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
requestAnimationFrame(animate);
|
|
33
|
-
}, [targetNumber, duration, disabled, easeOut]);
|
|
34
|
-
if (disabled) {
|
|
35
|
-
return targetNumber;
|
|
36
|
-
}
|
|
37
|
-
return animatedNumber;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// src/hooks/useControlled.ts
|
|
41
|
-
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
42
|
-
var useControlled = ({
|
|
43
|
-
value,
|
|
44
|
-
defaultValue,
|
|
45
|
-
onChange
|
|
46
|
-
}) => {
|
|
47
|
-
const isControlled = value !== void 0;
|
|
48
|
-
const [internalValue, setInternalValue] = useState2(
|
|
49
|
-
defaultValue
|
|
50
|
-
);
|
|
51
|
-
const currentValue = isControlled ? value : internalValue;
|
|
52
|
-
const handleChange = (newValue) => {
|
|
53
|
-
if (!isControlled) {
|
|
54
|
-
setInternalValue(newValue);
|
|
55
|
-
}
|
|
56
|
-
onChange?.(newValue);
|
|
57
|
-
};
|
|
58
|
-
useEffect2(() => {
|
|
59
|
-
if (!isControlled) {
|
|
60
|
-
setInternalValue(value ?? defaultValue ?? void 0);
|
|
61
|
-
}
|
|
62
|
-
}, [value, defaultValue, isControlled]);
|
|
63
|
-
return {
|
|
64
|
-
value: currentValue,
|
|
65
|
-
isControlled,
|
|
66
|
-
handleChange
|
|
67
|
-
};
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// src/hooks/useDebounce.ts
|
|
71
|
-
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
72
|
-
var useDebounce = (value, delay) => {
|
|
73
|
-
const [debouncedValue, setDebouncedValue] = useState3(value);
|
|
74
|
-
useEffect3(() => {
|
|
75
|
-
const handler = setTimeout(() => {
|
|
76
|
-
setDebouncedValue(value);
|
|
77
|
-
}, delay);
|
|
78
|
-
return () => {
|
|
79
|
-
clearTimeout(handler);
|
|
80
|
-
};
|
|
81
|
-
}, [value, delay]);
|
|
82
|
-
return debouncedValue;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// src/hooks/useDisclosure.ts
|
|
86
|
-
import { useState as useState4 } from "react";
|
|
87
|
-
var useDisclosure = (props) => {
|
|
88
|
-
const [isOpenInternal, setIsOpenInternal] = useState4(false);
|
|
89
|
-
const isOpen = props?.value !== void 0 ? props.value : isOpenInternal;
|
|
90
|
-
const open = () => {
|
|
91
|
-
setIsOpenInternal(true);
|
|
92
|
-
props?.setValue?.(true);
|
|
93
|
-
};
|
|
94
|
-
const close = () => {
|
|
95
|
-
setIsOpenInternal(false);
|
|
96
|
-
props?.setValue?.(false);
|
|
97
|
-
};
|
|
98
|
-
const toggle = () => {
|
|
99
|
-
setIsOpenInternal((prev) => !prev);
|
|
100
|
-
props?.setValue?.(!isOpen);
|
|
101
|
-
};
|
|
102
|
-
return {
|
|
103
|
-
isOpen,
|
|
104
|
-
open,
|
|
105
|
-
close,
|
|
106
|
-
toggle
|
|
107
|
-
};
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
// src/hooks/useForm.ts
|
|
111
|
-
import { useEffect as useEffect4, useMemo, useState as useState5 } from "react";
|
|
112
|
-
var useForm = ({
|
|
113
|
-
defaultValue,
|
|
114
|
-
resetOnDefaultValueChange = true
|
|
115
|
-
}) => {
|
|
116
|
-
const [form, setForm] = useState5(defaultValue);
|
|
117
|
-
const reset = () => setForm(defaultValue);
|
|
118
|
-
const setField = (field, value) => {
|
|
119
|
-
setForm((prev) => ({ ...prev, [field]: value }));
|
|
120
|
-
};
|
|
121
|
-
const isDirty = useMemo(
|
|
122
|
-
() => JSON.stringify(form) !== JSON.stringify(defaultValue),
|
|
123
|
-
[form, defaultValue]
|
|
124
|
-
);
|
|
125
|
-
useEffect4(() => {
|
|
126
|
-
if (defaultValue && resetOnDefaultValueChange) {
|
|
127
|
-
setForm(defaultValue);
|
|
128
|
-
}
|
|
129
|
-
}, [defaultValue, resetOnDefaultValueChange]);
|
|
130
|
-
return {
|
|
131
|
-
form,
|
|
132
|
-
isDirty,
|
|
133
|
-
setForm,
|
|
134
|
-
setField,
|
|
135
|
-
reset
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// src/hooks/useOutsideClick.ts
|
|
140
|
-
import { useEffect as useEffect5 } from "react";
|
|
141
|
-
function useOutsideClick({
|
|
142
|
-
refs,
|
|
143
|
-
handler,
|
|
144
|
-
enabled = true
|
|
145
|
-
}) {
|
|
146
|
-
useEffect5(() => {
|
|
147
|
-
if (!enabled) return;
|
|
148
|
-
const listener = (event) => {
|
|
149
|
-
const clickedInside = refs.some((ref) => {
|
|
150
|
-
const el = ref.current;
|
|
151
|
-
if (!el) return false;
|
|
152
|
-
return el.contains(event.target);
|
|
153
|
-
});
|
|
154
|
-
if (clickedInside) return;
|
|
155
|
-
setTimeout(() => handler(event), 0);
|
|
156
|
-
};
|
|
157
|
-
document.addEventListener("mousedown", listener);
|
|
158
|
-
document.addEventListener("touchstart", listener);
|
|
159
|
-
return () => {
|
|
160
|
-
document.removeEventListener("mousedown", listener);
|
|
161
|
-
document.removeEventListener("touchstart", listener);
|
|
162
|
-
};
|
|
163
|
-
}, [refs, handler, enabled]);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// src/hooks/usePaginationState.ts
|
|
167
|
-
import { useState as useState6 } from "react";
|
|
168
|
-
function usePaginationState(options = {}) {
|
|
169
|
-
const { initialPage = 1, initialPageSize = 10 } = options;
|
|
170
|
-
const [page, setPage] = useState6(initialPage);
|
|
171
|
-
const [pageSize, setPageSize] = useState6(initialPageSize);
|
|
172
|
-
const handleNextPage = (nextPage) => setPage(nextPage);
|
|
173
|
-
const handlePreviousPage = (prevPage) => setPage(prevPage);
|
|
174
|
-
const handlePageChange = (newPage) => setPage(newPage);
|
|
175
|
-
return {
|
|
176
|
-
page,
|
|
177
|
-
setPage,
|
|
178
|
-
pageSize,
|
|
179
|
-
setPageSize,
|
|
180
|
-
handleNextPage,
|
|
181
|
-
handlePreviousPage,
|
|
182
|
-
handlePageChange
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// src/utils/position.ts
|
|
187
|
-
var calculateOptimalPosition = (overlayRect, triggerRect, preferredPosition) => {
|
|
188
|
-
const viewport = {
|
|
189
|
-
width: window.innerWidth,
|
|
190
|
-
height: window.innerHeight
|
|
191
|
-
};
|
|
192
|
-
let newPosition = preferredPosition;
|
|
193
|
-
if (preferredPosition === "left" || preferredPosition === "right") {
|
|
194
|
-
const isLeft = preferredPosition === "left";
|
|
195
|
-
const spaceLeft = triggerRect.left;
|
|
196
|
-
const spaceRight = viewport.width - triggerRect.right;
|
|
197
|
-
if (isLeft && spaceLeft < overlayRect.width && spaceRight > overlayRect.width) {
|
|
198
|
-
return "right";
|
|
199
|
-
} else if (!isLeft && spaceRight < overlayRect.width && spaceLeft > overlayRect.width) {
|
|
200
|
-
return "left";
|
|
201
|
-
}
|
|
202
|
-
return newPosition;
|
|
203
|
-
}
|
|
204
|
-
const isBottom = preferredPosition.startsWith("bottom");
|
|
205
|
-
const spaceBelow = viewport.height - triggerRect.bottom;
|
|
206
|
-
const spaceAbove = triggerRect.top;
|
|
207
|
-
if (isBottom && spaceBelow < overlayRect.height && spaceAbove > overlayRect.height) {
|
|
208
|
-
newPosition = preferredPosition.replace("bottom", "top");
|
|
209
|
-
} else if (!isBottom && preferredPosition.startsWith("top") && spaceAbove < overlayRect.height && spaceBelow > overlayRect.height) {
|
|
210
|
-
newPosition = preferredPosition.replace("top", "bottom");
|
|
211
|
-
}
|
|
212
|
-
if (preferredPosition.includes("-")) {
|
|
213
|
-
const isLeft = preferredPosition.endsWith("left");
|
|
214
|
-
const spaceRight = viewport.width - triggerRect.right;
|
|
215
|
-
const spaceLeft = triggerRect.left;
|
|
216
|
-
if (isLeft && spaceRight < overlayRect.width && spaceLeft > overlayRect.width) {
|
|
217
|
-
newPosition = newPosition.replace("left", "right");
|
|
218
|
-
} else if (!isLeft && spaceRight < overlayRect.width && spaceLeft > overlayRect.width) {
|
|
219
|
-
newPosition = newPosition.replace("right", "left");
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return newPosition;
|
|
223
|
-
};
|
|
224
|
-
var calculatePositionValues = (overlayRect, triggerRect, position, offset) => {
|
|
225
|
-
if (!triggerRect) {
|
|
226
|
-
return { top: 0, left: 0 };
|
|
227
|
-
}
|
|
228
|
-
const scrollY = window.scrollY;
|
|
229
|
-
const scrollX = window.scrollX;
|
|
230
|
-
const gap = offset || 0;
|
|
231
|
-
let top = 0;
|
|
232
|
-
if (position.startsWith("bottom")) {
|
|
233
|
-
top = triggerRect.bottom + scrollY + gap;
|
|
234
|
-
} else if (position.startsWith("top")) {
|
|
235
|
-
top = triggerRect.top + scrollY - (overlayRect?.height || 0) - gap;
|
|
236
|
-
} else {
|
|
237
|
-
top = triggerRect.top + scrollY + triggerRect.height / 2 - (overlayRect?.height || 0) / 2;
|
|
238
|
-
}
|
|
239
|
-
let left = 0;
|
|
240
|
-
if (position === "left") {
|
|
241
|
-
left = triggerRect.left + scrollX - (overlayRect?.width || 0) - gap;
|
|
242
|
-
} else if (position === "right") {
|
|
243
|
-
left = triggerRect.right + scrollX + gap;
|
|
244
|
-
} else if (position.endsWith("left") || position === "bottom" || position === "top") {
|
|
245
|
-
left = triggerRect.left + scrollX;
|
|
246
|
-
} else if (position.endsWith("right")) {
|
|
247
|
-
left = triggerRect.right + scrollX - (overlayRect?.width || 0);
|
|
248
|
-
}
|
|
249
|
-
if (position === "bottom" || position === "top") {
|
|
250
|
-
left = triggerRect.left + scrollX + triggerRect.width / 2 - (overlayRect?.width || 0) / 2;
|
|
251
|
-
}
|
|
252
|
-
return { top, left };
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
// src/hooks/usePositionClose.ts
|
|
256
|
-
import { useEffect as useEffect6, useMemo as useMemo2, useState as useState7 } from "react";
|
|
257
|
-
var usePositionClose = ({
|
|
258
|
-
triggerRef,
|
|
259
|
-
targetRef,
|
|
260
|
-
position = "bottom-left",
|
|
261
|
-
offset = 8,
|
|
262
|
-
isOpen
|
|
263
|
-
}) => {
|
|
264
|
-
const [isMounted, setIsMounted] = useState7(false);
|
|
265
|
-
const { positionStyles, optimalPosition } = useMemo2(() => {
|
|
266
|
-
if (isMounted && targetRef.current && triggerRef.current) {
|
|
267
|
-
const overlayRect = targetRef.current.getBoundingClientRect();
|
|
268
|
-
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
269
|
-
const optimalPosition2 = calculateOptimalPosition(
|
|
270
|
-
overlayRect,
|
|
271
|
-
triggerRect,
|
|
272
|
-
position
|
|
273
|
-
);
|
|
274
|
-
const coords = calculatePositionValues(
|
|
275
|
-
overlayRect,
|
|
276
|
-
triggerRect,
|
|
277
|
-
optimalPosition2,
|
|
278
|
-
offset
|
|
279
|
-
);
|
|
280
|
-
return { positionStyles: coords, optimalPosition: optimalPosition2 };
|
|
281
|
-
}
|
|
282
|
-
return { positionStyles: { top: 0, left: 0 }, optimal: position };
|
|
283
|
-
}, [triggerRef, targetRef, position, offset, isMounted]);
|
|
284
|
-
useEffect6(() => {
|
|
285
|
-
if (isOpen) {
|
|
286
|
-
setIsMounted(true);
|
|
287
|
-
} else {
|
|
288
|
-
setIsMounted(false);
|
|
289
|
-
}
|
|
290
|
-
}, [isOpen]);
|
|
291
|
-
return {
|
|
292
|
-
positionStyles,
|
|
293
|
-
optimalPosition,
|
|
294
|
-
isMounted
|
|
295
|
-
};
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
// src/hooks/useValidation.ts
|
|
299
|
-
import { useCallback, useState as useState8 } from "react";
|
|
300
|
-
var useValidation = (defaultValue) => {
|
|
301
|
-
const [errors, setErrors] = useState8(defaultValue);
|
|
302
|
-
const setError = useCallback((field, value) => {
|
|
303
|
-
setErrors((prev) => {
|
|
304
|
-
prev[field] = value;
|
|
305
|
-
return { ...prev };
|
|
306
|
-
});
|
|
307
|
-
}, []);
|
|
308
|
-
const clearErrors = useCallback(() => {
|
|
309
|
-
setErrors(defaultValue);
|
|
310
|
-
}, [defaultValue]);
|
|
311
|
-
const clearError = useCallback((field) => {
|
|
312
|
-
setErrors((prev) => {
|
|
313
|
-
delete prev[field];
|
|
314
|
-
return { ...prev };
|
|
315
|
-
});
|
|
316
|
-
}, []);
|
|
317
|
-
return {
|
|
318
|
-
errors,
|
|
319
|
-
setError,
|
|
320
|
-
setErrors,
|
|
321
|
-
clearError,
|
|
322
|
-
clearErrors
|
|
323
|
-
};
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
// src/hooks/useWatchResize.ts
|
|
327
|
-
import { useEffect as useEffect7 } from "react";
|
|
328
|
-
var useWidthDynamicResize = ({ ref, skip }, deps) => {
|
|
329
|
-
useEffect7(() => {
|
|
330
|
-
const node = ref.current;
|
|
331
|
-
if (!node || skip) {
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
const currentWidth = node.offsetWidth;
|
|
335
|
-
node.style.width = `${currentWidth}px`;
|
|
336
|
-
requestAnimationFrame(() => {
|
|
337
|
-
node.style.width = "auto";
|
|
338
|
-
const newWidth = node.offsetWidth;
|
|
339
|
-
node.style.width = `${currentWidth}px`;
|
|
340
|
-
void node.offsetHeight;
|
|
341
|
-
node.style.width = `${newWidth}px`;
|
|
342
|
-
const handleTransitionEnd = () => {
|
|
343
|
-
if (node) {
|
|
344
|
-
node.style.width = "auto";
|
|
345
|
-
}
|
|
346
|
-
node?.removeEventListener("transitionend", handleTransitionEnd);
|
|
347
|
-
};
|
|
348
|
-
node.addEventListener("transitionend", handleTransitionEnd);
|
|
349
|
-
});
|
|
350
|
-
}, deps);
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
// src/store/colors.ts
|
|
354
|
-
import { create } from "zustand";
|
|
355
|
-
import { persist } from "zustand/middleware";
|
|
356
|
-
var PREFIX = "--cleen-";
|
|
357
|
-
var colorVars = [
|
|
358
|
-
"white",
|
|
359
|
-
"black",
|
|
360
|
-
"gray",
|
|
361
|
-
"pink",
|
|
362
|
-
"purple",
|
|
363
|
-
"indigo",
|
|
364
|
-
"blue",
|
|
365
|
-
"primary",
|
|
366
|
-
"success",
|
|
367
|
-
"warning",
|
|
368
|
-
"error",
|
|
369
|
-
"brand",
|
|
370
|
-
"sidebar",
|
|
371
|
-
"background"
|
|
372
|
-
];
|
|
373
|
-
var useCleenColors = create()(
|
|
374
|
-
persist(
|
|
375
|
-
(set, get) => ({
|
|
376
|
-
colors: {},
|
|
377
|
-
getColors: () => {
|
|
378
|
-
const colors = get().colors;
|
|
379
|
-
return colorVars.reduce(
|
|
380
|
-
(prev, colorVar) => {
|
|
381
|
-
if (colors[colorVar]) {
|
|
382
|
-
prev[colorVar] = colors[colorVar];
|
|
383
|
-
} else {
|
|
384
|
-
prev[colorVar] = getComputedStyle(
|
|
385
|
-
document.documentElement
|
|
386
|
-
).getPropertyValue(`${PREFIX}${colorVar}`);
|
|
387
|
-
}
|
|
388
|
-
return prev;
|
|
389
|
-
},
|
|
390
|
-
{}
|
|
391
|
-
);
|
|
392
|
-
},
|
|
393
|
-
getColor: (color) => {
|
|
394
|
-
const colors = get().colors;
|
|
395
|
-
if (colors[color]) {
|
|
396
|
-
return colors[color];
|
|
397
|
-
} else {
|
|
398
|
-
return getComputedStyle(document.documentElement).getPropertyValue(
|
|
399
|
-
`${PREFIX}${color}`
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
},
|
|
403
|
-
setColors: (colors) => Object.entries(colors).map(
|
|
404
|
-
([colorVar, value]) => set((state) => ({
|
|
405
|
-
colors: {
|
|
406
|
-
...state.colors,
|
|
407
|
-
[colorVar]: value
|
|
408
|
-
}
|
|
409
|
-
}))
|
|
410
|
-
),
|
|
411
|
-
setColor: (colorVar, value) => {
|
|
412
|
-
set((state) => ({
|
|
413
|
-
colors: {
|
|
414
|
-
...state.colors,
|
|
415
|
-
[colorVar]: value
|
|
416
|
-
}
|
|
417
|
-
}));
|
|
418
|
-
},
|
|
419
|
-
resetColors: () => {
|
|
420
|
-
set({ colors: {} });
|
|
421
|
-
},
|
|
422
|
-
resetColor: (colorVar) => {
|
|
423
|
-
const colors = get().colors;
|
|
424
|
-
delete colors[colorVar];
|
|
425
|
-
set({ colors });
|
|
426
|
-
}
|
|
427
|
-
}),
|
|
428
|
-
{
|
|
429
|
-
name: "cleen-colors"
|
|
430
|
-
}
|
|
431
|
-
)
|
|
432
|
-
);
|
|
433
|
-
|
|
434
|
-
// src/store/overlays.ts
|
|
435
|
-
import { create as create2 } from "zustand";
|
|
436
|
-
import { persist as persist2 } from "zustand/middleware";
|
|
437
|
-
var useCleenOverlays = create2()(
|
|
438
|
-
persist2(
|
|
439
|
-
(set) => ({
|
|
440
|
-
overlays: [],
|
|
441
|
-
addOverlay: (id) => {
|
|
442
|
-
set((state) => ({ overlays: [...state.overlays, id] }));
|
|
443
|
-
},
|
|
444
|
-
removeOverlay: (id) => {
|
|
445
|
-
set((state) => ({ overlays: state.overlays.filter((v) => v !== id) }));
|
|
446
|
-
},
|
|
447
|
-
clearOverlays: () => {
|
|
448
|
-
set({ overlays: [] });
|
|
449
|
-
}
|
|
450
|
-
}),
|
|
451
|
-
{
|
|
452
|
-
name: "cleen-overlays"
|
|
453
|
-
}
|
|
454
|
-
)
|
|
455
|
-
);
|
|
456
|
-
|
|
457
|
-
// src/utils/audio.ts
|
|
458
|
-
var encodeWav = (buffer) => {
|
|
459
|
-
const { numberOfChannels: channels, sampleRate, length } = buffer;
|
|
460
|
-
const bitsPerSample = 16;
|
|
461
|
-
const blockAlign = channels * bitsPerSample / 8;
|
|
462
|
-
const byteRate = sampleRate * blockAlign;
|
|
463
|
-
const dataSize = length * blockAlign;
|
|
464
|
-
const wavBuffer = new ArrayBuffer(44 + dataSize);
|
|
465
|
-
const v = new DataView(wavBuffer);
|
|
466
|
-
const str = (offset2, s) => {
|
|
467
|
-
for (let i = 0; i < s.length; i++) v.setUint8(offset2 + i, s.charCodeAt(i));
|
|
468
|
-
};
|
|
469
|
-
str(0, "RIFF");
|
|
470
|
-
v.setUint32(4, 36 + dataSize, true);
|
|
471
|
-
str(8, "WAVE");
|
|
472
|
-
str(12, "fmt ");
|
|
473
|
-
v.setUint32(16, 16, true);
|
|
474
|
-
v.setUint16(20, 1, true);
|
|
475
|
-
v.setUint16(22, channels, true);
|
|
476
|
-
v.setUint32(24, sampleRate, true);
|
|
477
|
-
v.setUint32(28, byteRate, true);
|
|
478
|
-
v.setUint16(32, blockAlign, true);
|
|
479
|
-
v.setUint16(34, bitsPerSample, true);
|
|
480
|
-
str(36, "data");
|
|
481
|
-
v.setUint32(40, dataSize, true);
|
|
482
|
-
let offset = 44;
|
|
483
|
-
for (let i = 0; i < length; i++) {
|
|
484
|
-
for (let ch = 0; ch < channels; ch++) {
|
|
485
|
-
const s = Math.max(-1, Math.min(1, buffer.getChannelData(ch)[i]));
|
|
486
|
-
v.setInt16(offset, s < 0 ? s * 32768 : s * 32767, true);
|
|
487
|
-
offset += 2;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
return new Blob([wavBuffer], { type: "audio/wav" });
|
|
491
|
-
};
|
|
492
|
-
var trimBlob = async (blob, startSec, endSec) => {
|
|
493
|
-
const ctx = new AudioContext();
|
|
494
|
-
const decoded = await ctx.decodeAudioData(await blob.arrayBuffer());
|
|
495
|
-
await ctx.close();
|
|
496
|
-
const { sampleRate, numberOfChannels } = decoded;
|
|
497
|
-
const startSample = Math.round(startSec * sampleRate);
|
|
498
|
-
const endSample = Math.round(endSec * sampleRate);
|
|
499
|
-
const trimLength = endSample - startSample;
|
|
500
|
-
const trimmedBuffer = new AudioContext().createBuffer(
|
|
501
|
-
numberOfChannels,
|
|
502
|
-
trimLength,
|
|
503
|
-
sampleRate
|
|
504
|
-
);
|
|
505
|
-
for (let ch = 0; ch < numberOfChannels; ch++) {
|
|
506
|
-
trimmedBuffer.copyToChannel(
|
|
507
|
-
decoded.getChannelData(ch).subarray(startSample, endSample),
|
|
508
|
-
ch
|
|
509
|
-
);
|
|
510
|
-
}
|
|
511
|
-
return encodeWav(trimmedBuffer);
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
// src/utils/cn.ts
|
|
515
|
-
import clsx from "clsx";
|
|
516
|
-
import { createTailwindMerge, getDefaultConfig } from "tailwind-merge";
|
|
517
|
-
var twConfig = () => ({
|
|
518
|
-
...getDefaultConfig(),
|
|
519
|
-
prefix: "cleen-"
|
|
520
|
-
});
|
|
521
|
-
var twMerge = createTailwindMerge(twConfig);
|
|
522
|
-
var cn = (...inputs) => {
|
|
523
|
-
return twMerge(clsx(inputs));
|
|
524
|
-
};
|
|
525
|
-
|
|
526
|
-
// src/utils/colors.ts
|
|
527
|
-
import {
|
|
528
|
-
darken,
|
|
529
|
-
getLuminance,
|
|
530
|
-
lighten,
|
|
531
|
-
parseToRgba,
|
|
532
|
-
toHex,
|
|
533
|
-
toRgba
|
|
534
|
-
} from "color2k";
|
|
535
|
-
var ColorHelpers = class _ColorHelpers {
|
|
536
|
-
/**
|
|
537
|
-
* Calculates the Delta E (CIE94) between two RGB colors.
|
|
538
|
-
*
|
|
539
|
-
* Delta E is a metric for color difference. Based on the value, we can describe how different the colors are:
|
|
540
|
-
*
|
|
541
|
-
* Perception Levels:
|
|
542
|
-
* - Delta E <= 1.0: Not perceptible by human eyes.
|
|
543
|
-
* - Delta E between 1-2: Perceptible through close observation.
|
|
544
|
-
* - Delta E between 2-10: Perceptible at a glance.
|
|
545
|
-
* - Delta E between 11-49: Colors are more similar than opposite.
|
|
546
|
-
* - Delta E = 100: Colors are exact opposites.
|
|
547
|
-
*
|
|
548
|
-
* @param {Array<number>} rgb1 - The first RGB color as an array [R, G, B].
|
|
549
|
-
* @param {Array<number>} rgb2 - The second RGB color as an array [R, G, B].
|
|
550
|
-
* @returns {number} The Delta E value representing the difference between the two colors.
|
|
551
|
-
*
|
|
552
|
-
* @example
|
|
553
|
-
* deltaE([128, 0, 255], [128, 0, 255]); // 0
|
|
554
|
-
* deltaE([128, 0, 255], [128, 0, 230]); // 3.175
|
|
555
|
-
* deltaE([128, 0, 255], [255, 0, 0]); // 61.24
|
|
556
|
-
*/
|
|
557
|
-
static deltaE(rgbA, rgbB) {
|
|
558
|
-
const labA = _ColorHelpers.rgb2lab(rgbA);
|
|
559
|
-
const labB = _ColorHelpers.rgb2lab(rgbB);
|
|
560
|
-
const deltaL = labA[0] - labB[0];
|
|
561
|
-
const deltaA = labA[1] - labB[1];
|
|
562
|
-
const deltaB = labA[2] - labB[2];
|
|
563
|
-
const c1 = Math.sqrt(labA[1] * labA[1] + labA[2] * labA[2]);
|
|
564
|
-
const c2 = Math.sqrt(labB[1] * labB[1] + labB[2] * labB[2]);
|
|
565
|
-
const deltaC = c1 - c2;
|
|
566
|
-
let deltaH = deltaA * deltaA + deltaB * deltaB - deltaC * deltaC;
|
|
567
|
-
deltaH = deltaH < 0 ? 0 : Math.sqrt(deltaH);
|
|
568
|
-
const sc = 1 + 0.045 * c1;
|
|
569
|
-
const sh = 1 + 0.015 * c1;
|
|
570
|
-
const deltaLKlsl = deltaL / 1;
|
|
571
|
-
const deltaCkcsc = deltaC / sc;
|
|
572
|
-
const deltaHkhsh = deltaH / sh;
|
|
573
|
-
const i = deltaLKlsl * deltaLKlsl + deltaCkcsc * deltaCkcsc + deltaHkhsh * deltaHkhsh;
|
|
574
|
-
return i < 0 ? 0 : Math.sqrt(i);
|
|
575
|
-
}
|
|
576
|
-
static rgb2lab(rgb) {
|
|
577
|
-
let r = rgb[0] / 255, g = rgb[1] / 255, b = rgb[2] / 255, x, y, z;
|
|
578
|
-
r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
|
|
579
|
-
g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
|
|
580
|
-
b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
|
|
581
|
-
x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
|
|
582
|
-
y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1;
|
|
583
|
-
z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
|
|
584
|
-
x = x > 8856e-6 ? Math.pow(x, 1 / 3) : 7.787 * x + 16 / 116;
|
|
585
|
-
y = y > 8856e-6 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116;
|
|
586
|
-
z = z > 8856e-6 ? Math.pow(z, 1 / 3) : 7.787 * z + 16 / 116;
|
|
587
|
-
return [116 * y - 16, 500 * (x - y), 200 * (y - z)];
|
|
588
|
-
}
|
|
589
|
-
static isSimilar(color1, color2, defaultDeltaE = 24) {
|
|
590
|
-
const e = _ColorHelpers.deltaE(parseToRgba(color1), parseToRgba(color2));
|
|
591
|
-
return e < defaultDeltaE;
|
|
592
|
-
}
|
|
593
|
-
static adjustColorForContrast(hexColor, amount = 0.25) {
|
|
594
|
-
let _colorAsHex = toHex(hexColor);
|
|
595
|
-
let result = hexColor;
|
|
596
|
-
try {
|
|
597
|
-
if (_colorAsHex.match(/^#f{2,}e{0,2}$/i) || getLuminance(_colorAsHex) > 0.98) {
|
|
598
|
-
_colorAsHex = "#ffffff";
|
|
599
|
-
}
|
|
600
|
-
if (getLuminance(_colorAsHex) > 0.6) {
|
|
601
|
-
const darkenedColorHSLA = darken(_colorAsHex, amount);
|
|
602
|
-
const darkenedColorRGBA = toRgba(darkenedColorHSLA);
|
|
603
|
-
result = darkenedColorRGBA;
|
|
604
|
-
} else {
|
|
605
|
-
const lightenedColorHSLA = lighten(_colorAsHex, amount);
|
|
606
|
-
const lightenedColorRGBA = toRgba(lightenedColorHSLA);
|
|
607
|
-
result = lightenedColorRGBA;
|
|
608
|
-
}
|
|
609
|
-
return result;
|
|
610
|
-
} catch {
|
|
611
|
-
return "rgba(var(--cleen-white)";
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
// Util functions to get color based on pass string (CSS variables can be parsed as well)
|
|
615
|
-
static getComputedColor(color) {
|
|
616
|
-
if (!color?.includes("var(")) {
|
|
617
|
-
return color;
|
|
618
|
-
}
|
|
619
|
-
const varName = color.match(/var\((--[^,)]+)/)?.[1];
|
|
620
|
-
if (varName && typeof window !== "undefined") {
|
|
621
|
-
const color2 = getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
|
|
622
|
-
return color2 ? `rgb(${color2})` : void 0;
|
|
623
|
-
}
|
|
624
|
-
return void 0;
|
|
625
|
-
}
|
|
626
|
-
static getComputedRgb(color) {
|
|
627
|
-
if (!color) {
|
|
628
|
-
return void 0;
|
|
629
|
-
}
|
|
630
|
-
if (!color?.includes("var(")) {
|
|
631
|
-
const [r, g, b] = parseToRgba(color);
|
|
632
|
-
return `${r}, ${g}, ${b}`;
|
|
633
|
-
}
|
|
634
|
-
const varName = color.match(/var\((--[^,)]+)/)?.[1];
|
|
635
|
-
if (varName && typeof window !== "undefined") {
|
|
636
|
-
return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
|
|
637
|
-
}
|
|
638
|
-
return void 0;
|
|
639
|
-
}
|
|
640
|
-
static trasparentize(color, value = 0) {
|
|
641
|
-
return `color-mix(in srgb, ${color} ${(1 - value) * 100}%, transparent)`;
|
|
642
|
-
}
|
|
643
|
-
};
|
|
644
|
-
|
|
645
|
-
// src/utils/images.ts
|
|
646
|
-
var PICSUM_BASE_URL = "https://picsum.photos";
|
|
647
|
-
var getRandomImageUrl = (options) => {
|
|
648
|
-
const { width, height, grayscale, blur, seed } = options;
|
|
649
|
-
let url = PICSUM_BASE_URL;
|
|
650
|
-
if (seed) {
|
|
651
|
-
url += `/seed/${encodeURIComponent(seed)}`;
|
|
652
|
-
}
|
|
653
|
-
url += `/${width}/${height || width}`;
|
|
654
|
-
const params = new URLSearchParams();
|
|
655
|
-
if (grayscale) {
|
|
656
|
-
params.append("grayscale", "");
|
|
657
|
-
}
|
|
658
|
-
if (blur) {
|
|
659
|
-
params.append("blur", blur.toString());
|
|
660
|
-
}
|
|
661
|
-
if (seed) {
|
|
662
|
-
params.append("seed", seed);
|
|
663
|
-
}
|
|
664
|
-
const queryString = params.toString();
|
|
665
|
-
if (queryString) {
|
|
666
|
-
url += `?${queryString}`;
|
|
667
|
-
}
|
|
668
|
-
return url;
|
|
669
|
-
};
|
|
670
|
-
|
|
671
|
-
// src/utils/object.ts
|
|
672
|
-
function isPlainObject(value) {
|
|
673
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
674
|
-
}
|
|
675
|
-
function applyDefaults(defaults, values) {
|
|
676
|
-
const merge = (d, v) => {
|
|
677
|
-
if (v === void 0) {
|
|
678
|
-
return cloneValue(d);
|
|
679
|
-
}
|
|
680
|
-
if (isPlainObject(d) && isPlainObject(v)) {
|
|
681
|
-
const result = {};
|
|
682
|
-
const keys = /* @__PURE__ */ new Set([...Object.keys(d), ...Object.keys(v)]);
|
|
683
|
-
keys.forEach((key) => {
|
|
684
|
-
const dv = d[key];
|
|
685
|
-
const vv = v[key];
|
|
686
|
-
result[key] = merge(dv, vv);
|
|
687
|
-
});
|
|
688
|
-
return result;
|
|
689
|
-
}
|
|
690
|
-
if (Array.isArray(d) || Array.isArray(v)) {
|
|
691
|
-
if (v === void 0) return cloneValue(d);
|
|
692
|
-
return cloneValue(v);
|
|
693
|
-
}
|
|
694
|
-
return v !== void 0 ? cloneValue(v) : cloneValue(d);
|
|
695
|
-
};
|
|
696
|
-
const cloneValue = (x) => {
|
|
697
|
-
if (x === void 0) return void 0;
|
|
698
|
-
if (x === null) return null;
|
|
699
|
-
if (Array.isArray(x)) return x.map((item) => cloneValue(item));
|
|
700
|
-
if (isPlainObject(x)) {
|
|
701
|
-
const o = {};
|
|
702
|
-
Object.keys(x).forEach((k) => {
|
|
703
|
-
o[k] = cloneValue(x[k]);
|
|
704
|
-
});
|
|
705
|
-
return o;
|
|
706
|
-
}
|
|
707
|
-
return x;
|
|
708
|
-
};
|
|
709
|
-
return merge(defaults, values);
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
// src/utils/string.ts
|
|
713
|
-
var formatFileSize = (bytes) => {
|
|
714
|
-
if (bytes === 0 || !bytes) {
|
|
715
|
-
return "0 B";
|
|
716
|
-
}
|
|
717
|
-
const k = 1024;
|
|
718
|
-
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
719
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
720
|
-
return Math.round(bytes / Math.pow(k, i)) + " " + sizes[i];
|
|
721
|
-
};
|
|
722
|
-
var formatAudioTime = (seconds) => {
|
|
723
|
-
const mins = Math.floor(seconds / 60);
|
|
724
|
-
const secs = Math.floor(seconds % 60);
|
|
725
|
-
return `${String(mins).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
|
|
726
|
-
};
|
|
727
|
-
var getCreatedDate = (date) => {
|
|
728
|
-
const created = new Date(date);
|
|
729
|
-
const now = /* @__PURE__ */ new Date();
|
|
730
|
-
const diffTime = Math.abs(now.getTime() - created.getTime());
|
|
731
|
-
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
732
|
-
return `Created ${diffDays} days ago`;
|
|
733
|
-
};
|
|
734
|
-
export {
|
|
735
|
-
ColorHelpers,
|
|
736
|
-
applyDefaults,
|
|
737
|
-
calculateOptimalPosition,
|
|
738
|
-
calculatePositionValues,
|
|
739
|
-
cn,
|
|
740
|
-
encodeWav,
|
|
741
|
-
formatAudioTime,
|
|
742
|
-
formatFileSize,
|
|
743
|
-
getCreatedDate,
|
|
744
|
-
getRandomImageUrl,
|
|
745
|
-
trimBlob,
|
|
746
|
-
useAnimateNumber,
|
|
747
|
-
useCleenColors,
|
|
748
|
-
useCleenOverlays,
|
|
749
|
-
useControlled,
|
|
750
|
-
useDebounce,
|
|
751
|
-
useDisclosure,
|
|
752
|
-
useForm,
|
|
753
|
-
useOutsideClick,
|
|
754
|
-
usePaginationState,
|
|
755
|
-
usePositionClose,
|
|
756
|
-
useValidation,
|
|
757
|
-
useWidthDynamicResize
|
|
758
|
-
};
|
|
1
|
+
import{useEffect as M,useState as A}from"react";var E=n=>1-(1-n)*(1-n),ae=({targetNumber:n,defaultNumber:r=0,duration:t=1e3,disabled:e=!1,easeOut:o=!0})=>{let[s,i]=A(r);return M(()=>{if(e)return;let a=null,l=c=>{a||(a=c);let u=c-a,f=Math.min(u/t,1);o&&(f=E(f));let m=f*n;i(m),m<n&&requestAnimationFrame(l)};requestAnimationFrame(l)},[n,t,e,o]),e?n:s};import{useEffect as U,useState as B}from"react";var ue=({value:n,defaultValue:r,onChange:t})=>{let e=n!==void 0,[o,s]=B(r),i=e?n:o,a=l=>{e||s(l),t?.(l)};return U(()=>{e||s(n??r??void 0)},[n,r,e]),{value:i,isControlled:e,handleChange:a}};import{useEffect as D,useState as V}from"react";var de=(n,r)=>{let[t,e]=V(n);return D(()=>{let o=setTimeout(()=>{e(n)},r);return()=>{clearTimeout(o)}},[n,r]),t};import{useState as L}from"react";var ge=n=>{let[r,t]=L(!1),e=n?.value!==void 0?n.value:r;return{isOpen:e,open:()=>{t(!0),n?.setValue?.(!0)},close:()=>{t(!1),n?.setValue?.(!1)},toggle:()=>{t(a=>!a),n?.setValue?.(!e)}}};import{useEffect as R,useMemo as $,useState as j}from"react";var Ce=({defaultValue:n,resetOnDefaultValueChange:r=!0})=>{let[t,e]=j(n),o=()=>e(n),s=(a,l)=>{e(c=>({...c,[a]:l}))},i=$(()=>JSON.stringify(t)!==JSON.stringify(n),[t,n]);return R(()=>{n&&r&&e(n)},[n,r]),{form:t,isDirty:i,setForm:e,setField:s,reset:o}};import{useEffect as W}from"react";function Te({refs:n,handler:r,enabled:t=!0}){W(()=>{if(!t)return;let e=o=>{n.some(i=>{let a=i.current;return a?a.contains(o.target):!1})||setTimeout(()=>r(o),0)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)}},[n,r,t])}import{useState as P}from"react";function ke(n={}){let{initialPage:r=1,initialPageSize:t=10}=n,[e,o]=P(r),[s,i]=P(t);return{page:e,setPage:o,pageSize:s,setPageSize:i,handleNextPage:u=>o(u),handlePreviousPage:u=>o(u),handlePageChange:u=>o(u)}}var T=(n,r,t)=>{let e={width:window.innerWidth,height:window.innerHeight},o=t;if(t==="left"||t==="right"){let l=t==="left",c=r.left,u=e.width-r.right;return l&&c<n.width&&u>n.width?"right":!l&&u<n.width&&c>n.width?"left":o}let s=t.startsWith("bottom"),i=e.height-r.bottom,a=r.top;if(s&&i<n.height&&a>n.height?o=t.replace("bottom","top"):!s&&t.startsWith("top")&&a<n.height&&i>n.height&&(o=t.replace("top","bottom")),t.includes("-")){let l=t.endsWith("left"),c=e.width-r.right,u=r.left;l&&c<n.width&&u>n.width?o=o.replace("left","right"):!l&&c<n.width&&u>n.width&&(o=o.replace("right","left"))}return o},x=(n,r,t,e)=>{if(!r)return{top:0,left:0};let o=window.scrollY,s=window.scrollX,i=e||0,a=0;t.startsWith("bottom")?a=r.bottom+o+i:t.startsWith("top")?a=r.top+o-(n?.height||0)-i:a=r.top+o+r.height/2-(n?.height||0)/2;let l=0;return t==="left"?l=r.left+s-(n?.width||0)-i:t==="right"?l=r.right+s+i:t.endsWith("left")||t==="bottom"||t==="top"?l=r.left+s:t.endsWith("right")&&(l=r.right+s-(n?.width||0)),(t==="bottom"||t==="top")&&(l=r.left+s+r.width/2-(n?.width||0)/2),{top:a,left:l}};import{useEffect as z,useMemo as F,useState as I}from"react";var Ee=({triggerRef:n,targetRef:r,position:t="bottom-left",offset:e=8,isOpen:o})=>{let[s,i]=I(!1),{positionStyles:a,optimalPosition:l}=F(()=>{if(s&&r.current&&n.current){let c=r.current.getBoundingClientRect(),u=n.current.getBoundingClientRect(),f=T(c,u,t);return{positionStyles:x(c,u,f,e),optimalPosition:f}}return{positionStyles:{top:0,left:0},optimal:t}},[n,r,t,e,s]);return z(()=>{i(!!o)},[o]),{positionStyles:a,optimalPosition:l,isMounted:s}};import{useCallback as h,useState as N}from"react";var De=n=>{let[r,t]=N(n),e=h((i,a)=>{t(l=>(l[i]=a,{...l}))},[]),o=h(()=>{t(n)},[n]),s=h(i=>{t(a=>(delete a[i],{...a}))},[]);return{errors:r,setError:e,setErrors:t,clearError:s,clearErrors:o}};import{useEffect as H}from"react";var Re=({ref:n,skip:r},t)=>{H(()=>{let e=n.current;if(!e||r)return;let o=e.offsetWidth;e.style.width=`${o}px`,requestAnimationFrame(()=>{e.style.width="auto";let s=e.offsetWidth;e.style.width=`${o}px`,e.offsetHeight,e.style.width=`${s}px`;let i=()=>{e&&(e.style.width="auto"),e?.removeEventListener("transitionend",i)};e.addEventListener("transitionend",i)})},t)};import{create as G}from"zustand";import{persist as q}from"zustand/middleware";var S="--cleen-",K=["white","black","gray","pink","purple","indigo","blue","primary","success","warning","error","brand","sidebar","background"],ze=G()(q((n,r)=>({colors:{},getColors:()=>{let t=r().colors;return K.reduce((e,o)=>(t[o]?e[o]=t[o]:e[o]=getComputedStyle(document.documentElement).getPropertyValue(`${S}${o}`),e),{})},getColor:t=>{let e=r().colors;return e[t]?e[t]:getComputedStyle(document.documentElement).getPropertyValue(`${S}${t}`)},setColors:t=>Object.entries(t).map(([e,o])=>n(s=>({colors:{...s.colors,[e]:o}}))),setColor:(t,e)=>{n(o=>({colors:{...o.colors,[t]:e}}))},resetColors:()=>{n({colors:{}})},resetColor:t=>{let e=r().colors;delete e[t],n({colors:e})}}),{name:"cleen-colors"}));import{create as X}from"zustand";import{persist as J}from"zustand/middleware";var He=X()(J(n=>({overlays:[],addOverlay:r=>{n(t=>({overlays:[...t.overlays,r]}))},removeOverlay:r=>{n(t=>({overlays:t.overlays.filter(e=>e!==r)}))},clearOverlays:()=>{n({overlays:[]})}}),{name:"cleen-overlays"}));var Y=n=>{let{numberOfChannels:r,sampleRate:t,length:e}=n,o=16,s=r*o/8,i=t*s,a=e*s,l=new ArrayBuffer(44+a),c=new DataView(l),u=(m,p)=>{for(let d=0;d<p.length;d++)c.setUint8(m+d,p.charCodeAt(d))};u(0,"RIFF"),c.setUint32(4,36+a,!0),u(8,"WAVE"),u(12,"fmt "),c.setUint32(16,16,!0),c.setUint16(20,1,!0),c.setUint16(22,r,!0),c.setUint32(24,t,!0),c.setUint32(28,i,!0),c.setUint16(32,s,!0),c.setUint16(34,o,!0),u(36,"data"),c.setUint32(40,a,!0);let f=44;for(let m=0;m<e;m++)for(let p=0;p<r;p++){let d=Math.max(-1,Math.min(1,n.getChannelData(p)[m]));c.setInt16(f,d<0?d*32768:d*32767,!0),f+=2}return new Blob([l],{type:"audio/wav"})},qe=async(n,r,t)=>{let e=new AudioContext,o=await e.decodeAudioData(await n.arrayBuffer());await e.close();let{sampleRate:s,numberOfChannels:i}=o,a=Math.round(r*s),l=Math.round(t*s),c=l-a,u=new AudioContext().createBuffer(i,c,s);for(let f=0;f<i;f++)u.copyToChannel(o.getChannelData(f).subarray(a,l),f);return Y(u)};import Q from"clsx";import{createTailwindMerge as Z,getDefaultConfig as _}from"tailwind-merge";var ee=()=>({..._(),prefix:"cleen-"}),te=Z(ee),Ye=(...n)=>te(Q(n));import{darken as ne,getLuminance as k,lighten as oe,parseToRgba as g,toHex as re,toRgba as O}from"color2k";var v=class n{static deltaE(r,t){let e=n.rgb2lab(r),o=n.rgb2lab(t),s=e[0]-o[0],i=e[1]-o[1],a=e[2]-o[2],l=Math.sqrt(e[1]*e[1]+e[2]*e[2]),c=Math.sqrt(o[1]*o[1]+o[2]*o[2]),u=l-c,f=i*i+a*a-u*u;f=f<0?0:Math.sqrt(f);let m=1+.045*l,p=1+.015*l,d=s/1,w=u/m,C=f/p,y=d*d+w*w+C*C;return y<0?0:Math.sqrt(y)}static rgb2lab(r){let t=r[0]/255,e=r[1]/255,o=r[2]/255,s,i,a;return t=t>.04045?Math.pow((t+.055)/1.055,2.4):t/12.92,e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,o=o>.04045?Math.pow((o+.055)/1.055,2.4):o/12.92,s=(t*.4124+e*.3576+o*.1805)/.95047,i=(t*.2126+e*.7152+o*.0722)/1,a=(t*.0193+e*.1192+o*.9505)/1.08883,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,i=i>.008856?Math.pow(i,1/3):7.787*i+16/116,a=a>.008856?Math.pow(a,1/3):7.787*a+16/116,[116*i-16,500*(s-i),200*(i-a)]}static isSimilar(r,t,e=24){return n.deltaE(g(r),g(t))<e}static adjustColorForContrast(r,t=.25){let e=re(r),o=r;try{if((e.match(/^#f{2,}e{0,2}$/i)||k(e)>.98)&&(e="#ffffff"),k(e)>.6){let s=ne(e,t);o=O(s)}else{let s=oe(e,t);o=O(s)}return o}catch{return"rgba(var(--cleen-white)"}}static getComputedColor(r){if(!r?.includes("var("))return r;let t=r.match(/var\((--[^,)]+)/)?.[1];if(t&&typeof window<"u"){let e=getComputedStyle(document.documentElement).getPropertyValue(t).trim();return e?`rgb(${e})`:void 0}}static getComputedRgb(r){if(!r)return;if(!r?.includes("var(")){let[e,o,s]=g(r);return`${e}, ${o}, ${s}`}let t=r.match(/var\((--[^,)]+)/)?.[1];if(t&&typeof window<"u")return getComputedStyle(document.documentElement).getPropertyValue(t).trim()}static trasparentize(r,t=0){return`color-mix(in srgb, ${r} ${(1-t)*100}%, transparent)`}};var se="https://picsum.photos",et=n=>{let{width:r,height:t,grayscale:e,blur:o,seed:s}=n,i=se;s&&(i+=`/seed/${encodeURIComponent(s)}`),i+=`/${r}/${t||r}`;let a=new URLSearchParams;e&&a.append("grayscale",""),o&&a.append("blur",o.toString()),s&&a.append("seed",s);let l=a.toString();return l&&(i+=`?${l}`),i};function b(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)&&Object.prototype.toString.call(n)==="[object Object]"}function nt(n,r){let t=(o,s)=>{if(s===void 0)return e(o);if(b(o)&&b(s)){let i={};return new Set([...Object.keys(o),...Object.keys(s)]).forEach(l=>{let c=o[l],u=s[l];i[l]=t(c,u)}),i}return Array.isArray(o)||Array.isArray(s)?e(s===void 0?o:s):e(s!==void 0?s:o)},e=o=>{if(o!==void 0){if(o===null)return null;if(Array.isArray(o))return o.map(s=>e(s));if(b(o)){let s={};return Object.keys(o).forEach(i=>{s[i]=e(o[i])}),s}return o}};return t(n,r)}var rt=n=>{if(n===0||!n)return"0 B";let r=1024,t=["B","KB","MB","GB","TB"],e=Math.floor(Math.log(n)/Math.log(r));return Math.round(n/Math.pow(r,e))+" "+t[e]},st=n=>{let r=Math.floor(n/60),t=Math.floor(n%60);return`${String(r).padStart(2,"0")}:${String(t).padStart(2,"0")}`},it=n=>{let r=new Date(n),e=Math.abs(new Date().getTime()-r.getTime());return`Created ${Math.ceil(e/(1e3*60*60*24))} days ago`};export{v as ColorHelpers,nt as applyDefaults,T as calculateOptimalPosition,x as calculatePositionValues,Ye as cn,Y as encodeWav,st as formatAudioTime,rt as formatFileSize,it as getCreatedDate,et as getRandomImageUrl,qe as trimBlob,ae as useAnimateNumber,ze as useCleenColors,He as useCleenOverlays,ue as useControlled,de as useDebounce,ge as useDisclosure,Ce as useForm,Te as useOutsideClick,ke as usePaginationState,Ee as usePositionClose,De as useValidation,Re as useWidthDynamicResize};
|