@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 @@
1
+ export { ResponsiveDialog, ResponsiveDialogTrigger, ResponsiveDialogClose, ResponsiveDialogContent, ResponsiveDialogHeader, ResponsiveDialogFooter, ResponsiveDialogTitle, ResponsiveDialogDescription, } from "./responsive-dialog/index.tsx";
@@ -0,0 +1,55 @@
1
+ import * as React from "react";
2
+ type ResponsiveMode = "auto" | "dialog" | "drawer";
3
+ type ResponsiveDialogProps = {
4
+ /** 'auto' 会按 useIsMobile() 判断;也可强制 'dialog' / 'drawer' */
5
+ mode?: ResponsiveMode;
6
+ open?: boolean;
7
+ defaultOpen?: boolean;
8
+ onOpenChange?: (open: boolean) => void;
9
+ modal?: boolean;
10
+ children?: React.ReactNode;
11
+ /** drawer 模式透传:方向、snap 等 */
12
+ drawerProps?: Record<string, any>;
13
+ /** dialog 模式透传 */
14
+ dialogProps?: Record<string, any>;
15
+ };
16
+ declare function ResponsiveDialog({ mode, children, drawerProps, dialogProps, ...props }: ResponsiveDialogProps): import("react/jsx-runtime").JSX.Element;
17
+ type TriggerProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
18
+ asChild?: boolean;
19
+ children?: React.ReactNode;
20
+ };
21
+ declare function ResponsiveDialogTrigger(props: TriggerProps): import("react/jsx-runtime").JSX.Element;
22
+ type CloseProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
23
+ asChild?: boolean;
24
+ children?: React.ReactNode;
25
+ };
26
+ declare function ResponsiveDialogClose(props: CloseProps): import("react/jsx-runtime").JSX.Element;
27
+ type ResponsiveDialogContentProps = React.HTMLAttributes<HTMLDivElement> & {
28
+ /** dialog 专属:是否展示右上角关闭按钮 */
29
+ showCloseButton?: boolean;
30
+ /** 仅 dialog 模式追加的 className */
31
+ dialogClassName?: string;
32
+ /** 仅 drawer 模式追加的 className */
33
+ drawerClassName?: string;
34
+ onEscapeKeyDown?: (e: KeyboardEvent) => void;
35
+ onPointerDownOutside?: (e: Event) => void;
36
+ };
37
+ declare function ResponsiveDialogContent({ className, dialogClassName, drawerClassName, children, showCloseButton, onEscapeKeyDown, onPointerDownOutside, ...props }: ResponsiveDialogContentProps): import("react/jsx-runtime").JSX.Element;
38
+ type HeaderProps = React.ComponentProps<"div">;
39
+ declare function ResponsiveDialogHeader(props: HeaderProps): import("react/jsx-runtime").JSX.Element;
40
+ type FooterProps = React.ComponentProps<"div"> & {
41
+ /** dialog 专属 */
42
+ showCloseButton?: boolean;
43
+ };
44
+ declare function ResponsiveDialogFooter({ showCloseButton, className, ...props }: FooterProps): import("react/jsx-runtime").JSX.Element;
45
+ type TitleProps = React.HTMLAttributes<HTMLHeadingElement> & {
46
+ asChild?: boolean;
47
+ children?: React.ReactNode;
48
+ };
49
+ declare function ResponsiveDialogTitle(props: TitleProps): import("react/jsx-runtime").JSX.Element;
50
+ type DescriptionProps = React.HTMLAttributes<HTMLParagraphElement> & {
51
+ asChild?: boolean;
52
+ children?: React.ReactNode;
53
+ };
54
+ declare function ResponsiveDialogDescription(props: DescriptionProps): import("react/jsx-runtime").JSX.Element;
55
+ export { ResponsiveDialog, ResponsiveDialogTrigger, ResponsiveDialogClose, ResponsiveDialogContent, ResponsiveDialogHeader, ResponsiveDialogFooter, ResponsiveDialogTitle, ResponsiveDialogDescription, };
@@ -0,0 +1,116 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { Dialog, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription } from "@springbrand/site-block/components/shadcn/dialog";
4
+ import { Drawer, DrawerTrigger, DrawerClose, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription } from "@springbrand/site-block/components/shadcn/drawer";
5
+ import { useIsMobile } from "@springbrand/site-block/hooks/use-mobile";
6
+ import { cn } from "@springbrand/site-block/lib/utils";
7
+ const ResponsiveDialogContext = React.createContext(null);
8
+ function useResponsiveDialogContext() {
9
+ const ctx = React.useContext(ResponsiveDialogContext);
10
+ if (!ctx) {
11
+ throw new Error(
12
+ "ResponsiveDialog.* components must be used inside <ResponsiveDialog>"
13
+ );
14
+ }
15
+ return ctx;
16
+ }
17
+ function ResponsiveDialog({
18
+ mode = "auto",
19
+ children,
20
+ drawerProps,
21
+ dialogProps,
22
+ ...props
23
+ }) {
24
+ const isMobile = useIsMobile();
25
+ const resolved = mode === "auto" ? isMobile ? "drawer" : "dialog" : mode;
26
+ const value = React.useMemo(
27
+ () => ({ mode: resolved }),
28
+ [resolved]
29
+ );
30
+ return /* @__PURE__ */ jsx(ResponsiveDialogContext.Provider, { value, children: resolved === "drawer" ? /* @__PURE__ */ jsx(Drawer, { ...props, ...drawerProps, children }) : /* @__PURE__ */ jsx(Dialog, { ...props, ...dialogProps, children }) });
31
+ }
32
+ function ResponsiveDialogTrigger(props) {
33
+ const { mode } = useResponsiveDialogContext();
34
+ const Comp = mode === "drawer" ? DrawerTrigger : DialogTrigger;
35
+ return /* @__PURE__ */ jsx(Comp, { ...props });
36
+ }
37
+ function ResponsiveDialogClose(props) {
38
+ const { mode } = useResponsiveDialogContext();
39
+ const Comp = mode === "drawer" ? DrawerClose : DialogClose;
40
+ return /* @__PURE__ */ jsx(Comp, { ...props });
41
+ }
42
+ function ResponsiveDialogContent({
43
+ className,
44
+ dialogClassName,
45
+ drawerClassName,
46
+ children,
47
+ showCloseButton,
48
+ onEscapeKeyDown,
49
+ onPointerDownOutside,
50
+ ...props
51
+ }) {
52
+ const { mode } = useResponsiveDialogContext();
53
+ if (mode === "drawer") {
54
+ return /* @__PURE__ */ jsx(
55
+ DrawerContent,
56
+ {
57
+ className: cn(className, drawerClassName),
58
+ ...props,
59
+ children
60
+ }
61
+ );
62
+ }
63
+ return /* @__PURE__ */ jsx(
64
+ DialogContent,
65
+ {
66
+ className: cn(className, dialogClassName),
67
+ showCloseButton,
68
+ onEscapeKeyDown,
69
+ onPointerDownOutside,
70
+ ...props,
71
+ children
72
+ }
73
+ );
74
+ }
75
+ function ResponsiveDialogHeader(props) {
76
+ const { mode } = useResponsiveDialogContext();
77
+ return mode === "drawer" ? /* @__PURE__ */ jsx(DrawerHeader, { ...props }) : /* @__PURE__ */ jsx(DialogHeader, { ...props });
78
+ }
79
+ function ResponsiveDialogFooter({
80
+ showCloseButton,
81
+ className,
82
+ ...props
83
+ }) {
84
+ const { mode } = useResponsiveDialogContext();
85
+ if (mode === "drawer") {
86
+ return /* @__PURE__ */ jsx(DrawerFooter, { className: cn("flex-col-reverse", className), ...props });
87
+ }
88
+ return /* @__PURE__ */ jsx(
89
+ DialogFooter,
90
+ {
91
+ showCloseButton,
92
+ className,
93
+ ...props
94
+ }
95
+ );
96
+ }
97
+ function ResponsiveDialogTitle(props) {
98
+ const { mode } = useResponsiveDialogContext();
99
+ const Comp = mode === "drawer" ? DrawerTitle : DialogTitle;
100
+ return /* @__PURE__ */ jsx(Comp, { ...props });
101
+ }
102
+ function ResponsiveDialogDescription(props) {
103
+ const { mode } = useResponsiveDialogContext();
104
+ const Comp = mode === "drawer" ? DrawerDescription : DialogDescription;
105
+ return /* @__PURE__ */ jsx(Comp, { ...props });
106
+ }
107
+ export {
108
+ ResponsiveDialog,
109
+ ResponsiveDialogClose,
110
+ ResponsiveDialogContent,
111
+ ResponsiveDialogDescription,
112
+ ResponsiveDialogFooter,
113
+ ResponsiveDialogHeader,
114
+ ResponsiveDialogTitle,
115
+ ResponsiveDialogTrigger
116
+ };
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from "react";
2
+ interface IBlurryBackgroundProps {
3
+ children?: ReactNode;
4
+ primaryColor?: string;
5
+ secondaryColor?: string;
6
+ }
7
+ export default function Background({ children, primaryColor, secondaryColor, }: IBlurryBackgroundProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,51 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ function Background({
3
+ children,
4
+ primaryColor = "bg-primary-500",
5
+ secondaryColor = "bg-primary-400"
6
+ }) {
7
+ return /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
8
+ /* @__PURE__ */ jsx("div", { className: "bg-base-100 fixed z-[-10] flex h-full w-full", children: /* @__PURE__ */ jsxs("div", { className: "bg-base-100 flex h-full w-full", children: [
9
+ /* @__PURE__ */ jsx("div", { className: "h-3/6 w-2/5 translate-y-1/2 opacity-40", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full opacity-70 blur-2xl", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full blur-2xl", children: /* @__PURE__ */ jsx(
10
+ "div",
11
+ {
12
+ className: `h-full w-full ${primaryColor} blur-2xl`,
13
+ style: {
14
+ transform: "rotate(30deg)",
15
+ clipPath: "polygon(40% 0%, 100% 30%, 80% 100%, 20% 100%, 0% 30%)"
16
+ }
17
+ }
18
+ ) }) }) }),
19
+ /* @__PURE__ */ jsx("div", { className: "h-2/6 w-1/6 translate-x-3/4 -translate-y-40 opacity-40", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full opacity-80 blur-2xl", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full blur-2xl", children: /* @__PURE__ */ jsx(
20
+ "div",
21
+ {
22
+ className: `h-full w-full rotate-45 ${secondaryColor}`,
23
+ style: {
24
+ clipPath: "polygon(60% 0%, 100% 40%, 70% 100%, 30% 100%, 0% 40%)"
25
+ }
26
+ }
27
+ ) }) }) }),
28
+ /* @__PURE__ */ jsx(
29
+ "div",
30
+ {
31
+ className: "absolute top-96 -right-40 h-2/6 w-1/5 opacity-40",
32
+ style: { transform: "translateY(-50%)" },
33
+ children: /* @__PURE__ */ jsx("div", { className: "h-full w-full opacity-60 blur-2xl", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full blur-2xl", children: /* @__PURE__ */ jsx(
34
+ "div",
35
+ {
36
+ className: `h-full w-full ${secondaryColor} blur-2xl`,
37
+ style: {
38
+ transform: "rotate(12deg)",
39
+ clipPath: "polygon(50% 0%, 100% 20%, 80% 100%, 20% 100%, 0% 20%)"
40
+ }
41
+ }
42
+ ) }) })
43
+ }
44
+ )
45
+ ] }) }),
46
+ /* @__PURE__ */ jsx("div", { className: "relative z-10 w-full", children })
47
+ ] });
48
+ }
49
+ export {
50
+ Background as default
51
+ };
@@ -0,0 +1,17 @@
1
+ import { motion } from "motion/react";
2
+ import React from "react";
3
+ export declare const Cover: ({ children, className, }: {
4
+ children?: React.ReactNode;
5
+ className?: string;
6
+ }) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const Beam: ({ className, delay, duration, hovered, width, ...svgProps }: {
8
+ className?: string;
9
+ delay?: number;
10
+ duration?: number;
11
+ hovered?: boolean;
12
+ width?: number;
13
+ } & React.ComponentProps<typeof motion.svg>) => import("react/jsx-runtime").JSX.Element;
14
+ export declare const CircleIcon: ({ className, }: {
15
+ className?: string;
16
+ delay?: number;
17
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,232 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { cn } from "../../../utils/css-utils.js";
4
+ import { AnimatePresence, motion } from "motion/react";
5
+ import { useState, useRef, useEffect, useId } from "react";
6
+ import { SparklesCore } from "../sparkles/index.js";
7
+ const Cover = ({
8
+ children,
9
+ className
10
+ }) => {
11
+ const [hovered, setHovered] = useState(false);
12
+ const ref = useRef(null);
13
+ const [containerWidth, setContainerWidth] = useState(0);
14
+ const [beamPositions, setBeamPositions] = useState([]);
15
+ useEffect(() => {
16
+ var _a, _b;
17
+ if (ref.current) {
18
+ setContainerWidth(((_a = ref.current) == null ? void 0 : _a.clientWidth) ?? 0);
19
+ const height = ((_b = ref.current) == null ? void 0 : _b.clientHeight) ?? 0;
20
+ const numberOfBeams = Math.floor(height / 10);
21
+ const positions = Array.from(
22
+ { length: numberOfBeams },
23
+ (_, i) => (i + 1) * (height / (numberOfBeams + 1))
24
+ );
25
+ setBeamPositions(positions);
26
+ }
27
+ }, []);
28
+ return /* @__PURE__ */ jsxs(
29
+ "div",
30
+ {
31
+ onMouseEnter: () => setHovered(true),
32
+ onMouseLeave: () => setHovered(false),
33
+ ref,
34
+ className: "group/cover relative inline-block rounded-sm bg-neutral-100 px-2 py-2 transition duration-200 hover:bg-neutral-900 dark:bg-neutral-900",
35
+ children: [
36
+ /* @__PURE__ */ jsx(AnimatePresence, { children: hovered && /* @__PURE__ */ jsx(
37
+ motion.div,
38
+ {
39
+ initial: { opacity: 0 },
40
+ animate: { opacity: 1 },
41
+ exit: { opacity: 0 },
42
+ transition: {
43
+ opacity: {
44
+ duration: 0.2
45
+ }
46
+ },
47
+ className: "absolute inset-0 h-full w-full overflow-hidden",
48
+ children: /* @__PURE__ */ jsxs(
49
+ motion.div,
50
+ {
51
+ animate: {
52
+ translateX: ["-50%", "0%"]
53
+ },
54
+ transition: {
55
+ translateX: {
56
+ duration: 10,
57
+ ease: "linear",
58
+ repeat: Infinity
59
+ }
60
+ },
61
+ className: "flex h-full w-[200%]",
62
+ children: [
63
+ /* @__PURE__ */ jsx(
64
+ SparklesCore,
65
+ {
66
+ background: "transparent",
67
+ minSize: 0.4,
68
+ maxSize: 1,
69
+ particleDensity: 500,
70
+ className: "h-full w-full",
71
+ particleColor: "#FFFFFF"
72
+ }
73
+ ),
74
+ /* @__PURE__ */ jsx(
75
+ SparklesCore,
76
+ {
77
+ background: "transparent",
78
+ minSize: 0.4,
79
+ maxSize: 1,
80
+ particleDensity: 500,
81
+ className: "h-full w-full",
82
+ particleColor: "#FFFFFF"
83
+ }
84
+ )
85
+ ]
86
+ }
87
+ )
88
+ }
89
+ ) }),
90
+ beamPositions.map((position, index) => /* @__PURE__ */ jsx(
91
+ Beam,
92
+ {
93
+ hovered,
94
+ duration: Math.random() * 2 + 1,
95
+ delay: Math.random() * 2 + 1,
96
+ width: containerWidth,
97
+ style: {
98
+ top: `${position}px`
99
+ }
100
+ },
101
+ index
102
+ )),
103
+ /* @__PURE__ */ jsx(
104
+ motion.span,
105
+ {
106
+ animate: {
107
+ scale: hovered ? 0.8 : 1,
108
+ x: hovered ? [0, -30, 30, -30, 30, 0] : 0,
109
+ y: hovered ? [0, 30, -30, 30, -30, 0] : 0
110
+ },
111
+ exit: {
112
+ filter: "none",
113
+ scale: 1,
114
+ x: 0,
115
+ y: 0
116
+ },
117
+ transition: {
118
+ duration: 0.2,
119
+ x: {
120
+ duration: 0.2,
121
+ repeat: Infinity,
122
+ repeatType: "loop"
123
+ },
124
+ y: {
125
+ duration: 0.2,
126
+ repeat: Infinity,
127
+ repeatType: "loop"
128
+ },
129
+ scale: {
130
+ duration: 0.2
131
+ },
132
+ filter: {
133
+ duration: 0.2
134
+ }
135
+ },
136
+ className: cn(
137
+ "relative z-20 inline-block text-neutral-900 transition duration-200 group-hover/cover:text-white dark:text-white",
138
+ className
139
+ ),
140
+ children
141
+ },
142
+ String(hovered)
143
+ ),
144
+ /* @__PURE__ */ jsx(CircleIcon, { className: "absolute -top-[2px] -right-[2px]" }),
145
+ /* @__PURE__ */ jsx(CircleIcon, { className: "absolute -right-[2px] -bottom-[2px]", delay: 0.4 }),
146
+ /* @__PURE__ */ jsx(CircleIcon, { className: "absolute -top-[2px] -left-[2px]", delay: 0.8 }),
147
+ /* @__PURE__ */ jsx(CircleIcon, { className: "absolute -bottom-[2px] -left-[2px]", delay: 1.6 })
148
+ ]
149
+ }
150
+ );
151
+ };
152
+ const Beam = ({
153
+ className,
154
+ delay,
155
+ duration,
156
+ hovered,
157
+ width = 600,
158
+ ...svgProps
159
+ }) => {
160
+ const id = useId();
161
+ return /* @__PURE__ */ jsxs(
162
+ motion.svg,
163
+ {
164
+ width: width ?? "600",
165
+ height: "1",
166
+ viewBox: `0 0 ${width ?? "600"} 1`,
167
+ fill: "none",
168
+ xmlns: "http://www.w3.org/2000/svg",
169
+ className: cn("absolute inset-x-0 w-full", className),
170
+ ...svgProps,
171
+ children: [
172
+ /* @__PURE__ */ jsx(
173
+ motion.path,
174
+ {
175
+ d: `M0 0.5H${width ?? "600"}`,
176
+ stroke: `url(#svgGradient-${id})`
177
+ }
178
+ ),
179
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
180
+ motion.linearGradient,
181
+ {
182
+ id: `svgGradient-${id}`,
183
+ gradientUnits: "userSpaceOnUse",
184
+ initial: {
185
+ x1: "0%",
186
+ x2: hovered ? "-10%" : "-5%",
187
+ y1: 0,
188
+ y2: 0
189
+ },
190
+ animate: {
191
+ x1: "110%",
192
+ x2: hovered ? "100%" : "105%",
193
+ y1: 0,
194
+ y2: 0
195
+ },
196
+ transition: {
197
+ duration: hovered ? 0.5 : duration ?? 2,
198
+ ease: "linear",
199
+ repeat: Infinity,
200
+ delay: hovered ? Math.random() * (1 - 0.2) + 0.2 : 0,
201
+ repeatDelay: hovered ? Math.random() * (2 - 1) + 1 : delay ?? 1
202
+ },
203
+ children: [
204
+ /* @__PURE__ */ jsx("stop", { stopColor: "#2EB9DF", stopOpacity: "0" }),
205
+ /* @__PURE__ */ jsx("stop", { stopColor: "#3b82f6" }),
206
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#3b82f6", stopOpacity: "0" })
207
+ ]
208
+ },
209
+ String(hovered)
210
+ ) })
211
+ ]
212
+ }
213
+ );
214
+ };
215
+ const CircleIcon = ({
216
+ className
217
+ }) => {
218
+ return /* @__PURE__ */ jsx(
219
+ "div",
220
+ {
221
+ className: cn(
222
+ "group pointer-events-none h-2 w-2 animate-pulse rounded-full bg-neutral-600 opacity-20 group-hover/cover:hidden group-hover/cover:bg-white group-hover/cover:opacity-100 dark:bg-white",
223
+ className
224
+ )
225
+ }
226
+ );
227
+ };
228
+ export {
229
+ Beam,
230
+ CircleIcon,
231
+ Cover
232
+ };
@@ -0,0 +1,4 @@
1
+ export { default as Background } from "./background/index.tsx";
2
+ export { Cover } from "./cover/index.tsx";
3
+ export { SparklesCore } from "./sparkles/index.tsx";
4
+ export { Spotlight } from "./spotlight/index.tsx";
@@ -0,0 +1,13 @@
1
+ type ParticlesProps = {
2
+ id?: string;
3
+ className?: string;
4
+ background?: string;
5
+ particleSize?: number;
6
+ minSize?: number;
7
+ maxSize?: number;
8
+ speed?: number;
9
+ particleColor?: string;
10
+ particleDensity?: number;
11
+ };
12
+ export declare const SparklesCore: (props: ParticlesProps) => import("react/jsx-runtime").JSX.Element;
13
+ export {};