@wealthx/shadcn 1.1.0 → 1.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 (300) hide show
  1. package/.turbo/turbo-build.log +235 -154
  2. package/CHANGELOG.md +6 -0
  3. package/dist/{chunk-6OJF6XRN.mjs → chunk-24FUO7TD.mjs} +4 -8
  4. package/dist/{chunk-4AJ5HWHD.mjs → chunk-2I5S2AMY.mjs} +3 -3
  5. package/dist/chunk-2SF672SZ.mjs +161 -0
  6. package/dist/{chunk-GPRJQ24C.mjs → chunk-34NWQURD.mjs} +2 -2
  7. package/dist/{chunk-MQ72DIBH.mjs → chunk-3GF7OVTP.mjs} +14 -5
  8. package/dist/chunk-3WMX6KWS.mjs +245 -0
  9. package/dist/{chunk-PMKODV6M.mjs → chunk-462HMNO4.mjs} +6 -10
  10. package/dist/chunk-4CX4SBRO.mjs +153 -0
  11. package/dist/chunk-4MN6UQHG.mjs +443 -0
  12. package/dist/{chunk-GLW2UO6O.mjs → chunk-5QQVZTVZ.mjs} +82 -61
  13. package/dist/{chunk-BGP2N52Z.mjs → chunk-66MI7Q4B.mjs} +5 -5
  14. package/dist/chunk-6FCGKSZX.mjs +268 -0
  15. package/dist/{chunk-CGOKTPXU.mjs → chunk-6JQFUE5I.mjs} +20 -23
  16. package/dist/{chunk-Z3MK2KKZ.mjs → chunk-7DHU4VGG.mjs} +7 -3
  17. package/dist/{chunk-VZ2NR7L3.mjs → chunk-7PYJD5JI.mjs} +35 -27
  18. package/dist/{chunk-JU2RUWHF.mjs → chunk-7XJHLGUV.mjs} +1 -1
  19. package/dist/{chunk-BMFN37JH.mjs → chunk-7YAU5CY6.mjs} +1 -1
  20. package/dist/chunk-A56YQQHG.mjs +402 -0
  21. package/dist/chunk-AH52LG6N.mjs +315 -0
  22. package/dist/{chunk-SLWCCURD.mjs → chunk-CLIN5525.mjs} +8 -4
  23. package/dist/{chunk-3VQNJ235.mjs → chunk-CSDO6VBW.mjs} +7 -0
  24. package/dist/chunk-D4ILTPOG.mjs +293 -0
  25. package/dist/{chunk-HS7TFG7V.mjs → chunk-D6ID6M4V.mjs} +1 -1
  26. package/dist/chunk-DOH3EHX7.mjs +378 -0
  27. package/dist/{chunk-MJIEMGRD.mjs → chunk-EFRENWEJ.mjs} +9 -17
  28. package/dist/{chunk-YBXCIF5Q.mjs → chunk-ERGGHC2V.mjs} +36 -49
  29. package/dist/{chunk-OXQQNQZI.mjs → chunk-FEZKMUCF.mjs} +10 -1
  30. package/dist/{chunk-55CEW76V.mjs → chunk-FH6QVUVZ.mjs} +1 -1
  31. package/dist/chunk-FMAXJ2SI.mjs +71 -0
  32. package/dist/chunk-FZIXGLMV.mjs +173 -0
  33. package/dist/{chunk-DS2AMHN2.mjs → chunk-GYMYRIZP.mjs} +2 -2
  34. package/dist/{chunk-KQDD5MU3.mjs → chunk-H45TKD34.mjs} +5 -5
  35. package/dist/{chunk-BBJBJSXQ.mjs → chunk-J5UICVJS.mjs} +1 -1
  36. package/dist/{chunk-RL772EH7.mjs → chunk-JHJHG4GO.mjs} +4 -12
  37. package/dist/{chunk-RN67642N.mjs → chunk-KMCGSZTX.mjs} +47 -41
  38. package/dist/{chunk-FHNT55I5.mjs → chunk-KUDCQ4FI.mjs} +4 -4
  39. package/dist/chunk-LE6YFY6D.mjs +209 -0
  40. package/dist/{chunk-NLLKTU4B.mjs → chunk-LLVQKSU3.mjs} +21 -17
  41. package/dist/{chunk-KKHTJNMM.mjs → chunk-MARPPFOJ.mjs} +8 -4
  42. package/dist/{chunk-6AFMNC42.mjs → chunk-N2PT566P.mjs} +15 -11
  43. package/dist/chunk-NLCKVHWB.mjs +161 -0
  44. package/dist/{chunk-YN5SYTOO.mjs → chunk-NQPOYKAQ.mjs} +9 -5
  45. package/dist/{chunk-ZZV5JVNW.mjs → chunk-NSLMILBT.mjs} +3 -7
  46. package/dist/chunk-NXA3CZ7A.mjs +248 -0
  47. package/dist/chunk-OGOYQ7BG.mjs +150 -0
  48. package/dist/{chunk-3NQGYJEZ.mjs → chunk-P6AM5V7O.mjs} +10 -18
  49. package/dist/{chunk-CZ3BW5GL.mjs → chunk-P76HMUI6.mjs} +5 -11
  50. package/dist/chunk-PCPLO5HT.mjs +671 -0
  51. package/dist/chunk-PG6K5XEC.mjs +475 -0
  52. package/dist/{chunk-5JGQAAQV.mjs → chunk-PJHPSRYD.mjs} +84 -62
  53. package/dist/{chunk-DDPA2XXS.mjs → chunk-PMB3A7V3.mjs} +2 -2
  54. package/dist/chunk-PR6V5XKM.mjs +209 -0
  55. package/dist/{chunk-46OFHMQA.mjs → chunk-Q76O3RIQ.mjs} +10 -6
  56. package/dist/chunk-QVKWW6KE.mjs +272 -0
  57. package/dist/chunk-RGU7HOEC.mjs +140 -0
  58. package/dist/{chunk-JF4PHPD5.mjs → chunk-RGVKLTLH.mjs} +4 -4
  59. package/dist/{chunk-VG6UF6UT.mjs → chunk-RP3SQYA3.mjs} +2 -2
  60. package/dist/chunk-RRBS6D63.mjs +163 -0
  61. package/dist/{chunk-UEL4RD5P.mjs → chunk-SMQ3DG25.mjs} +80 -67
  62. package/dist/chunk-SPJ5KXW7.mjs +199 -0
  63. package/dist/chunk-SYOD63OZ.mjs +225 -0
  64. package/dist/chunk-UFYSFDER.mjs +42 -0
  65. package/dist/chunk-VACKZOMY.mjs +190 -0
  66. package/dist/chunk-VLQZANBF.mjs +42 -0
  67. package/dist/chunk-WA6O6EUR.mjs +1885 -0
  68. package/dist/{chunk-E3K6O4FZ.mjs → chunk-WAZD7NFU.mjs} +5 -2
  69. package/dist/chunk-WG6JGJXB.mjs +165 -0
  70. package/dist/{chunk-I64K754C.mjs → chunk-WNGWBVLV.mjs} +2 -2
  71. package/dist/{chunk-3U7SD3MS.mjs → chunk-WOEHFRGB.mjs} +3 -3
  72. package/dist/{chunk-DKZRJOMF.mjs → chunk-XIRTEFKH.mjs} +12 -12
  73. package/dist/chunk-Y6DWJSKZ.mjs +79 -0
  74. package/dist/chunk-YKPROFLB.mjs +161 -0
  75. package/dist/{chunk-CJ46PDXE.mjs → chunk-ZRO5JO3H.mjs} +106 -66
  76. package/dist/{chunk-VYMHBV6D.mjs → chunk-ZU4NV6RG.mjs} +5 -3
  77. package/dist/components/ui/accordion.js +40 -4
  78. package/dist/components/ui/accordion.mjs +2 -2
  79. package/dist/components/ui/add-column-modal.js +789 -0
  80. package/dist/components/ui/add-column-modal.mjs +17 -0
  81. package/dist/components/ui/add-lead-modal.js +647 -0
  82. package/dist/components/ui/add-lead-modal.mjs +16 -0
  83. package/dist/components/ui/ai-assistant-drawer.js +686 -0
  84. package/dist/components/ui/ai-assistant-drawer.mjs +16 -0
  85. package/dist/components/ui/alert-dialog.js +37 -5
  86. package/dist/components/ui/alert-dialog.mjs +4 -4
  87. package/dist/components/ui/alert.js +37 -11
  88. package/dist/components/ui/alert.mjs +2 -2
  89. package/dist/components/ui/avatar.js +36 -8
  90. package/dist/components/ui/avatar.mjs +2 -2
  91. package/dist/components/ui/backoffice-alert-history-chart.js +624 -0
  92. package/dist/components/ui/backoffice-alert-history-chart.mjs +16 -0
  93. package/dist/components/ui/backoffice-contact-history-chart.js +687 -0
  94. package/dist/components/ui/backoffice-contact-history-chart.mjs +16 -0
  95. package/dist/components/ui/badge.js +37 -2
  96. package/dist/components/ui/badge.mjs +2 -2
  97. package/dist/components/ui/borrowing-capacity-line-chart.js +639 -0
  98. package/dist/components/ui/borrowing-capacity-line-chart.mjs +16 -0
  99. package/dist/components/ui/button.js +35 -3
  100. package/dist/components/ui/button.mjs +2 -2
  101. package/dist/components/ui/calendar.js +43 -19
  102. package/dist/components/ui/calendar.mjs +3 -3
  103. package/dist/components/ui/card.js +40 -4
  104. package/dist/components/ui/card.mjs +2 -2
  105. package/dist/components/ui/cash-balance-line-chart.js +627 -0
  106. package/dist/components/ui/cash-balance-line-chart.mjs +16 -0
  107. package/dist/components/ui/cashflow-bar-chart.js +123 -69
  108. package/dist/components/ui/cashflow-bar-chart.mjs +8 -8
  109. package/dist/components/ui/checkbox.js +36 -5
  110. package/dist/components/ui/checkbox.mjs +2 -3
  111. package/dist/components/ui/chip.js +37 -2
  112. package/dist/components/ui/chip.mjs +3 -3
  113. package/dist/components/ui/combobox.js +68 -49
  114. package/dist/components/ui/combobox.mjs +2 -2
  115. package/dist/components/ui/data-table.js +160 -88
  116. package/dist/components/ui/data-table.mjs +10 -11
  117. package/dist/components/ui/date-picker.js +44 -20
  118. package/dist/components/ui/date-picker.mjs +6 -7
  119. package/dist/components/ui/dialog.js +44 -12
  120. package/dist/components/ui/dialog.mjs +4 -4
  121. package/dist/components/ui/drawer.js +46 -10
  122. package/dist/components/ui/drawer.mjs +3 -3
  123. package/dist/components/ui/dropdown-menu.js +40 -16
  124. package/dist/components/ui/dropdown-menu.mjs +3 -3
  125. package/dist/components/ui/empty.js +41 -5
  126. package/dist/components/ui/empty.mjs +2 -2
  127. package/dist/components/ui/expense-bar-chart.js +165 -66
  128. package/dist/components/ui/expense-bar-chart.mjs +8 -8
  129. package/dist/components/ui/field.js +53 -21
  130. package/dist/components/ui/field.mjs +4 -4
  131. package/dist/components/ui/financial-cards.js +1002 -0
  132. package/dist/components/ui/financial-cards.mjs +24 -0
  133. package/dist/components/ui/financial-drawers.js +637 -0
  134. package/dist/components/ui/financial-drawers.mjs +17 -0
  135. package/dist/components/ui/financial-primitives.js +218 -0
  136. package/dist/components/ui/financial-primitives.mjs +22 -0
  137. package/dist/components/ui/financial-sections.js +1422 -0
  138. package/dist/components/ui/financial-sections.mjs +30 -0
  139. package/dist/components/ui/form-primitives.js +682 -0
  140. package/dist/components/ui/form-primitives.mjs +19 -0
  141. package/dist/components/ui/income-bar-chart.js +163 -65
  142. package/dist/components/ui/income-bar-chart.mjs +8 -8
  143. package/dist/components/ui/input-group.js +43 -7
  144. package/dist/components/ui/input-group.mjs +5 -5
  145. package/dist/components/ui/input-otp.js +39 -3
  146. package/dist/components/ui/input-otp.mjs +2 -2
  147. package/dist/components/ui/input.js +34 -2
  148. package/dist/components/ui/input.mjs +2 -2
  149. package/dist/components/ui/kanban-column.js +1143 -0
  150. package/dist/components/ui/kanban-column.mjs +20 -0
  151. package/dist/components/ui/label.js +35 -7
  152. package/dist/components/ui/label.mjs +2 -2
  153. package/dist/components/ui/opportunity-card.js +960 -0
  154. package/dist/components/ui/opportunity-card.mjs +20 -0
  155. package/dist/components/ui/opportunity-edit-modals.js +3360 -0
  156. package/dist/components/ui/opportunity-edit-modals.mjs +37 -0
  157. package/dist/components/ui/opportunity-summary-tab.js +4365 -0
  158. package/dist/components/ui/opportunity-summary-tab.mjs +34 -0
  159. package/dist/components/ui/pagination.js +35 -3
  160. package/dist/components/ui/pagination.mjs +3 -3
  161. package/dist/components/ui/pipeline-alerts.js +103 -0
  162. package/dist/components/ui/pipeline-alerts.mjs +8 -0
  163. package/dist/components/ui/pipeline-board.js +1408 -0
  164. package/dist/components/ui/pipeline-board.mjs +24 -0
  165. package/dist/components/ui/pipeline-chart.js +216 -0
  166. package/dist/components/ui/pipeline-chart.mjs +10 -0
  167. package/dist/components/ui/pipeline-dialogs.js +1183 -0
  168. package/dist/components/ui/pipeline-dialogs.mjs +23 -0
  169. package/dist/components/ui/pipeline-primitives.js +300 -0
  170. package/dist/components/ui/pipeline-primitives.mjs +11 -0
  171. package/dist/components/ui/popover.js +45 -4
  172. package/dist/components/ui/popover.mjs +3 -3
  173. package/dist/components/ui/progress.js +33 -1
  174. package/dist/components/ui/progress.mjs +2 -2
  175. package/dist/components/ui/property-cashflow-doughnut-chart.js +523 -0
  176. package/dist/components/ui/property-cashflow-doughnut-chart.mjs +16 -0
  177. package/dist/components/ui/property-debt-equity-doughnut-chart.js +521 -0
  178. package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +16 -0
  179. package/dist/components/ui/property-mobile-estimate-line-chart.js +682 -0
  180. package/dist/components/ui/property-mobile-estimate-line-chart.mjs +16 -0
  181. package/dist/components/ui/radio-group.js +33 -1
  182. package/dist/components/ui/radio-group.mjs +2 -2
  183. package/dist/components/ui/select.js +66 -26
  184. package/dist/components/ui/select.mjs +3 -3
  185. package/dist/components/ui/separator.js +33 -1
  186. package/dist/components/ui/separator.mjs +2 -2
  187. package/dist/components/ui/sheet.js +37 -9
  188. package/dist/components/ui/sheet.mjs +3 -3
  189. package/dist/components/ui/skeleton.js +33 -1
  190. package/dist/components/ui/skeleton.mjs +2 -2
  191. package/dist/components/ui/slider.js +86 -102
  192. package/dist/components/ui/slider.mjs +2 -2
  193. package/dist/components/ui/spinner.js +33 -1
  194. package/dist/components/ui/spinner.mjs +2 -2
  195. package/dist/components/ui/stage-timeline.js +579 -0
  196. package/dist/components/ui/stage-timeline.mjs +15 -0
  197. package/dist/components/ui/switch.js +37 -4
  198. package/dist/components/ui/switch.mjs +2 -3
  199. package/dist/components/ui/table.js +37 -5
  200. package/dist/components/ui/table.mjs +2 -2
  201. package/dist/components/ui/tabs.js +36 -12
  202. package/dist/components/ui/tabs.mjs +2 -2
  203. package/dist/components/ui/textarea.js +34 -2
  204. package/dist/components/ui/textarea.mjs +2 -2
  205. package/dist/components/ui/toggle-group.js +35 -4
  206. package/dist/components/ui/toggle-group.mjs +3 -4
  207. package/dist/components/ui/toggle.js +35 -4
  208. package/dist/components/ui/toggle.mjs +2 -3
  209. package/dist/components/ui/tooltip.js +51 -22
  210. package/dist/components/ui/tooltip.mjs +3 -3
  211. package/dist/components/ui/transactions-expense-categories-doughnut-chart.js +528 -0
  212. package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +16 -0
  213. package/dist/components/ui/transactions-income-expense-bar-chart.js +76 -38
  214. package/dist/components/ui/transactions-income-expense-bar-chart.mjs +8 -8
  215. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.js +528 -0
  216. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +16 -0
  217. package/dist/index.js +11616 -3831
  218. package/dist/index.mjs +333 -161
  219. package/dist/lib/theme-provider.js +10 -1
  220. package/dist/lib/theme-provider.mjs +1 -1
  221. package/dist/lib/typography.js +8 -0
  222. package/dist/lib/typography.mjs +3 -1
  223. package/dist/lib/utils.js +33 -1
  224. package/dist/lib/utils.mjs +1 -1
  225. package/dist/styles.css +1 -1
  226. package/package.json +140 -5
  227. package/src/components/index.tsx +296 -42
  228. package/src/components/ui/accordion.tsx +6 -3
  229. package/src/components/ui/add-column-modal.tsx +339 -0
  230. package/src/components/ui/add-lead-modal.tsx +290 -0
  231. package/src/components/ui/ai-assistant-drawer.tsx +408 -0
  232. package/src/components/ui/alert-dialog.tsx +80 -54
  233. package/src/components/ui/alert.tsx +28 -28
  234. package/src/components/ui/avatar.tsx +30 -29
  235. package/src/components/ui/backoffice-alert-history-chart.tsx +260 -0
  236. package/src/components/ui/backoffice-contact-history-chart.tsx +325 -0
  237. package/src/components/ui/badge.tsx +17 -15
  238. package/src/components/ui/borrowing-capacity-line-chart.tsx +357 -0
  239. package/src/components/ui/button.tsx +30 -27
  240. package/src/components/ui/calendar.tsx +53 -67
  241. package/src/components/ui/card.tsx +27 -24
  242. package/src/components/ui/cash-balance-line-chart.tsx +302 -0
  243. package/src/components/ui/cashflow-bar-chart.tsx +104 -77
  244. package/src/components/ui/chart-shared.tsx +176 -15
  245. package/src/components/ui/checkbox.tsx +30 -26
  246. package/src/components/ui/combobox.tsx +78 -72
  247. package/src/components/ui/data-table.tsx +160 -99
  248. package/src/components/ui/date-picker.tsx +0 -2
  249. package/src/components/ui/dialog.tsx +70 -60
  250. package/src/components/ui/drawer.tsx +57 -48
  251. package/src/components/ui/dropdown-menu.tsx +90 -82
  252. package/src/components/ui/empty.tsx +31 -27
  253. package/src/components/ui/expense-bar-chart.tsx +83 -65
  254. package/src/components/ui/field.tsx +70 -62
  255. package/src/components/ui/financial-cards.tsx +830 -0
  256. package/src/components/ui/financial-drawers.tsx +339 -0
  257. package/src/components/ui/financial-primitives.tsx +331 -0
  258. package/src/components/ui/financial-sections.tsx +672 -0
  259. package/src/components/ui/form-primitives.tsx +536 -0
  260. package/src/components/ui/income-bar-chart.tsx +79 -60
  261. package/src/components/ui/input-group.tsx +41 -34
  262. package/src/components/ui/input-otp.tsx +29 -24
  263. package/src/components/ui/input.tsx +8 -8
  264. package/src/components/ui/kanban-column.tsx +333 -0
  265. package/src/components/ui/label.tsx +9 -12
  266. package/src/components/ui/opportunity-card.tsx +616 -0
  267. package/src/components/ui/opportunity-edit-modals.tsx +2528 -0
  268. package/src/components/ui/opportunity-summary-tab.tsx +579 -0
  269. package/src/components/ui/pipeline-alerts.tsx +74 -0
  270. package/src/components/ui/pipeline-board.tsx +268 -0
  271. package/src/components/ui/pipeline-chart.tsx +173 -0
  272. package/src/components/ui/pipeline-dialogs.tsx +303 -0
  273. package/src/components/ui/pipeline-primitives.tsx +108 -0
  274. package/src/components/ui/popover.tsx +41 -36
  275. package/src/components/ui/property-cashflow-doughnut-chart.tsx +188 -0
  276. package/src/components/ui/property-debt-equity-doughnut-chart.tsx +185 -0
  277. package/src/components/ui/property-mobile-estimate-line-chart.tsx +393 -0
  278. package/src/components/ui/select.tsx +65 -52
  279. package/src/components/ui/sheet.tsx +55 -52
  280. package/src/components/ui/slider.tsx +54 -77
  281. package/src/components/ui/stage-timeline.tsx +205 -0
  282. package/src/components/ui/switch.tsx +42 -29
  283. package/src/components/ui/table.tsx +28 -28
  284. package/src/components/ui/tabs.tsx +22 -28
  285. package/src/components/ui/textarea.tsx +8 -8
  286. package/src/components/ui/toggle-group.tsx +0 -2
  287. package/src/components/ui/toggle.tsx +13 -15
  288. package/src/components/ui/tooltip.tsx +30 -28
  289. package/src/components/ui/transactions-expense-categories-doughnut-chart.tsx +191 -0
  290. package/src/components/ui/transactions-income-expense-bar-chart.tsx +45 -38
  291. package/src/components/ui/transactions-liabilities-breakdown-doughnut-chart.tsx +191 -0
  292. package/src/lib/theme-provider.tsx +10 -0
  293. package/src/lib/typography.ts +9 -0
  294. package/src/lib/utils.ts +41 -3
  295. package/src/styles/globals.css +371 -124
  296. package/src/styles/styles-css.ts +1 -1
  297. package/tsup.config.ts +27 -0
  298. package/dist/chunk-3EQP72AW.mjs +0 -58
  299. package/dist/chunk-K74JRTJR.mjs +0 -105
  300. package/dist/chunk-V7CNWJT3.mjs +0 -10
@@ -19,6 +19,7 @@ import {
19
19
  hexToRgba,
20
20
  DATASET_ALPHAS,
21
21
  FALLBACK_TICK,
22
+ FALLBACK_SECONDARY,
22
23
  CHART_SLICE_COUNT,
23
24
  CHART_PERIODS,
24
25
  formatTooltipDate,
@@ -82,11 +83,6 @@ export interface ExpenseBarChartProps {
82
83
  }
83
84
 
84
85
  // ---------------------------------------------------------------------------
85
- // Constants
86
- // ---------------------------------------------------------------------------
87
-
88
- const FALLBACK_SECONDARY = "#162029";
89
-
90
86
  // ---------------------------------------------------------------------------
91
87
  // Component
92
88
  // ---------------------------------------------------------------------------
@@ -112,17 +108,27 @@ export function ExpenseBarChart({
112
108
  // (defaultPeriod handles the initial value).
113
109
  const isFirstRender = useRef(true);
114
110
  useEffect(() => {
115
- if (isFirstRender.current) { isFirstRender.current = false; return; }
111
+ if (isFirstRender.current) {
112
+ isFirstRender.current = false;
113
+ return;
114
+ }
116
115
  setPeriod(CHART_PERIODS[granularity][0]);
117
116
  }, [granularity]);
118
117
 
119
118
  const themeVars = useThemeVars();
120
119
  const brandSecondary: string =
121
- (themeVars["--theme-secondary"] as string | undefined) || FALLBACK_SECONDARY;
120
+ (themeVars["--theme-secondary"] as string | undefined) ||
121
+ FALLBACK_SECONDARY;
122
+ const fontFamily: string =
123
+ (themeVars["--font-sans"] as string | undefined) || "Figtree, sans-serif";
122
124
 
123
125
  const sliced = useMemo<ExpenseBarChartData | null>(() => {
124
- if (!expenseData?.months?.length || !expenseData.datasets.length) return null;
125
- const count = Math.min(CHART_SLICE_COUNT[granularity][period], expenseData.months.length);
126
+ if (!expenseData?.months?.length || !expenseData.datasets.length)
127
+ return null;
128
+ const count = Math.min(
129
+ CHART_SLICE_COUNT[granularity][period],
130
+ expenseData.months.length,
131
+ );
126
132
  const start = expenseData.months.length - count;
127
133
  return {
128
134
  months: expenseData.months.slice(start),
@@ -135,10 +141,11 @@ export function ExpenseBarChart({
135
141
  }, [expenseData, period, granularity]);
136
142
 
137
143
  const datasetColors = useMemo(
138
- () => sliced?.datasets.map((_, i) =>
139
- hexToRgba(brandSecondary, DATASET_ALPHAS[i % DATASET_ALPHAS.length])
140
- ) ?? [],
141
- [sliced, brandSecondary]
144
+ () =>
145
+ sliced?.datasets.map((_, i) =>
146
+ hexToRgba(brandSecondary, DATASET_ALPHAS[i % DATASET_ALPHAS.length]),
147
+ ) ?? [],
148
+ [sliced, brandSecondary],
142
149
  );
143
150
 
144
151
  const chartData = useMemo<ChartData<"bar">>(() => {
@@ -151,7 +158,7 @@ export function ExpenseBarChart({
151
158
  backgroundColor: datasetColors[i],
152
159
  hoverBackgroundColor: hexToRgba(
153
160
  brandSecondary,
154
- Math.min(DATASET_ALPHAS[i % DATASET_ALPHAS.length] + 0.15, 1)
161
+ Math.min(DATASET_ALPHAS[i % DATASET_ALPHAS.length] + 0.15, 1),
155
162
  ),
156
163
  borderWidth: 0,
157
164
  borderRadius: 0,
@@ -163,64 +170,67 @@ export function ExpenseBarChart({
163
170
  };
164
171
  }, [sliced, datasetColors, brandSecondary]);
165
172
 
166
- const options = useMemo<ChartOptions<"bar">>(() => ({
167
- responsive: true,
168
- maintainAspectRatio: false,
169
- animation: { duration: 800, easing: "easeOutQuart" },
170
- layout: { padding: 0 },
171
- plugins: {
172
- legend: { display: false },
173
- tooltip: {
174
- mode: "index",
175
- intersect: false,
176
- padding: 12,
177
- cornerRadius: 0,
178
- titleFont: { size: 11, weight: "600" },
179
- bodyFont: { size: 12, weight: "500" },
180
- callbacks: {
181
- title: (tooltipItems) => {
182
- const idx = tooltipItems[0]?.dataIndex;
183
- if (idx != null && sliced?.dates?.[idx]) {
184
- return formatTooltipDate(sliced.dates[idx], granularity);
185
- }
186
- return tooltipItems[0]?.label ?? "";
187
- },
188
- label: (ctx) => {
189
- const val = ctx.raw as number;
190
- if (val === 0) return null;
191
- return ` ${ctx.dataset.label}: $${val.toLocaleString()}`;
173
+ const options = useMemo<ChartOptions<"bar">>(
174
+ () => ({
175
+ responsive: true,
176
+ maintainAspectRatio: false,
177
+ animation: { duration: 800, easing: "easeOutQuart" },
178
+ layout: { padding: 0 },
179
+ plugins: {
180
+ legend: { display: false },
181
+ tooltip: {
182
+ mode: "index",
183
+ intersect: false,
184
+ padding: 12,
185
+ cornerRadius: 0,
186
+ titleFont: { size: 11, weight: 600 },
187
+ bodyFont: { size: 12, weight: 500 },
188
+ callbacks: {
189
+ title: (tooltipItems) => {
190
+ const idx = tooltipItems[0]?.dataIndex;
191
+ if (idx != null && sliced?.dates?.[idx]) {
192
+ return formatTooltipDate(sliced.dates[idx], granularity);
193
+ }
194
+ return tooltipItems[0]?.label ?? "";
195
+ },
196
+ label: (ctx) => {
197
+ const val = ctx.raw as number;
198
+ if (val === 0) return;
199
+ return ` ${ctx.dataset.label}: $${val.toLocaleString()}`;
200
+ },
192
201
  },
193
202
  },
194
203
  },
195
- },
196
- scales: {
197
- x: {
198
- display: showXAxis,
199
- stacked: true,
200
- grid: { display: false },
201
- border: { display: false },
202
- ticks: { font: { size: 10 }, color: FALLBACK_TICK },
203
- },
204
- y: {
205
- display: showYAxis,
206
- stacked: true,
207
- grid: { display: false },
208
- border: { display: false },
209
- ticks: {
210
- font: { size: 10 },
211
- color: FALLBACK_TICK,
212
- maxTicksLimit: 5,
213
- padding: 8,
214
- callback: (v) => `$${Number(v).toLocaleString()}`,
204
+ scales: {
205
+ x: {
206
+ display: showXAxis,
207
+ stacked: true,
208
+ grid: { display: false },
209
+ border: { display: false },
210
+ ticks: { font: { size: 10 }, color: FALLBACK_TICK },
211
+ },
212
+ y: {
213
+ display: showYAxis,
214
+ stacked: true,
215
+ grid: { display: false },
216
+ border: { display: false },
217
+ ticks: {
218
+ font: { size: 10 },
219
+ color: FALLBACK_TICK,
220
+ maxTicksLimit: 5,
221
+ padding: 8,
222
+ callback: (v) => `$${Number(v).toLocaleString()}`,
223
+ },
215
224
  },
216
225
  },
217
- },
218
- }), [showXAxis, showYAxis, sliced, granularity]);
226
+ }),
227
+ [showXAxis, showYAxis, sliced, granularity],
228
+ );
219
229
 
220
230
  return (
221
231
  <Card
222
232
  className={cn("w-full py-4 sm:py-6 gap-2", className)}
223
- style={{ maxWidth: width }}
233
+ style={{ maxWidth: width, fontFamily }}
224
234
  >
225
235
  <CardHeader className="px-3 sm:px-6">
226
236
  <CardTitle className="text-sm sm:text-base">{title}</CardTitle>
@@ -250,7 +260,11 @@ export function ExpenseBarChart({
250
260
  {showLegend && legendPosition === "top" && (
251
261
  <div className="flex flex-wrap gap-x-3 gap-y-1.5 pb-2">
252
262
  {sliced.datasets.map((ds, i) => (
253
- <ChartLegendItem key={ds.label} label={ds.label} color={datasetColors[i]} />
263
+ <ChartLegendItem
264
+ key={ds.label}
265
+ label={ds.label}
266
+ color={datasetColors[i]}
267
+ />
254
268
  ))}
255
269
  </div>
256
270
  )}
@@ -266,7 +280,11 @@ export function ExpenseBarChart({
266
280
  {showLegend && legendPosition === "bottom" && (
267
281
  <div className="flex flex-wrap gap-x-3 gap-y-1.5 pt-2">
268
282
  {sliced.datasets.map((ds, i) => (
269
- <ChartLegendItem key={ds.label} label={ds.label} color={datasetColors[i]} />
283
+ <ChartLegendItem
284
+ key={ds.label}
285
+ label={ds.label}
286
+ color={datasetColors[i]}
287
+ />
270
288
  ))}
271
289
  </div>
272
290
  )}
@@ -1,8 +1,8 @@
1
- import { type ReactElement, useMemo } from "react"
2
- import { cva, type VariantProps } from "class-variance-authority"
3
- import { cn } from "@/lib/utils"
4
- import { Label } from "@/components/ui/label"
5
- import { Separator } from "@/components/ui/separator"
1
+ import { type ReactElement, useMemo } from "react";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+ import { cn } from "@/lib/utils";
4
+ import { Label } from "@/components/ui/label";
5
+ import { Separator } from "@/components/ui/separator";
6
6
 
7
7
  /**
8
8
  * Field — shadcn/WealthX
@@ -14,7 +14,7 @@ import { Separator } from "@/components/ui/separator"
14
14
  * - FieldError.uniqueErrors: Array.from() instead of spread on Map iterator (es5 compat)
15
15
  */
16
16
 
17
- export type FieldSetProps = React.ComponentProps<"fieldset">
17
+ export type FieldSetProps = React.ComponentProps<"fieldset">;
18
18
 
19
19
  function FieldSet({ className, ...props }: FieldSetProps): ReactElement {
20
20
  return (
@@ -22,15 +22,17 @@ function FieldSet({ className, ...props }: FieldSetProps): ReactElement {
22
22
  className={cn(
23
23
  "flex flex-col gap-6",
24
24
  "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
25
- className
25
+ className,
26
26
  )}
27
27
  data-slot="field-set"
28
28
  {...props}
29
29
  />
30
- )
30
+ );
31
31
  }
32
32
 
33
- export type FieldLegendProps = React.ComponentProps<"legend"> & { variant?: "legend" | "label" }
33
+ export type FieldLegendProps = React.ComponentProps<"legend"> & {
34
+ variant?: "legend" | "label";
35
+ };
34
36
 
35
37
  function FieldLegend({
36
38
  className,
@@ -40,31 +42,31 @@ function FieldLegend({
40
42
  return (
41
43
  <legend
42
44
  className={cn(
43
- "mb-3 font-medium",
44
- "data-[variant=legend]:text-base",
45
- "data-[variant=label]:text-sm",
46
- className
45
+ "mb-3",
46
+ "data-[variant=legend]:text-label-large",
47
+ "data-[variant=label]:text-label-medium",
48
+ className,
47
49
  )}
48
50
  data-slot="field-legend"
49
51
  data-variant={variant}
50
52
  {...props}
51
53
  />
52
- )
54
+ );
53
55
  }
54
56
 
55
- export type FieldGroupProps = React.ComponentProps<"div">
57
+ export type FieldGroupProps = React.ComponentProps<"div">;
56
58
 
57
59
  function FieldGroup({ className, ...props }: FieldGroupProps): ReactElement {
58
60
  return (
59
61
  <div
60
62
  className={cn(
61
63
  "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
62
- className
64
+ className,
63
65
  )}
64
66
  data-slot="field-group"
65
67
  {...props}
66
68
  />
67
- )
69
+ );
68
70
  }
69
71
 
70
72
  const fieldVariants = cva(
@@ -88,10 +90,11 @@ const fieldVariants = cva(
88
90
  defaultVariants: {
89
91
  orientation: "vertical",
90
92
  },
91
- }
92
- )
93
+ },
94
+ );
93
95
 
94
- export type FieldProps = React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>
96
+ export type FieldProps = React.ComponentProps<"div"> &
97
+ VariantProps<typeof fieldVariants>;
95
98
 
96
99
  function Field({
97
100
  className,
@@ -106,79 +109,82 @@ function Field({
106
109
  role="group"
107
110
  {...props}
108
111
  />
109
- )
112
+ );
110
113
  }
111
114
 
112
- export type FieldContentProps = React.ComponentProps<"div">
115
+ export type FieldContentProps = React.ComponentProps<"div">;
113
116
 
114
- function FieldContent({ className, ...props }: FieldContentProps): ReactElement {
117
+ function FieldContent({
118
+ className,
119
+ ...props
120
+ }: FieldContentProps): ReactElement {
115
121
  return (
116
122
  <div
117
123
  className={cn(
118
124
  "group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
119
- className
125
+ className,
120
126
  )}
121
127
  data-slot="field-content"
122
128
  {...props}
123
129
  />
124
- )
130
+ );
125
131
  }
126
132
 
127
- export type FieldLabelProps = React.ComponentProps<typeof Label>
133
+ export type FieldLabelProps = React.ComponentProps<typeof Label>;
128
134
 
129
- function FieldLabel({
130
- className,
131
- ...props
132
- }: FieldLabelProps): ReactElement {
135
+ function FieldLabel({ className, ...props }: FieldLabelProps): ReactElement {
133
136
  return (
134
137
  <Label
135
138
  className={cn(
136
139
  "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
137
140
  "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
138
141
  "has-data-checked:border-primary has-data-checked:bg-primary/5 dark:has-data-checked:bg-primary/10",
139
- className
142
+ className,
140
143
  )}
141
144
  data-slot="field-label"
142
145
  {...props}
143
146
  />
144
- )
147
+ );
145
148
  }
146
149
 
147
- export type FieldTitleProps = React.ComponentProps<"div">
150
+ export type FieldTitleProps = React.ComponentProps<"div">;
148
151
 
149
152
  function FieldTitle({ className, ...props }: FieldTitleProps): ReactElement {
150
153
  return (
151
154
  <div
152
155
  className={cn(
153
- "flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50",
154
- className
156
+ "flex w-fit items-center gap-2 text-label-medium leading-snug group-data-[disabled=true]/field:opacity-50",
157
+ className,
155
158
  )}
156
159
  data-slot="field-label"
157
160
  {...props}
158
161
  />
159
- )
162
+ );
160
163
  }
161
164
 
162
- export type FieldDescriptionProps = React.ComponentProps<"p">
165
+ export type FieldDescriptionProps = React.ComponentProps<"p">;
163
166
 
164
- function FieldDescription({ className, ...props }: FieldDescriptionProps): ReactElement {
167
+ function FieldDescription({
168
+ className,
169
+ ...props
170
+ }: FieldDescriptionProps): ReactElement {
165
171
  return (
166
172
  <p
167
173
  className={cn(
168
- "text-xs leading-normal font-normal text-muted-foreground group-has-[[data-orientation=horizontal]]/field:text-balance",
174
+ "text-caption leading-normal text-muted-foreground group-has-[[data-orientation=horizontal]]/field:text-balance",
169
175
  "last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
170
176
  "[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
171
- className
177
+ className,
172
178
  )}
173
179
  data-slot="field-description"
174
180
  {...props}
175
181
  />
176
- )
182
+ );
177
183
  }
178
184
 
179
185
  export type FieldSeparatorProps = React.ComponentProps<"div"> & {
180
- children?: React.ReactNode
181
- }
186
+ children?: React.ReactNode;
187
+ };
182
188
 
183
189
  function FieldSeparator({
184
190
  children,
@@ -188,27 +194,29 @@ function FieldSeparator({
188
194
  return (
189
195
  <div
190
196
  className={cn(
191
- "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
192
- className
197
+ "relative -my-2 h-5 text-body-small group-data-[variant=outline]/field-group:-mb-2",
198
+ className,
193
199
  )}
194
200
  data-content={Boolean(children)}
195
201
  data-slot="field-separator"
196
202
  {...props}
197
203
  >
198
204
  <Separator className="absolute inset-0 top-1/2" />
199
- {children ? <span
205
+ {children ? (
206
+ <span
200
207
  className="relative mx-auto block w-fit bg-background px-2 text-muted-foreground"
201
208
  data-slot="field-separator-content"
202
209
  >
203
210
  {children}
204
- </span> : null}
211
+ </span>
212
+ ) : null}
205
213
  </div>
206
- )
214
+ );
207
215
  }
208
216
 
209
217
  export type FieldErrorProps = React.ComponentProps<"div"> & {
210
- errors?: ({ message?: string } | undefined)[]
211
- }
218
+ errors?: ({ message?: string } | undefined)[];
219
+ };
212
220
 
213
221
  function FieldError({
214
222
  className,
@@ -218,45 +226,45 @@ function FieldError({
218
226
  }: FieldErrorProps): ReactElement | null {
219
227
  const content = useMemo(() => {
220
228
  if (children) {
221
- return children
229
+ return children;
222
230
  }
223
231
 
224
232
  if (!errors?.length) {
225
- return null
233
+ return null;
226
234
  }
227
235
 
228
236
  const uniqueErrors = Array.from(
229
- new Map(errors.map((error) => [error?.message, error])).values()
230
- )
237
+ new Map(errors.map((error) => [error?.message, error])).values(),
238
+ );
231
239
 
232
240
  if (uniqueErrors.length === 1) {
233
- return uniqueErrors[0]?.message
241
+ return uniqueErrors[0]?.message;
234
242
  }
235
243
 
236
244
  return (
237
245
  <ul className="ml-4 flex list-disc flex-col gap-1">
238
246
  {uniqueErrors.map(
239
247
  (error) =>
240
- error?.message && <li key={error.message}>{error.message}</li>
248
+ error?.message && <li key={error.message}>{error.message}</li>,
241
249
  )}
242
250
  </ul>
243
- )
244
- }, [children, errors])
251
+ );
252
+ }, [children, errors]);
245
253
 
246
254
  if (!content) {
247
- return null
255
+ return null;
248
256
  }
249
257
 
250
258
  return (
251
259
  <div
252
- className={cn("text-xs font-normal text-destructive", className)}
260
+ className={cn("text-caption text-destructive", className)}
253
261
  data-slot="field-error"
254
262
  role="alert"
255
263
  {...props}
256
264
  >
257
265
  {content}
258
266
  </div>
259
- )
267
+ );
260
268
  }
261
269
 
262
270
  export {
@@ -270,4 +278,4 @@ export {
270
278
  FieldSet,
271
279
  FieldContent,
272
280
  FieldTitle,
273
- }
281
+ };