@wealthx/shadcn 1.1.0 → 1.2.1

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 +12 -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-GPRJQ24C.mjs → chunk-34NWQURD.mjs} +2 -2
  6. package/dist/{chunk-MQ72DIBH.mjs → chunk-3GF7OVTP.mjs} +14 -5
  7. package/dist/chunk-3WMX6KWS.mjs +245 -0
  8. package/dist/{chunk-PMKODV6M.mjs → chunk-462HMNO4.mjs} +6 -10
  9. package/dist/chunk-4CX4SBRO.mjs +153 -0
  10. package/dist/chunk-4MN6UQHG.mjs +443 -0
  11. package/dist/chunk-4Y6R4WEC.mjs +250 -0
  12. package/dist/{chunk-BGP2N52Z.mjs → chunk-66MI7Q4B.mjs} +5 -5
  13. package/dist/{chunk-CGOKTPXU.mjs → chunk-6JQFUE5I.mjs} +20 -23
  14. package/dist/{chunk-Z3MK2KKZ.mjs → chunk-7DHU4VGG.mjs} +7 -3
  15. package/dist/chunk-7MMXNK3C.mjs +317 -0
  16. package/dist/{chunk-VZ2NR7L3.mjs → chunk-7PYJD5JI.mjs} +35 -27
  17. package/dist/{chunk-JU2RUWHF.mjs → chunk-7XJHLGUV.mjs} +1 -1
  18. package/dist/{chunk-BMFN37JH.mjs → chunk-7YAU5CY6.mjs} +1 -1
  19. package/dist/chunk-A56YQQHG.mjs +402 -0
  20. package/dist/{chunk-GLW2UO6O.mjs → chunk-BL3DXM2X.mjs} +84 -62
  21. package/dist/{chunk-SLWCCURD.mjs → chunk-CLIN5525.mjs} +8 -4
  22. package/dist/{chunk-3VQNJ235.mjs → chunk-CSDO6VBW.mjs} +7 -0
  23. package/dist/chunk-D4ILTPOG.mjs +293 -0
  24. package/dist/{chunk-HS7TFG7V.mjs → chunk-D6ID6M4V.mjs} +1 -1
  25. package/dist/chunk-DOH3EHX7.mjs +378 -0
  26. package/dist/{chunk-MJIEMGRD.mjs → chunk-EFRENWEJ.mjs} +9 -17
  27. package/dist/{chunk-YBXCIF5Q.mjs → chunk-ERGGHC2V.mjs} +36 -49
  28. package/dist/{chunk-OXQQNQZI.mjs → chunk-FEZKMUCF.mjs} +10 -1
  29. package/dist/{chunk-55CEW76V.mjs → chunk-FH6QVUVZ.mjs} +1 -1
  30. package/dist/chunk-FMAXJ2SI.mjs +71 -0
  31. package/dist/chunk-FZIXGLMV.mjs +173 -0
  32. package/dist/chunk-GGM2UYGG.mjs +273 -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-JNQORUPP.mjs} +49 -42
  38. package/dist/{chunk-5JGQAAQV.mjs → chunk-K3JYD4IU.mjs} +86 -63
  39. package/dist/{chunk-FHNT55I5.mjs → chunk-KUDCQ4FI.mjs} +4 -4
  40. package/dist/{chunk-UEL4RD5P.mjs → chunk-LHYCMLVA.mjs} +82 -68
  41. package/dist/{chunk-NLLKTU4B.mjs → chunk-LLVQKSU3.mjs} +21 -17
  42. package/dist/{chunk-KKHTJNMM.mjs → chunk-MARPPFOJ.mjs} +8 -4
  43. package/dist/{chunk-6AFMNC42.mjs → chunk-N2PT566P.mjs} +15 -11
  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-OGOYQ7BG.mjs +150 -0
  47. package/dist/chunk-OPNQAVVH.mjs +162 -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-DDPA2XXS.mjs → chunk-PMB3A7V3.mjs} +2 -2
  53. package/dist/chunk-PR6V5XKM.mjs +209 -0
  54. package/dist/{chunk-46OFHMQA.mjs → chunk-Q76O3RIQ.mjs} +10 -6
  55. package/dist/chunk-RGU7HOEC.mjs +140 -0
  56. package/dist/{chunk-JF4PHPD5.mjs → chunk-RGVKLTLH.mjs} +4 -4
  57. package/dist/{chunk-VG6UF6UT.mjs → chunk-RP3SQYA3.mjs} +2 -2
  58. package/dist/chunk-RYCLWMZ7.mjs +162 -0
  59. package/dist/chunk-SIZMLSRU.mjs +162 -0
  60. package/dist/chunk-SPJ5KXW7.mjs +199 -0
  61. package/dist/chunk-SWGT756Z.mjs +210 -0
  62. package/dist/chunk-SYOD63OZ.mjs +225 -0
  63. package/dist/chunk-TS2ZX2VS.mjs +270 -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-VPBN3WOO.mjs +164 -0
  68. package/dist/chunk-WA6O6EUR.mjs +1885 -0
  69. package/dist/{chunk-E3K6O4FZ.mjs → chunk-WAZD7NFU.mjs} +5 -2
  70. package/dist/chunk-WG6JGJXB.mjs +165 -0
  71. package/dist/{chunk-I64K754C.mjs → chunk-WNGWBVLV.mjs} +2 -2
  72. package/dist/{chunk-3U7SD3MS.mjs → chunk-WOEHFRGB.mjs} +3 -3
  73. package/dist/{chunk-DKZRJOMF.mjs → chunk-XIRTEFKH.mjs} +12 -12
  74. package/dist/chunk-Y6DWJSKZ.mjs +79 -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 +640 -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 +628 -0
  106. package/dist/components/ui/cash-balance-line-chart.mjs +16 -0
  107. package/dist/components/ui/cashflow-bar-chart.js +124 -70
  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 +166 -67
  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 +164 -66
  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 +683 -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 +77 -39
  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 +11620 -3832
  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 +261 -0
  236. package/src/components/ui/backoffice-contact-history-chart.tsx +326 -0
  237. package/src/components/ui/badge.tsx +17 -15
  238. package/src/components/ui/borrowing-capacity-line-chart.tsx +359 -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 +304 -0
  243. package/src/components/ui/cashflow-bar-chart.tsx +106 -78
  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 +85 -66
  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 +81 -61
  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 +189 -0
  276. package/src/components/ui/property-debt-equity-doughnut-chart.tsx +186 -0
  277. package/src/components/ui/property-mobile-estimate-line-chart.tsx +395 -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 +192 -0
  290. package/src/components/ui/transactions-income-expense-bar-chart.tsx +47 -39
  291. package/src/components/ui/transactions-liabilities-breakdown-doughnut-chart.tsx +192 -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
@@ -3,6 +3,7 @@ import {
3
3
  Chart as ChartJS,
4
4
  CategoryScale,
5
5
  LinearScale,
6
+ BarController,
6
7
  BarElement,
7
8
  Tooltip,
8
9
  Legend,
@@ -19,6 +20,7 @@ import {
19
20
  hexToRgba,
20
21
  DATASET_ALPHAS,
21
22
  FALLBACK_TICK,
23
+ FALLBACK_PRIMARY,
22
24
  CHART_SLICE_COUNT,
23
25
  CHART_PERIODS,
24
26
  formatTooltipDate,
@@ -28,7 +30,7 @@ import {
28
30
  type ChartGranularity,
29
31
  } from "./chart-shared";
30
32
 
31
- ChartJS.register(CategoryScale, LinearScale, BarElement, Tooltip, Legend);
33
+ ChartJS.register(CategoryScale, LinearScale, BarController, BarElement, Tooltip, Legend);
32
34
 
33
35
  // ---------------------------------------------------------------------------
34
36
  // Types
@@ -85,8 +87,6 @@ export interface IncomeBarChartProps {
85
87
  // Constants
86
88
  // ---------------------------------------------------------------------------
87
89
 
88
- const FALLBACK_PRIMARY = "#33FF99";
89
-
90
90
  // ---------------------------------------------------------------------------
91
91
  // Component
92
92
  // ---------------------------------------------------------------------------
@@ -112,17 +112,25 @@ export function IncomeBarChart({
112
112
  // (defaultPeriod handles the initial value).
113
113
  const isFirstRender = useRef(true);
114
114
  useEffect(() => {
115
- if (isFirstRender.current) { isFirstRender.current = false; return; }
115
+ if (isFirstRender.current) {
116
+ isFirstRender.current = false;
117
+ return;
118
+ }
116
119
  setPeriod(CHART_PERIODS[granularity][0]);
117
120
  }, [granularity]);
118
121
 
119
122
  const themeVars = useThemeVars();
120
123
  const brandPrimary: string =
121
124
  (themeVars["--theme-primary"] as string | undefined) || FALLBACK_PRIMARY;
125
+ const fontFamily: string =
126
+ (themeVars["--font-sans"] as string | undefined) || "Figtree, sans-serif";
122
127
 
123
128
  const sliced = useMemo<IncomeBarChartData | null>(() => {
124
129
  if (!incomeData?.months?.length || !incomeData.datasets.length) return null;
125
- const count = Math.min(CHART_SLICE_COUNT[granularity][period], incomeData.months.length);
130
+ const count = Math.min(
131
+ CHART_SLICE_COUNT[granularity][period],
132
+ incomeData.months.length,
133
+ );
126
134
  const start = incomeData.months.length - count;
127
135
  return {
128
136
  months: incomeData.months.slice(start),
@@ -135,10 +143,11 @@ export function IncomeBarChart({
135
143
  }, [incomeData, period, granularity]);
136
144
 
137
145
  const datasetColors = useMemo(
138
- () => sliced?.datasets.map((_, i) =>
139
- hexToRgba(brandPrimary, DATASET_ALPHAS[i % DATASET_ALPHAS.length])
140
- ) ?? [],
141
- [sliced, brandPrimary]
146
+ () =>
147
+ sliced?.datasets.map((_, i) =>
148
+ hexToRgba(brandPrimary, DATASET_ALPHAS[i % DATASET_ALPHAS.length]),
149
+ ) ?? [],
150
+ [sliced, brandPrimary],
142
151
  );
143
152
 
144
153
  const chartData = useMemo<ChartData<"bar">>(() => {
@@ -151,7 +160,7 @@ export function IncomeBarChart({
151
160
  backgroundColor: datasetColors[i],
152
161
  hoverBackgroundColor: hexToRgba(
153
162
  brandPrimary,
154
- Math.min(DATASET_ALPHAS[i % DATASET_ALPHAS.length] + 0.15, 1)
163
+ Math.min(DATASET_ALPHAS[i % DATASET_ALPHAS.length] + 0.15, 1),
155
164
  ),
156
165
  borderWidth: 0,
157
166
  borderRadius: 0,
@@ -163,64 +172,67 @@ export function IncomeBarChart({
163
172
  };
164
173
  }, [sliced, datasetColors, brandPrimary]);
165
174
 
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()}`;
175
+ const options = useMemo<ChartOptions<"bar">>(
176
+ () => ({
177
+ responsive: true,
178
+ maintainAspectRatio: false,
179
+ animation: { duration: 800, easing: "easeOutQuart" },
180
+ layout: { padding: 0 },
181
+ plugins: {
182
+ legend: { display: false },
183
+ tooltip: {
184
+ mode: "index",
185
+ intersect: false,
186
+ padding: 12,
187
+ cornerRadius: 0,
188
+ titleFont: { size: 11, weight: 600 },
189
+ bodyFont: { size: 12, weight: 500 },
190
+ callbacks: {
191
+ title: (tooltipItems) => {
192
+ const idx = tooltipItems[0]?.dataIndex;
193
+ if (idx != null && sliced?.dates?.[idx]) {
194
+ return formatTooltipDate(sliced.dates[idx], granularity);
195
+ }
196
+ return tooltipItems[0]?.label ?? "";
197
+ },
198
+ label: (ctx) => {
199
+ const val = ctx.raw as number;
200
+ if (val === 0) return;
201
+ return ` ${ctx.dataset.label}: $${val.toLocaleString()}`;
202
+ },
192
203
  },
193
204
  },
194
205
  },
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()}`,
206
+ scales: {
207
+ x: {
208
+ display: showXAxis,
209
+ stacked: true,
210
+ grid: { display: false },
211
+ border: { display: false },
212
+ ticks: { font: { size: 10 }, color: FALLBACK_TICK },
213
+ },
214
+ y: {
215
+ display: showYAxis,
216
+ stacked: true,
217
+ grid: { display: false },
218
+ border: { display: false },
219
+ ticks: {
220
+ font: { size: 10 },
221
+ color: FALLBACK_TICK,
222
+ maxTicksLimit: 5,
223
+ padding: 8,
224
+ callback: (v) => `$${Number(v).toLocaleString()}`,
225
+ },
215
226
  },
216
227
  },
217
- },
218
- }), [showXAxis, showYAxis, sliced, granularity]);
228
+ }),
229
+ [showXAxis, showYAxis, sliced, granularity],
230
+ );
219
231
 
220
232
  return (
221
233
  <Card
222
234
  className={cn("w-full py-4 sm:py-6 gap-2", className)}
223
- style={{ maxWidth: width }}
235
+ style={{ maxWidth: width, fontFamily }}
224
236
  >
225
237
  <CardHeader className="px-3 sm:px-6">
226
238
  <CardTitle className="text-sm sm:text-base">{title}</CardTitle>
@@ -250,7 +262,11 @@ export function IncomeBarChart({
250
262
  {showLegend && legendPosition === "top" && (
251
263
  <div className="flex flex-wrap gap-x-3 gap-y-1.5 pb-2">
252
264
  {sliced.datasets.map((ds, i) => (
253
- <ChartLegendItem key={ds.label} label={ds.label} color={datasetColors[i]} />
265
+ <ChartLegendItem
266
+ key={ds.label}
267
+ label={ds.label}
268
+ color={datasetColors[i]}
269
+ />
254
270
  ))}
255
271
  </div>
256
272
  )}
@@ -266,7 +282,11 @@ export function IncomeBarChart({
266
282
  {showLegend && legendPosition === "bottom" && (
267
283
  <div className="flex flex-wrap gap-x-3 gap-y-1.5 pt-2">
268
284
  {sliced.datasets.map((ds, i) => (
269
- <ChartLegendItem key={ds.label} label={ds.label} color={datasetColors[i]} />
285
+ <ChartLegendItem
286
+ key={ds.label}
287
+ label={ds.label}
288
+ color={datasetColors[i]}
289
+ />
270
290
  ))}
271
291
  </div>
272
292
  )}
@@ -1,17 +1,17 @@
1
- import { type ReactElement } from "react"
2
- import * as React from "react"
3
- import { cva, type VariantProps } from "class-variance-authority"
4
- import { cn } from "@/lib/utils"
5
- import { Button } from "@/components/ui/button"
6
- import { Input } from "@/components/ui/input"
7
- import { Textarea } from "@/components/ui/textarea"
1
+ import { type ReactElement } from "react";
2
+ import * as React from "react";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import { cn } from "@/lib/utils";
5
+ import { Button } from "@/components/ui/button";
6
+ import { Input } from "@/components/ui/input";
7
+ import { Textarea } from "@/components/ui/textarea";
8
8
 
9
9
  /**
10
10
  * InputGroup — shadcn/WealthX
11
11
  * Base: npx shadcn\@latest add input-group
12
12
  * WealthX: removed rounded-md (square corners per brand)
13
13
  */
14
- export type InputGroupProps = React.ComponentProps<"div">
14
+ export type InputGroupProps = React.ComponentProps<"div">;
15
15
 
16
16
  function InputGroup({ className, ...props }: InputGroupProps): ReactElement {
17
17
  return (
@@ -32,13 +32,13 @@ function InputGroup({ className, ...props }: InputGroupProps): ReactElement {
32
32
  // Error state.
33
33
  "has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-destructive/20 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
34
34
 
35
- className
35
+ className,
36
36
  )}
37
37
  data-slot="input-group"
38
38
  role="group"
39
39
  {...props}
40
40
  />
41
- )
41
+ );
42
42
  }
43
43
 
44
44
  const inputGroupAddonVariants = cva(
@@ -59,10 +59,11 @@ const inputGroupAddonVariants = cva(
59
59
  defaultVariants: {
60
60
  align: "inline-start",
61
61
  },
62
- }
63
- )
62
+ },
63
+ );
64
64
 
65
- export type InputGroupAddonProps = React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>
65
+ export type InputGroupAddonProps = React.ComponentProps<"div"> &
66
+ VariantProps<typeof inputGroupAddonVariants>;
66
67
 
67
68
  function InputGroupAddon({
68
69
  className,
@@ -77,19 +78,19 @@ function InputGroupAddon({
77
78
  data-slot="input-group-addon"
78
79
  onClick={(e) => {
79
80
  if ((e.target as HTMLElement).closest("button")) {
80
- return
81
+ return;
81
82
  }
82
- e.currentTarget.parentElement?.querySelector("input")?.focus()
83
+ e.currentTarget.parentElement?.querySelector("input")?.focus();
83
84
  }}
84
85
  onKeyDown={(e) => {
85
86
  if (e.key === "Enter" || e.key === " ") {
86
- e.currentTarget.parentElement?.querySelector("input")?.focus()
87
+ e.currentTarget.parentElement?.querySelector("input")?.focus();
87
88
  }
88
89
  }}
89
90
  role="group"
90
91
  {...props}
91
92
  />
92
- )
93
+ );
93
94
  }
94
95
 
95
96
  const inputGroupButtonVariants = cva(
@@ -106,11 +107,14 @@ const inputGroupButtonVariants = cva(
106
107
  defaultVariants: {
107
108
  size: "xs",
108
109
  },
109
- }
110
- )
110
+ },
111
+ );
111
112
 
112
- export type InputGroupButtonProps = Omit<React.ComponentProps<typeof Button>, "size"> &
113
- VariantProps<typeof inputGroupButtonVariants>
113
+ export type InputGroupButtonProps = Omit<
114
+ React.ComponentProps<typeof Button>,
115
+ "size"
116
+ > &
117
+ VariantProps<typeof inputGroupButtonVariants>;
114
118
 
115
119
  function InputGroupButton({
116
120
  className,
@@ -127,24 +131,27 @@ function InputGroupButton({
127
131
  variant={variant}
128
132
  {...props}
129
133
  />
130
- )
134
+ );
131
135
  }
132
136
 
133
- export type InputGroupTextProps = React.ComponentProps<"span">
137
+ export type InputGroupTextProps = React.ComponentProps<"span">;
134
138
 
135
- function InputGroupText({ className, ...props }: InputGroupTextProps): ReactElement {
139
+ function InputGroupText({
140
+ className,
141
+ ...props
142
+ }: InputGroupTextProps): ReactElement {
136
143
  return (
137
144
  <span
138
145
  className={cn(
139
- "flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
140
- className
146
+ "flex items-center gap-2 text-body-small text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
147
+ className,
141
148
  )}
142
149
  {...props}
143
150
  />
144
- )
151
+ );
145
152
  }
146
153
 
147
- export type InputGroupInputProps = React.ComponentProps<"input">
154
+ export type InputGroupInputProps = React.ComponentProps<"input">;
148
155
 
149
156
  function InputGroupInput({
150
157
  className,
@@ -154,15 +161,15 @@ function InputGroupInput({
154
161
  <Input
155
162
  className={cn(
156
163
  "flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
157
- className
164
+ className,
158
165
  )}
159
166
  data-slot="input-group-control"
160
167
  {...props}
161
168
  />
162
- )
169
+ );
163
170
  }
164
171
 
165
- export type InputGroupTextareaProps = React.ComponentProps<"textarea">
172
+ export type InputGroupTextareaProps = React.ComponentProps<"textarea">;
166
173
 
167
174
  function InputGroupTextarea({
168
175
  className,
@@ -172,12 +179,12 @@ function InputGroupTextarea({
172
179
  <Textarea
173
180
  className={cn(
174
181
  "flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
175
- className
182
+ className,
176
183
  )}
177
184
  data-slot="input-group-control"
178
185
  {...props}
179
186
  />
180
- )
187
+ );
181
188
  }
182
189
 
183
190
  export {
@@ -187,4 +194,4 @@ export {
187
194
  InputGroupText,
188
195
  InputGroupInput,
189
196
  InputGroupTextarea,
190
- }
197
+ };
@@ -7,15 +7,15 @@
7
7
  * - InputOTPSlot: removed first:rounded-l-md last:rounded-r-md — sharp corners (radius-none)
8
8
  */
9
9
 
10
- import { type ReactElement } from "react"
11
- import * as React from "react"
12
- import { OTPInput, OTPInputContext } from "input-otp"
13
- import { MinusIcon } from "lucide-react"
14
- import { cn } from "@/lib/utils"
10
+ import { type ReactElement } from "react";
11
+ import * as React from "react";
12
+ import { OTPInput, OTPInputContext } from "input-otp";
13
+ import { MinusIcon } from "lucide-react";
14
+ import { cn } from "@/lib/utils";
15
15
 
16
16
  export type InputOTPProps = React.ComponentProps<typeof OTPInput> & {
17
- containerClassName?: string
18
- }
17
+ containerClassName?: string;
18
+ };
19
19
 
20
20
  function InputOTP({
21
21
  className,
@@ -27,64 +27,69 @@ function InputOTP({
27
27
  className={cn("disabled:cursor-not-allowed", className)}
28
28
  containerClassName={cn(
29
29
  "flex items-center gap-2 has-disabled:opacity-50",
30
- containerClassName
30
+ containerClassName,
31
31
  )}
32
32
  data-slot="input-otp"
33
33
  {...props}
34
34
  />
35
- )
35
+ );
36
36
  }
37
37
 
38
- export type InputOTPGroupProps = React.ComponentProps<"div">
38
+ export type InputOTPGroupProps = React.ComponentProps<"div">;
39
39
 
40
- function InputOTPGroup({ className, ...props }: InputOTPGroupProps): ReactElement {
40
+ function InputOTPGroup({
41
+ className,
42
+ ...props
43
+ }: InputOTPGroupProps): ReactElement {
41
44
  return (
42
45
  <div
43
46
  className={cn("flex items-center", className)}
44
47
  data-slot="input-otp-group"
45
48
  {...props}
46
49
  />
47
- )
50
+ );
48
51
  }
49
52
 
50
53
  export type InputOTPSlotProps = React.ComponentProps<"div"> & {
51
- index: number
52
- }
54
+ index: number;
55
+ };
53
56
 
54
57
  function InputOTPSlot({
55
58
  index,
56
59
  className,
57
60
  ...props
58
61
  }: InputOTPSlotProps): ReactElement {
59
- const inputOTPContext = React.useContext(OTPInputContext)
60
- const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index] ?? {}
62
+ const inputOTPContext = React.useContext(OTPInputContext);
63
+ const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index] ?? {};
61
64
 
62
65
  return (
63
66
  <div
64
67
  className={cn(
65
- "relative flex h-9 w-9 items-center justify-center border-y border-r border-input text-sm shadow-xs transition-all outline-none first:border-l aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-[3px] data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40",
66
- className
68
+ "relative flex h-9 w-9 items-center justify-center border-y border-r border-input text-body-small shadow-xs transition-all outline-none first:border-l aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-[3px] data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40",
69
+ className,
67
70
  )}
68
71
  data-active={isActive}
69
72
  data-slot="input-otp-slot"
70
73
  {...props}
71
74
  >
72
75
  {char}
73
- {hasFakeCaret ? <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
76
+ {hasFakeCaret ? (
77
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
74
78
  <div className="h-4 w-px animate-caret-blink bg-foreground duration-1000" />
75
- </div> : null}
79
+ </div>
80
+ ) : null}
76
81
  </div>
77
- )
82
+ );
78
83
  }
79
84
 
80
- export type InputOTPSeparatorProps = React.ComponentProps<"div">
85
+ export type InputOTPSeparatorProps = React.ComponentProps<"div">;
81
86
 
82
87
  function InputOTPSeparator({ ...props }: InputOTPSeparatorProps): ReactElement {
83
88
  return (
84
89
  <div data-slot="input-otp-separator" role="separator" {...props}>
85
90
  <MinusIcon />
86
91
  </div>
87
- )
92
+ );
88
93
  }
89
94
 
90
- export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
95
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
@@ -1,28 +1,28 @@
1
- import { type ReactElement } from "react"
2
- import * as React from "react"
3
- import { cn } from "@/lib/utils"
1
+ import { type ReactElement } from "react";
2
+ import * as React from "react";
3
+ import { cn } from "@/lib/utils";
4
4
 
5
5
  /**
6
6
  * Input — shadcn/WealthX
7
7
  * Base: npx shadcn\@latest add input
8
8
  * WealthX: removed rounded-md (square corners), added font-sans.
9
9
  */
10
- export type InputProps = React.ComponentProps<"input">
10
+ export type InputProps = React.ComponentProps<"input">;
11
11
 
12
12
  function Input({ className, type, ...props }: InputProps): ReactElement {
13
13
  return (
14
14
  <input
15
15
  className={cn(
16
- "h-9 w-full min-w-0 border border-input bg-transparent px-3 py-1 text-base font-sans shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30",
16
+ "h-9 w-full min-w-0 border border-input bg-transparent px-3 py-1 text-body-medium font-sans shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-label-medium file:text-foreground placeholder:font-normal placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30",
17
17
  "focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-primary/20",
18
18
  "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
19
- className
19
+ className,
20
20
  )}
21
21
  data-slot="input"
22
22
  type={type}
23
23
  {...props}
24
24
  />
25
- )
25
+ );
26
26
  }
27
27
 
28
- export { Input }
28
+ export { Input };