@arolariu/components 0.1.1 → 0.2.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 (326) hide show
  1. package/DEBUGGING.md +396 -396
  2. package/LICENSE.md +21 -21
  3. package/changelog.md +109 -118
  4. package/dist/components/ui/accordion.d.ts +2 -2
  5. package/dist/components/ui/accordion.d.ts.map +1 -1
  6. package/dist/components/ui/accordion.js +4 -4
  7. package/dist/components/ui/accordion.js.map +1 -1
  8. package/dist/components/ui/alert-dialog.d.ts +13 -13
  9. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  10. package/dist/components/ui/alert-dialog.js +4 -4
  11. package/dist/components/ui/alert-dialog.js.map +1 -1
  12. package/dist/components/ui/alert.d.ts +5 -5
  13. package/dist/components/ui/alert.d.ts.map +1 -1
  14. package/dist/components/ui/alert.js +3 -3
  15. package/dist/components/ui/alert.js.map +1 -1
  16. package/dist/components/ui/aspect-ratio.d.ts +1 -1
  17. package/dist/components/ui/aspect-ratio.d.ts.map +1 -1
  18. package/dist/components/ui/aspect-ratio.js +1 -1
  19. package/dist/components/ui/aspect-ratio.js.map +1 -1
  20. package/dist/components/ui/avatar.d.ts +2 -2
  21. package/dist/components/ui/avatar.d.ts.map +1 -1
  22. package/dist/components/ui/avatar.js +3 -3
  23. package/dist/components/ui/avatar.js.map +1 -1
  24. package/dist/components/ui/background-beams.d.ts.map +1 -1
  25. package/dist/components/ui/background-beams.js +6 -6
  26. package/dist/components/ui/background-beams.js.map +1 -1
  27. package/dist/components/ui/badge.d.ts +4 -4
  28. package/dist/components/ui/badge.d.ts.map +1 -1
  29. package/dist/components/ui/badge.js +2 -2
  30. package/dist/components/ui/badge.js.map +1 -1
  31. package/dist/components/ui/breadcrumb.d.ts +6 -6
  32. package/dist/components/ui/breadcrumb.d.ts.map +1 -1
  33. package/dist/components/ui/breadcrumb.js +5 -5
  34. package/dist/components/ui/breadcrumb.js.map +1 -1
  35. package/dist/components/ui/bubble-background.d.ts +1 -1
  36. package/dist/components/ui/bubble-background.d.ts.map +1 -1
  37. package/dist/components/ui/bubble-background.js +13 -13
  38. package/dist/components/ui/bubble-background.js.map +1 -1
  39. package/dist/components/ui/button.d.ts +5 -5
  40. package/dist/components/ui/button.d.ts.map +1 -1
  41. package/dist/components/ui/button.js +2 -2
  42. package/dist/components/ui/button.js.map +1 -1
  43. package/dist/components/ui/calendar.d.ts.map +1 -1
  44. package/dist/components/ui/calendar.js +4 -4
  45. package/dist/components/ui/calendar.js.map +1 -1
  46. package/dist/components/ui/card.d.ts +1 -1
  47. package/dist/components/ui/card.d.ts.map +1 -1
  48. package/dist/components/ui/card.js +3 -3
  49. package/dist/components/ui/card.js.map +1 -1
  50. package/dist/components/ui/carousel.d.ts +2 -2
  51. package/dist/components/ui/carousel.d.ts.map +1 -1
  52. package/dist/components/ui/carousel.js +3 -3
  53. package/dist/components/ui/carousel.js.map +1 -1
  54. package/dist/components/ui/chart.d.ts +4 -4
  55. package/dist/components/ui/chart.d.ts.map +1 -1
  56. package/dist/components/ui/chart.js +1 -1
  57. package/dist/components/ui/chart.js.map +1 -1
  58. package/dist/components/ui/checkbox.d.ts +1 -1
  59. package/dist/components/ui/checkbox.d.ts.map +1 -1
  60. package/dist/components/ui/checkbox.js +3 -3
  61. package/dist/components/ui/checkbox.js.map +1 -1
  62. package/dist/components/ui/collapsible.d.ts +2 -2
  63. package/dist/components/ui/collapsible.d.ts.map +1 -1
  64. package/dist/components/ui/collapsible.js +1 -1
  65. package/dist/components/ui/collapsible.js.map +1 -1
  66. package/dist/components/ui/command.d.ts +2 -2
  67. package/dist/components/ui/command.d.ts.map +1 -1
  68. package/dist/components/ui/command.js +9 -9
  69. package/dist/components/ui/command.js.map +1 -1
  70. package/dist/components/ui/context-menu.d.ts +2 -2
  71. package/dist/components/ui/context-menu.d.ts.map +1 -1
  72. package/dist/components/ui/context-menu.js +11 -11
  73. package/dist/components/ui/context-menu.js.map +1 -1
  74. package/dist/components/ui/counting-number.d.ts +1 -1
  75. package/dist/components/ui/counting-number.d.ts.map +1 -1
  76. package/dist/components/ui/counting-number.js +4 -3
  77. package/dist/components/ui/counting-number.js.map +1 -1
  78. package/dist/components/ui/dialog.d.ts +1 -1
  79. package/dist/components/ui/dialog.d.ts.map +1 -1
  80. package/dist/components/ui/dialog.js +6 -6
  81. package/dist/components/ui/dialog.js.map +1 -1
  82. package/dist/components/ui/dot-background.d.ts +10 -17
  83. package/dist/components/ui/dot-background.d.ts.map +1 -1
  84. package/dist/components/ui/dot-background.js +2 -2
  85. package/dist/components/ui/dot-background.js.map +1 -1
  86. package/dist/components/ui/drawer.d.ts +1 -1
  87. package/dist/components/ui/drawer.d.ts.map +1 -1
  88. package/dist/components/ui/drawer.js +5 -5
  89. package/dist/components/ui/drawer.js.map +1 -1
  90. package/dist/components/ui/dropdown-menu.d.ts +2 -2
  91. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  92. package/dist/components/ui/dropdown-menu.js +10 -10
  93. package/dist/components/ui/dropdown-menu.js.map +1 -1
  94. package/dist/components/ui/dropdrawer.d.ts +2 -2
  95. package/dist/components/ui/dropdrawer.d.ts.map +1 -1
  96. package/dist/components/ui/dropdrawer.js +13 -13
  97. package/dist/components/ui/dropdrawer.js.map +1 -1
  98. package/dist/components/ui/fireworks-background.d.ts.map +1 -1
  99. package/dist/components/ui/fireworks-background.js +1 -1
  100. package/dist/components/ui/fireworks-background.js.map +1 -1
  101. package/dist/components/ui/flip-button.d.ts +1 -1
  102. package/dist/components/ui/flip-button.d.ts.map +1 -1
  103. package/dist/components/ui/flip-button.js +3 -3
  104. package/dist/components/ui/flip-button.js.map +1 -1
  105. package/dist/components/ui/form.d.ts +3 -3
  106. package/dist/components/ui/form.d.ts.map +1 -1
  107. package/dist/components/ui/form.js +4 -4
  108. package/dist/components/ui/form.js.map +1 -1
  109. package/dist/components/ui/gradient-background.d.ts +1 -1
  110. package/dist/components/ui/gradient-background.d.ts.map +1 -1
  111. package/dist/components/ui/gradient-background.js +2 -2
  112. package/dist/components/ui/gradient-background.js.map +1 -1
  113. package/dist/components/ui/gradient-text.d.ts +1 -1
  114. package/dist/components/ui/gradient-text.d.ts.map +1 -1
  115. package/dist/components/ui/gradient-text.js +5 -5
  116. package/dist/components/ui/gradient-text.js.map +1 -1
  117. package/dist/components/ui/highlight-text.d.ts +1 -1
  118. package/dist/components/ui/highlight-text.d.ts.map +1 -1
  119. package/dist/components/ui/highlight-text.js +3 -3
  120. package/dist/components/ui/highlight-text.js.map +1 -1
  121. package/dist/components/ui/hole-background.d.ts.map +1 -1
  122. package/dist/components/ui/hole-background.js +11 -10
  123. package/dist/components/ui/hole-background.js.map +1 -1
  124. package/dist/components/ui/hover-card.d.ts +2 -2
  125. package/dist/components/ui/hover-card.d.ts.map +1 -1
  126. package/dist/components/ui/hover-card.js +3 -3
  127. package/dist/components/ui/hover-card.js.map +1 -1
  128. package/dist/components/ui/input-otp.d.ts +2 -2
  129. package/dist/components/ui/input-otp.d.ts.map +1 -1
  130. package/dist/components/ui/input-otp.js +5 -5
  131. package/dist/components/ui/input-otp.js.map +1 -1
  132. package/dist/components/ui/input.d.ts.map +1 -1
  133. package/dist/components/ui/input.js +2 -2
  134. package/dist/components/ui/input.js.map +1 -1
  135. package/dist/components/ui/label.d.ts +1 -1
  136. package/dist/components/ui/label.d.ts.map +1 -1
  137. package/dist/components/ui/label.js +2 -2
  138. package/dist/components/ui/label.js.map +1 -1
  139. package/dist/components/ui/menubar.d.ts +2 -2
  140. package/dist/components/ui/menubar.d.ts.map +1 -1
  141. package/dist/components/ui/menubar.js +12 -12
  142. package/dist/components/ui/menubar.js.map +1 -1
  143. package/dist/components/ui/navigation-menu.d.ts +3 -3
  144. package/dist/components/ui/navigation-menu.d.ts.map +1 -1
  145. package/dist/components/ui/navigation-menu.js +6 -7
  146. package/dist/components/ui/navigation-menu.js.map +1 -1
  147. package/dist/components/ui/pagination.d.ts +2 -2
  148. package/dist/components/ui/pagination.d.ts.map +1 -1
  149. package/dist/components/ui/pagination.js +8 -4
  150. package/dist/components/ui/pagination.js.map +1 -1
  151. package/dist/components/ui/popover.d.ts +2 -2
  152. package/dist/components/ui/popover.d.ts.map +1 -1
  153. package/dist/components/ui/popover.js +3 -3
  154. package/dist/components/ui/popover.js.map +1 -1
  155. package/dist/components/ui/progress.d.ts +1 -1
  156. package/dist/components/ui/progress.d.ts.map +1 -1
  157. package/dist/components/ui/progress.js +4 -4
  158. package/dist/components/ui/progress.js.map +1 -1
  159. package/dist/components/ui/radio-group.d.ts +1 -1
  160. package/dist/components/ui/radio-group.d.ts.map +1 -1
  161. package/dist/components/ui/radio-group.js +3 -3
  162. package/dist/components/ui/radio-group.js.map +1 -1
  163. package/dist/components/ui/resizable.d.ts +1 -1
  164. package/dist/components/ui/resizable.d.ts.map +1 -1
  165. package/dist/components/ui/resizable.js +5 -5
  166. package/dist/components/ui/resizable.js.map +1 -1
  167. package/dist/components/ui/ripple-button.d.ts +1 -1
  168. package/dist/components/ui/ripple-button.d.ts.map +1 -1
  169. package/dist/components/ui/ripple-button.js +4 -4
  170. package/dist/components/ui/ripple-button.js.map +1 -1
  171. package/dist/components/ui/scratcher.d.ts.map +1 -1
  172. package/dist/components/ui/scratcher.js +7 -5
  173. package/dist/components/ui/scratcher.js.map +1 -1
  174. package/dist/components/ui/scroll-area.d.ts +1 -1
  175. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  176. package/dist/components/ui/scroll-area.js +4 -4
  177. package/dist/components/ui/scroll-area.js.map +1 -1
  178. package/dist/components/ui/select.d.ts +1 -1
  179. package/dist/components/ui/select.d.ts.map +1 -1
  180. package/dist/components/ui/select.js +7 -7
  181. package/dist/components/ui/select.js.map +1 -1
  182. package/dist/components/ui/separator.d.ts +1 -1
  183. package/dist/components/ui/separator.d.ts.map +1 -1
  184. package/dist/components/ui/separator.js +3 -3
  185. package/dist/components/ui/separator.js.map +1 -1
  186. package/dist/components/ui/sheet.d.ts +2 -2
  187. package/dist/components/ui/sheet.d.ts.map +1 -1
  188. package/dist/components/ui/sheet.js +6 -6
  189. package/dist/components/ui/sheet.js.map +1 -1
  190. package/dist/components/ui/sidebar.d.ts +5 -5
  191. package/dist/components/ui/sidebar.d.ts.map +1 -1
  192. package/dist/components/ui/sidebar.js +5 -5
  193. package/dist/components/ui/sidebar.js.map +1 -1
  194. package/dist/components/ui/skeleton.d.ts.map +1 -1
  195. package/dist/components/ui/skeleton.js +2 -2
  196. package/dist/components/ui/skeleton.js.map +1 -1
  197. package/dist/components/ui/slider.d.ts +1 -1
  198. package/dist/components/ui/slider.d.ts.map +1 -1
  199. package/dist/components/ui/slider.js +5 -5
  200. package/dist/components/ui/slider.js.map +1 -1
  201. package/dist/components/ui/sonner.d.ts +1 -1
  202. package/dist/components/ui/sonner.d.ts.map +1 -1
  203. package/dist/components/ui/sonner.js +1 -1
  204. package/dist/components/ui/sonner.js.map +1 -1
  205. package/dist/components/ui/switch.d.ts +1 -1
  206. package/dist/components/ui/switch.d.ts.map +1 -1
  207. package/dist/components/ui/switch.js +4 -4
  208. package/dist/components/ui/switch.js.map +1 -1
  209. package/dist/components/ui/table.d.ts +1 -1
  210. package/dist/components/ui/table.d.ts.map +1 -1
  211. package/dist/components/ui/table.js +5 -5
  212. package/dist/components/ui/table.js.map +1 -1
  213. package/dist/components/ui/tabs.d.ts +2 -2
  214. package/dist/components/ui/tabs.d.ts.map +1 -1
  215. package/dist/components/ui/tabs.js +4 -4
  216. package/dist/components/ui/tabs.js.map +1 -1
  217. package/dist/components/ui/textarea.d.ts +1 -1
  218. package/dist/components/ui/textarea.d.ts.map +1 -1
  219. package/dist/components/ui/textarea.js +2 -2
  220. package/dist/components/ui/textarea.js.map +1 -1
  221. package/dist/components/ui/toggle-group.d.ts +3 -3
  222. package/dist/components/ui/toggle-group.d.ts.map +1 -1
  223. package/dist/components/ui/toggle-group.js +2 -2
  224. package/dist/components/ui/toggle-group.js.map +1 -1
  225. package/dist/components/ui/toggle.d.ts +6 -6
  226. package/dist/components/ui/toggle.d.ts.map +1 -1
  227. package/dist/components/ui/toggle.js +2 -2
  228. package/dist/components/ui/toggle.js.map +1 -1
  229. package/dist/components/ui/tooltip.d.ts +6 -6
  230. package/dist/components/ui/tooltip.d.ts.map +1 -1
  231. package/dist/components/ui/tooltip.js +4 -4
  232. package/dist/components/ui/tooltip.js.map +1 -1
  233. package/dist/components/ui/typewriter.d.ts.map +1 -1
  234. package/dist/components/ui/typewriter.js +15 -11
  235. package/dist/components/ui/typewriter.js.map +1 -1
  236. package/dist/hooks/{use-mobile.d.ts → useIsMobile.d.ts} +3 -6
  237. package/dist/hooks/useIsMobile.d.ts.map +1 -0
  238. package/dist/hooks/useIsMobile.js +19 -0
  239. package/dist/hooks/useIsMobile.js.map +1 -0
  240. package/dist/hooks/useWindowSize.d.ts +29 -0
  241. package/dist/hooks/useWindowSize.d.ts.map +1 -0
  242. package/dist/hooks/useWindowSize.js +28 -0
  243. package/dist/hooks/useWindowSize.js.map +1 -0
  244. package/dist/index.css +2 -2
  245. package/dist/index.css.map +1 -1
  246. package/dist/index.d.ts +39 -38
  247. package/dist/index.d.ts.map +1 -1
  248. package/dist/index.js +5 -4
  249. package/dist/lib/utilities.d.ts +9 -0
  250. package/dist/lib/utilities.d.ts.map +1 -0
  251. package/dist/lib/{utils.js → utilities.js} +1 -1
  252. package/dist/lib/utilities.js.map +1 -0
  253. package/package.json +95 -94
  254. package/{README.md → readme.md} +627 -627
  255. package/src/components/ui/accordion.tsx +56 -66
  256. package/src/components/ui/alert-dialog.tsx +135 -160
  257. package/src/components/ui/alert.tsx +58 -69
  258. package/src/components/ui/aspect-ratio.tsx +15 -12
  259. package/src/components/ui/avatar.tsx +38 -53
  260. package/src/components/ui/background-beams.tsx +145 -142
  261. package/src/components/ui/badge.tsx +47 -48
  262. package/src/components/ui/breadcrumb.tsx +97 -117
  263. package/src/components/ui/bubble-background.tsx +170 -189
  264. package/src/components/ui/button.tsx +61 -61
  265. package/src/components/ui/calendar.tsx +177 -216
  266. package/src/components/ui/card.tsx +83 -97
  267. package/src/components/ui/carousel.tsx +204 -241
  268. package/src/components/ui/chart.tsx +303 -385
  269. package/src/components/ui/checkbox.tsx +27 -32
  270. package/src/components/ui/collapsible.tsx +33 -34
  271. package/src/components/ui/command.tsx +137 -184
  272. package/src/components/ui/context-menu.tsx +229 -255
  273. package/src/components/ui/counting-number.tsx +92 -108
  274. package/src/components/ui/dialog.tsx +141 -146
  275. package/src/components/ui/dot-background.tsx +153 -158
  276. package/src/components/ui/drawer.tsx +133 -141
  277. package/src/components/ui/dropdown-menu.tsx +235 -260
  278. package/src/components/ui/dropdrawer.tsx +870 -973
  279. package/src/components/ui/fireworks-background.tsx +325 -378
  280. package/src/components/ui/flip-button.tsx +89 -110
  281. package/src/components/ui/form.tsx +145 -174
  282. package/src/components/ui/gradient-background.tsx +30 -43
  283. package/src/components/ui/gradient-text.tsx +62 -65
  284. package/src/components/ui/highlight-text.tsx +54 -71
  285. package/src/components/ui/hole-background.tsx +326 -361
  286. package/src/components/ui/hover-card.tsx +48 -44
  287. package/src/components/ui/input-otp.tsx +76 -77
  288. package/src/components/ui/input.tsx +22 -22
  289. package/src/components/ui/label.tsx +21 -24
  290. package/src/components/ui/menubar.tsx +256 -279
  291. package/src/components/ui/navigation-menu.tsx +135 -171
  292. package/src/components/ui/pagination.tsx +103 -129
  293. package/src/components/ui/popover.tsx +52 -48
  294. package/src/components/ui/progress.tsx +23 -31
  295. package/src/components/ui/radio-group.tsx +37 -45
  296. package/src/components/ui/resizable.tsx +52 -56
  297. package/src/components/ui/ripple-button.tsx +90 -111
  298. package/src/components/ui/scratcher.tsx +167 -171
  299. package/src/components/ui/scroll-area.tsx +45 -58
  300. package/src/components/ui/select.tsx +160 -191
  301. package/src/components/ui/separator.tsx +28 -28
  302. package/src/components/ui/sheet.tsx +133 -145
  303. package/src/components/ui/sidebar.tsx +673 -729
  304. package/src/components/ui/skeleton.tsx +16 -19
  305. package/src/components/ui/slider.tsx +49 -63
  306. package/src/components/ui/sonner.tsx +30 -26
  307. package/src/components/ui/switch.tsx +27 -31
  308. package/src/components/ui/table.tsx +98 -119
  309. package/src/components/ui/tabs.tsx +54 -66
  310. package/src/components/ui/textarea.tsx +20 -20
  311. package/src/components/ui/toggle-group.tsx +66 -73
  312. package/src/components/ui/toggle.tsx +46 -47
  313. package/src/components/ui/tooltip.tsx +56 -61
  314. package/src/components/ui/typewriter.tsx +174 -188
  315. package/src/hooks/{use-mobile.tsx → useIsMobile.tsx} +42 -44
  316. package/src/hooks/useWindowSize.tsx +66 -0
  317. package/src/index.css +73 -73
  318. package/src/index.ts +303 -407
  319. package/src/lib/utilities.ts +12 -0
  320. package/dist/hooks/use-mobile.d.ts.map +0 -1
  321. package/dist/hooks/use-mobile.js +0 -18
  322. package/dist/hooks/use-mobile.js.map +0 -1
  323. package/dist/lib/utils.d.ts +0 -7
  324. package/dist/lib/utils.d.ts.map +0 -1
  325. package/dist/lib/utils.js.map +0 -1
  326. package/src/lib/utils.ts +0 -10
@@ -1,361 +1,326 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { motion } from "motion/react";
5
-
6
- import { cn } from "@/lib/utils";
7
-
8
- interface HoleBackgroundProps extends React.HTMLAttributes<HTMLCanvasElement> {
9
- strokeColor?: string;
10
- numberOfLines?: number;
11
- numberOfDiscs?: number;
12
- particleRGBColor?: [number, number, number];
13
- }
14
-
15
- const HoleBackground = React.forwardRef<HTMLCanvasElement, HoleBackgroundProps>(
16
- (
17
- {
18
- strokeColor = "#737373",
19
- numberOfLines = 50,
20
- numberOfDiscs = 50,
21
- particleRGBColor = [255, 255, 255],
22
- className,
23
- children,
24
- ...props
25
- },
26
- ref,
27
- ) => {
28
- const canvasRef = React.useRef<HTMLCanvasElement>(null);
29
- React.useImperativeHandle(
30
- ref,
31
- () => canvasRef.current as HTMLCanvasElement,
32
- );
33
-
34
- const animationFrameIdRef = React.useRef<number>(0);
35
- const stateRef = React.useRef<any>({
36
- discs: [] as any[],
37
- lines: [] as any[],
38
- particles: [] as any[],
39
- clip: {},
40
- startDisc: {},
41
- endDisc: {},
42
- rect: { width: 0, height: 0 },
43
- render: { width: 0, height: 0, dpi: 1 },
44
- particleArea: {},
45
- linesCanvas: null,
46
- });
47
-
48
- const linear = (p: number) => p;
49
- const easeInExpo = (p: number) => (p === 0 ? 0 : Math.pow(2, 10 * (p - 1)));
50
-
51
- const tweenValue = React.useCallback(
52
- (start: number, end: number, p: number, ease: "inExpo" | null = null) => {
53
- const delta = end - start;
54
- const easeFn = ease === "inExpo" ? easeInExpo : linear;
55
- return start + delta * easeFn(p);
56
- },
57
- [],
58
- );
59
-
60
- const tweenDisc = React.useCallback(
61
- (disc: any) => {
62
- const { startDisc, endDisc } = stateRef.current;
63
- disc.x = tweenValue(startDisc.x, endDisc.x, disc.p);
64
- disc.y = tweenValue(startDisc.y, endDisc.y, disc.p, "inExpo");
65
- disc.w = tweenValue(startDisc.w, endDisc.w, disc.p);
66
- disc.h = tweenValue(startDisc.h, endDisc.h, disc.p);
67
- },
68
- [tweenValue],
69
- );
70
-
71
- const setSize = React.useCallback(() => {
72
- const canvas = canvasRef.current;
73
- if (!canvas) return;
74
- const rect = canvas.getBoundingClientRect();
75
- stateRef.current.rect = { width: rect.width, height: rect.height };
76
- stateRef.current.render = {
77
- width: rect.width,
78
- height: rect.height,
79
- dpi: window.devicePixelRatio || 1,
80
- };
81
- canvas.width =
82
- stateRef.current.render.width * stateRef.current.render.dpi;
83
- canvas.height =
84
- stateRef.current.render.height * stateRef.current.render.dpi;
85
- }, []);
86
-
87
- const setDiscs = React.useCallback(() => {
88
- const { width, height } = stateRef.current.rect;
89
- stateRef.current.discs = [];
90
- stateRef.current.startDisc = {
91
- x: width * 0.5,
92
- y: height * 0.45,
93
- w: width * 0.75,
94
- h: height * 0.7,
95
- };
96
- stateRef.current.endDisc = {
97
- x: width * 0.5,
98
- y: height * 0.95,
99
- w: 0,
100
- h: 0,
101
- };
102
- let prevBottom = height;
103
- stateRef.current.clip = {};
104
- for (let i = 0; i < numberOfDiscs; i++) {
105
- const p = i / numberOfDiscs;
106
- const disc = { p, x: 0, y: 0, w: 0, h: 0 };
107
- tweenDisc(disc);
108
- const bottom = disc.y + disc.h;
109
- if (bottom <= prevBottom) {
110
- stateRef.current.clip = { disc: { ...disc }, i };
111
- }
112
- prevBottom = bottom;
113
- stateRef.current.discs.push(disc);
114
- }
115
- const clipPath = new Path2D();
116
- const disc = stateRef.current.clip.disc;
117
- clipPath.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);
118
- clipPath.rect(disc.x - disc.w, 0, disc.w * 2, disc.y);
119
- stateRef.current.clip.path = clipPath;
120
- }, [tweenDisc]);
121
-
122
- const setLines = React.useCallback(() => {
123
- const { width, height } = stateRef.current.rect;
124
- stateRef.current.lines = [];
125
- const linesAngle = (Math.PI * 2) / numberOfLines;
126
- for (let i = 0; i < numberOfLines; i++) {
127
- stateRef.current.lines.push([]);
128
- }
129
- stateRef.current.discs.forEach((disc: any) => {
130
- for (let i = 0; i < numberOfLines; i++) {
131
- const angle = i * linesAngle;
132
- const p = {
133
- x: disc.x + Math.cos(angle) * disc.w,
134
- y: disc.y + Math.sin(angle) * disc.h,
135
- };
136
- stateRef.current.lines[i].push(p);
137
- }
138
- });
139
- const offCanvas = document.createElement("canvas");
140
- offCanvas.width = width;
141
- offCanvas.height = height;
142
- const ctx = offCanvas.getContext("2d");
143
- if (!ctx) return;
144
- stateRef.current.lines.forEach((line: any) => {
145
- ctx.save();
146
- let lineIsIn = false;
147
- line.forEach((p1: any, j: number) => {
148
- if (j === 0) return;
149
- const p0 = line[j - 1];
150
- if (
151
- !lineIsIn &&
152
- (ctx.isPointInPath(stateRef.current.clip.path, p1.x, p1.y) ||
153
- ctx.isPointInStroke(stateRef.current.clip.path, p1.x, p1.y))
154
- ) {
155
- lineIsIn = true;
156
- } else if (lineIsIn) {
157
- ctx.clip(stateRef.current.clip.path);
158
- }
159
- ctx.beginPath();
160
- ctx.moveTo(p0.x, p0.y);
161
- ctx.lineTo(p1.x, p1.y);
162
- ctx.strokeStyle = strokeColor;
163
- ctx.lineWidth = 2;
164
- ctx.stroke();
165
- ctx.closePath();
166
- });
167
- ctx.restore();
168
- });
169
- stateRef.current.linesCanvas = offCanvas;
170
- }, [strokeColor]);
171
-
172
- const initParticle = React.useCallback((start: boolean = false) => {
173
- const sx =
174
- stateRef.current.particleArea.sx +
175
- stateRef.current.particleArea.sw * Math.random();
176
- const ex =
177
- stateRef.current.particleArea.ex +
178
- stateRef.current.particleArea.ew * Math.random();
179
- const dx = ex - sx;
180
- const y = start
181
- ? stateRef.current.particleArea.h * Math.random()
182
- : stateRef.current.particleArea.h;
183
- const r = 0.5 + Math.random() * 4;
184
- const vy = 0.5 + Math.random();
185
- return {
186
- x: sx,
187
- sx,
188
- dx,
189
- y,
190
- vy,
191
- p: 0,
192
- r,
193
- c: `rgba(${particleRGBColor[0]}, ${particleRGBColor[1]}, ${
194
- particleRGBColor[2]
195
- }, ${Math.random()})`,
196
- };
197
- }, []);
198
-
199
- const setParticles = React.useCallback(() => {
200
- const { width, height } = stateRef.current.rect;
201
- stateRef.current.particles = [];
202
- const disc = stateRef.current.clip.disc;
203
- stateRef.current.particleArea = {
204
- sw: disc.w * 0.5,
205
- ew: disc.w * 2,
206
- h: height * 0.85,
207
- };
208
- stateRef.current.particleArea.sx =
209
- (width - stateRef.current.particleArea.sw) / 2;
210
- stateRef.current.particleArea.ex =
211
- (width - stateRef.current.particleArea.ew) / 2;
212
- const totalParticles = 100;
213
- for (let i = 0; i < totalParticles; i++) {
214
- stateRef.current.particles.push(initParticle(true));
215
- }
216
- }, [initParticle]);
217
-
218
- const drawDiscs = React.useCallback(
219
- (ctx: CanvasRenderingContext2D) => {
220
- ctx.strokeStyle = strokeColor;
221
- ctx.lineWidth = 2;
222
- const outerDisc = stateRef.current.startDisc;
223
- ctx.beginPath();
224
- ctx.ellipse(
225
- outerDisc.x,
226
- outerDisc.y,
227
- outerDisc.w,
228
- outerDisc.h,
229
- 0,
230
- 0,
231
- Math.PI * 2,
232
- );
233
- ctx.stroke();
234
- ctx.closePath();
235
- stateRef.current.discs.forEach((disc: any, i: number) => {
236
- if (i % 5 !== 0) return;
237
- if (disc.w < stateRef.current.clip.disc.w - 5) {
238
- ctx.save();
239
- ctx.clip(stateRef.current.clip.path);
240
- }
241
- ctx.beginPath();
242
- ctx.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);
243
- ctx.stroke();
244
- ctx.closePath();
245
- if (disc.w < stateRef.current.clip.disc.w - 5) {
246
- ctx.restore();
247
- }
248
- });
249
- },
250
- [strokeColor],
251
- );
252
-
253
- const drawLines = React.useCallback((ctx: CanvasRenderingContext2D) => {
254
- if (stateRef.current.linesCanvas) {
255
- ctx.drawImage(stateRef.current.linesCanvas, 0, 0);
256
- }
257
- }, []);
258
-
259
- const drawParticles = React.useCallback((ctx: CanvasRenderingContext2D) => {
260
- ctx.save();
261
- ctx.clip(stateRef.current.clip.path);
262
- stateRef.current.particles.forEach((particle: any) => {
263
- ctx.fillStyle = particle.c;
264
- ctx.beginPath();
265
- ctx.rect(particle.x, particle.y, particle.r, particle.r);
266
- ctx.closePath();
267
- ctx.fill();
268
- });
269
- ctx.restore();
270
- }, []);
271
-
272
- const moveDiscs = React.useCallback(() => {
273
- stateRef.current.discs.forEach((disc: any) => {
274
- disc.p = (disc.p + 0.001) % 1;
275
- tweenDisc(disc);
276
- });
277
- }, [tweenDisc]);
278
-
279
- const moveParticles = React.useCallback(() => {
280
- stateRef.current.particles.forEach((particle: any, idx: number) => {
281
- particle.p = 1 - particle.y / stateRef.current.particleArea.h;
282
- particle.x = particle.sx + particle.dx * particle.p;
283
- particle.y -= particle.vy;
284
- if (particle.y < 0) {
285
- stateRef.current.particles[idx] = initParticle();
286
- }
287
- });
288
- }, [initParticle]);
289
-
290
- const tick = React.useCallback(() => {
291
- const canvas = canvasRef.current;
292
- if (!canvas) return;
293
- const ctx = canvas.getContext("2d");
294
- if (!ctx) return;
295
- ctx.clearRect(0, 0, canvas.width, canvas.height);
296
- ctx.save();
297
- ctx.scale(stateRef.current.render.dpi, stateRef.current.render.dpi);
298
- moveDiscs();
299
- moveParticles();
300
- drawDiscs(ctx);
301
- drawLines(ctx);
302
- drawParticles(ctx);
303
- ctx.restore();
304
- animationFrameIdRef.current = requestAnimationFrame(tick);
305
- }, [moveDiscs, moveParticles, drawDiscs, drawLines, drawParticles]);
306
-
307
- const init = React.useCallback(() => {
308
- setSize();
309
- setDiscs();
310
- setLines();
311
- setParticles();
312
- }, [setSize, setDiscs, setLines, setParticles]);
313
-
314
- React.useEffect(() => {
315
- const canvas = canvasRef.current;
316
- if (!canvas) return;
317
- init();
318
- tick();
319
- const handleResize = () => {
320
- setSize();
321
- setDiscs();
322
- setLines();
323
- setParticles();
324
- };
325
- window.addEventListener("resize", handleResize);
326
- return () => {
327
- window.removeEventListener("resize", handleResize);
328
- cancelAnimationFrame(animationFrameIdRef.current);
329
- };
330
- }, [init, tick, setSize, setDiscs, setLines, setParticles]);
331
-
332
- return (
333
- <div
334
- className={cn(
335
- "relative size-full overflow-hidden",
336
- 'before:content-[""] before:absolute before:top-1/2 before:left-1/2 before:block before:size-[140%] dark:before:[background:radial-gradient(ellipse_at_50%_55%,transparent_10%,black_50%)] before:[background:radial-gradient(ellipse_at_50%_55%,transparent_10%,white_50%)] before:[transform:translate3d(-50%,-50%,0)]',
337
- 'after:content-[""] after:absolute after:z-[5] after:top-1/2 after:left-1/2 after:block after:size-full after:[background:radial-gradient(ellipse_at_50%_75%,#a900ff_20%,transparent_75%)] after:[transform:translate3d(-50%,-50%,0)] after:mix-blend-overlay',
338
- className,
339
- )}
340
- >
341
- {children}
342
- <canvas
343
- ref={canvasRef}
344
- className="absolute inset-0 block size-full dark:opacity-20 opacity-10"
345
- {...props}
346
- />
347
- <motion.div
348
- className={cn(
349
- "absolute top-[-71.5%] left-1/2 z-[3] w-[30%] h-[140%] rounded-b-full blur-3xl opacity-75 dark:mix-blend-plus-lighter mix-blend-plus-darker [transform:translate3d(-50%,0,0)] [background-position:0%_100%] [background-size:100%_200%]",
350
- "dark:[background:linear-gradient(20deg,#00f8f1,#ffbd1e20_16.5%,#fe848f_33%,#fe848f20_49.5%,#00f8f1_66%,#00f8f160_85.5%,#ffbd1e_100%)_0_100%_/_100%_200%] [background:linear-gradient(20deg,#00f8f1,#ffbd1e40_16.5%,#fe848f_33%,#fe848f40_49.5%,#00f8f1_66%,#00f8f180_85.5%,#ffbd1e_100%)_0_100%_/_100%_200%]",
351
- )}
352
- animate={{ backgroundPosition: "0% 300%" }}
353
- transition={{ duration: 5, ease: "linear", repeat: Infinity }}
354
- />
355
- <div className="absolute top-0 left-0 z-[7] size-full dark:[background:repeating-linear-gradient(transparent,transparent_1px,white_1px,white_2px)] mix-blend-overlay opacity-50" />
356
- </div>
357
- );
358
- },
359
- );
360
-
361
- export { HoleBackground, type HoleBackgroundProps };
1
+ "use client";
2
+
3
+ import {motion} from "motion/react";
4
+ import * as React from "react";
5
+
6
+ import {cn} from "@/lib/utilities";
7
+
8
+ interface HoleBackgroundProps extends React.HTMLAttributes<HTMLCanvasElement> {
9
+ strokeColor?: string;
10
+ numberOfLines?: number;
11
+ numberOfDiscs?: number;
12
+ particleRGBColor?: [number, number, number];
13
+ }
14
+
15
+ const linear = (p: number) => p;
16
+ const easeInExpo = (p: number) => (p === 0 ? 0 : 2 ** (10 * (p - 1)));
17
+
18
+ const HoleBackground = React.forwardRef<HTMLCanvasElement, HoleBackgroundProps>(
19
+ (
20
+ {strokeColor = "#737373", numberOfLines = 50, numberOfDiscs = 50, particleRGBColor = [255, 255, 255], className, children, ...props},
21
+ ref,
22
+ ) => {
23
+ const canvasRef = React.useRef<HTMLCanvasElement>(null);
24
+ React.useImperativeHandle(ref, () => canvasRef.current as HTMLCanvasElement);
25
+
26
+ const animationFrameIdRef = React.useRef<number>(0);
27
+ const stateRef = React.useRef<any>({
28
+ discs: [] as any[],
29
+ lines: [] as any[],
30
+ particles: [] as any[],
31
+ clip: {},
32
+ startDisc: {},
33
+ endDisc: {},
34
+ rect: {width: 0, height: 0},
35
+ render: {width: 0, height: 0, dpi: 1},
36
+ particleArea: {},
37
+ linesCanvas: null,
38
+ });
39
+
40
+ const tweenValue = React.useCallback((start: number, end: number, p: number, ease: "inExpo" | null = null) => {
41
+ const delta = end - start;
42
+ const easeFn = ease === "inExpo" ? easeInExpo : linear;
43
+ return start + delta * easeFn(p);
44
+ }, []);
45
+
46
+ const tweenDisc = React.useCallback(
47
+ (disc: any) => {
48
+ const {startDisc, endDisc} = stateRef.current;
49
+ disc.x = tweenValue(startDisc.x, endDisc.x, disc.p);
50
+ disc.y = tweenValue(startDisc.y, endDisc.y, disc.p, "inExpo");
51
+ disc.w = tweenValue(startDisc.w, endDisc.w, disc.p);
52
+ disc.h = tweenValue(startDisc.h, endDisc.h, disc.p);
53
+ },
54
+ [tweenValue],
55
+ );
56
+
57
+ const setSize = React.useCallback(() => {
58
+ const canvas = canvasRef.current;
59
+ if (!canvas) return;
60
+ const rect = canvas.getBoundingClientRect();
61
+ stateRef.current.rect = {width: rect.width, height: rect.height};
62
+ stateRef.current.render = {
63
+ width: rect.width,
64
+ height: rect.height,
65
+ dpi: window.devicePixelRatio || 1,
66
+ };
67
+ canvas.width = stateRef.current.render.width * stateRef.current.render.dpi;
68
+ canvas.height = stateRef.current.render.height * stateRef.current.render.dpi;
69
+ }, []);
70
+
71
+ const setDiscs = React.useCallback(() => {
72
+ const {width, height} = stateRef.current.rect;
73
+ stateRef.current.discs = [];
74
+ stateRef.current.startDisc = {
75
+ x: width * 0.5,
76
+ y: height * 0.45,
77
+ w: width * 0.75,
78
+ h: height * 0.7,
79
+ };
80
+ stateRef.current.endDisc = {
81
+ x: width * 0.5,
82
+ y: height * 0.95,
83
+ w: 0,
84
+ h: 0,
85
+ };
86
+ let prevBottom = height;
87
+ stateRef.current.clip = {};
88
+ for (let i = 0; i < numberOfDiscs; i++) {
89
+ const p = i / numberOfDiscs;
90
+ const disc = {p, x: 0, y: 0, w: 0, h: 0};
91
+ tweenDisc(disc);
92
+ const bottom = disc.y + disc.h;
93
+ if (bottom <= prevBottom) {
94
+ stateRef.current.clip = {disc: {...disc}, i};
95
+ }
96
+ prevBottom = bottom;
97
+ stateRef.current.discs.push(disc);
98
+ }
99
+ const clipPath = new Path2D();
100
+ const {disc} = stateRef.current.clip;
101
+ clipPath.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);
102
+ clipPath.rect(disc.x - disc.w, 0, disc.w * 2, disc.y);
103
+ stateRef.current.clip.path = clipPath;
104
+ }, [tweenDisc]);
105
+
106
+ const setLines = React.useCallback(() => {
107
+ const {width, height} = stateRef.current.rect;
108
+ stateRef.current.lines = [];
109
+ const linesAngle = (Math.PI * 2) / numberOfLines;
110
+ for (let i = 0; i < numberOfLines; i++) {
111
+ stateRef.current.lines.push([]);
112
+ }
113
+ stateRef.current.discs.forEach((disc: any) => {
114
+ for (let i = 0; i < numberOfLines; i++) {
115
+ const angle = i * linesAngle;
116
+ const p = {
117
+ x: disc.x + Math.cos(angle) * disc.w,
118
+ y: disc.y + Math.sin(angle) * disc.h,
119
+ };
120
+ stateRef.current.lines[i].push(p);
121
+ }
122
+ });
123
+ const offCanvas = document.createElement("canvas");
124
+ offCanvas.width = width;
125
+ offCanvas.height = height;
126
+ const ctx = offCanvas.getContext("2d");
127
+ if (!ctx) return;
128
+ stateRef.current.lines.forEach((line: any) => {
129
+ ctx.save();
130
+ let lineIsIn = false;
131
+ line.forEach((p1: any, j: number) => {
132
+ if (j === 0) return;
133
+ const p0 = line[j - 1];
134
+ if (
135
+ !lineIsIn
136
+ && (ctx.isPointInPath(stateRef.current.clip.path, p1.x, p1.y) || ctx.isPointInStroke(stateRef.current.clip.path, p1.x, p1.y))
137
+ ) {
138
+ lineIsIn = true;
139
+ } else if (lineIsIn) {
140
+ ctx.clip(stateRef.current.clip.path);
141
+ }
142
+ ctx.beginPath();
143
+ ctx.moveTo(p0.x, p0.y);
144
+ ctx.lineTo(p1.x, p1.y);
145
+ ctx.strokeStyle = strokeColor;
146
+ ctx.lineWidth = 2;
147
+ ctx.stroke();
148
+ ctx.closePath();
149
+ });
150
+ ctx.restore();
151
+ });
152
+ stateRef.current.linesCanvas = offCanvas;
153
+ }, [strokeColor]);
154
+
155
+ const initParticle = React.useCallback((start: boolean = false) => {
156
+ const sx = stateRef.current.particleArea.sx + stateRef.current.particleArea.sw * Math.random();
157
+ const ex = stateRef.current.particleArea.ex + stateRef.current.particleArea.ew * Math.random();
158
+ const dx = ex - sx;
159
+ const y = start ? stateRef.current.particleArea.h * Math.random() : stateRef.current.particleArea.h;
160
+ const r = 0.5 + Math.random() * 4;
161
+ const vy = 0.5 + Math.random();
162
+ return {
163
+ x: sx,
164
+ sx,
165
+ dx,
166
+ y,
167
+ vy,
168
+ p: 0,
169
+ r,
170
+ c: `rgba(${particleRGBColor[0]}, ${particleRGBColor[1]}, ${particleRGBColor[2]}, ${Math.random()})`,
171
+ };
172
+ }, []);
173
+
174
+ const setParticles = React.useCallback(() => {
175
+ const {width, height} = stateRef.current.rect;
176
+ stateRef.current.particles = [];
177
+ const {disc} = stateRef.current.clip;
178
+ stateRef.current.particleArea = {
179
+ sw: disc.w * 0.5,
180
+ ew: disc.w * 2,
181
+ h: height * 0.85,
182
+ };
183
+ stateRef.current.particleArea.sx = (width - stateRef.current.particleArea.sw) / 2;
184
+ stateRef.current.particleArea.ex = (width - stateRef.current.particleArea.ew) / 2;
185
+ const totalParticles = 100;
186
+ for (let i = 0; i < totalParticles; i++) {
187
+ stateRef.current.particles.push(initParticle(true));
188
+ }
189
+ }, [initParticle]);
190
+
191
+ const drawDiscs = React.useCallback(
192
+ (ctx: CanvasRenderingContext2D) => {
193
+ ctx.strokeStyle = strokeColor;
194
+ ctx.lineWidth = 2;
195
+ const outerDisc = stateRef.current.startDisc;
196
+ ctx.beginPath();
197
+ ctx.ellipse(outerDisc.x, outerDisc.y, outerDisc.w, outerDisc.h, 0, 0, Math.PI * 2);
198
+ ctx.stroke();
199
+ ctx.closePath();
200
+ stateRef.current.discs.forEach((disc: any, i: number) => {
201
+ if (i % 5 !== 0) return;
202
+ if (disc.w < stateRef.current.clip.disc.w - 5) {
203
+ ctx.save();
204
+ ctx.clip(stateRef.current.clip.path);
205
+ }
206
+ ctx.beginPath();
207
+ ctx.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);
208
+ ctx.stroke();
209
+ ctx.closePath();
210
+ if (disc.w < stateRef.current.clip.disc.w - 5) {
211
+ ctx.restore();
212
+ }
213
+ });
214
+ },
215
+ [strokeColor],
216
+ );
217
+
218
+ const drawLines = React.useCallback((ctx: CanvasRenderingContext2D) => {
219
+ if (stateRef.current.linesCanvas) {
220
+ ctx.drawImage(stateRef.current.linesCanvas, 0, 0);
221
+ }
222
+ }, []);
223
+
224
+ const drawParticles = React.useCallback((ctx: CanvasRenderingContext2D) => {
225
+ ctx.save();
226
+ ctx.clip(stateRef.current.clip.path);
227
+ stateRef.current.particles.forEach((particle: any) => {
228
+ ctx.fillStyle = particle.c;
229
+ ctx.beginPath();
230
+ ctx.rect(particle.x, particle.y, particle.r, particle.r);
231
+ ctx.closePath();
232
+ ctx.fill();
233
+ });
234
+ ctx.restore();
235
+ }, []);
236
+
237
+ const moveDiscs = React.useCallback(() => {
238
+ stateRef.current.discs.forEach((disc: any) => {
239
+ disc.p = (disc.p + 0.001) % 1;
240
+ tweenDisc(disc);
241
+ });
242
+ }, [tweenDisc]);
243
+
244
+ const moveParticles = React.useCallback(() => {
245
+ stateRef.current.particles.forEach((particle: any, idx: number) => {
246
+ particle.p = 1 - particle.y / stateRef.current.particleArea.h;
247
+ particle.x = particle.sx + particle.dx * particle.p;
248
+ particle.y -= particle.vy;
249
+ if (particle.y < 0) {
250
+ stateRef.current.particles[idx] = initParticle();
251
+ }
252
+ });
253
+ }, [initParticle]);
254
+
255
+ const tick = React.useCallback(() => {
256
+ const canvas = canvasRef.current;
257
+ if (!canvas) return;
258
+ const ctx = canvas.getContext("2d");
259
+ if (!ctx) return;
260
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
261
+ ctx.save();
262
+ ctx.scale(stateRef.current.render.dpi, stateRef.current.render.dpi);
263
+ moveDiscs();
264
+ moveParticles();
265
+ drawDiscs(ctx);
266
+ drawLines(ctx);
267
+ drawParticles(ctx);
268
+ ctx.restore();
269
+ animationFrameIdRef.current = requestAnimationFrame(tick);
270
+ }, [moveDiscs, moveParticles, drawDiscs, drawLines, drawParticles]);
271
+
272
+ const init = React.useCallback(() => {
273
+ setSize();
274
+ setDiscs();
275
+ setLines();
276
+ setParticles();
277
+ }, [setSize, setDiscs, setLines, setParticles]);
278
+
279
+ React.useEffect(() => {
280
+ const canvas = canvasRef.current;
281
+ if (!canvas) return;
282
+ init();
283
+ tick();
284
+ const handleResize = () => {
285
+ setSize();
286
+ setDiscs();
287
+ setLines();
288
+ setParticles();
289
+ };
290
+ window.addEventListener("resize", handleResize);
291
+ return () => {
292
+ window.removeEventListener("resize", handleResize);
293
+ cancelAnimationFrame(animationFrameIdRef.current);
294
+ };
295
+ }, [init, tick, setSize, setDiscs, setLines, setParticles]);
296
+
297
+ return (
298
+ <div
299
+ className={cn(
300
+ "relative size-full overflow-hidden",
301
+ 'before:absolute before:top-1/2 before:left-1/2 before:block before:size-[140%] before:[transform:translate3d(-50%,-50%,0)] before:content-[""] before:[background:radial-gradient(ellipse_at_50%_55%,transparent_10%,white_50%)] dark:before:[background:radial-gradient(ellipse_at_50%_55%,transparent_10%,black_50%)]',
302
+ 'after:absolute after:top-1/2 after:left-1/2 after:z-[5] after:block after:size-full after:[transform:translate3d(-50%,-50%,0)] after:mix-blend-overlay after:content-[""] after:[background:radial-gradient(ellipse_at_50%_75%,#a900ff_20%,transparent_75%)]',
303
+ className,
304
+ )}>
305
+ {children}
306
+ <canvas
307
+ ref={canvasRef}
308
+ className='absolute inset-0 block size-full opacity-10 dark:opacity-20'
309
+ {...props}
310
+ />
311
+ <motion.div
312
+ className={cn(
313
+ "absolute top-[-71.5%] left-1/2 z-[3] h-[140%] w-[30%] [transform:translate3d(-50%,0,0)] rounded-b-full [background-size:100%_200%] [background-position:0%_100%] opacity-75 mix-blend-plus-darker blur-3xl dark:mix-blend-plus-lighter",
314
+ "[background:linear-gradient(20deg,#00f8f1,#ffbd1e40_16.5%,#fe848f_33%,#fe848f40_49.5%,#00f8f1_66%,#00f8f180_85.5%,#ffbd1e_100%)_0_100%_/_100%_200%] dark:[background:linear-gradient(20deg,#00f8f1,#ffbd1e20_16.5%,#fe848f_33%,#fe848f20_49.5%,#00f8f1_66%,#00f8f160_85.5%,#ffbd1e_100%)_0_100%_/_100%_200%]",
315
+ )}
316
+ animate={{backgroundPosition: "0% 300%"}}
317
+ transition={{duration: 5, ease: "linear", repeat: Infinity}}
318
+ />
319
+ <div className='absolute top-0 left-0 z-[7] size-full opacity-50 mix-blend-overlay dark:[background:repeating-linear-gradient(transparent,transparent_1px,white_1px,white_2px)]' />
320
+ </div>
321
+ );
322
+ },
323
+ );
324
+
325
+ HoleBackground.displayName = "HoleBackground";
326
+ export {HoleBackground, type HoleBackgroundProps};