@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.
- package/.turbo/turbo-build.log +235 -154
- package/CHANGELOG.md +12 -0
- package/dist/{chunk-6OJF6XRN.mjs → chunk-24FUO7TD.mjs} +4 -8
- package/dist/{chunk-4AJ5HWHD.mjs → chunk-2I5S2AMY.mjs} +3 -3
- package/dist/{chunk-GPRJQ24C.mjs → chunk-34NWQURD.mjs} +2 -2
- package/dist/{chunk-MQ72DIBH.mjs → chunk-3GF7OVTP.mjs} +14 -5
- package/dist/chunk-3WMX6KWS.mjs +245 -0
- package/dist/{chunk-PMKODV6M.mjs → chunk-462HMNO4.mjs} +6 -10
- package/dist/chunk-4CX4SBRO.mjs +153 -0
- package/dist/chunk-4MN6UQHG.mjs +443 -0
- package/dist/chunk-4Y6R4WEC.mjs +250 -0
- package/dist/{chunk-BGP2N52Z.mjs → chunk-66MI7Q4B.mjs} +5 -5
- package/dist/{chunk-CGOKTPXU.mjs → chunk-6JQFUE5I.mjs} +20 -23
- package/dist/{chunk-Z3MK2KKZ.mjs → chunk-7DHU4VGG.mjs} +7 -3
- package/dist/chunk-7MMXNK3C.mjs +317 -0
- package/dist/{chunk-VZ2NR7L3.mjs → chunk-7PYJD5JI.mjs} +35 -27
- package/dist/{chunk-JU2RUWHF.mjs → chunk-7XJHLGUV.mjs} +1 -1
- package/dist/{chunk-BMFN37JH.mjs → chunk-7YAU5CY6.mjs} +1 -1
- package/dist/chunk-A56YQQHG.mjs +402 -0
- package/dist/{chunk-GLW2UO6O.mjs → chunk-BL3DXM2X.mjs} +84 -62
- package/dist/{chunk-SLWCCURD.mjs → chunk-CLIN5525.mjs} +8 -4
- package/dist/{chunk-3VQNJ235.mjs → chunk-CSDO6VBW.mjs} +7 -0
- package/dist/chunk-D4ILTPOG.mjs +293 -0
- package/dist/{chunk-HS7TFG7V.mjs → chunk-D6ID6M4V.mjs} +1 -1
- package/dist/chunk-DOH3EHX7.mjs +378 -0
- package/dist/{chunk-MJIEMGRD.mjs → chunk-EFRENWEJ.mjs} +9 -17
- package/dist/{chunk-YBXCIF5Q.mjs → chunk-ERGGHC2V.mjs} +36 -49
- package/dist/{chunk-OXQQNQZI.mjs → chunk-FEZKMUCF.mjs} +10 -1
- package/dist/{chunk-55CEW76V.mjs → chunk-FH6QVUVZ.mjs} +1 -1
- package/dist/chunk-FMAXJ2SI.mjs +71 -0
- package/dist/chunk-FZIXGLMV.mjs +173 -0
- package/dist/chunk-GGM2UYGG.mjs +273 -0
- package/dist/{chunk-DS2AMHN2.mjs → chunk-GYMYRIZP.mjs} +2 -2
- package/dist/{chunk-KQDD5MU3.mjs → chunk-H45TKD34.mjs} +5 -5
- package/dist/{chunk-BBJBJSXQ.mjs → chunk-J5UICVJS.mjs} +1 -1
- package/dist/{chunk-RL772EH7.mjs → chunk-JHJHG4GO.mjs} +4 -12
- package/dist/{chunk-RN67642N.mjs → chunk-JNQORUPP.mjs} +49 -42
- package/dist/{chunk-5JGQAAQV.mjs → chunk-K3JYD4IU.mjs} +86 -63
- package/dist/{chunk-FHNT55I5.mjs → chunk-KUDCQ4FI.mjs} +4 -4
- package/dist/{chunk-UEL4RD5P.mjs → chunk-LHYCMLVA.mjs} +82 -68
- package/dist/{chunk-NLLKTU4B.mjs → chunk-LLVQKSU3.mjs} +21 -17
- package/dist/{chunk-KKHTJNMM.mjs → chunk-MARPPFOJ.mjs} +8 -4
- package/dist/{chunk-6AFMNC42.mjs → chunk-N2PT566P.mjs} +15 -11
- package/dist/{chunk-YN5SYTOO.mjs → chunk-NQPOYKAQ.mjs} +9 -5
- package/dist/{chunk-ZZV5JVNW.mjs → chunk-NSLMILBT.mjs} +3 -7
- package/dist/chunk-OGOYQ7BG.mjs +150 -0
- package/dist/chunk-OPNQAVVH.mjs +162 -0
- package/dist/{chunk-3NQGYJEZ.mjs → chunk-P6AM5V7O.mjs} +10 -18
- package/dist/{chunk-CZ3BW5GL.mjs → chunk-P76HMUI6.mjs} +5 -11
- package/dist/chunk-PCPLO5HT.mjs +671 -0
- package/dist/chunk-PG6K5XEC.mjs +475 -0
- package/dist/{chunk-DDPA2XXS.mjs → chunk-PMB3A7V3.mjs} +2 -2
- package/dist/chunk-PR6V5XKM.mjs +209 -0
- package/dist/{chunk-46OFHMQA.mjs → chunk-Q76O3RIQ.mjs} +10 -6
- package/dist/chunk-RGU7HOEC.mjs +140 -0
- package/dist/{chunk-JF4PHPD5.mjs → chunk-RGVKLTLH.mjs} +4 -4
- package/dist/{chunk-VG6UF6UT.mjs → chunk-RP3SQYA3.mjs} +2 -2
- package/dist/chunk-RYCLWMZ7.mjs +162 -0
- package/dist/chunk-SIZMLSRU.mjs +162 -0
- package/dist/chunk-SPJ5KXW7.mjs +199 -0
- package/dist/chunk-SWGT756Z.mjs +210 -0
- package/dist/chunk-SYOD63OZ.mjs +225 -0
- package/dist/chunk-TS2ZX2VS.mjs +270 -0
- package/dist/chunk-UFYSFDER.mjs +42 -0
- package/dist/chunk-VACKZOMY.mjs +190 -0
- package/dist/chunk-VLQZANBF.mjs +42 -0
- package/dist/chunk-VPBN3WOO.mjs +164 -0
- package/dist/chunk-WA6O6EUR.mjs +1885 -0
- package/dist/{chunk-E3K6O4FZ.mjs → chunk-WAZD7NFU.mjs} +5 -2
- package/dist/chunk-WG6JGJXB.mjs +165 -0
- package/dist/{chunk-I64K754C.mjs → chunk-WNGWBVLV.mjs} +2 -2
- package/dist/{chunk-3U7SD3MS.mjs → chunk-WOEHFRGB.mjs} +3 -3
- package/dist/{chunk-DKZRJOMF.mjs → chunk-XIRTEFKH.mjs} +12 -12
- package/dist/chunk-Y6DWJSKZ.mjs +79 -0
- package/dist/{chunk-CJ46PDXE.mjs → chunk-ZRO5JO3H.mjs} +106 -66
- package/dist/{chunk-VYMHBV6D.mjs → chunk-ZU4NV6RG.mjs} +5 -3
- package/dist/components/ui/accordion.js +40 -4
- package/dist/components/ui/accordion.mjs +2 -2
- package/dist/components/ui/add-column-modal.js +789 -0
- package/dist/components/ui/add-column-modal.mjs +17 -0
- package/dist/components/ui/add-lead-modal.js +647 -0
- package/dist/components/ui/add-lead-modal.mjs +16 -0
- package/dist/components/ui/ai-assistant-drawer.js +686 -0
- package/dist/components/ui/ai-assistant-drawer.mjs +16 -0
- package/dist/components/ui/alert-dialog.js +37 -5
- package/dist/components/ui/alert-dialog.mjs +4 -4
- package/dist/components/ui/alert.js +37 -11
- package/dist/components/ui/alert.mjs +2 -2
- package/dist/components/ui/avatar.js +36 -8
- package/dist/components/ui/avatar.mjs +2 -2
- package/dist/components/ui/backoffice-alert-history-chart.js +624 -0
- package/dist/components/ui/backoffice-alert-history-chart.mjs +16 -0
- package/dist/components/ui/backoffice-contact-history-chart.js +687 -0
- package/dist/components/ui/backoffice-contact-history-chart.mjs +16 -0
- package/dist/components/ui/badge.js +37 -2
- package/dist/components/ui/badge.mjs +2 -2
- package/dist/components/ui/borrowing-capacity-line-chart.js +640 -0
- package/dist/components/ui/borrowing-capacity-line-chart.mjs +16 -0
- package/dist/components/ui/button.js +35 -3
- package/dist/components/ui/button.mjs +2 -2
- package/dist/components/ui/calendar.js +43 -19
- package/dist/components/ui/calendar.mjs +3 -3
- package/dist/components/ui/card.js +40 -4
- package/dist/components/ui/card.mjs +2 -2
- package/dist/components/ui/cash-balance-line-chart.js +628 -0
- package/dist/components/ui/cash-balance-line-chart.mjs +16 -0
- package/dist/components/ui/cashflow-bar-chart.js +124 -70
- package/dist/components/ui/cashflow-bar-chart.mjs +8 -8
- package/dist/components/ui/checkbox.js +36 -5
- package/dist/components/ui/checkbox.mjs +2 -3
- package/dist/components/ui/chip.js +37 -2
- package/dist/components/ui/chip.mjs +3 -3
- package/dist/components/ui/combobox.js +68 -49
- package/dist/components/ui/combobox.mjs +2 -2
- package/dist/components/ui/data-table.js +160 -88
- package/dist/components/ui/data-table.mjs +10 -11
- package/dist/components/ui/date-picker.js +44 -20
- package/dist/components/ui/date-picker.mjs +6 -7
- package/dist/components/ui/dialog.js +44 -12
- package/dist/components/ui/dialog.mjs +4 -4
- package/dist/components/ui/drawer.js +46 -10
- package/dist/components/ui/drawer.mjs +3 -3
- package/dist/components/ui/dropdown-menu.js +40 -16
- package/dist/components/ui/dropdown-menu.mjs +3 -3
- package/dist/components/ui/empty.js +41 -5
- package/dist/components/ui/empty.mjs +2 -2
- package/dist/components/ui/expense-bar-chart.js +166 -67
- package/dist/components/ui/expense-bar-chart.mjs +8 -8
- package/dist/components/ui/field.js +53 -21
- package/dist/components/ui/field.mjs +4 -4
- package/dist/components/ui/financial-cards.js +1002 -0
- package/dist/components/ui/financial-cards.mjs +24 -0
- package/dist/components/ui/financial-drawers.js +637 -0
- package/dist/components/ui/financial-drawers.mjs +17 -0
- package/dist/components/ui/financial-primitives.js +218 -0
- package/dist/components/ui/financial-primitives.mjs +22 -0
- package/dist/components/ui/financial-sections.js +1422 -0
- package/dist/components/ui/financial-sections.mjs +30 -0
- package/dist/components/ui/form-primitives.js +682 -0
- package/dist/components/ui/form-primitives.mjs +19 -0
- package/dist/components/ui/income-bar-chart.js +164 -66
- package/dist/components/ui/income-bar-chart.mjs +8 -8
- package/dist/components/ui/input-group.js +43 -7
- package/dist/components/ui/input-group.mjs +5 -5
- package/dist/components/ui/input-otp.js +39 -3
- package/dist/components/ui/input-otp.mjs +2 -2
- package/dist/components/ui/input.js +34 -2
- package/dist/components/ui/input.mjs +2 -2
- package/dist/components/ui/kanban-column.js +1143 -0
- package/dist/components/ui/kanban-column.mjs +20 -0
- package/dist/components/ui/label.js +35 -7
- package/dist/components/ui/label.mjs +2 -2
- package/dist/components/ui/opportunity-card.js +960 -0
- package/dist/components/ui/opportunity-card.mjs +20 -0
- package/dist/components/ui/opportunity-edit-modals.js +3360 -0
- package/dist/components/ui/opportunity-edit-modals.mjs +37 -0
- package/dist/components/ui/opportunity-summary-tab.js +4365 -0
- package/dist/components/ui/opportunity-summary-tab.mjs +34 -0
- package/dist/components/ui/pagination.js +35 -3
- package/dist/components/ui/pagination.mjs +3 -3
- package/dist/components/ui/pipeline-alerts.js +103 -0
- package/dist/components/ui/pipeline-alerts.mjs +8 -0
- package/dist/components/ui/pipeline-board.js +1408 -0
- package/dist/components/ui/pipeline-board.mjs +24 -0
- package/dist/components/ui/pipeline-chart.js +216 -0
- package/dist/components/ui/pipeline-chart.mjs +10 -0
- package/dist/components/ui/pipeline-dialogs.js +1183 -0
- package/dist/components/ui/pipeline-dialogs.mjs +23 -0
- package/dist/components/ui/pipeline-primitives.js +300 -0
- package/dist/components/ui/pipeline-primitives.mjs +11 -0
- package/dist/components/ui/popover.js +45 -4
- package/dist/components/ui/popover.mjs +3 -3
- package/dist/components/ui/progress.js +33 -1
- package/dist/components/ui/progress.mjs +2 -2
- package/dist/components/ui/property-cashflow-doughnut-chart.js +523 -0
- package/dist/components/ui/property-cashflow-doughnut-chart.mjs +16 -0
- package/dist/components/ui/property-debt-equity-doughnut-chart.js +521 -0
- package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +16 -0
- package/dist/components/ui/property-mobile-estimate-line-chart.js +683 -0
- package/dist/components/ui/property-mobile-estimate-line-chart.mjs +16 -0
- package/dist/components/ui/radio-group.js +33 -1
- package/dist/components/ui/radio-group.mjs +2 -2
- package/dist/components/ui/select.js +66 -26
- package/dist/components/ui/select.mjs +3 -3
- package/dist/components/ui/separator.js +33 -1
- package/dist/components/ui/separator.mjs +2 -2
- package/dist/components/ui/sheet.js +37 -9
- package/dist/components/ui/sheet.mjs +3 -3
- package/dist/components/ui/skeleton.js +33 -1
- package/dist/components/ui/skeleton.mjs +2 -2
- package/dist/components/ui/slider.js +86 -102
- package/dist/components/ui/slider.mjs +2 -2
- package/dist/components/ui/spinner.js +33 -1
- package/dist/components/ui/spinner.mjs +2 -2
- package/dist/components/ui/stage-timeline.js +579 -0
- package/dist/components/ui/stage-timeline.mjs +15 -0
- package/dist/components/ui/switch.js +37 -4
- package/dist/components/ui/switch.mjs +2 -3
- package/dist/components/ui/table.js +37 -5
- package/dist/components/ui/table.mjs +2 -2
- package/dist/components/ui/tabs.js +36 -12
- package/dist/components/ui/tabs.mjs +2 -2
- package/dist/components/ui/textarea.js +34 -2
- package/dist/components/ui/textarea.mjs +2 -2
- package/dist/components/ui/toggle-group.js +35 -4
- package/dist/components/ui/toggle-group.mjs +3 -4
- package/dist/components/ui/toggle.js +35 -4
- package/dist/components/ui/toggle.mjs +2 -3
- package/dist/components/ui/tooltip.js +51 -22
- package/dist/components/ui/tooltip.mjs +3 -3
- package/dist/components/ui/transactions-expense-categories-doughnut-chart.js +528 -0
- package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +16 -0
- package/dist/components/ui/transactions-income-expense-bar-chart.js +77 -39
- package/dist/components/ui/transactions-income-expense-bar-chart.mjs +8 -8
- package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.js +528 -0
- package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +16 -0
- package/dist/index.js +11620 -3832
- package/dist/index.mjs +333 -161
- package/dist/lib/theme-provider.js +10 -1
- package/dist/lib/theme-provider.mjs +1 -1
- package/dist/lib/typography.js +8 -0
- package/dist/lib/typography.mjs +3 -1
- package/dist/lib/utils.js +33 -1
- package/dist/lib/utils.mjs +1 -1
- package/dist/styles.css +1 -1
- package/package.json +140 -5
- package/src/components/index.tsx +296 -42
- package/src/components/ui/accordion.tsx +6 -3
- package/src/components/ui/add-column-modal.tsx +339 -0
- package/src/components/ui/add-lead-modal.tsx +290 -0
- package/src/components/ui/ai-assistant-drawer.tsx +408 -0
- package/src/components/ui/alert-dialog.tsx +80 -54
- package/src/components/ui/alert.tsx +28 -28
- package/src/components/ui/avatar.tsx +30 -29
- package/src/components/ui/backoffice-alert-history-chart.tsx +261 -0
- package/src/components/ui/backoffice-contact-history-chart.tsx +326 -0
- package/src/components/ui/badge.tsx +17 -15
- package/src/components/ui/borrowing-capacity-line-chart.tsx +359 -0
- package/src/components/ui/button.tsx +30 -27
- package/src/components/ui/calendar.tsx +53 -67
- package/src/components/ui/card.tsx +27 -24
- package/src/components/ui/cash-balance-line-chart.tsx +304 -0
- package/src/components/ui/cashflow-bar-chart.tsx +106 -78
- package/src/components/ui/chart-shared.tsx +176 -15
- package/src/components/ui/checkbox.tsx +30 -26
- package/src/components/ui/combobox.tsx +78 -72
- package/src/components/ui/data-table.tsx +160 -99
- package/src/components/ui/date-picker.tsx +0 -2
- package/src/components/ui/dialog.tsx +70 -60
- package/src/components/ui/drawer.tsx +57 -48
- package/src/components/ui/dropdown-menu.tsx +90 -82
- package/src/components/ui/empty.tsx +31 -27
- package/src/components/ui/expense-bar-chart.tsx +85 -66
- package/src/components/ui/field.tsx +70 -62
- package/src/components/ui/financial-cards.tsx +830 -0
- package/src/components/ui/financial-drawers.tsx +339 -0
- package/src/components/ui/financial-primitives.tsx +331 -0
- package/src/components/ui/financial-sections.tsx +672 -0
- package/src/components/ui/form-primitives.tsx +536 -0
- package/src/components/ui/income-bar-chart.tsx +81 -61
- package/src/components/ui/input-group.tsx +41 -34
- package/src/components/ui/input-otp.tsx +29 -24
- package/src/components/ui/input.tsx +8 -8
- package/src/components/ui/kanban-column.tsx +333 -0
- package/src/components/ui/label.tsx +9 -12
- package/src/components/ui/opportunity-card.tsx +616 -0
- package/src/components/ui/opportunity-edit-modals.tsx +2528 -0
- package/src/components/ui/opportunity-summary-tab.tsx +579 -0
- package/src/components/ui/pipeline-alerts.tsx +74 -0
- package/src/components/ui/pipeline-board.tsx +268 -0
- package/src/components/ui/pipeline-chart.tsx +173 -0
- package/src/components/ui/pipeline-dialogs.tsx +303 -0
- package/src/components/ui/pipeline-primitives.tsx +108 -0
- package/src/components/ui/popover.tsx +41 -36
- package/src/components/ui/property-cashflow-doughnut-chart.tsx +189 -0
- package/src/components/ui/property-debt-equity-doughnut-chart.tsx +186 -0
- package/src/components/ui/property-mobile-estimate-line-chart.tsx +395 -0
- package/src/components/ui/select.tsx +65 -52
- package/src/components/ui/sheet.tsx +55 -52
- package/src/components/ui/slider.tsx +54 -77
- package/src/components/ui/stage-timeline.tsx +205 -0
- package/src/components/ui/switch.tsx +42 -29
- package/src/components/ui/table.tsx +28 -28
- package/src/components/ui/tabs.tsx +22 -28
- package/src/components/ui/textarea.tsx +8 -8
- package/src/components/ui/toggle-group.tsx +0 -2
- package/src/components/ui/toggle.tsx +13 -15
- package/src/components/ui/tooltip.tsx +30 -28
- package/src/components/ui/transactions-expense-categories-doughnut-chart.tsx +192 -0
- package/src/components/ui/transactions-income-expense-bar-chart.tsx +47 -39
- package/src/components/ui/transactions-liabilities-breakdown-doughnut-chart.tsx +192 -0
- package/src/lib/theme-provider.tsx +10 -0
- package/src/lib/typography.ts +9 -0
- package/src/lib/utils.ts +41 -3
- package/src/styles/globals.css +371 -124
- package/src/styles/styles-css.ts +1 -1
- package/tsup.config.ts +27 -0
- package/dist/chunk-3EQP72AW.mjs +0 -58
- package/dist/chunk-K74JRTJR.mjs +0 -105
- 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_SECONDARY,
|
|
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
|
|
@@ -82,11 +84,6 @@ export interface ExpenseBarChartProps {
|
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
// ---------------------------------------------------------------------------
|
|
85
|
-
// Constants
|
|
86
|
-
// ---------------------------------------------------------------------------
|
|
87
|
-
|
|
88
|
-
const FALLBACK_SECONDARY = "#162029";
|
|
89
|
-
|
|
90
87
|
// ---------------------------------------------------------------------------
|
|
91
88
|
// Component
|
|
92
89
|
// ---------------------------------------------------------------------------
|
|
@@ -112,17 +109,27 @@ export function ExpenseBarChart({
|
|
|
112
109
|
// (defaultPeriod handles the initial value).
|
|
113
110
|
const isFirstRender = useRef(true);
|
|
114
111
|
useEffect(() => {
|
|
115
|
-
if (isFirstRender.current) {
|
|
112
|
+
if (isFirstRender.current) {
|
|
113
|
+
isFirstRender.current = false;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
116
|
setPeriod(CHART_PERIODS[granularity][0]);
|
|
117
117
|
}, [granularity]);
|
|
118
118
|
|
|
119
119
|
const themeVars = useThemeVars();
|
|
120
120
|
const brandSecondary: string =
|
|
121
|
-
(themeVars["--theme-secondary"] as string | undefined) ||
|
|
121
|
+
(themeVars["--theme-secondary"] as string | undefined) ||
|
|
122
|
+
FALLBACK_SECONDARY;
|
|
123
|
+
const fontFamily: string =
|
|
124
|
+
(themeVars["--font-sans"] as string | undefined) || "Figtree, sans-serif";
|
|
122
125
|
|
|
123
126
|
const sliced = useMemo<ExpenseBarChartData | null>(() => {
|
|
124
|
-
if (!expenseData?.months?.length || !expenseData.datasets.length)
|
|
125
|
-
|
|
127
|
+
if (!expenseData?.months?.length || !expenseData.datasets.length)
|
|
128
|
+
return null;
|
|
129
|
+
const count = Math.min(
|
|
130
|
+
CHART_SLICE_COUNT[granularity][period],
|
|
131
|
+
expenseData.months.length,
|
|
132
|
+
);
|
|
126
133
|
const start = expenseData.months.length - count;
|
|
127
134
|
return {
|
|
128
135
|
months: expenseData.months.slice(start),
|
|
@@ -135,10 +142,11 @@ export function ExpenseBarChart({
|
|
|
135
142
|
}, [expenseData, period, granularity]);
|
|
136
143
|
|
|
137
144
|
const datasetColors = useMemo(
|
|
138
|
-
() =>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
145
|
+
() =>
|
|
146
|
+
sliced?.datasets.map((_, i) =>
|
|
147
|
+
hexToRgba(brandSecondary, DATASET_ALPHAS[i % DATASET_ALPHAS.length]),
|
|
148
|
+
) ?? [],
|
|
149
|
+
[sliced, brandSecondary],
|
|
142
150
|
);
|
|
143
151
|
|
|
144
152
|
const chartData = useMemo<ChartData<"bar">>(() => {
|
|
@@ -151,7 +159,7 @@ export function ExpenseBarChart({
|
|
|
151
159
|
backgroundColor: datasetColors[i],
|
|
152
160
|
hoverBackgroundColor: hexToRgba(
|
|
153
161
|
brandSecondary,
|
|
154
|
-
Math.min(DATASET_ALPHAS[i % DATASET_ALPHAS.length] + 0.15, 1)
|
|
162
|
+
Math.min(DATASET_ALPHAS[i % DATASET_ALPHAS.length] + 0.15, 1),
|
|
155
163
|
),
|
|
156
164
|
borderWidth: 0,
|
|
157
165
|
borderRadius: 0,
|
|
@@ -163,64 +171,67 @@ export function ExpenseBarChart({
|
|
|
163
171
|
};
|
|
164
172
|
}, [sliced, datasetColors, brandSecondary]);
|
|
165
173
|
|
|
166
|
-
const options = useMemo<ChartOptions<"bar">>(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
174
|
+
const options = useMemo<ChartOptions<"bar">>(
|
|
175
|
+
() => ({
|
|
176
|
+
responsive: true,
|
|
177
|
+
maintainAspectRatio: false,
|
|
178
|
+
animation: { duration: 800, easing: "easeOutQuart" },
|
|
179
|
+
layout: { padding: 0 },
|
|
180
|
+
plugins: {
|
|
181
|
+
legend: { display: false },
|
|
182
|
+
tooltip: {
|
|
183
|
+
mode: "index",
|
|
184
|
+
intersect: false,
|
|
185
|
+
padding: 12,
|
|
186
|
+
cornerRadius: 0,
|
|
187
|
+
titleFont: { size: 11, weight: 600 },
|
|
188
|
+
bodyFont: { size: 12, weight: 500 },
|
|
189
|
+
callbacks: {
|
|
190
|
+
title: (tooltipItems) => {
|
|
191
|
+
const idx = tooltipItems[0]?.dataIndex;
|
|
192
|
+
if (idx != null && sliced?.dates?.[idx]) {
|
|
193
|
+
return formatTooltipDate(sliced.dates[idx], granularity);
|
|
194
|
+
}
|
|
195
|
+
return tooltipItems[0]?.label ?? "";
|
|
196
|
+
},
|
|
197
|
+
label: (ctx) => {
|
|
198
|
+
const val = ctx.raw as number;
|
|
199
|
+
if (val === 0) return;
|
|
200
|
+
return ` ${ctx.dataset.label}: $${val.toLocaleString()}`;
|
|
201
|
+
},
|
|
192
202
|
},
|
|
193
203
|
},
|
|
194
204
|
},
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
205
|
+
scales: {
|
|
206
|
+
x: {
|
|
207
|
+
display: showXAxis,
|
|
208
|
+
stacked: true,
|
|
209
|
+
grid: { display: false },
|
|
210
|
+
border: { display: false },
|
|
211
|
+
ticks: { font: { size: 10 }, color: FALLBACK_TICK },
|
|
212
|
+
},
|
|
213
|
+
y: {
|
|
214
|
+
display: showYAxis,
|
|
215
|
+
stacked: true,
|
|
216
|
+
grid: { display: false },
|
|
217
|
+
border: { display: false },
|
|
218
|
+
ticks: {
|
|
219
|
+
font: { size: 10 },
|
|
220
|
+
color: FALLBACK_TICK,
|
|
221
|
+
maxTicksLimit: 5,
|
|
222
|
+
padding: 8,
|
|
223
|
+
callback: (v) => `$${Number(v).toLocaleString()}`,
|
|
224
|
+
},
|
|
215
225
|
},
|
|
216
226
|
},
|
|
217
|
-
},
|
|
218
|
-
|
|
227
|
+
}),
|
|
228
|
+
[showXAxis, showYAxis, sliced, granularity],
|
|
229
|
+
);
|
|
219
230
|
|
|
220
231
|
return (
|
|
221
232
|
<Card
|
|
222
233
|
className={cn("w-full py-4 sm:py-6 gap-2", className)}
|
|
223
|
-
style={{ maxWidth: width }}
|
|
234
|
+
style={{ maxWidth: width, fontFamily }}
|
|
224
235
|
>
|
|
225
236
|
<CardHeader className="px-3 sm:px-6">
|
|
226
237
|
<CardTitle className="text-sm sm:text-base">{title}</CardTitle>
|
|
@@ -250,7 +261,11 @@ export function ExpenseBarChart({
|
|
|
250
261
|
{showLegend && legendPosition === "top" && (
|
|
251
262
|
<div className="flex flex-wrap gap-x-3 gap-y-1.5 pb-2">
|
|
252
263
|
{sliced.datasets.map((ds, i) => (
|
|
253
|
-
<ChartLegendItem
|
|
264
|
+
<ChartLegendItem
|
|
265
|
+
key={ds.label}
|
|
266
|
+
label={ds.label}
|
|
267
|
+
color={datasetColors[i]}
|
|
268
|
+
/>
|
|
254
269
|
))}
|
|
255
270
|
</div>
|
|
256
271
|
)}
|
|
@@ -266,7 +281,11 @@ export function ExpenseBarChart({
|
|
|
266
281
|
{showLegend && legendPosition === "bottom" && (
|
|
267
282
|
<div className="flex flex-wrap gap-x-3 gap-y-1.5 pt-2">
|
|
268
283
|
{sliced.datasets.map((ds, i) => (
|
|
269
|
-
<ChartLegendItem
|
|
284
|
+
<ChartLegendItem
|
|
285
|
+
key={ds.label}
|
|
286
|
+
label={ds.label}
|
|
287
|
+
color={datasetColors[i]}
|
|
288
|
+
/>
|
|
270
289
|
))}
|
|
271
290
|
</div>
|
|
272
291
|
)}
|
|
@@ -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"> & {
|
|
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
|
|
44
|
-
"data-[variant=legend]:text-
|
|
45
|
-
"data-[variant=label]:text-
|
|
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"> &
|
|
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({
|
|
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-
|
|
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({
|
|
167
|
+
function FieldDescription({
|
|
168
|
+
className,
|
|
169
|
+
...props
|
|
170
|
+
}: FieldDescriptionProps): ReactElement {
|
|
165
171
|
return (
|
|
166
172
|
<p
|
|
167
173
|
className={cn(
|
|
168
|
-
"text-
|
|
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-
|
|
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 ?
|
|
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>
|
|
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-
|
|
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
|
+
};
|