@arolariu/components 0.1.2 → 0.3.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 (360) hide show
  1. package/DEBUGGING.md +396 -396
  2. package/LICENSE.md +21 -21
  3. package/changelog.md +120 -118
  4. package/dist/components/ui/accordion.d.ts +6 -6
  5. package/dist/components/ui/accordion.d.ts.map +1 -1
  6. package/dist/components/ui/accordion.js +20 -28
  7. package/dist/components/ui/accordion.js.map +1 -1
  8. package/dist/components/ui/alert-dialog.d.ts +19 -13
  9. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  10. package/dist/components/ui/alert-dialog.js +40 -63
  11. package/dist/components/ui/alert-dialog.js.map +1 -1
  12. package/dist/components/ui/alert.d.ts +7 -8
  13. package/dist/components/ui/alert.d.ts.map +1 -1
  14. package/dist/components/ui/alert.js +18 -21
  15. package/dist/components/ui/alert.js.map +1 -1
  16. package/dist/components/ui/aspect-ratio.d.ts +1 -2
  17. package/dist/components/ui/aspect-ratio.d.ts.map +1 -1
  18. package/dist/components/ui/aspect-ratio.js +1 -8
  19. package/dist/components/ui/aspect-ratio.js.map +1 -1
  20. package/dist/components/ui/avatar.d.ts +5 -5
  21. package/dist/components/ui/avatar.d.ts.map +1 -1
  22. package/dist/components/ui/avatar.js +17 -20
  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 +7 -7
  28. package/dist/components/ui/badge.d.ts.map +1 -1
  29. package/dist/components/ui/badge.js +9 -12
  30. package/dist/components/ui/badge.js.map +1 -1
  31. package/dist/components/ui/breadcrumb.d.ts +17 -9
  32. package/dist/components/ui/breadcrumb.d.ts.map +1 -1
  33. package/dist/components/ui/breadcrumb.js +32 -39
  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-group.d.ts +13 -0
  40. package/dist/components/ui/button-group.d.ts.map +1 -0
  41. package/dist/components/ui/button-group.js +47 -0
  42. package/dist/components/ui/button-group.js.map +1 -0
  43. package/dist/components/ui/button.d.ts +8 -7
  44. package/dist/components/ui/button.d.ts.map +1 -1
  45. package/dist/components/ui/button.js +16 -15
  46. package/dist/components/ui/button.js.map +1 -1
  47. package/dist/components/ui/calendar.d.ts.map +1 -1
  48. package/dist/components/ui/calendar.js +22 -22
  49. package/dist/components/ui/calendar.js.map +1 -1
  50. package/dist/components/ui/card.d.ts +7 -8
  51. package/dist/components/ui/card.d.ts.map +1 -1
  52. package/dist/components/ui/card.js +33 -46
  53. package/dist/components/ui/card.js.map +1 -1
  54. package/dist/components/ui/carousel.d.ts +7 -8
  55. package/dist/components/ui/carousel.d.ts.map +1 -1
  56. package/dist/components/ui/carousel.js +30 -21
  57. package/dist/components/ui/carousel.js.map +1 -1
  58. package/dist/components/ui/chart.d.ts +37 -29
  59. package/dist/components/ui/chart.d.ts.map +1 -1
  60. package/dist/components/ui/chart.js +29 -27
  61. package/dist/components/ui/chart.js.map +1 -1
  62. package/dist/components/ui/checkbox.d.ts +2 -2
  63. package/dist/components/ui/checkbox.d.ts.map +1 -1
  64. package/dist/components/ui/checkbox.js +11 -13
  65. package/dist/components/ui/checkbox.js.map +1 -1
  66. package/dist/components/ui/collapsible.d.ts +4 -5
  67. package/dist/components/ui/collapsible.d.ts.map +1 -1
  68. package/dist/components/ui/collapsible.js +3 -20
  69. package/dist/components/ui/collapsible.js.map +1 -1
  70. package/dist/components/ui/command.d.ts +79 -17
  71. package/dist/components/ui/command.d.ts.map +1 -1
  72. package/dist/components/ui/command.js +52 -77
  73. package/dist/components/ui/command.js.map +1 -1
  74. package/dist/components/ui/context-menu.d.ts +23 -21
  75. package/dist/components/ui/context-menu.d.ts.map +1 -1
  76. package/dist/components/ui/context-menu.js +60 -104
  77. package/dist/components/ui/context-menu.js.map +1 -1
  78. package/dist/components/ui/counting-number.d.ts +1 -1
  79. package/dist/components/ui/counting-number.d.ts.map +1 -1
  80. package/dist/components/ui/counting-number.js +4 -3
  81. package/dist/components/ui/counting-number.js.map +1 -1
  82. package/dist/components/ui/dialog.d.ts +17 -13
  83. package/dist/components/ui/dialog.d.ts.map +1 -1
  84. package/dist/components/ui/dialog.js +38 -66
  85. package/dist/components/ui/dialog.js.map +1 -1
  86. package/dist/components/ui/dot-background.d.ts +10 -17
  87. package/dist/components/ui/dot-background.d.ts.map +1 -1
  88. package/dist/components/ui/dot-background.js +2 -2
  89. package/dist/components/ui/dot-background.js.map +1 -1
  90. package/dist/components/ui/drawer.d.ts +20 -11
  91. package/dist/components/ui/drawer.d.ts.map +1 -1
  92. package/dist/components/ui/drawer.js +37 -62
  93. package/dist/components/ui/drawer.js.map +1 -1
  94. package/dist/components/ui/dropdown-menu.d.ts +23 -21
  95. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  96. package/dist/components/ui/dropdown-menu.js +65 -109
  97. package/dist/components/ui/dropdown-menu.js.map +1 -1
  98. package/dist/components/ui/dropdrawer.d.ts +3 -3
  99. package/dist/components/ui/dropdrawer.d.ts.map +1 -1
  100. package/dist/components/ui/dropdrawer.js +13 -16
  101. package/dist/components/ui/dropdrawer.js.map +1 -1
  102. package/dist/components/ui/empty.d.ts +13 -0
  103. package/dist/components/ui/empty.d.ts.map +1 -0
  104. package/dist/components/ui/empty.js +65 -0
  105. package/dist/components/ui/empty.js.map +1 -0
  106. package/dist/components/ui/field.d.ts +25 -0
  107. package/dist/components/ui/field.d.ts.map +1 -0
  108. package/dist/components/ui/field.js +135 -0
  109. package/dist/components/ui/field.js.map +1 -0
  110. package/dist/components/ui/fireworks-background.d.ts.map +1 -1
  111. package/dist/components/ui/fireworks-background.js +1 -1
  112. package/dist/components/ui/fireworks-background.js.map +1 -1
  113. package/dist/components/ui/flip-button.d.ts +1 -1
  114. package/dist/components/ui/flip-button.d.ts.map +1 -1
  115. package/dist/components/ui/flip-button.js +3 -3
  116. package/dist/components/ui/flip-button.js.map +1 -1
  117. package/dist/components/ui/form.d.ts +7 -8
  118. package/dist/components/ui/form.d.ts.map +1 -1
  119. package/dist/components/ui/form.js +29 -28
  120. package/dist/components/ui/form.js.map +1 -1
  121. package/dist/components/ui/gradient-background.d.ts +1 -1
  122. package/dist/components/ui/gradient-background.d.ts.map +1 -1
  123. package/dist/components/ui/gradient-background.js +2 -2
  124. package/dist/components/ui/gradient-background.js.map +1 -1
  125. package/dist/components/ui/gradient-text.d.ts +1 -1
  126. package/dist/components/ui/gradient-text.d.ts.map +1 -1
  127. package/dist/components/ui/gradient-text.js +5 -5
  128. package/dist/components/ui/gradient-text.js.map +1 -1
  129. package/dist/components/ui/highlight-text.d.ts +1 -1
  130. package/dist/components/ui/highlight-text.d.ts.map +1 -1
  131. package/dist/components/ui/highlight-text.js +3 -3
  132. package/dist/components/ui/highlight-text.js.map +1 -1
  133. package/dist/components/ui/hole-background.d.ts.map +1 -1
  134. package/dist/components/ui/hole-background.js +11 -10
  135. package/dist/components/ui/hole-background.js.map +1 -1
  136. package/dist/components/ui/hover-card.d.ts +5 -5
  137. package/dist/components/ui/hover-card.d.ts.map +1 -1
  138. package/dist/components/ui/hover-card.js +12 -26
  139. package/dist/components/ui/hover-card.js.map +1 -1
  140. package/dist/components/ui/input-group.d.ts +17 -0
  141. package/dist/components/ui/input-group.d.ts.map +1 -0
  142. package/dist/components/ui/input-group.js +91 -0
  143. package/dist/components/ui/input-group.js.map +1 -0
  144. package/dist/components/ui/input-otp.d.ts +31 -8
  145. package/dist/components/ui/input-otp.d.ts.map +1 -1
  146. package/dist/components/ui/input-otp.js +24 -27
  147. package/dist/components/ui/input-otp.js.map +1 -1
  148. package/dist/components/ui/input.d.ts +1 -1
  149. package/dist/components/ui/input.d.ts.map +1 -1
  150. package/dist/components/ui/input.js +7 -8
  151. package/dist/components/ui/input.js.map +1 -1
  152. package/dist/components/ui/item.d.ts +24 -0
  153. package/dist/components/ui/item.d.ts.map +1 -0
  154. package/dist/components/ui/item.js +122 -0
  155. package/dist/components/ui/item.js.map +1 -0
  156. package/dist/components/ui/kbd.d.ts +5 -0
  157. package/dist/components/ui/kbd.d.ts.map +1 -0
  158. package/dist/components/ui/kbd.js +21 -0
  159. package/dist/components/ui/kbd.js.map +1 -0
  160. package/dist/components/ui/label.d.ts +3 -2
  161. package/dist/components/ui/label.d.ts.map +1 -1
  162. package/dist/components/ui/label.js +9 -8
  163. package/dist/components/ui/label.js.map +1 -1
  164. package/dist/components/ui/menubar.d.ts +20 -18
  165. package/dist/components/ui/menubar.d.ts.map +1 -1
  166. package/dist/components/ui/menubar.js +75 -95
  167. package/dist/components/ui/menubar.js.map +1 -1
  168. package/dist/components/ui/navigation-menu.d.ts +11 -13
  169. package/dist/components/ui/navigation-menu.d.ts.map +1 -1
  170. package/dist/components/ui/navigation-menu.js +39 -58
  171. package/dist/components/ui/navigation-menu.js.map +1 -1
  172. package/dist/components/ui/pagination.d.ts +25 -10
  173. package/dist/components/ui/pagination.d.ts.map +1 -1
  174. package/dist/components/ui/pagination.js +33 -41
  175. package/dist/components/ui/pagination.js.map +1 -1
  176. package/dist/components/ui/popover.d.ts +6 -6
  177. package/dist/components/ui/popover.d.ts.map +1 -1
  178. package/dist/components/ui/popover.js +10 -26
  179. package/dist/components/ui/popover.js.map +1 -1
  180. package/dist/components/ui/progress.d.ts +2 -2
  181. package/dist/components/ui/progress.d.ts.map +1 -1
  182. package/dist/components/ui/progress.js +8 -10
  183. package/dist/components/ui/progress.js.map +1 -1
  184. package/dist/components/ui/radio-group.d.ts +3 -3
  185. package/dist/components/ui/radio-group.d.ts.map +1 -1
  186. package/dist/components/ui/radio-group.js +17 -20
  187. package/dist/components/ui/radio-group.js.map +1 -1
  188. package/dist/components/ui/resizable.d.ts +21 -6
  189. package/dist/components/ui/resizable.d.ts.map +1 -1
  190. package/dist/components/ui/resizable.js +9 -21
  191. package/dist/components/ui/resizable.js.map +1 -1
  192. package/dist/components/ui/ripple-button.d.ts +1 -1
  193. package/dist/components/ui/ripple-button.d.ts.map +1 -1
  194. package/dist/components/ui/ripple-button.js +4 -4
  195. package/dist/components/ui/ripple-button.js.map +1 -1
  196. package/dist/components/ui/scratcher.d.ts.map +1 -1
  197. package/dist/components/ui/scratcher.js +7 -5
  198. package/dist/components/ui/scratcher.js.map +1 -1
  199. package/dist/components/ui/scroll-area.d.ts +3 -3
  200. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  201. package/dist/components/ui/scroll-area.js +14 -18
  202. package/dist/components/ui/scroll-area.js.map +1 -1
  203. package/dist/components/ui/select.d.ts +11 -13
  204. package/dist/components/ui/select.d.ts.map +1 -1
  205. package/dist/components/ui/select.js +55 -78
  206. package/dist/components/ui/select.js.map +1 -1
  207. package/dist/components/ui/separator.d.ts +2 -2
  208. package/dist/components/ui/separator.d.ts.map +1 -1
  209. package/dist/components/ui/separator.js +7 -8
  210. package/dist/components/ui/separator.js.map +1 -1
  211. package/dist/components/ui/sheet.d.ts +24 -12
  212. package/dist/components/ui/sheet.d.ts.map +1 -1
  213. package/dist/components/ui/sheet.js +56 -68
  214. package/dist/components/ui/sheet.js.map +1 -1
  215. package/dist/components/ui/sidebar.d.ts +35 -39
  216. package/dist/components/ui/sidebar.d.ts.map +1 -1
  217. package/dist/components/ui/sidebar.js +115 -124
  218. package/dist/components/ui/sidebar.js.map +1 -1
  219. package/dist/components/ui/skeleton.d.ts +1 -1
  220. package/dist/components/ui/skeleton.d.ts.map +1 -1
  221. package/dist/components/ui/skeleton.js +2 -3
  222. package/dist/components/ui/skeleton.js.map +1 -1
  223. package/dist/components/ui/slider.d.ts +2 -2
  224. package/dist/components/ui/slider.d.ts.map +1 -1
  225. package/dist/components/ui/slider.js +12 -31
  226. package/dist/components/ui/slider.js.map +1 -1
  227. package/dist/components/ui/sonner.d.ts +4 -2
  228. package/dist/components/ui/sonner.d.ts.map +1 -1
  229. package/dist/components/ui/sonner.js +8 -5
  230. package/dist/components/ui/sonner.js.map +1 -1
  231. package/dist/components/ui/spinner.d.ts +4 -0
  232. package/dist/components/ui/spinner.d.ts.map +1 -0
  233. package/dist/components/ui/spinner.js +16 -0
  234. package/dist/components/ui/spinner.js.map +1 -0
  235. package/dist/components/ui/switch.d.ts +2 -2
  236. package/dist/components/ui/switch.d.ts.map +1 -1
  237. package/dist/components/ui/switch.js +8 -10
  238. package/dist/components/ui/switch.js.map +1 -1
  239. package/dist/components/ui/table.d.ts +9 -9
  240. package/dist/components/ui/table.d.ts.map +1 -1
  241. package/dist/components/ui/table.js +40 -49
  242. package/dist/components/ui/table.js.map +1 -1
  243. package/dist/components/ui/tabs.d.ts +6 -6
  244. package/dist/components/ui/tabs.d.ts.map +1 -1
  245. package/dist/components/ui/tabs.js +18 -27
  246. package/dist/components/ui/tabs.js.map +1 -1
  247. package/dist/components/ui/textarea.d.ts +1 -1
  248. package/dist/components/ui/textarea.d.ts.map +1 -1
  249. package/dist/components/ui/textarea.js +7 -8
  250. package/dist/components/ui/textarea.js.map +1 -1
  251. package/dist/components/ui/toggle-group.d.ts +9 -4
  252. package/dist/components/ui/toggle-group.d.ts.map +1 -1
  253. package/dist/components/ui/toggle-group.js +12 -16
  254. package/dist/components/ui/toggle-group.js.map +1 -1
  255. package/dist/components/ui/toggle.d.ts +9 -6
  256. package/dist/components/ui/toggle.d.ts.map +1 -1
  257. package/dist/components/ui/toggle.js +8 -9
  258. package/dist/components/ui/toggle.js.map +1 -1
  259. package/dist/components/ui/tooltip.d.ts +6 -6
  260. package/dist/components/ui/tooltip.d.ts.map +1 -1
  261. package/dist/components/ui/tooltip.js +14 -39
  262. package/dist/components/ui/tooltip.js.map +1 -1
  263. package/dist/components/ui/typewriter.d.ts.map +1 -1
  264. package/dist/components/ui/typewriter.js +9 -9
  265. package/dist/components/ui/typewriter.js.map +1 -1
  266. package/dist/hooks/useIsMobile.d.ts +2 -5
  267. package/dist/hooks/useIsMobile.d.ts.map +1 -1
  268. package/dist/hooks/useIsMobile.js +1 -1
  269. package/dist/hooks/useIsMobile.js.map +1 -1
  270. package/dist/hooks/useWindowSize.d.ts +0 -1
  271. package/dist/hooks/useWindowSize.d.ts.map +1 -1
  272. package/dist/hooks/useWindowSize.js +1 -1
  273. package/dist/hooks/useWindowSize.js.map +1 -1
  274. package/dist/index.css +841 -1128
  275. package/dist/index.css.map +1 -1
  276. package/dist/index.d.ts +43 -37
  277. package/dist/index.d.ts.map +1 -1
  278. package/dist/index.js +11 -5
  279. package/dist/lib/utilities.d.ts +9 -0
  280. package/dist/lib/utilities.d.ts.map +1 -0
  281. package/dist/lib/{utils.js → utilities.js} +1 -1
  282. package/dist/lib/utilities.js.map +1 -0
  283. package/package.json +121 -90
  284. package/{README.md → readme.md} +627 -627
  285. package/src/components/ui/accordion.tsx +55 -66
  286. package/src/components/ui/alert-dialog.tsx +124 -160
  287. package/src/components/ui/alert.tsx +56 -69
  288. package/src/components/ui/aspect-ratio.tsx +7 -12
  289. package/src/components/ui/avatar.tsx +43 -53
  290. package/src/components/ui/background-beams.tsx +145 -142
  291. package/src/components/ui/badge.tsx +39 -48
  292. package/src/components/ui/breadcrumb.tsx +94 -117
  293. package/src/components/ui/bubble-background.tsx +170 -189
  294. package/src/components/ui/button-group.tsx +69 -0
  295. package/src/components/ui/button.tsx +55 -61
  296. package/src/components/ui/calendar.tsx +175 -216
  297. package/src/components/ui/card.tsx +64 -97
  298. package/src/components/ui/carousel.tsx +216 -241
  299. package/src/components/ui/chart.tsx +293 -385
  300. package/src/components/ui/checkbox.tsx +27 -32
  301. package/src/components/ui/collapsible.tsx +11 -34
  302. package/src/components/ui/command.tsx +138 -184
  303. package/src/components/ui/context-menu.tsx +186 -255
  304. package/src/components/ui/counting-number.tsx +92 -108
  305. package/src/components/ui/dialog.tsx +106 -146
  306. package/src/components/ui/dot-background.tsx +153 -158
  307. package/src/components/ui/drawer.tsx +105 -141
  308. package/src/components/ui/dropdown-menu.tsx +188 -260
  309. package/src/components/ui/dropdrawer.tsx +865 -973
  310. package/src/components/ui/empty.tsx +86 -0
  311. package/src/components/ui/field.tsx +198 -0
  312. package/src/components/ui/fireworks-background.tsx +325 -378
  313. package/src/components/ui/flip-button.tsx +89 -110
  314. package/src/components/ui/form.tsx +144 -174
  315. package/src/components/ui/gradient-background.tsx +30 -43
  316. package/src/components/ui/gradient-text.tsx +62 -65
  317. package/src/components/ui/highlight-text.tsx +54 -71
  318. package/src/components/ui/hole-background.tsx +326 -361
  319. package/src/components/ui/hover-card.tsx +29 -44
  320. package/src/components/ui/input-group.tsx +145 -0
  321. package/src/components/ui/input-otp.tsx +66 -77
  322. package/src/components/ui/input.tsx +21 -22
  323. package/src/components/ui/item.tsx +163 -0
  324. package/src/components/ui/kbd.tsx +31 -0
  325. package/src/components/ui/label.tsx +23 -24
  326. package/src/components/ui/menubar.tsx +233 -279
  327. package/src/components/ui/navigation-menu.tsx +120 -171
  328. package/src/components/ui/pagination.tsx +92 -129
  329. package/src/components/ui/popover.tsx +33 -48
  330. package/src/components/ui/progress.tsx +24 -31
  331. package/src/components/ui/radio-group.tsx +43 -45
  332. package/src/components/ui/resizable.tsx +38 -56
  333. package/src/components/ui/ripple-button.tsx +90 -111
  334. package/src/components/ui/scratcher.tsx +167 -171
  335. package/src/components/ui/scroll-area.tsx +42 -58
  336. package/src/components/ui/select.tsx +145 -191
  337. package/src/components/ui/separator.tsx +26 -28
  338. package/src/components/ui/sheet.tsx +112 -145
  339. package/src/components/ui/sidebar.tsx +664 -729
  340. package/src/components/ui/skeleton.tsx +15 -19
  341. package/src/components/ui/slider.tsx +23 -63
  342. package/src/components/ui/sonner.tsx +36 -26
  343. package/src/components/ui/spinner.tsx +18 -0
  344. package/src/components/ui/switch.tsx +28 -31
  345. package/src/components/ui/table.tsx +93 -119
  346. package/src/components/ui/tabs.tsx +54 -66
  347. package/src/components/ui/textarea.tsx +21 -20
  348. package/src/components/ui/toggle-group.tsx +53 -73
  349. package/src/components/ui/toggle.tsx +44 -47
  350. package/src/components/ui/tooltip.tsx +32 -61
  351. package/src/components/ui/typewriter.tsx +173 -188
  352. package/src/hooks/useIsMobile.tsx +42 -45
  353. package/src/hooks/useWindowSize.tsx +66 -72
  354. package/src/index.css +67 -67
  355. package/src/index.ts +342 -408
  356. package/src/lib/utilities.ts +12 -0
  357. package/dist/lib/utils.d.ts +0 -7
  358. package/dist/lib/utils.d.ts.map +0 -1
  359. package/dist/lib/utils.js.map +0 -1
  360. package/src/lib/utils.ts +0 -10
@@ -1,385 +1,293 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import * as RechartsPrimitive from "recharts";
5
-
6
- import type { LegendPayload } from "recharts/types/component/DefaultLegendContent";
7
- import {
8
- NameType,
9
- Payload,
10
- ValueType,
11
- } from "recharts/types/component/DefaultTooltipContent";
12
- import type { Props as LegendProps } from "recharts/types/component/Legend";
13
- import { TooltipContentProps } from "recharts/types/component/Tooltip";
14
-
15
- import { cn } from "@/lib/utils";
16
-
17
- // Format: { THEME_NAME: CSS_SELECTOR }
18
- const THEMES = { light: "", dark: ".dark" } as const;
19
-
20
- export type ChartConfig = {
21
- [k in string]: {
22
- label?: React.ReactNode;
23
- icon?: React.ComponentType;
24
- } & (
25
- | { color?: string; theme?: never }
26
- | { color?: never; theme: Record<keyof typeof THEMES, string> }
27
- );
28
- };
29
-
30
- type ChartContextProps = {
31
- config: ChartConfig;
32
- };
33
-
34
- export type CustomTooltipProps = TooltipContentProps<ValueType, NameType> & {
35
- className?: string;
36
- hideLabel?: boolean;
37
- hideIndicator?: boolean;
38
- indicator?: "line" | "dot" | "dashed";
39
- nameKey?: string;
40
- labelKey?: string;
41
- labelFormatter?: (
42
- label: TooltipContentProps<number, string>["label"],
43
- payload: TooltipContentProps<number, string>["payload"],
44
- ) => React.ReactNode;
45
- formatter?: (
46
- value: number | string,
47
- name: string,
48
- item: Payload<number | string, string>,
49
- index: number,
50
- payload: ReadonlyArray<Payload<number | string, string>>,
51
- ) => React.ReactNode;
52
- labelClassName?: string;
53
- color?: string;
54
- };
55
-
56
- export type ChartLegendContentProps = {
57
- className?: string;
58
- hideIcon?: boolean;
59
- verticalAlign?: LegendProps["verticalAlign"];
60
- payload?: LegendPayload[];
61
- nameKey?: string;
62
- };
63
-
64
- const ChartContext = React.createContext<ChartContextProps | null>(null);
65
-
66
- function useChart() {
67
- const context = React.useContext(ChartContext);
68
-
69
- if (!context) {
70
- throw new Error("useChart must be used within a <ChartContainer />");
71
- }
72
-
73
- return context;
74
- }
75
-
76
- function ChartContainer({
77
- id,
78
- className,
79
- children,
80
- config,
81
- ...props
82
- }: React.ComponentProps<"div"> & {
83
- config: ChartConfig;
84
- children: React.ComponentProps<
85
- typeof RechartsPrimitive.ResponsiveContainer
86
- >["children"];
87
- }) {
88
- const uniqueId = React.useId();
89
- const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
90
-
91
- return (
92
- <ChartContext.Provider value={{ config }}>
93
- <div
94
- data-slot="chart"
95
- data-chart={chartId}
96
- className={cn(
97
- "[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
98
- className,
99
- )}
100
- {...props}
101
- >
102
- <ChartStyle id={chartId} config={config} />
103
- <RechartsPrimitive.ResponsiveContainer>
104
- {children}
105
- </RechartsPrimitive.ResponsiveContainer>
106
- </div>
107
- </ChartContext.Provider>
108
- );
109
- }
110
-
111
- const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
112
- const colorConfig = Object.entries(config).filter(
113
- ([, config]) => config.theme || config.color,
114
- );
115
-
116
- if (!colorConfig.length) {
117
- return null;
118
- }
119
-
120
- return (
121
- <style
122
- dangerouslySetInnerHTML={{
123
- __html: Object.entries(THEMES)
124
- .map(
125
- ([theme, prefix]) => `
126
- ${prefix} [data-chart=${id}] {
127
- ${colorConfig
128
- .map(([key, itemConfig]) => {
129
- const color =
130
- itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
131
- itemConfig.color;
132
- return color ? ` --color-${key}: ${color};` : null;
133
- })
134
- .join("\n")}
135
- }
136
- `,
137
- )
138
- .join("\n"),
139
- }}
140
- />
141
- );
142
- };
143
-
144
- const ChartTooltip = RechartsPrimitive.Tooltip;
145
-
146
- function ChartTooltipContent({
147
- active,
148
- payload,
149
- label,
150
- className,
151
- indicator = "dot",
152
- hideLabel = false,
153
- hideIndicator = false,
154
- labelFormatter,
155
- formatter,
156
- labelClassName,
157
- color,
158
- nameKey,
159
- labelKey,
160
- }: CustomTooltipProps) {
161
- const { config } = useChart();
162
-
163
- const tooltipLabel = React.useMemo(() => {
164
- if (hideLabel || !payload?.length) {
165
- return null;
166
- }
167
-
168
- const [item] = payload;
169
- const key = `${labelKey || item?.dataKey || item?.name || "value"}`;
170
- const itemConfig = getPayloadConfigFromPayload(config, item, key);
171
- const value = (() => {
172
- const v =
173
- !labelKey && typeof label === "string"
174
- ? (config[label as keyof typeof config]?.label ?? label)
175
- : itemConfig?.label;
176
-
177
- return typeof v === "string" || typeof v === "number" ? v : undefined;
178
- })();
179
-
180
- if (labelFormatter) {
181
- return (
182
- <div className={cn("font-medium", labelClassName)}>
183
- {labelFormatter(value, payload)}
184
- </div>
185
- );
186
- }
187
-
188
- if (!value) {
189
- return null;
190
- }
191
-
192
- return <div className={cn("font-medium", labelClassName)}>{value}</div>;
193
- }, [
194
- label,
195
- labelFormatter,
196
- payload,
197
- hideLabel,
198
- labelClassName,
199
- config,
200
- labelKey,
201
- ]);
202
-
203
- if (!active || !payload?.length) {
204
- return null;
205
- }
206
-
207
- const nestLabel = payload.length === 1 && indicator !== "dot";
208
-
209
- return (
210
- <div
211
- className={cn(
212
- "border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl",
213
- className,
214
- )}
215
- >
216
- {!nestLabel ? tooltipLabel : null}
217
- <div className="grid gap-1.5">
218
- {payload.map((item, index) => {
219
- const key = `${nameKey || item.name || item.dataKey || "value"}`;
220
- const itemConfig = getPayloadConfigFromPayload(config, item, key);
221
- const indicatorColor = color || item.payload.fill || item.color;
222
-
223
- return (
224
- <div
225
- key={item.dataKey}
226
- className={cn(
227
- "[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
228
- indicator === "dot" && "items-center",
229
- )}
230
- >
231
- {formatter && item?.value !== undefined && item.name ? (
232
- formatter(item.value, item.name, item, index, item.payload)
233
- ) : (
234
- <>
235
- {itemConfig?.icon ? (
236
- <itemConfig.icon />
237
- ) : (
238
- !hideIndicator && (
239
- <div
240
- className={cn(
241
- "shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
242
- {
243
- "h-2.5 w-2.5": indicator === "dot",
244
- "w-1": indicator === "line",
245
- "w-0 border-[1.5px] border-dashed bg-transparent":
246
- indicator === "dashed",
247
- "my-0.5": nestLabel && indicator === "dashed",
248
- },
249
- )}
250
- style={
251
- {
252
- "--color-bg": indicatorColor,
253
- "--color-border": indicatorColor,
254
- } as React.CSSProperties
255
- }
256
- />
257
- )
258
- )}
259
- <div
260
- className={cn(
261
- "flex flex-1 justify-between leading-none",
262
- nestLabel ? "items-end" : "items-center",
263
- )}
264
- >
265
- <div className="grid gap-1.5">
266
- {nestLabel ? tooltipLabel : null}
267
- <span className="text-muted-foreground">
268
- {itemConfig?.label || item.name}
269
- </span>
270
- </div>
271
- {item.value && (
272
- <span className="text-foreground font-mono font-medium tabular-nums">
273
- {item.value.toLocaleString()}
274
- </span>
275
- )}
276
- </div>
277
- </>
278
- )}
279
- </div>
280
- );
281
- })}
282
- </div>
283
- </div>
284
- );
285
- }
286
-
287
- const ChartLegend = RechartsPrimitive.Legend;
288
-
289
- function ChartLegendContent({
290
- className,
291
- hideIcon = false,
292
- payload,
293
- verticalAlign = "bottom",
294
- nameKey,
295
- }: ChartLegendContentProps) {
296
- const { config } = useChart();
297
-
298
- if (!payload?.length) {
299
- return null;
300
- }
301
-
302
- return (
303
- <div
304
- className={cn(
305
- "flex items-center justify-center gap-4",
306
- verticalAlign === "top" ? "pb-3" : "pt-3",
307
- className,
308
- )}
309
- >
310
- {payload.map((item) => {
311
- const key = `${nameKey || item.dataKey || "value"}`;
312
- const itemConfig = getPayloadConfigFromPayload(config, item, key);
313
-
314
- return (
315
- <div
316
- key={item.value}
317
- className={cn(
318
- "[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3",
319
- )}
320
- >
321
- {itemConfig?.icon && !hideIcon ? (
322
- <itemConfig.icon />
323
- ) : (
324
- <div
325
- className="h-2 w-2 shrink-0 rounded-[2px]"
326
- style={{
327
- backgroundColor: item.color,
328
- }}
329
- />
330
- )}
331
- {itemConfig?.label}
332
- </div>
333
- );
334
- })}
335
- </div>
336
- );
337
- }
338
-
339
- // Helper to extract item config from a payload.
340
- function getPayloadConfigFromPayload(
341
- config: ChartConfig,
342
- payload: unknown,
343
- key: string,
344
- ) {
345
- if (typeof payload !== "object" || payload === null) {
346
- return undefined;
347
- }
348
-
349
- const payloadPayload =
350
- "payload" in payload &&
351
- typeof payload.payload === "object" &&
352
- payload.payload !== null
353
- ? payload.payload
354
- : undefined;
355
-
356
- let configLabelKey: string = key;
357
-
358
- if (
359
- key in payload &&
360
- typeof payload[key as keyof typeof payload] === "string"
361
- ) {
362
- configLabelKey = payload[key as keyof typeof payload] as string;
363
- } else if (
364
- payloadPayload &&
365
- key in payloadPayload &&
366
- typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
367
- ) {
368
- configLabelKey = payloadPayload[
369
- key as keyof typeof payloadPayload
370
- ] as string;
371
- }
372
-
373
- return configLabelKey in config
374
- ? config[configLabelKey]
375
- : config[key as keyof typeof config];
376
- }
377
-
378
- export {
379
- ChartContainer,
380
- ChartTooltip,
381
- ChartTooltipContent,
382
- ChartLegend,
383
- ChartLegendContent,
384
- ChartStyle,
385
- };
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import * as RechartsPrimitive from "recharts";
5
+
6
+ import {cn} from "@/lib/utilities";
7
+
8
+ // Format: { THEME_NAME: CSS_SELECTOR }
9
+ const THEMES = {light: "", dark: ".dark"} as const;
10
+
11
+ export type ChartConfig = {
12
+ [k in string]: {
13
+ label?: React.ReactNode;
14
+ icon?: React.ComponentType;
15
+ } & ({color?: string; theme?: never} | {color?: never; theme: Record<keyof typeof THEMES, string>});
16
+ };
17
+
18
+ type ChartContextProps = {
19
+ config: ChartConfig;
20
+ };
21
+
22
+ const ChartContext = React.createContext<ChartContextProps | null>(null);
23
+
24
+ function useChart() {
25
+ const context = React.useContext(ChartContext);
26
+
27
+ if (!context) {
28
+ throw new Error("useChart must be used within a <ChartContainer />");
29
+ }
30
+
31
+ return context;
32
+ }
33
+
34
+ const ChartContainer = React.forwardRef<
35
+ HTMLDivElement,
36
+ React.ComponentProps<"div"> & {
37
+ config: ChartConfig;
38
+ children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>["children"];
39
+ }
40
+ >(({id, className, children, config, ...props}, ref) => {
41
+ const uniqueId = React.useId();
42
+ const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
43
+
44
+ return (
45
+ <ChartContext.Provider value={{config}}>
46
+ <div
47
+ data-chart={chartId}
48
+ ref={ref}
49
+ className={cn(
50
+ "[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-sector]:outline-none [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-none",
51
+ className,
52
+ )}
53
+ {...props}>
54
+ <ChartStyle
55
+ id={chartId}
56
+ config={config}
57
+ />
58
+ <RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>
59
+ </div>
60
+ </ChartContext.Provider>
61
+ );
62
+ });
63
+ ChartContainer.displayName = "Chart";
64
+
65
+ const ChartStyle = ({id, config}: {id: string; config: ChartConfig}) => {
66
+ const colorConfig = Object.entries(config).filter(([, config]) => config.theme || config.color);
67
+
68
+ if (!colorConfig.length) {
69
+ return null;
70
+ }
71
+
72
+ return (
73
+ <style
74
+ dangerouslySetInnerHTML={{
75
+ __html: Object.entries(THEMES)
76
+ .map(
77
+ ([theme, prefix]) => `
78
+ ${prefix} [data-chart=${id}] {
79
+ ${colorConfig
80
+ .map(([key, itemConfig]) => {
81
+ const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] || itemConfig.color;
82
+ return color ? ` --color-${key}: ${color};` : null;
83
+ })
84
+ .join("")}
85
+ }
86
+ `,
87
+ )
88
+ .join(""),
89
+ }}
90
+ />
91
+ );
92
+ };
93
+
94
+ const ChartTooltip = RechartsPrimitive.Tooltip;
95
+
96
+ const ChartTooltipContent = React.forwardRef<
97
+ HTMLDivElement,
98
+ React.ComponentProps<typeof RechartsPrimitive.Tooltip>
99
+ & React.ComponentProps<"div"> & {
100
+ hideLabel?: boolean;
101
+ hideIndicator?: boolean;
102
+ indicator?: "line" | "dot" | "dashed";
103
+ nameKey?: string;
104
+ labelKey?: string;
105
+ }
106
+ >(
107
+ (
108
+ {
109
+ active,
110
+ payload,
111
+ className,
112
+ indicator = "dot",
113
+ hideLabel = false,
114
+ hideIndicator = false,
115
+ label,
116
+ labelFormatter,
117
+ labelClassName,
118
+ formatter,
119
+ color,
120
+ nameKey,
121
+ labelKey,
122
+ },
123
+ ref,
124
+ ) => {
125
+ const {config} = useChart();
126
+
127
+ const tooltipLabel = React.useMemo(() => {
128
+ if (hideLabel || !payload?.length) {
129
+ return null;
130
+ }
131
+
132
+ const [item] = payload;
133
+ const key = `${labelKey || item?.dataKey || item?.name || "value"}`;
134
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
135
+ const value = !labelKey && typeof label === "string" ? config[label as keyof typeof config]?.label || label : itemConfig?.label;
136
+
137
+ if (labelFormatter) {
138
+ return <div className={cn("font-medium", labelClassName)}>{labelFormatter(value, payload)}</div>;
139
+ }
140
+
141
+ if (!value) {
142
+ return null;
143
+ }
144
+
145
+ return <div className={cn("font-medium", labelClassName)}>{value}</div>;
146
+ }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
147
+
148
+ if (!active || !payload?.length) {
149
+ return null;
150
+ }
151
+
152
+ const nestLabel = payload.length === 1 && indicator !== "dot";
153
+
154
+ return (
155
+ <div
156
+ ref={ref}
157
+ className={cn(
158
+ "grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-neutral-200 border-neutral-200/50 bg-white px-2.5 py-1.5 text-xs shadow-xl dark:border-neutral-800 dark:border-neutral-800/50 dark:bg-neutral-950",
159
+ className,
160
+ )}>
161
+ {!nestLabel ? tooltipLabel : null}
162
+ <div className='grid gap-1.5'>
163
+ {payload
164
+ .filter((item) => item.type !== "none")
165
+ .map((item, index) => {
166
+ const key = `${nameKey || item.name || item.dataKey || "value"}`;
167
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
168
+ const indicatorColor = color || item.payload.fill || item.color;
169
+
170
+ return (
171
+ <div
172
+ key={item.dataKey}
173
+ className={cn(
174
+ "flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-neutral-500 dark:[&>svg]:text-neutral-400",
175
+ indicator === "dot" && "items-center",
176
+ )}>
177
+ {formatter && item?.value !== undefined && item.name ? (
178
+ formatter(item.value, item.name, item, index, item.payload)
179
+ ) : (
180
+ <>
181
+ {itemConfig?.icon ? (
182
+ <itemConfig.icon />
183
+ ) : (
184
+ !hideIndicator && (
185
+ <div
186
+ className={cn("shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]", {
187
+ "h-2.5 w-2.5": indicator === "dot",
188
+ "w-1": indicator === "line",
189
+ "w-0 border-[1.5px] border-dashed bg-transparent": indicator === "dashed",
190
+ "my-0.5": nestLabel && indicator === "dashed",
191
+ })}
192
+ style={
193
+ {
194
+ "--color-bg": indicatorColor,
195
+ "--color-border": indicatorColor,
196
+ } as React.CSSProperties
197
+ }
198
+ />
199
+ )
200
+ )}
201
+ <div className={cn("flex flex-1 justify-between leading-none", nestLabel ? "items-end" : "items-center")}>
202
+ <div className='grid gap-1.5'>
203
+ {nestLabel ? tooltipLabel : null}
204
+ <span className='text-neutral-500 dark:text-neutral-400'>{itemConfig?.label || item.name}</span>
205
+ </div>
206
+ {item.value && (
207
+ <span className='font-mono font-medium text-neutral-950 tabular-nums dark:text-neutral-50'>
208
+ {item.value.toLocaleString()}
209
+ </span>
210
+ )}
211
+ </div>
212
+ </>
213
+ )}
214
+ </div>
215
+ );
216
+ })}
217
+ </div>
218
+ </div>
219
+ );
220
+ },
221
+ );
222
+ ChartTooltipContent.displayName = "ChartTooltip";
223
+
224
+ const ChartLegend = RechartsPrimitive.Legend;
225
+
226
+ const ChartLegendContent = React.forwardRef<
227
+ HTMLDivElement,
228
+ React.ComponentProps<"div">
229
+ & Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
230
+ hideIcon?: boolean;
231
+ nameKey?: string;
232
+ }
233
+ >(({className, hideIcon = false, payload, verticalAlign = "bottom", nameKey}, ref) => {
234
+ const {config} = useChart();
235
+
236
+ if (!payload?.length) {
237
+ return null;
238
+ }
239
+
240
+ return (
241
+ <div
242
+ ref={ref}
243
+ className={cn("flex items-center justify-center gap-4", verticalAlign === "top" ? "pb-3" : "pt-3", className)}>
244
+ {payload
245
+ .filter((item) => item.type !== "none")
246
+ .map((item) => {
247
+ const key = `${nameKey || item.dataKey || "value"}`;
248
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
249
+
250
+ return (
251
+ <div
252
+ key={item.value}
253
+ className={cn("flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-neutral-500 dark:[&>svg]:text-neutral-400")}>
254
+ {itemConfig?.icon && !hideIcon ? (
255
+ <itemConfig.icon />
256
+ ) : (
257
+ <div
258
+ className='h-2 w-2 shrink-0 rounded-[2px]'
259
+ style={{
260
+ backgroundColor: item.color,
261
+ }}
262
+ />
263
+ )}
264
+ {itemConfig?.label}
265
+ </div>
266
+ );
267
+ })}
268
+ </div>
269
+ );
270
+ });
271
+ ChartLegendContent.displayName = "ChartLegend";
272
+
273
+ // Helper to extract item config from a payload.
274
+ function getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {
275
+ if (typeof payload !== "object" || payload === null) {
276
+ return undefined;
277
+ }
278
+
279
+ const payloadPayload =
280
+ "payload" in payload && typeof payload.payload === "object" && payload.payload !== null ? payload.payload : undefined;
281
+
282
+ let configLabelKey: string = key;
283
+
284
+ if (key in payload && typeof payload[key as keyof typeof payload] === "string") {
285
+ configLabelKey = payload[key as keyof typeof payload] as string;
286
+ } else if (payloadPayload && key in payloadPayload && typeof payloadPayload[key as keyof typeof payloadPayload] === "string") {
287
+ configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;
288
+ }
289
+
290
+ return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config];
291
+ }
292
+
293
+ export {ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent};