@springbrand/gravel 0.1.0

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.
Files changed (39) hide show
  1. package/dist/components/ui-base/index.d.ts +1 -0
  2. package/dist/components/ui-base/responsive-dialog/index.d.ts +55 -0
  3. package/dist/components/ui-base/responsive-dialog/index.js +116 -0
  4. package/dist/components/ui-block/background/index.d.ts +8 -0
  5. package/dist/components/ui-block/background/index.js +51 -0
  6. package/dist/components/ui-block/cover/index.d.ts +17 -0
  7. package/dist/components/ui-block/cover/index.js +232 -0
  8. package/dist/components/ui-block/index.d.ts +4 -0
  9. package/dist/components/ui-block/sparkles/index.d.ts +13 -0
  10. package/dist/components/ui-block/sparkles/index.js +287 -0
  11. package/dist/components/ui-block/spotlight/index.d.ts +13 -0
  12. package/dist/components/ui-block/spotlight/index.js +158 -0
  13. package/dist/hooks/use-media-query.d.ts +1 -0
  14. package/dist/hooks/use-media-query.js +15 -0
  15. package/dist/hooks/use-prefers-reduced-motion.d.ts +1 -0
  16. package/dist/hooks/use-prefers-reduced-motion.js +23 -0
  17. package/dist/hooks/use-scroll-container.d.ts +18 -0
  18. package/dist/hooks/use-scroll-container.js +25 -0
  19. package/dist/index.d.ts +6 -0
  20. package/dist/index.js +57 -0
  21. package/dist/utils/css-utils.d.ts +10 -0
  22. package/dist/utils/css-utils.js +17 -0
  23. package/dist/utils/index.d.ts +9 -0
  24. package/dist/utils/index.js +34 -0
  25. package/dist/utils/storage-qetag.d.ts +22 -0
  26. package/dist/utils/storage-qetag.js +101 -0
  27. package/dist/utils/utils-api.d.ts +17 -0
  28. package/dist/utils/utils-api.js +31 -0
  29. package/dist/utils/utils-canvas.d.ts +30 -0
  30. package/dist/utils/utils-canvas.js +54 -0
  31. package/dist/utils/utils-common.d.ts +6 -0
  32. package/dist/utils/utils-common.js +15 -0
  33. package/dist/utils/utils-image.d.ts +33 -0
  34. package/dist/utils/utils-image.js +57 -0
  35. package/dist/utils/utils-random.d.ts +1 -0
  36. package/dist/utils/utils-random.js +6 -0
  37. package/dist/utils/utils-time.d.ts +49 -0
  38. package/dist/utils/utils-time.js +112 -0
  39. package/package.json +386 -0
@@ -0,0 +1,287 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { cn } from "../../../utils/css-utils.js";
4
+ import Particles, { initParticlesEngine } from "@tsparticles/react";
5
+ import { loadSlim } from "@tsparticles/slim";
6
+ import { useAnimation, motion } from "motion/react";
7
+ import { useState, useEffect, useId } from "react";
8
+ const SparklesCore = (props) => {
9
+ const {
10
+ id,
11
+ className,
12
+ background,
13
+ minSize,
14
+ maxSize,
15
+ speed,
16
+ particleColor,
17
+ particleDensity
18
+ } = props;
19
+ const [init, setInit] = useState(false);
20
+ useEffect(() => {
21
+ initParticlesEngine(async (engine) => {
22
+ await loadSlim(engine);
23
+ }).then(() => {
24
+ setInit(true);
25
+ });
26
+ }, []);
27
+ const controls = useAnimation();
28
+ const particlesLoaded = async (container) => {
29
+ if (container) {
30
+ controls.start({
31
+ opacity: 1,
32
+ transition: {
33
+ duration: 1
34
+ }
35
+ });
36
+ }
37
+ };
38
+ const generatedId = useId();
39
+ return /* @__PURE__ */ jsx(motion.div, { animate: controls, className: cn("opacity-0", className), children: init && /* @__PURE__ */ jsx(
40
+ Particles,
41
+ {
42
+ id: id || generatedId,
43
+ className: cn("h-full w-full"),
44
+ particlesLoaded,
45
+ options: {
46
+ background: {
47
+ color: {
48
+ value: background || "#0d47a1"
49
+ }
50
+ },
51
+ fullScreen: {
52
+ enable: false,
53
+ zIndex: 1
54
+ },
55
+ fpsLimit: 120,
56
+ interactivity: {
57
+ events: {
58
+ onClick: {
59
+ enable: true,
60
+ mode: "push"
61
+ },
62
+ onHover: {
63
+ enable: false,
64
+ mode: "repulse"
65
+ },
66
+ resize: true
67
+ },
68
+ modes: {
69
+ push: {
70
+ quantity: 4
71
+ },
72
+ repulse: {
73
+ distance: 200,
74
+ duration: 0.4
75
+ }
76
+ }
77
+ },
78
+ particles: {
79
+ bounce: {
80
+ horizontal: {
81
+ value: 1
82
+ },
83
+ vertical: {
84
+ value: 1
85
+ }
86
+ },
87
+ collisions: {
88
+ absorb: {
89
+ speed: 2
90
+ },
91
+ bounce: {
92
+ horizontal: {
93
+ value: 1
94
+ },
95
+ vertical: {
96
+ value: 1
97
+ }
98
+ },
99
+ enable: false,
100
+ maxSpeed: 50,
101
+ mode: "bounce",
102
+ overlap: {
103
+ enable: true,
104
+ retries: 0
105
+ }
106
+ },
107
+ color: {
108
+ value: particleColor || "#ffffff",
109
+ animation: {
110
+ h: {
111
+ count: 0,
112
+ enable: false,
113
+ speed: 1,
114
+ decay: 0,
115
+ delay: 0,
116
+ sync: true,
117
+ offset: 0
118
+ },
119
+ s: {
120
+ count: 0,
121
+ enable: false,
122
+ speed: 1,
123
+ decay: 0,
124
+ delay: 0,
125
+ sync: true,
126
+ offset: 0
127
+ },
128
+ l: {
129
+ count: 0,
130
+ enable: false,
131
+ speed: 1,
132
+ decay: 0,
133
+ delay: 0,
134
+ sync: true,
135
+ offset: 0
136
+ }
137
+ }
138
+ },
139
+ effect: {
140
+ close: true,
141
+ fill: true,
142
+ options: {},
143
+ type: {}
144
+ },
145
+ groups: {},
146
+ move: {
147
+ angle: {
148
+ offset: 0,
149
+ value: 90
150
+ },
151
+ attract: {
152
+ distance: 200,
153
+ enable: false,
154
+ rotate: {
155
+ x: 3e3,
156
+ y: 3e3
157
+ }
158
+ },
159
+ center: {
160
+ x: 50,
161
+ y: 50,
162
+ mode: "percent",
163
+ radius: 0
164
+ },
165
+ decay: 0,
166
+ distance: {},
167
+ direction: "none",
168
+ drift: 0,
169
+ enable: true,
170
+ gravity: {
171
+ acceleration: 9.81,
172
+ enable: false,
173
+ inverse: false,
174
+ maxSpeed: 50
175
+ },
176
+ path: {
177
+ clamp: true,
178
+ delay: {
179
+ value: 0
180
+ },
181
+ enable: false,
182
+ options: {}
183
+ },
184
+ outModes: {
185
+ default: "out"
186
+ },
187
+ random: false,
188
+ size: false,
189
+ speed: {
190
+ min: 0.1,
191
+ max: 1
192
+ },
193
+ spin: {
194
+ acceleration: 0,
195
+ enable: false
196
+ },
197
+ straight: false,
198
+ trail: {
199
+ enable: false,
200
+ length: 10,
201
+ fill: {}
202
+ },
203
+ vibrate: false,
204
+ warp: false
205
+ },
206
+ number: {
207
+ density: {
208
+ enable: true,
209
+ width: 400,
210
+ height: 400
211
+ },
212
+ limit: {
213
+ mode: "delete",
214
+ value: 0
215
+ },
216
+ value: particleDensity || 120
217
+ },
218
+ opacity: {
219
+ value: {
220
+ min: 0.1,
221
+ max: 1
222
+ },
223
+ animation: {
224
+ count: 0,
225
+ enable: true,
226
+ speed: speed || 4,
227
+ decay: 0,
228
+ delay: 0,
229
+ sync: false,
230
+ mode: "auto",
231
+ startValue: "random",
232
+ destroy: "none"
233
+ }
234
+ },
235
+ reduceDuplicates: false,
236
+ shadow: {
237
+ blur: 0,
238
+ color: {
239
+ value: "#000"
240
+ },
241
+ enable: false,
242
+ offset: {
243
+ x: 0,
244
+ y: 0
245
+ }
246
+ },
247
+ shape: {
248
+ close: true,
249
+ fill: true,
250
+ options: {},
251
+ type: "circle"
252
+ },
253
+ size: {
254
+ value: {
255
+ min: minSize || 1,
256
+ max: maxSize || 3
257
+ },
258
+ animation: {
259
+ count: 0,
260
+ enable: false,
261
+ speed: 5,
262
+ decay: 0,
263
+ delay: 0,
264
+ sync: false,
265
+ mode: "auto",
266
+ startValue: "random",
267
+ destroy: "none"
268
+ }
269
+ },
270
+ stroke: {
271
+ width: 0
272
+ },
273
+ zIndex: {
274
+ value: 0,
275
+ opacityRate: 1,
276
+ sizeRate: 1,
277
+ velocityRate: 1
278
+ }
279
+ },
280
+ detectRetina: true
281
+ }
282
+ }
283
+ ) });
284
+ };
285
+ export {
286
+ SparklesCore
287
+ };
@@ -0,0 +1,13 @@
1
+ type SpotlightProps = {
2
+ gradientFirst?: string;
3
+ gradientSecond?: string;
4
+ gradientThird?: string;
5
+ translateY?: number;
6
+ width?: number;
7
+ height?: number;
8
+ smallWidth?: number;
9
+ duration?: number;
10
+ xOffset?: number;
11
+ };
12
+ export declare const Spotlight: ({ gradientFirst, gradientSecond, gradientThird, translateY, width, height, smallWidth, duration, xOffset, }?: SpotlightProps) => import("react/jsx-runtime").JSX.Element | null;
13
+ export {};
@@ -0,0 +1,158 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { motion } from "motion/react";
3
+ import { useState, useEffect, useMemo } from "react";
4
+ const Spotlight = ({
5
+ gradientFirst,
6
+ gradientSecond,
7
+ gradientThird,
8
+ translateY = -350,
9
+ width = 560,
10
+ height = 1380,
11
+ smallWidth = 240,
12
+ duration = 7,
13
+ xOffset = 100
14
+ } = {}) => {
15
+ const [mounted, setMounted] = useState(false);
16
+ useEffect(() => setMounted(true), []);
17
+ const isDark = true;
18
+ const { firstBg, secondBg, thirdBg } = useMemo(() => {
19
+ const darkDefaults = {
20
+ first: "radial-gradient(68.54% 68.72% at 55.02% 31.46%, hsla(210, 100%, 85%, .08) 0, hsla(210, 100%, 55%, .02) 50%, hsla(210, 100%, 45%, 0) 80%)",
21
+ second: "radial-gradient(50% 50% at 50% 50%, hsla(210, 100%, 85%, .06) 0, hsla(210, 100%, 55%, .02) 80%, transparent 100%)",
22
+ third: "radial-gradient(50% 50% at 50% 50%, hsla(210, 100%, 85%, .04) 0, hsla(210, 100%, 45%, .02) 80%, transparent 100%)"
23
+ };
24
+ const themeDefaults = darkDefaults;
25
+ return {
26
+ firstBg: gradientFirst ?? themeDefaults.first,
27
+ secondBg: gradientSecond ?? themeDefaults.second,
28
+ thirdBg: gradientThird ?? themeDefaults.third
29
+ };
30
+ }, [gradientFirst, gradientSecond, gradientThird, isDark]);
31
+ if (!mounted) return null;
32
+ return /* @__PURE__ */ jsxs(
33
+ motion.div,
34
+ {
35
+ initial: {
36
+ opacity: 0
37
+ },
38
+ animate: {
39
+ opacity: 1
40
+ },
41
+ transition: {
42
+ duration: 1.5
43
+ },
44
+ className: "pointer-events-none absolute inset-0 h-full w-full",
45
+ children: [
46
+ /* @__PURE__ */ jsxs(
47
+ motion.div,
48
+ {
49
+ animate: {
50
+ x: [0, xOffset, 0]
51
+ },
52
+ transition: {
53
+ duration,
54
+ repeat: Infinity,
55
+ repeatType: "reverse",
56
+ ease: "easeInOut"
57
+ },
58
+ className: "pointer-events-none absolute top-0 left-0 z-40 h-screen w-screen",
59
+ children: [
60
+ /* @__PURE__ */ jsx(
61
+ "div",
62
+ {
63
+ style: {
64
+ transform: `translateY(${translateY}px) rotate(-45deg)`,
65
+ background: firstBg,
66
+ width: `${width}px`,
67
+ height: `${height}px`
68
+ },
69
+ className: "absolute top-0 left-0"
70
+ }
71
+ ),
72
+ /* @__PURE__ */ jsx(
73
+ "div",
74
+ {
75
+ style: {
76
+ transform: "rotate(-45deg) translate(5%, -50%)",
77
+ background: secondBg,
78
+ width: `${smallWidth}px`,
79
+ height: `${height}px`
80
+ },
81
+ className: "absolute top-0 left-0 origin-top-left"
82
+ }
83
+ ),
84
+ /* @__PURE__ */ jsx(
85
+ "div",
86
+ {
87
+ style: {
88
+ transform: "rotate(-45deg) translate(-180%, -70%)",
89
+ background: thirdBg,
90
+ width: `${smallWidth}px`,
91
+ height: `${height}px`
92
+ },
93
+ className: "absolute top-0 left-0 origin-top-left"
94
+ }
95
+ )
96
+ ]
97
+ }
98
+ ),
99
+ /* @__PURE__ */ jsxs(
100
+ motion.div,
101
+ {
102
+ animate: {
103
+ x: [0, -xOffset, 0]
104
+ },
105
+ transition: {
106
+ duration,
107
+ repeat: Infinity,
108
+ repeatType: "reverse",
109
+ ease: "easeInOut"
110
+ },
111
+ className: "pointer-events-none absolute top-0 right-0 z-40 h-screen w-screen",
112
+ children: [
113
+ /* @__PURE__ */ jsx(
114
+ "div",
115
+ {
116
+ style: {
117
+ transform: `translateY(${translateY}px) rotate(45deg)`,
118
+ background: firstBg,
119
+ width: `${width}px`,
120
+ height: `${height}px`
121
+ },
122
+ className: "absolute top-0 right-0"
123
+ }
124
+ ),
125
+ /* @__PURE__ */ jsx(
126
+ "div",
127
+ {
128
+ style: {
129
+ transform: "rotate(45deg) translate(-5%, -50%)",
130
+ background: secondBg,
131
+ width: `${smallWidth}px`,
132
+ height: `${height}px`
133
+ },
134
+ className: "absolute top-0 right-0 origin-top-right"
135
+ }
136
+ ),
137
+ /* @__PURE__ */ jsx(
138
+ "div",
139
+ {
140
+ style: {
141
+ transform: "rotate(45deg) translate(180%, -70%)",
142
+ background: thirdBg,
143
+ width: `${smallWidth}px`,
144
+ height: `${height}px`
145
+ },
146
+ className: "absolute top-0 right-0 origin-top-right"
147
+ }
148
+ )
149
+ ]
150
+ }
151
+ )
152
+ ]
153
+ }
154
+ );
155
+ };
156
+ export {
157
+ Spotlight
158
+ };
@@ -0,0 +1 @@
1
+ export declare function useMediaQuery(query: string): boolean;
@@ -0,0 +1,15 @@
1
+ import { useState, useEffect } from "react";
2
+ function useMediaQuery(query) {
3
+ const [matches, setMatches] = useState(false);
4
+ useEffect(() => {
5
+ const mql = window.matchMedia(query);
6
+ const onChange = () => setMatches(mql.matches);
7
+ mql.addEventListener("change", onChange);
8
+ setMatches(mql.matches);
9
+ return () => mql.removeEventListener("change", onChange);
10
+ }, [query]);
11
+ return matches;
12
+ }
13
+ export {
14
+ useMediaQuery
15
+ };
@@ -0,0 +1 @@
1
+ export declare function usePrefersReducedMotion(): boolean;
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ const QUERY = "(prefers-reduced-motion: no-preference)";
3
+ const isRenderingOnServer = typeof window === "undefined";
4
+ const getInitialState = () => {
5
+ return isRenderingOnServer ? true : !window.matchMedia(QUERY).matches;
6
+ };
7
+ function usePrefersReducedMotion() {
8
+ const [prefersReducedMotion, setPrefersReducedMotion] = React.useState(getInitialState);
9
+ React.useEffect(() => {
10
+ const mediaQueryList = window.matchMedia(QUERY);
11
+ const listener = (event) => {
12
+ setPrefersReducedMotion(!event.matches);
13
+ };
14
+ mediaQueryList.addEventListener("change", listener);
15
+ return () => {
16
+ mediaQueryList.removeEventListener("change", listener);
17
+ };
18
+ }, []);
19
+ return prefersReducedMotion;
20
+ }
21
+ export {
22
+ usePrefersReducedMotion
23
+ };
@@ -0,0 +1,18 @@
1
+ import { type RefObject } from "react";
2
+ /**
3
+ * 自动查找目标元素最近的可滚动祖先,返回一个 ref 供 framer-motion useScroll 的 container 使用。
4
+ *
5
+ * 解决:在 Puck 编辑器 iframe 中,滚动发生在 iframe 内部容器(而非 window),
6
+ * useScroll({ target }) 默认找不到正确的滚动容器。
7
+ *
8
+ * @returns [containerRef, ready] — ready 为 true 时 containerRef 已就绪
9
+ *
10
+ * @example
11
+ * const targetRef = useRef(null);
12
+ * const [containerRef, ready] = useScrollContainer(targetRef);
13
+ * const { scrollYProgress } = useScroll({
14
+ * target: targetRef,
15
+ * container: containerRef,
16
+ * });
17
+ */
18
+ export declare function useScrollContainer<T extends HTMLElement>(targetRef: RefObject<T | null>): [RefObject<HTMLElement | null>, boolean];
@@ -0,0 +1,25 @@
1
+ import { useRef, useState, useLayoutEffect } from "react";
2
+ function useScrollContainer(targetRef) {
3
+ const containerRef = useRef(null);
4
+ const [ready, setReady] = useState(false);
5
+ useLayoutEffect(() => {
6
+ const el = targetRef.current;
7
+ if (!el) return;
8
+ let ancestor = el.parentElement;
9
+ while (ancestor && ancestor !== document.documentElement) {
10
+ const { overflowY } = getComputedStyle(ancestor);
11
+ if (overflowY === "auto" || overflowY === "scroll") {
12
+ containerRef.current = ancestor;
13
+ setReady(true);
14
+ return;
15
+ }
16
+ ancestor = ancestor.parentElement;
17
+ }
18
+ containerRef.current = null;
19
+ setReady(true);
20
+ }, [targetRef]);
21
+ return [containerRef, ready];
22
+ }
23
+ export {
24
+ useScrollContainer
25
+ };
@@ -0,0 +1,6 @@
1
+ export * from "./components/ui-base/index.ts";
2
+ export * from "./components/ui-block/index.ts";
3
+ export * from "./hooks/use-media-query.ts";
4
+ export * from "./hooks/use-prefers-reduced-motion.ts";
5
+ export * from "./hooks/use-scroll-container.ts";
6
+ export * from "./utils/index.ts";
package/dist/index.js ADDED
@@ -0,0 +1,57 @@
1
+ import { useMediaQuery } from "./hooks/use-media-query.js";
2
+ import { usePrefersReducedMotion } from "./hooks/use-prefers-reduced-motion.js";
3
+ import { useScrollContainer } from "./hooks/use-scroll-container.js";
4
+ import { filterEmptyValues } from "./utils/utils-common.js";
5
+ import { formatLargeNumber, getUrlWithParams } from "./utils/utils-api.js";
6
+ import { formatTimeAgo, formatTimeString, getTimeDetails, getTimestamp, sleep, timeAgo } from "./utils/utils-time.js";
7
+ import { base64ToFile, base64ToUrl, blobToBase64, blobToUrl, convertBase64ToBlob, structureFile } from "./utils/utils-canvas.js";
8
+ import { cn, liquidGlass } from "./utils/css-utils.js";
9
+ import "./utils/storage-qetag.js";
10
+ import { downloadImage, downloadImageClient, fetchHasOnlineFile, getBase64Client, isValidFileSize, isValidFileType } from "./utils/utils-image.js";
11
+ import { nanoid } from "./utils/utils-random.js";
12
+ import { default as default2 } from "./components/ui-block/background/index.js";
13
+ import { Cover } from "./components/ui-block/cover/index.js";
14
+ import { ResponsiveDialog, ResponsiveDialogClose, ResponsiveDialogContent, ResponsiveDialogDescription, ResponsiveDialogFooter, ResponsiveDialogHeader, ResponsiveDialogTitle, ResponsiveDialogTrigger } from "./components/ui-base/responsive-dialog/index.js";
15
+ import { SparklesCore } from "./components/ui-block/sparkles/index.js";
16
+ import { Spotlight } from "./components/ui-block/spotlight/index.js";
17
+ export {
18
+ default2 as Background,
19
+ Cover,
20
+ ResponsiveDialog,
21
+ ResponsiveDialogClose,
22
+ ResponsiveDialogContent,
23
+ ResponsiveDialogDescription,
24
+ ResponsiveDialogFooter,
25
+ ResponsiveDialogHeader,
26
+ ResponsiveDialogTitle,
27
+ ResponsiveDialogTrigger,
28
+ SparklesCore,
29
+ Spotlight,
30
+ base64ToFile,
31
+ base64ToUrl,
32
+ blobToBase64,
33
+ blobToUrl,
34
+ cn,
35
+ convertBase64ToBlob,
36
+ downloadImage,
37
+ downloadImageClient,
38
+ fetchHasOnlineFile,
39
+ filterEmptyValues,
40
+ formatLargeNumber,
41
+ formatTimeAgo,
42
+ formatTimeString,
43
+ getBase64Client,
44
+ getTimeDetails,
45
+ getTimestamp,
46
+ getUrlWithParams,
47
+ isValidFileSize,
48
+ isValidFileType,
49
+ liquidGlass,
50
+ nanoid,
51
+ sleep,
52
+ structureFile,
53
+ timeAgo,
54
+ useMediaQuery,
55
+ usePrefersReducedMotion,
56
+ useScrollContainer
57
+ };
@@ -0,0 +1,10 @@
1
+ import { type ClassValue } from "clsx";
2
+ /**
3
+ * 合并CSS类名,支持条件类名和Tailwind冲突解决
4
+ * 支持Fluid Tailwind功能
5
+ */
6
+ export declare function cn(...inputs: ClassValue[]): string;
7
+ /**
8
+ * 液体玻璃效果样式
9
+ */
10
+ export declare function liquidGlass(...args: ClassValue[]): string;
@@ -0,0 +1,17 @@
1
+ import { withFluid } from "@fluid-tailwind/tailwind-merge";
2
+ import { clsx } from "clsx";
3
+ import { extendTailwindMerge } from "tailwind-merge";
4
+ const twMerge = extendTailwindMerge({}, withFluid);
5
+ function cn(...inputs) {
6
+ return twMerge(clsx(inputs));
7
+ }
8
+ function liquidGlass(...args) {
9
+ return cn(
10
+ "shadow-[0px_-1px_0px_0px_#FFFFFF40_inset,_0px_1px_0px_0px_#FFFFFF40_inset]",
11
+ args
12
+ );
13
+ }
14
+ export {
15
+ cn,
16
+ liquidGlass
17
+ };
@@ -0,0 +1,9 @@
1
+ export * from "./utils-common.ts";
2
+ export * from "./utils-api.ts";
3
+ export * from "./utils-time.ts";
4
+ export * from "./utils-canvas.ts";
5
+ export * from "./css-utils.ts";
6
+ export * from "./storage-qetag.ts";
7
+ export * from "./utils-image.ts";
8
+ export * from "./utils-time.ts";
9
+ export * from "./utils-random.ts";
@@ -0,0 +1,34 @@
1
+ import { filterEmptyValues } from "./utils-common.js";
2
+ import { formatLargeNumber, getUrlWithParams } from "./utils-api.js";
3
+ import { formatTimeAgo, formatTimeString, getTimeDetails, getTimestamp, sleep, timeAgo } from "./utils-time.js";
4
+ import { base64ToFile, base64ToUrl, blobToBase64, blobToUrl, convertBase64ToBlob, structureFile } from "./utils-canvas.js";
5
+ import { cn, liquidGlass } from "./css-utils.js";
6
+ import "./storage-qetag.js";
7
+ import { downloadImage, downloadImageClient, fetchHasOnlineFile, getBase64Client, isValidFileSize, isValidFileType } from "./utils-image.js";
8
+ import { nanoid } from "./utils-random.js";
9
+ export {
10
+ base64ToFile,
11
+ base64ToUrl,
12
+ blobToBase64,
13
+ blobToUrl,
14
+ cn,
15
+ convertBase64ToBlob,
16
+ downloadImage,
17
+ downloadImageClient,
18
+ fetchHasOnlineFile,
19
+ filterEmptyValues,
20
+ formatLargeNumber,
21
+ formatTimeAgo,
22
+ formatTimeString,
23
+ getBase64Client,
24
+ getTimeDetails,
25
+ getTimestamp,
26
+ getUrlWithParams,
27
+ isValidFileSize,
28
+ isValidFileType,
29
+ liquidGlass,
30
+ nanoid,
31
+ sleep,
32
+ structureFile,
33
+ timeAgo
34
+ };