@wealthx/shadcn 1.0.2 → 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 -138
  2. package/CHANGELOG.md +12 -0
  3. package/README.md +82 -0
  4. package/dist/{chunk-6OJF6XRN.mjs → chunk-24FUO7TD.mjs} +4 -8
  5. package/dist/{chunk-4AJ5HWHD.mjs → chunk-2I5S2AMY.mjs} +3 -3
  6. package/dist/chunk-2SF672SZ.mjs +161 -0
  7. package/dist/{chunk-GPRJQ24C.mjs → chunk-34NWQURD.mjs} +2 -2
  8. package/dist/{chunk-MQ72DIBH.mjs → chunk-3GF7OVTP.mjs} +14 -5
  9. package/dist/chunk-3WMX6KWS.mjs +245 -0
  10. package/dist/{chunk-PMKODV6M.mjs → chunk-462HMNO4.mjs} +6 -10
  11. package/dist/chunk-4CX4SBRO.mjs +153 -0
  12. package/dist/chunk-4MN6UQHG.mjs +443 -0
  13. package/dist/chunk-5QQVZTVZ.mjs +233 -0
  14. package/dist/{chunk-BGP2N52Z.mjs → chunk-66MI7Q4B.mjs} +5 -5
  15. package/dist/chunk-6FCGKSZX.mjs +268 -0
  16. package/dist/{chunk-CGOKTPXU.mjs → chunk-6JQFUE5I.mjs} +20 -23
  17. package/dist/{chunk-Z3MK2KKZ.mjs → chunk-7DHU4VGG.mjs} +7 -3
  18. package/dist/{chunk-VZ2NR7L3.mjs → chunk-7PYJD5JI.mjs} +35 -27
  19. package/dist/{chunk-JU2RUWHF.mjs → chunk-7XJHLGUV.mjs} +1 -1
  20. package/dist/{chunk-BMFN37JH.mjs → chunk-7YAU5CY6.mjs} +1 -1
  21. package/dist/chunk-A56YQQHG.mjs +402 -0
  22. package/dist/chunk-AH52LG6N.mjs +315 -0
  23. package/dist/{chunk-SLWCCURD.mjs → chunk-CLIN5525.mjs} +8 -4
  24. package/dist/{chunk-3VQNJ235.mjs → chunk-CSDO6VBW.mjs} +7 -0
  25. package/dist/chunk-D4ILTPOG.mjs +293 -0
  26. package/dist/{chunk-HS7TFG7V.mjs → chunk-D6ID6M4V.mjs} +1 -1
  27. package/dist/chunk-DOH3EHX7.mjs +378 -0
  28. package/dist/{chunk-MJIEMGRD.mjs → chunk-EFRENWEJ.mjs} +9 -17
  29. package/dist/chunk-ERGGHC2V.mjs +185 -0
  30. package/dist/{chunk-OXQQNQZI.mjs → chunk-FEZKMUCF.mjs} +10 -1
  31. package/dist/{chunk-55CEW76V.mjs → chunk-FH6QVUVZ.mjs} +1 -1
  32. package/dist/chunk-FMAXJ2SI.mjs +71 -0
  33. package/dist/chunk-FZIXGLMV.mjs +173 -0
  34. package/dist/{chunk-DS2AMHN2.mjs → chunk-GYMYRIZP.mjs} +2 -2
  35. package/dist/{chunk-KQDD5MU3.mjs → chunk-H45TKD34.mjs} +5 -5
  36. package/dist/{chunk-BBJBJSXQ.mjs → chunk-J5UICVJS.mjs} +1 -1
  37. package/dist/{chunk-RL772EH7.mjs → chunk-JHJHG4GO.mjs} +4 -12
  38. package/dist/chunk-KMCGSZTX.mjs +177 -0
  39. package/dist/{chunk-FHNT55I5.mjs → chunk-KUDCQ4FI.mjs} +4 -4
  40. package/dist/chunk-LE6YFY6D.mjs +209 -0
  41. package/dist/{chunk-HUVTPUV2.mjs → chunk-LLVQKSU3.mjs} +23 -19
  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-NLCKVHWB.mjs +161 -0
  45. package/dist/{chunk-YN5SYTOO.mjs → chunk-NQPOYKAQ.mjs} +9 -5
  46. package/dist/{chunk-ZZV5JVNW.mjs → chunk-NSLMILBT.mjs} +3 -7
  47. package/dist/chunk-NXA3CZ7A.mjs +248 -0
  48. package/dist/chunk-OGOYQ7BG.mjs +150 -0
  49. package/dist/{chunk-3NQGYJEZ.mjs → chunk-P6AM5V7O.mjs} +10 -18
  50. package/dist/{chunk-CZ3BW5GL.mjs → chunk-P76HMUI6.mjs} +5 -11
  51. package/dist/chunk-PCPLO5HT.mjs +671 -0
  52. package/dist/chunk-PG6K5XEC.mjs +475 -0
  53. package/dist/chunk-PJHPSRYD.mjs +234 -0
  54. package/dist/{chunk-DDPA2XXS.mjs → chunk-PMB3A7V3.mjs} +2 -2
  55. package/dist/chunk-PR6V5XKM.mjs +209 -0
  56. package/dist/{chunk-46OFHMQA.mjs → chunk-Q76O3RIQ.mjs} +10 -6
  57. package/dist/chunk-QVKWW6KE.mjs +272 -0
  58. package/dist/chunk-RGU7HOEC.mjs +140 -0
  59. package/dist/{chunk-JF4PHPD5.mjs → chunk-RGVKLTLH.mjs} +4 -4
  60. package/dist/{chunk-VG6UF6UT.mjs → chunk-RP3SQYA3.mjs} +2 -2
  61. package/dist/chunk-RRBS6D63.mjs +163 -0
  62. package/dist/chunk-SMQ3DG25.mjs +285 -0
  63. package/dist/chunk-SPJ5KXW7.mjs +199 -0
  64. package/dist/chunk-SYOD63OZ.mjs +225 -0
  65. package/dist/chunk-UFYSFDER.mjs +42 -0
  66. package/dist/chunk-VACKZOMY.mjs +190 -0
  67. package/dist/chunk-VLQZANBF.mjs +42 -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-YKPROFLB.mjs +161 -0
  76. package/dist/{chunk-K76E2TQU.mjs → chunk-ZRO5JO3H.mjs} +107 -67
  77. package/dist/{chunk-VYMHBV6D.mjs → chunk-ZU4NV6RG.mjs} +5 -3
  78. package/dist/components/ui/accordion.js +40 -4
  79. package/dist/components/ui/accordion.mjs +2 -2
  80. package/dist/components/ui/add-column-modal.js +789 -0
  81. package/dist/components/ui/add-column-modal.mjs +17 -0
  82. package/dist/components/ui/add-lead-modal.js +647 -0
  83. package/dist/components/ui/add-lead-modal.mjs +16 -0
  84. package/dist/components/ui/ai-assistant-drawer.js +686 -0
  85. package/dist/components/ui/ai-assistant-drawer.mjs +16 -0
  86. package/dist/components/ui/alert-dialog.js +37 -5
  87. package/dist/components/ui/alert-dialog.mjs +4 -4
  88. package/dist/components/ui/alert.js +37 -11
  89. package/dist/components/ui/alert.mjs +2 -2
  90. package/dist/components/ui/avatar.js +36 -8
  91. package/dist/components/ui/avatar.mjs +2 -2
  92. package/dist/components/ui/backoffice-alert-history-chart.js +624 -0
  93. package/dist/components/ui/backoffice-alert-history-chart.mjs +16 -0
  94. package/dist/components/ui/backoffice-contact-history-chart.js +687 -0
  95. package/dist/components/ui/backoffice-contact-history-chart.mjs +16 -0
  96. package/dist/components/ui/badge.js +37 -2
  97. package/dist/components/ui/badge.mjs +2 -2
  98. package/dist/components/ui/borrowing-capacity-line-chart.js +639 -0
  99. package/dist/components/ui/borrowing-capacity-line-chart.mjs +16 -0
  100. package/dist/components/ui/button.js +35 -3
  101. package/dist/components/ui/button.mjs +2 -2
  102. package/dist/components/ui/calendar.js +43 -19
  103. package/dist/components/ui/calendar.mjs +3 -3
  104. package/dist/components/ui/card.js +40 -4
  105. package/dist/components/ui/card.mjs +2 -2
  106. package/dist/components/ui/cash-balance-line-chart.js +627 -0
  107. package/dist/components/ui/cash-balance-line-chart.mjs +16 -0
  108. package/dist/components/ui/cashflow-bar-chart.js +650 -0
  109. package/dist/components/ui/cashflow-bar-chart.mjs +16 -0
  110. package/dist/components/ui/checkbox.js +36 -5
  111. package/dist/components/ui/checkbox.mjs +2 -3
  112. package/dist/components/ui/chip.js +37 -2
  113. package/dist/components/ui/chip.mjs +3 -3
  114. package/dist/components/ui/combobox.js +280 -0
  115. package/dist/components/ui/combobox.mjs +28 -0
  116. package/dist/components/ui/data-table.js +160 -88
  117. package/dist/components/ui/data-table.mjs +10 -11
  118. package/dist/components/ui/date-picker.js +44 -20
  119. package/dist/components/ui/date-picker.mjs +6 -7
  120. package/dist/components/ui/dialog.js +44 -12
  121. package/dist/components/ui/dialog.mjs +4 -4
  122. package/dist/components/ui/drawer.js +46 -10
  123. package/dist/components/ui/drawer.mjs +3 -3
  124. package/dist/components/ui/dropdown-menu.js +40 -16
  125. package/dist/components/ui/dropdown-menu.mjs +3 -3
  126. package/dist/components/ui/empty.js +41 -5
  127. package/dist/components/ui/empty.mjs +2 -2
  128. package/dist/components/ui/expense-bar-chart.js +642 -0
  129. package/dist/components/ui/expense-bar-chart.mjs +16 -0
  130. package/dist/components/ui/field.js +53 -21
  131. package/dist/components/ui/field.mjs +4 -4
  132. package/dist/components/ui/financial-cards.js +1002 -0
  133. package/dist/components/ui/financial-cards.mjs +24 -0
  134. package/dist/components/ui/financial-drawers.js +637 -0
  135. package/dist/components/ui/financial-drawers.mjs +17 -0
  136. package/dist/components/ui/financial-primitives.js +218 -0
  137. package/dist/components/ui/financial-primitives.mjs +22 -0
  138. package/dist/components/ui/financial-sections.js +1422 -0
  139. package/dist/components/ui/financial-sections.mjs +30 -0
  140. package/dist/components/ui/form-primitives.js +682 -0
  141. package/dist/components/ui/form-primitives.mjs +19 -0
  142. package/dist/components/ui/income-bar-chart.js +641 -0
  143. package/dist/components/ui/income-bar-chart.mjs +16 -0
  144. package/dist/components/ui/input-group.js +43 -7
  145. package/dist/components/ui/input-group.mjs +5 -5
  146. package/dist/components/ui/input-otp.js +39 -3
  147. package/dist/components/ui/input-otp.mjs +2 -2
  148. package/dist/components/ui/input.js +34 -2
  149. package/dist/components/ui/input.mjs +2 -2
  150. package/dist/components/ui/kanban-column.js +1143 -0
  151. package/dist/components/ui/kanban-column.mjs +20 -0
  152. package/dist/components/ui/label.js +35 -7
  153. package/dist/components/ui/label.mjs +2 -2
  154. package/dist/components/ui/opportunity-card.js +960 -0
  155. package/dist/components/ui/opportunity-card.mjs +20 -0
  156. package/dist/components/ui/opportunity-edit-modals.js +3360 -0
  157. package/dist/components/ui/opportunity-edit-modals.mjs +37 -0
  158. package/dist/components/ui/opportunity-summary-tab.js +4365 -0
  159. package/dist/components/ui/opportunity-summary-tab.mjs +34 -0
  160. package/dist/components/ui/pagination.js +35 -3
  161. package/dist/components/ui/pagination.mjs +3 -3
  162. package/dist/components/ui/pipeline-alerts.js +103 -0
  163. package/dist/components/ui/pipeline-alerts.mjs +8 -0
  164. package/dist/components/ui/pipeline-board.js +1408 -0
  165. package/dist/components/ui/pipeline-board.mjs +24 -0
  166. package/dist/components/ui/pipeline-chart.js +216 -0
  167. package/dist/components/ui/pipeline-chart.mjs +10 -0
  168. package/dist/components/ui/pipeline-dialogs.js +1183 -0
  169. package/dist/components/ui/pipeline-dialogs.mjs +23 -0
  170. package/dist/components/ui/pipeline-primitives.js +300 -0
  171. package/dist/components/ui/pipeline-primitives.mjs +11 -0
  172. package/dist/components/ui/popover.js +45 -4
  173. package/dist/components/ui/popover.mjs +3 -3
  174. package/dist/components/ui/progress.js +33 -1
  175. package/dist/components/ui/progress.mjs +2 -2
  176. package/dist/components/ui/property-cashflow-doughnut-chart.js +523 -0
  177. package/dist/components/ui/property-cashflow-doughnut-chart.mjs +16 -0
  178. package/dist/components/ui/property-debt-equity-doughnut-chart.js +521 -0
  179. package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +16 -0
  180. package/dist/components/ui/property-mobile-estimate-line-chart.js +682 -0
  181. package/dist/components/ui/property-mobile-estimate-line-chart.mjs +16 -0
  182. package/dist/components/ui/radio-group.js +33 -1
  183. package/dist/components/ui/radio-group.mjs +2 -2
  184. package/dist/components/ui/select.js +66 -26
  185. package/dist/components/ui/select.mjs +3 -3
  186. package/dist/components/ui/separator.js +33 -1
  187. package/dist/components/ui/separator.mjs +2 -2
  188. package/dist/components/ui/sheet.js +37 -9
  189. package/dist/components/ui/sheet.mjs +3 -3
  190. package/dist/components/ui/skeleton.js +33 -1
  191. package/dist/components/ui/skeleton.mjs +2 -2
  192. package/dist/components/ui/slider.js +86 -102
  193. package/dist/components/ui/slider.mjs +2 -2
  194. package/dist/components/ui/spinner.js +33 -1
  195. package/dist/components/ui/spinner.mjs +2 -2
  196. package/dist/components/ui/stage-timeline.js +579 -0
  197. package/dist/components/ui/stage-timeline.mjs +15 -0
  198. package/dist/components/ui/switch.js +37 -4
  199. package/dist/components/ui/switch.mjs +2 -3
  200. package/dist/components/ui/table.js +37 -5
  201. package/dist/components/ui/table.mjs +2 -2
  202. package/dist/components/ui/tabs.js +36 -12
  203. package/dist/components/ui/tabs.mjs +2 -2
  204. package/dist/components/ui/textarea.js +34 -2
  205. package/dist/components/ui/textarea.mjs +2 -2
  206. package/dist/components/ui/toggle-group.js +35 -4
  207. package/dist/components/ui/toggle-group.mjs +3 -4
  208. package/dist/components/ui/toggle.js +35 -4
  209. package/dist/components/ui/toggle.mjs +2 -3
  210. package/dist/components/ui/tooltip.js +51 -22
  211. package/dist/components/ui/tooltip.mjs +3 -3
  212. package/dist/components/ui/transactions-expense-categories-doughnut-chart.js +528 -0
  213. package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +16 -0
  214. package/dist/components/ui/transactions-income-expense-bar-chart.js +516 -0
  215. package/dist/components/ui/transactions-income-expense-bar-chart.mjs +16 -0
  216. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.js +528 -0
  217. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +16 -0
  218. package/dist/index.js +11613 -2868
  219. package/dist/index.mjs +377 -164
  220. package/dist/lib/theme-provider.js +10 -1
  221. package/dist/lib/theme-provider.mjs +1 -1
  222. package/dist/lib/typography.js +8 -0
  223. package/dist/lib/typography.mjs +3 -1
  224. package/dist/lib/utils.js +33 -1
  225. package/dist/lib/utils.mjs +1 -1
  226. package/dist/styles.css +1 -1
  227. package/package.json +169 -6
  228. package/src/components/index.tsx +323 -13
  229. package/src/components/ui/accordion.tsx +6 -3
  230. package/src/components/ui/add-column-modal.tsx +339 -0
  231. package/src/components/ui/add-lead-modal.tsx +290 -0
  232. package/src/components/ui/ai-assistant-drawer.tsx +408 -0
  233. package/src/components/ui/alert-dialog.tsx +80 -54
  234. package/src/components/ui/alert.tsx +28 -28
  235. package/src/components/ui/avatar.tsx +30 -29
  236. package/src/components/ui/backoffice-alert-history-chart.tsx +260 -0
  237. package/src/components/ui/backoffice-contact-history-chart.tsx +325 -0
  238. package/src/components/ui/badge.tsx +17 -15
  239. package/src/components/ui/borrowing-capacity-line-chart.tsx +357 -0
  240. package/src/components/ui/button.tsx +30 -27
  241. package/src/components/ui/calendar.tsx +53 -67
  242. package/src/components/ui/card.tsx +27 -24
  243. package/src/components/ui/cash-balance-line-chart.tsx +302 -0
  244. package/src/components/ui/cashflow-bar-chart.tsx +363 -0
  245. package/src/components/ui/chart-shared.tsx +261 -0
  246. package/src/components/ui/checkbox.tsx +30 -26
  247. package/src/components/ui/combobox.tsx +223 -0
  248. package/src/components/ui/data-table.tsx +160 -99
  249. package/src/components/ui/date-picker.tsx +0 -2
  250. package/src/components/ui/dialog.tsx +70 -60
  251. package/src/components/ui/drawer.tsx +57 -48
  252. package/src/components/ui/dropdown-menu.tsx +90 -82
  253. package/src/components/ui/empty.tsx +31 -27
  254. package/src/components/ui/expense-bar-chart.tsx +296 -0
  255. package/src/components/ui/field.tsx +70 -62
  256. package/src/components/ui/financial-cards.tsx +830 -0
  257. package/src/components/ui/financial-drawers.tsx +339 -0
  258. package/src/components/ui/financial-primitives.tsx +331 -0
  259. package/src/components/ui/financial-sections.tsx +672 -0
  260. package/src/components/ui/form-primitives.tsx +536 -0
  261. package/src/components/ui/income-bar-chart.tsx +297 -0
  262. package/src/components/ui/input-group.tsx +41 -34
  263. package/src/components/ui/input-otp.tsx +29 -24
  264. package/src/components/ui/input.tsx +8 -8
  265. package/src/components/ui/kanban-column.tsx +333 -0
  266. package/src/components/ui/label.tsx +9 -12
  267. package/src/components/ui/opportunity-card.tsx +616 -0
  268. package/src/components/ui/opportunity-edit-modals.tsx +2528 -0
  269. package/src/components/ui/opportunity-summary-tab.tsx +579 -0
  270. package/src/components/ui/pipeline-alerts.tsx +74 -0
  271. package/src/components/ui/pipeline-board.tsx +268 -0
  272. package/src/components/ui/pipeline-chart.tsx +173 -0
  273. package/src/components/ui/pipeline-dialogs.tsx +303 -0
  274. package/src/components/ui/pipeline-primitives.tsx +108 -0
  275. package/src/components/ui/popover.tsx +41 -36
  276. package/src/components/ui/property-cashflow-doughnut-chart.tsx +188 -0
  277. package/src/components/ui/property-debt-equity-doughnut-chart.tsx +185 -0
  278. package/src/components/ui/property-mobile-estimate-line-chart.tsx +393 -0
  279. package/src/components/ui/select.tsx +65 -52
  280. package/src/components/ui/sheet.tsx +55 -52
  281. package/src/components/ui/slider.tsx +54 -77
  282. package/src/components/ui/stage-timeline.tsx +205 -0
  283. package/src/components/ui/switch.tsx +42 -29
  284. package/src/components/ui/table.tsx +28 -28
  285. package/src/components/ui/tabs.tsx +22 -28
  286. package/src/components/ui/textarea.tsx +8 -8
  287. package/src/components/ui/toggle-group.tsx +0 -2
  288. package/src/components/ui/toggle.tsx +13 -15
  289. package/src/components/ui/tooltip.tsx +30 -28
  290. package/src/components/ui/transactions-expense-categories-doughnut-chart.tsx +191 -0
  291. package/src/components/ui/transactions-income-expense-bar-chart.tsx +205 -0
  292. package/src/components/ui/transactions-liabilities-breakdown-doughnut-chart.tsx +191 -0
  293. package/src/lib/theme-provider.tsx +10 -0
  294. package/src/lib/typography.ts +9 -0
  295. package/src/lib/utils.ts +41 -3
  296. package/src/styles/globals.css +371 -124
  297. package/src/styles/styles-css.ts +1 -1
  298. package/tsup.config.ts +32 -0
  299. package/dist/chunk-K74JRTJR.mjs +0 -105
  300. package/dist/chunk-V7CNWJT3.mjs +0 -10
@@ -7,56 +7,56 @@
7
7
  * - SheetTitle: added `text-lg` — matches Figma Text-lg/Semibold
8
8
  * - Close button: matches DialogClose — no radius, `hover:bg-foreground/5`, `focus:ring-border`
9
9
  */
10
- import { type ReactElement } from "react"
11
- import * as React from "react"
12
- import { XIcon } from "lucide-react"
13
- import { Dialog as SheetPrimitive } from "@base-ui/react/dialog"
14
- import { cn } from "@/lib/utils"
15
- import { useThemeVars } from "@/lib/theme-provider"
10
+ import { type ReactElement } from "react";
11
+ import * as React from "react";
12
+ import { XIcon } from "lucide-react";
13
+ import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
14
+ import { cn } from "@/lib/utils";
15
+ import { useThemeVars } from "@/lib/theme-provider";
16
16
 
17
17
  // ---------------------------------------------------------------------------
18
18
  // Side-specific panel classes
19
19
  // ---------------------------------------------------------------------------
20
20
 
21
21
  const SIDE_CLASSES = {
22
- right: "inset-y-0 right-0 h-full w-3/4 border-l data-ending-style:slide-out-to-right data-open:slide-in-from-right sm:max-w-sm",
23
- left: "inset-y-0 left-0 h-full w-3/4 border-r data-ending-style:slide-out-to-left data-open:slide-in-from-left sm:max-w-sm",
24
- top: "inset-x-0 top-0 h-auto border-b data-ending-style:slide-out-to-top data-open:slide-in-from-top",
25
- bottom: "inset-x-0 bottom-0 h-auto border-t data-ending-style:slide-out-to-bottom data-open:slide-in-from-bottom",
26
- } satisfies Record<string, string>
22
+ right:
23
+ "inset-y-0 right-0 h-full w-1/2 border-l data-ending-style:slide-out-to-right data-open:slide-in-from-right",
24
+ left: "inset-y-0 left-0 h-full w-1/2 border-r data-ending-style:slide-out-to-left data-open:slide-in-from-left",
25
+ top: "inset-x-0 top-0 h-auto border-b data-ending-style:slide-out-to-top data-open:slide-in-from-top",
26
+ bottom:
27
+ "inset-x-0 bottom-0 h-auto border-t data-ending-style:slide-out-to-bottom data-open:slide-in-from-bottom",
28
+ } satisfies Record<string, string>;
27
29
 
28
30
  // ---------------------------------------------------------------------------
29
31
  // Components
30
32
  // ---------------------------------------------------------------------------
31
33
 
32
- export type SheetProps = React.ComponentProps<typeof SheetPrimitive.Root>
34
+ export type SheetProps = React.ComponentProps<typeof SheetPrimitive.Root>;
33
35
 
34
36
  function Sheet({ ...props }: SheetProps): ReactElement {
35
- return <SheetPrimitive.Root data-slot="sheet" {...props} />
37
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />;
36
38
  }
37
39
 
38
- export type SheetTriggerProps = React.ComponentProps<typeof SheetPrimitive.Trigger>
40
+ export type SheetTriggerProps = React.ComponentProps<
41
+ typeof SheetPrimitive.Trigger
42
+ >;
39
43
 
40
- function SheetTrigger({
41
- ...props
42
- }: SheetTriggerProps): ReactElement {
43
- return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
44
+ function SheetTrigger({ ...props }: SheetTriggerProps): ReactElement {
45
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
44
46
  }
45
47
 
46
- export type SheetCloseProps = React.ComponentProps<typeof SheetPrimitive.Close>
48
+ export type SheetCloseProps = React.ComponentProps<typeof SheetPrimitive.Close>;
47
49
 
48
- function SheetClose({
49
- ...props
50
- }: SheetCloseProps): ReactElement {
51
- return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
50
+ function SheetClose({ ...props }: SheetCloseProps): ReactElement {
51
+ return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
52
52
  }
53
53
 
54
- export type SheetPortalProps = React.ComponentProps<typeof SheetPrimitive.Portal>
54
+ export type SheetPortalProps = React.ComponentProps<
55
+ typeof SheetPrimitive.Portal
56
+ >;
55
57
 
56
- function SheetPortal({
57
- ...props
58
- }: SheetPortalProps): ReactElement {
59
- return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
58
+ function SheetPortal({ ...props }: SheetPortalProps): ReactElement {
59
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
60
60
  }
61
61
 
62
62
  function SheetOverlay({
@@ -67,18 +67,20 @@ function SheetOverlay({
67
67
  <SheetPrimitive.Backdrop
68
68
  className={cn(
69
69
  "fixed inset-0 z-50 bg-foreground/50 data-ending-style:animate-out data-ending-style:fade-out-0 data-ending-style:fill-mode-forwards data-open:animate-in data-open:fade-in-0",
70
- className
70
+ className,
71
71
  )}
72
72
  data-slot="sheet-overlay"
73
73
  {...props}
74
74
  />
75
- )
75
+ );
76
76
  }
77
77
 
78
- export type SheetContentProps = React.ComponentProps<typeof SheetPrimitive.Popup> & {
79
- side?: keyof typeof SIDE_CLASSES
80
- showCloseButton?: boolean
81
- }
78
+ export type SheetContentProps = React.ComponentProps<
79
+ typeof SheetPrimitive.Popup
80
+ > & {
81
+ side?: keyof typeof SIDE_CLASSES;
82
+ showCloseButton?: boolean;
83
+ };
82
84
 
83
85
  function SheetContent({
84
86
  className,
@@ -96,26 +98,28 @@ function SheetContent({
96
98
  className={cn(
97
99
  "fixed z-50 flex flex-col gap-4 bg-background transition ease-in-out data-ending-style:animate-out data-ending-style:duration-300 data-ending-style:fill-mode-forwards data-open:animate-in data-open:duration-500",
98
100
  SIDE_CLASSES[side],
99
- className
101
+ className,
100
102
  )}
101
103
  data-slot="sheet-content"
102
104
  style={{ ...themeVars, ...style } as React.CSSProperties}
103
105
  {...props}
104
106
  >
105
107
  {children}
106
- {showCloseButton ? <SheetPrimitive.Close
108
+ {showCloseButton ? (
109
+ <SheetPrimitive.Close
107
110
  className="absolute top-4 right-4 transition-colors hover:bg-foreground/5 focus:outline-hidden focus:ring-2 focus:ring-border focus:ring-offset-0 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
108
111
  data-slot="sheet-icon-close"
109
112
  >
110
113
  <XIcon />
111
114
  <span className="sr-only">Close</span>
112
- </SheetPrimitive.Close> : null}
115
+ </SheetPrimitive.Close>
116
+ ) : null}
113
117
  </SheetPrimitive.Popup>
114
118
  </SheetPortal>
115
- )
119
+ );
116
120
  }
117
121
 
118
- export type SheetHeaderProps = React.ComponentProps<"div">
122
+ export type SheetHeaderProps = React.ComponentProps<"div">;
119
123
 
120
124
  function SheetHeader({ className, ...props }: SheetHeaderProps): ReactElement {
121
125
  return (
@@ -124,10 +128,10 @@ function SheetHeader({ className, ...props }: SheetHeaderProps): ReactElement {
124
128
  data-slot="sheet-header"
125
129
  {...props}
126
130
  />
127
- )
131
+ );
128
132
  }
129
133
 
130
- export type SheetFooterProps = React.ComponentProps<"div">
134
+ export type SheetFooterProps = React.ComponentProps<"div">;
131
135
 
132
136
  function SheetFooter({ className, ...props }: SheetFooterProps): ReactElement {
133
137
  return (
@@ -136,25 +140,24 @@ function SheetFooter({ className, ...props }: SheetFooterProps): ReactElement {
136
140
  data-slot="sheet-footer"
137
141
  {...props}
138
142
  />
139
- )
143
+ );
140
144
  }
141
145
 
142
- export type SheetTitleProps = React.ComponentProps<typeof SheetPrimitive.Title>
146
+ export type SheetTitleProps = React.ComponentProps<typeof SheetPrimitive.Title>;
143
147
 
144
- function SheetTitle({
145
- className,
146
- ...props
147
- }: SheetTitleProps): ReactElement {
148
+ function SheetTitle({ className, ...props }: SheetTitleProps): ReactElement {
148
149
  return (
149
150
  <SheetPrimitive.Title
150
151
  className={cn("text-lg font-semibold text-foreground", className)}
151
152
  data-slot="sheet-title"
152
153
  {...props}
153
154
  />
154
- )
155
+ );
155
156
  }
156
157
 
157
- export type SheetDescriptionProps = React.ComponentProps<typeof SheetPrimitive.Description>
158
+ export type SheetDescriptionProps = React.ComponentProps<
159
+ typeof SheetPrimitive.Description
160
+ >;
158
161
 
159
162
  function SheetDescription({
160
163
  className,
@@ -162,11 +165,11 @@ function SheetDescription({
162
165
  }: SheetDescriptionProps): ReactElement {
163
166
  return (
164
167
  <SheetPrimitive.Description
165
- className={cn("text-sm text-muted-foreground", className)}
168
+ className={cn("text-body-small text-muted-foreground", className)}
166
169
  data-slot="sheet-description"
167
170
  {...props}
168
171
  />
169
- )
172
+ );
170
173
  }
171
174
 
172
175
  export {
@@ -179,4 +182,4 @@ export {
179
182
  SheetPortal,
180
183
  SheetTitle,
181
184
  SheetTrigger,
182
- }
185
+ };
@@ -1,26 +1,26 @@
1
- import * as React from "react"
2
-
3
- import { cn } from "@/lib/utils"
1
+ import * as React from "react";
2
+ import { Slider as SliderPrimitive } from "@base-ui/react/slider";
3
+ import { cn } from "@/lib/utils";
4
4
 
5
5
  /**
6
6
  * Slider — WealthX Design System
7
7
  *
8
- * Base HTML range input styled to match WealthX design tokens.
9
- * Supports single value. Track bg-muted, range bg-primary, rounded corners.
8
+ * Built on @base-ui/react/slider. Uses thumbAlignment="edge" so the thumb
9
+ * stays fully within the control at min/max without overflowing.
10
10
  */
11
11
 
12
- interface SliderProps
13
- extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "type"> {
14
- value?: number
15
- defaultValue?: number
16
- min?: number
17
- max?: number
18
- step?: number
19
- disabled?: boolean
20
- onValueChange?: (value: number) => void
12
+ interface SliderProps {
13
+ value?: number;
14
+ defaultValue?: number;
15
+ min?: number;
16
+ max?: number;
17
+ step?: number;
18
+ disabled?: boolean;
19
+ onValueChange?: (value: number) => void;
20
+ className?: string;
21
21
  }
22
22
 
23
- const Slider = React.forwardRef<HTMLInputElement, SliderProps>(
23
+ const Slider = React.forwardRef<HTMLDivElement, SliderProps>(
24
24
  (
25
25
  {
26
26
  className,
@@ -31,77 +31,54 @@ const Slider = React.forwardRef<HTMLInputElement, SliderProps>(
31
31
  step = 1,
32
32
  disabled = false,
33
33
  onValueChange,
34
- ...props
35
34
  },
36
- ref
35
+ ref,
37
36
  ) => {
38
- const [internalValue, setInternalValue] = React.useState(defaultValue)
39
- const currentValue = value !== undefined ? value : internalValue
40
-
41
- const percentage = ((currentValue - min) / (max - min)) * 100
42
-
43
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
44
- const newValue = Number(e.target.value)
45
- if (value === undefined) {
46
- setInternalValue(newValue)
47
- }
48
- onValueChange?.(newValue)
49
- }
50
-
51
37
  return (
52
- <div
38
+ <SliderPrimitive.Root
39
+ ref={ref}
40
+ value={value}
41
+ defaultValue={defaultValue}
42
+ min={min}
43
+ max={max}
44
+ step={step}
45
+ disabled={disabled}
46
+ thumbAlignment="edge"
47
+ onValueChange={(val) => onValueChange?.(val as number)}
53
48
  data-slot="slider"
54
49
  className={cn(
55
- "relative flex w-full touch-none items-center select-none",
50
+ "relative w-full touch-none select-none",
56
51
  disabled && "opacity-50",
57
- className
52
+ className,
58
53
  )}
59
54
  >
60
- {/* Track */}
61
- <div
62
- data-slot="slider-track"
63
- className="relative h-2 w-full overflow-hidden rounded-full bg-muted"
55
+ <SliderPrimitive.Control
56
+ className="relative flex h-5 w-full cursor-pointer items-center"
57
+ data-slot="slider-control"
64
58
  >
65
- {/* Range fill */}
66
- <div
67
- data-slot="slider-range"
68
- className="absolute h-full rounded-full bg-primary"
69
- style={{ width: `${percentage}%` }}
59
+ <SliderPrimitive.Track
60
+ className="relative h-2 w-full overflow-hidden rounded-full bg-muted"
61
+ data-slot="slider-track"
62
+ >
63
+ <SliderPrimitive.Indicator
64
+ className="absolute h-full rounded-full bg-primary"
65
+ data-slot="slider-indicator"
66
+ />
67
+ </SliderPrimitive.Track>
68
+ <SliderPrimitive.Thumb
69
+ className={cn(
70
+ "block size-5 rounded-full border-2 border-primary bg-background shadow-sm",
71
+ "outline-none",
72
+ )}
73
+ data-slot="slider-thumb"
70
74
  />
71
- </div>
72
-
73
- {/* Native range input (invisible, covers full width for interaction) */}
74
- <input
75
- ref={ref}
76
- type="range"
77
- min={min}
78
- max={max}
79
- step={step}
80
- value={currentValue}
81
- disabled={disabled}
82
- onChange={handleChange}
83
- className={cn(
84
- "absolute inset-0 h-full w-full cursor-pointer opacity-0",
85
- disabled && "cursor-not-allowed"
86
- )}
87
- {...props}
88
- />
89
-
90
- {/* Visual thumb */}
91
- <div
92
- data-slot="slider-thumb"
93
- className={cn(
94
- "pointer-events-none absolute top-1/2 -translate-x-1/2 -translate-y-1/2",
95
- "block size-5 rounded-full border-2 border-primary bg-background shadow-sm"
96
- )}
97
- style={{ left: `${percentage}%` }}
98
- />
99
- </div>
100
- )
101
- }
102
- )
75
+ </SliderPrimitive.Control>
76
+ </SliderPrimitive.Root>
77
+ );
78
+ },
79
+ );
103
80
 
104
- Slider.displayName = "Slider"
81
+ Slider.displayName = "Slider";
105
82
 
106
- export { Slider }
107
- export type { SliderProps }
83
+ export { Slider };
84
+ export type { SliderProps };
@@ -0,0 +1,205 @@
1
+ import { Check } from "lucide-react";
2
+ import { cn } from "@/lib/utils";
3
+ import {
4
+ Accordion,
5
+ AccordionContent,
6
+ AccordionItem,
7
+ AccordionTrigger,
8
+ } from "@/components/ui/accordion";
9
+ import { Progress } from "@/components/ui/progress";
10
+ import { TaskCheckItem } from "@/components/ui/pipeline-primitives";
11
+ import { Spinner } from "@/components/ui/spinner";
12
+
13
+ /**
14
+ * StageTimeline — WealthX DS (L4 Section)
15
+ *
16
+ * Progress bar + accordion list of pipeline stages with task checklists.
17
+ * Used in the Tasks tab of OpportunityDetailsDrawer.
18
+ *
19
+ * Layout:
20
+ * • Top: progress bar showing completed stages / total stages
21
+ * • Below: accordion with one item per stage
22
+ *
23
+ * Data source: `listColumns()` + `listLoans()` → tasks per stage
24
+ */
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Types
28
+ // ---------------------------------------------------------------------------
29
+
30
+ export interface StageTimelineTask {
31
+ id: string;
32
+ title: string;
33
+ completed: boolean;
34
+ aiAgentName?: string | null;
35
+ }
36
+
37
+ export interface StageTimelineStage {
38
+ id: string;
39
+ name: string;
40
+ tasks: StageTimelineTask[];
41
+ /** Stage the opportunity is currently in. */
42
+ isCurrentStage?: boolean;
43
+ /** Stage has been fully passed through. */
44
+ isCompleted?: boolean;
45
+ }
46
+
47
+ export interface StageTimelineProps {
48
+ stages: StageTimelineStage[];
49
+ /** Called when a task checkbox is toggled. */
50
+ onTaskToggle?: (stageId: string, taskId: string) => void;
51
+ /** Shows a loading skeleton instead of stages. */
52
+ isLoading?: boolean;
53
+ className?: string;
54
+ }
55
+
56
+ // ---------------------------------------------------------------------------
57
+ // StageTimeline
58
+ // ---------------------------------------------------------------------------
59
+
60
+ export function StageTimeline({
61
+ stages,
62
+ onTaskToggle,
63
+ isLoading = false,
64
+ className,
65
+ }: StageTimelineProps) {
66
+ if (isLoading) {
67
+ return (
68
+ <div
69
+ className={cn(
70
+ "flex flex-col items-center justify-center gap-3 py-10",
71
+ className,
72
+ )}
73
+ data-slot="stage-timeline"
74
+ >
75
+ <Spinner size="lg" className="text-muted-foreground" />
76
+ <p className="text-sm text-muted-foreground">Loading stages…</p>
77
+ </div>
78
+ );
79
+ }
80
+
81
+ if (stages.length === 0) {
82
+ return (
83
+ <div
84
+ className={cn(
85
+ "flex items-center justify-center py-10 text-sm text-muted-foreground",
86
+ className,
87
+ )}
88
+ data-slot="stage-timeline"
89
+ >
90
+ No stages available.
91
+ </div>
92
+ );
93
+ }
94
+
95
+ const completedCount = stages.filter((s) => s.isCompleted).length;
96
+ const progressPct = Math.round((completedCount / stages.length) * 100);
97
+
98
+ // Default open: current stage (or first if none flagged)
99
+ const defaultOpen = stages.find((s) => s.isCurrentStage)?.id ?? stages[0].id;
100
+
101
+ return (
102
+ <div
103
+ className={cn("flex flex-col gap-4", className)}
104
+ data-slot="stage-timeline"
105
+ >
106
+ {/* Progress bar */}
107
+ <div className="flex flex-col gap-2">
108
+ <div className="flex items-center justify-between text-sm text-muted-foreground">
109
+ <span>Stage progress</span>
110
+ <span>
111
+ {completedCount} / {stages.length} completed
112
+ </span>
113
+ </div>
114
+ <Progress value={progressPct} className="h-2.5" />
115
+ </div>
116
+
117
+ {/* Stage accordion */}
118
+ <Accordion
119
+ type="single"
120
+ collapsible
121
+ defaultValue={defaultOpen}
122
+ className="w-full"
123
+ >
124
+ {stages.map((stage) => {
125
+ const completedTasks = stage.tasks.filter((t) => t.completed).length;
126
+ const hasTasks = stage.tasks.length > 0;
127
+
128
+ return (
129
+ <AccordionItem
130
+ key={stage.id}
131
+ value={stage.id}
132
+ className="border-b border-border last:border-0"
133
+ >
134
+ <AccordionTrigger
135
+ className={cn(
136
+ "py-3.5 text-sm hover:no-underline [&>svg]:size-4",
137
+ stage.isCompleted
138
+ ? "text-muted-foreground"
139
+ : stage.isCurrentStage
140
+ ? "font-semibold text-foreground"
141
+ : "font-normal text-muted-foreground",
142
+ )}
143
+ disabled={!hasTasks}
144
+ >
145
+ <span className="flex items-center gap-2.5">
146
+ {/* Stage status icon */}
147
+ {stage.isCompleted ? (
148
+ <span
149
+ className="flex size-5 shrink-0 items-center justify-center rounded-full bg-primary"
150
+ aria-hidden="true"
151
+ >
152
+ <Check
153
+ className="size-3 text-primary-foreground"
154
+ strokeWidth={2.5}
155
+ />
156
+ </span>
157
+ ) : stage.isCurrentStage ? (
158
+ <span
159
+ className="size-5 shrink-0 rounded-full border-2 border-primary bg-background"
160
+ aria-hidden="true"
161
+ />
162
+ ) : (
163
+ <span
164
+ className="size-5 shrink-0 rounded-full border-2 border-muted-foreground/30 bg-background"
165
+ aria-hidden="true"
166
+ />
167
+ )}
168
+
169
+ <span className={cn(stage.isCompleted && "line-through")}>
170
+ {stage.name}
171
+ </span>
172
+
173
+ {hasTasks && (
174
+ <span className="text-xs text-muted-foreground">
175
+ {completedTasks}/{stage.tasks.length}
176
+ </span>
177
+ )}
178
+ </span>
179
+ </AccordionTrigger>
180
+
181
+ {hasTasks && (
182
+ <AccordionContent className="p-0 pb-3 pl-8">
183
+ {stage.tasks.map((task) => (
184
+ <TaskCheckItem
185
+ key={task.id}
186
+ title={task.title}
187
+ completed={task.completed}
188
+ aiAgentName={task.aiAgentName}
189
+ size="sm"
190
+ onToggle={
191
+ onTaskToggle
192
+ ? () => onTaskToggle(stage.id, task.id)
193
+ : undefined
194
+ }
195
+ />
196
+ ))}
197
+ </AccordionContent>
198
+ )}
199
+ </AccordionItem>
200
+ );
201
+ })}
202
+ </Accordion>
203
+ </div>
204
+ );
205
+ }