@mx-cartographer/experiences 9.0.10 → 9.0.12

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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [9.0.12] - 06-02-2026
2
+
3
+ - **FIXED** - Debts widget briefly displaying zero percent interest rates before account data finished loading
4
+
5
+ ## [9.0.11] - 06-01-2026
6
+
7
+ - **ADDED** - Spending chart accessibility description for screen readers
8
+
1
9
  ## [9.0.10] - 05-27-2026
2
10
 
3
11
  - **UPDATED** - Adds Tab indexes to the BubbleWeek component to make it accessable to screen readers.
@@ -0,0 +1,203 @@
1
+ import { g as D } from "./TransactionUtils-BphBJBbU.mjs";
2
+ import { C as p } from "./Category-DEKZGLYe.mjs";
3
+ import { jsxs as f, jsx as d } from "react/jsx-runtime";
4
+ import S from "react";
5
+ import { observer as N } from "mobx-react-lite";
6
+ import T from "@mui/material/Box";
7
+ import k from "@mui/material/Button";
8
+ import h from "@mui/material/Stack";
9
+ import { useTheme as A } from "@mui/material/styles";
10
+ import { CategoryIcon as M, CategoryIconVariants as G, Text as y, P as O } from "@mxenabled/mxui";
11
+ import { f as b } from "./NumberFormatting--XMeeBfr.mjs";
12
+ import { D as $ } from "./Donut-SzzfZDHF.mjs";
13
+ import { u as j } from "./useAriaLive-MkYebyUR.mjs";
14
+ import { u as v } from "./hooks-97sNJ_lf.mjs";
15
+ import { u as R } from "./useScreenSize-mWpmnh5w.mjs";
16
+ const _ = 5, V = (i, g, s, c) => c.reduce((o, n) => {
17
+ const a = i.find((u) => u.guid === n.category_guid);
18
+ if (!a) return o;
19
+ const t = a.parent_guid ?? a.guid, r = i.find((u) => u.guid === t);
20
+ if (!r || n.total <= 0) return o;
21
+ const m = {
22
+ guid: a.guid,
23
+ name: a.guid === t ? `${g.parent_category_totals_label_general} ${a.name}` : a.name,
24
+ color: D(r.guid, s),
25
+ amount: n.total
26
+ }, e = o.find((u) => u.guid === t);
27
+ return e ? (e.amount += n.total, e.categoryTotals?.push(m)) : o.push({
28
+ guid: t,
29
+ name: r.name,
30
+ color: D(r.guid, s),
31
+ categoryTotals: [m],
32
+ amount: n.total
33
+ }), o;
34
+ }, []), ot = (i, g, s, c) => {
35
+ const n = V(i, g, s, c).filter(
36
+ (e) => e.guid !== p.INCOME && e.guid !== p.INVESTMENTS && e.guid !== p.TRANSFER && e.amount > 0
37
+ ).sort((e, u) => u.amount - e.amount), a = n.reduce(
38
+ (e, u) => e + u.amount,
39
+ 0
40
+ ), t = n.length > _ ? _ : n.length, r = n.slice(0, t), m = r.map((e) => ({
41
+ id: e.guid,
42
+ color: D(e.guid, s),
43
+ label: e.name,
44
+ value: e.amount / a * 100
45
+ }));
46
+ if (n.length > 5) {
47
+ const e = n.slice(_), u = e.reduce(
48
+ (C, l) => C + l.amount,
49
+ 0
50
+ );
51
+ r.push({
52
+ guid: "other",
53
+ color: s.palette.categories.others || "",
54
+ name: g.saving_goal_other,
55
+ categoryTotals: e,
56
+ amount: u
57
+ }), m.push({
58
+ id: "other",
59
+ color: s.palette.categories.others || "",
60
+ label: g.saving_goal_other,
61
+ value: u / a * 100
62
+ });
63
+ }
64
+ return {
65
+ categoryData: r,
66
+ donutData: m,
67
+ totalAmount: a
68
+ };
69
+ }, nt = (i, g, s) => {
70
+ const c = i.filter(
71
+ (t) => t.guid === p.INCOME || t.parent_guid === p.INCOME
72
+ ), o = g.filter((t) => c.some((r) => r.guid === t.category_guid)).sort((t, r) => t.total - r.total).map((t, r) => ({
73
+ guid: t.category_guid,
74
+ name: i.find((m) => m.guid === t.category_guid)?.name,
75
+ color: s[r % s.length],
76
+ categoryTotals: [],
77
+ amount: Math.abs(t.total)
78
+ })), n = o.reduce(
79
+ (t, r) => t + r.amount,
80
+ 0
81
+ ), a = o.map((t) => ({
82
+ id: t.guid,
83
+ color: t.color,
84
+ label: t.name,
85
+ value: t.amount / n * 100
86
+ }));
87
+ return {
88
+ categoryData: o,
89
+ donutData: a,
90
+ totalAmount: n
91
+ };
92
+ }, B = ({
93
+ data: i,
94
+ isIncome: g = !1,
95
+ onSelected: s,
96
+ onViewTransactions: c,
97
+ selectedId: o,
98
+ size: n = 150,
99
+ totalLabel: a,
100
+ variant: t = "mini"
101
+ }) => {
102
+ const { spending: r } = v(), m = A(), { isTablet: e } = R(), { announce: u, ariaLive: C } = j(), l = S.useMemo(
103
+ () => o ? i.categoryData.find((x) => x.guid === o) : void 0,
104
+ [o]
105
+ );
106
+ S.useEffect(() => {
107
+ if (l) {
108
+ const x = b(l.amount, t === "mini" ? "0,0" : "0,0.00");
109
+ u(`${l.name}: ${x}`);
110
+ }
111
+ }, [l, u, t]);
112
+ const E = i.donutData.length > 0 ? i.donutData : [{ id: "0", color: m.palette.divider, value: 100 }], w = () => {
113
+ c?.(o);
114
+ }, I = e ? 32 : 48;
115
+ return /* @__PURE__ */ f(
116
+ T,
117
+ {
118
+ "aria-label": r.chart_description,
119
+ height: n,
120
+ position: "relative",
121
+ role: "group",
122
+ width: n,
123
+ children: [
124
+ C,
125
+ /* @__PURE__ */ d($, { data: E, onClick: s, selectedId: o, size: n, children: /* @__PURE__ */ d(h, { alignItems: "center", height: "100%", justifyContent: "center", width: "100%", children: /* @__PURE__ */ f(h, { alignItems: "center", justifyContent: "center", minHeight: n, minWidth: n, children: [
126
+ l && /* @__PURE__ */ f(
127
+ h,
128
+ {
129
+ alignItems: "center",
130
+ gap: t === "mini" ? 0 : 8,
131
+ mb: t === "mini" ? 0 : 8,
132
+ mt: t === "mini" ? 0 : -16,
133
+ sx: t === "mini" ? { gap: 0, mb: 0 } : { gap: { xs: 4, xl: 8 }, mb: { xs: 4, xl: 8 } },
134
+ children: [
135
+ /* @__PURE__ */ d(T, { "aria-hidden": "true", role: "presentation", children: /* @__PURE__ */ d(
136
+ M,
137
+ {
138
+ categoryGuid: g ? p.INCOME : l.guid,
139
+ size: t === "mini" ? 24 : I,
140
+ variant: G.Transparent
141
+ }
142
+ ) }),
143
+ /* @__PURE__ */ d(
144
+ y,
145
+ {
146
+ color: "text.secondary",
147
+ noWrap: !0,
148
+ variant: t === "mini" ? "tiny" : "body1",
149
+ children: l ? l.name : a
150
+ }
151
+ )
152
+ ]
153
+ }
154
+ ),
155
+ !l && t === "full" && /* @__PURE__ */ d(y, { bold: !0, color: "text.secondary", sx: { mb: { xs: 4, xl: 8 } }, children: a }),
156
+ /* @__PURE__ */ d(O, { variant: t === "mini" ? "h2" : "h1", children: l ? b(l.amount, t === "mini" ? "0,0" : "0,0.00") : b(i.totalAmount, t === "mini" ? "0,0" : "0,0.00") }),
157
+ !l && t === "mini" && /* @__PURE__ */ d(y, { color: "text.secondary", noWrap: !0, variant: "tiny", children: a }),
158
+ t === "full" && /* @__PURE__ */ d(
159
+ k,
160
+ {
161
+ "aria-label": `View ${l?.name || ""} Transactions`,
162
+ disabled: i.categoryData.length === 0,
163
+ onClick: w,
164
+ sx: { mt: { xl: 4, xs: 0 }, zIndex: 1 },
165
+ variant: "text",
166
+ children: r.view_transactions
167
+ }
168
+ )
169
+ ] }) }) })
170
+ ]
171
+ }
172
+ );
173
+ }, et = N(B), rt = ({ data: i, onSelected: g, selectedId: s }) => {
174
+ const c = (o, n) => {
175
+ (o.key === "Enter" || o.key === " ") && (o.preventDefault(), g(n));
176
+ };
177
+ return /* @__PURE__ */ d(h, { gap: 8, height: "100%", justifyContent: "center", my: "auto", children: i.categoryData.map((o) => /* @__PURE__ */ f(
178
+ h,
179
+ {
180
+ alignItems: "center",
181
+ "aria-label": o.name,
182
+ "aria-pressed": o.guid === s,
183
+ direction: "row",
184
+ gap: 8,
185
+ onClick: () => g(o.guid),
186
+ onKeyDown: (n) => c(n, o.guid),
187
+ role: "button",
188
+ sx: { cursor: "pointer", touchAction: "manipulation" },
189
+ tabIndex: 0,
190
+ children: [
191
+ /* @__PURE__ */ d(T, { borderRadius: 4, height: 8, sx: { backgroundColor: o.color }, width: 8 }),
192
+ /* @__PURE__ */ d(y, { bold: o.guid === s, variant: "caption", children: o.name })
193
+ ]
194
+ },
195
+ o.guid
196
+ )) });
197
+ };
198
+ export {
199
+ et as S,
200
+ nt as a,
201
+ rt as b,
202
+ ot as g
203
+ };
@@ -1,5 +1,6 @@
1
1
  export interface SpendingCopy {
2
2
  by_category: string;
3
+ chart_description: string;
3
4
  close_drawer_aria: string;
4
5
  income_tab_title: string;
5
6
  mini_title: string;
@@ -5,7 +5,7 @@ import y from "@mui/material/Stack";
5
5
  import { useTheme as j, Card as ge, Stack as u, Box as W } from "@mui/material";
6
6
  import { Text as i, P as xe, H3 as Be, InstitutionLogo as Pe, Icon as ne } from "@mxenabled/mxui";
7
7
  import { intervalToDuration as Re, formatDuration as Le } from "date-fns";
8
- import { s as Fe, D as F, t as $e, b as Oe } from "../DebtUtils-i4pI2Uoe.mjs";
8
+ import { s as Fe, D as $, t as $e, b as Oe } from "../DebtUtils-i4pI2Uoe.mjs";
9
9
  import { f as I, a as We } from "../NumberFormatting--XMeeBfr.mjs";
10
10
  import { f as J, D as Q } from "../DateFormats-HudZ3Bjs.mjs";
11
11
  import { G as Ge, q as ee, u as w, k as V, f as k, c as te, i as He, a as ze } from "../hooks-97sNJ_lf.mjs";
@@ -56,7 +56,7 @@ function ht(r, n, o = 0) {
56
56
  let m = !1;
57
57
  for (const [v, x] of t.entries()) {
58
58
  if (x.balance <= 0.01 || x.is_impossible) continue;
59
- const L = (x.interest_rate ?? 0) / 100 / 12, N = x.balance * L;
59
+ const F = (x.interest_rate ?? 0) / 100 / 12, N = x.balance * F;
60
60
  let A = x.monthly_payment ?? 0;
61
61
  v === 0 && o && (A += o), x.balance += N;
62
62
  const E = Math.min(x.balance, A + s);
@@ -525,10 +525,10 @@ const De = ({
525
525
  }), x = v.reduce(
526
526
  (p, g) => p + (g.dataset[0]?.y ?? 0),
527
527
  0
528
- ), $ = m.map((p, g) => {
528
+ ), L = m.map((p, g) => {
529
529
  const D = g / (m.length - 1), M = x * (1 - D);
530
530
  return { x: p, y: M };
531
- }), L = Math.ceil(x / 100) * 100, N = m, A = v.map((p, g) => {
531
+ }), F = Math.ceil(x / 100) * 100, N = m, A = v.map((p, g) => {
532
532
  const D = 1 - g / v.length * 0.5, M = gt(ft, D);
533
533
  return {
534
534
  id: `debt-${g}`,
@@ -546,7 +546,7 @@ const De = ({
546
546
  A.push({
547
547
  id: "payoff-line",
548
548
  label: "Payoff Line",
549
- data: $.map((p) => p.y),
549
+ data: L.map((p) => p.y),
550
550
  color: c.palette.grey[700],
551
551
  curve: "linear",
552
552
  type: "line",
@@ -632,7 +632,7 @@ const De = ({
632
632
  yAxis: [
633
633
  {
634
634
  min: 0,
635
- max: L,
635
+ max: F,
636
636
  disableTicks: !0,
637
637
  valueFormatter: (p) => I(p, "0a")
638
638
  }
@@ -1148,7 +1148,7 @@ const Wt = (r) => {
1148
1148
  minWidth: 122,
1149
1149
  flex: 0.6
1150
1150
  }
1151
- ], $ = [
1151
+ ], L = [
1152
1152
  ...x.slice(0, 3),
1153
1153
  {
1154
1154
  field: "chevron",
@@ -1162,7 +1162,7 @@ const Wt = (r) => {
1162
1162
  headerAlign: "right",
1163
1163
  width: 20
1164
1164
  }
1165
- ], L = f.useMemo(() => n.map((_, p) => ({
1165
+ ], F = f.useMemo(() => n.map((_, p) => ({
1166
1166
  ..._,
1167
1167
  id: p,
1168
1168
  priority: Ot(_)
@@ -1173,7 +1173,7 @@ const Wt = (r) => {
1173
1173
  c || N(_);
1174
1174
  }, E = (_) => {
1175
1175
  c && N(_);
1176
- }, Y = (_) => L.find((p) => p.guid === _)?.id;
1176
+ }, Y = (_) => F.find((p) => p.guid === _)?.id;
1177
1177
  return /* @__PURE__ */ e(
1178
1178
  le,
1179
1179
  {
@@ -1189,7 +1189,7 @@ const Wt = (r) => {
1189
1189
  children: /* @__PURE__ */ e(
1190
1190
  ot,
1191
1191
  {
1192
- columns: c ? $ : x,
1192
+ columns: c ? L : x,
1193
1193
  disableColumnFilter: !0,
1194
1194
  disableColumnMenu: !0,
1195
1195
  hideFooter: !0,
@@ -1200,7 +1200,7 @@ const Wt = (r) => {
1200
1200
  onSortModelChange: (_) => {
1201
1201
  v(_), d(S.DEBTS_CLICK_TABLE_SORT);
1202
1202
  },
1203
- rows: L,
1203
+ rows: F,
1204
1204
  slotProps: {
1205
1205
  baseIconButton: { color: "secondary", sx: { ml: 8 } },
1206
1206
  row: {
@@ -1259,19 +1259,19 @@ const Wt = (r) => {
1259
1259
  }, Vt = C(({ buttonEl: r, onClose: n }) => {
1260
1260
  const { onEvent: o } = k(), { debts: t } = w(), { selectedDebtPriority: a, setSelectedDebtPriority: s } = P(), d = !!r, c = [
1261
1261
  {
1262
- priority: F.FASTEST_PAYOFF_FIRST,
1262
+ priority: $.FASTEST_PAYOFF_FIRST,
1263
1263
  text: t.priority_sort_fastest_payoff
1264
1264
  },
1265
1265
  {
1266
- priority: F.HIGHEST_INTEREST,
1266
+ priority: $.HIGHEST_INTEREST,
1267
1267
  text: t.priority_sort_highest_interest
1268
1268
  },
1269
1269
  {
1270
- priority: F.LOWEST_BALANCE,
1270
+ priority: $.LOWEST_BALANCE,
1271
1271
  text: t.priority_sort_lowest_balance
1272
1272
  },
1273
1273
  {
1274
- priority: F.HIGHEST_BALANCE,
1274
+ priority: $.HIGHEST_BALANCE,
1275
1275
  text: t.priority_sort_highest_balance
1276
1276
  }
1277
1277
  ], b = (h) => {
@@ -1325,10 +1325,10 @@ const Wt = (r) => {
1325
1325
  }, b = () => {
1326
1326
  d(null);
1327
1327
  }, h = !!s, m = f.useMemo(() => ({
1328
- [F.FASTEST_PAYOFF_FIRST]: t.priority_sort_fastest_payoff,
1329
- [F.HIGHEST_INTEREST]: t.priority_sort_highest_interest,
1330
- [F.HIGHEST_BALANCE]: t.priority_sort_highest_balance,
1331
- [F.LOWEST_BALANCE]: t.priority_sort_lowest_balance
1328
+ [$.FASTEST_PAYOFF_FIRST]: t.priority_sort_fastest_payoff,
1329
+ [$.HIGHEST_INTEREST]: t.priority_sort_highest_interest,
1330
+ [$.HIGHEST_BALANCE]: t.priority_sort_highest_balance,
1331
+ [$.LOWEST_BALANCE]: t.priority_sort_lowest_balance
1332
1332
  })[a] ?? t.priority_sort_lowest_balance, [a]);
1333
1333
  return /* @__PURE__ */ l(u, { children: [
1334
1334
  /* @__PURE__ */ e(
@@ -1362,21 +1362,21 @@ const Wt = (r) => {
1362
1362
  const { isDesktop: t, isMobile: a } = ae(), { connect: s, debts: d } = w(), { onEvent: c } = k(), {
1363
1363
  config: { show_connections_widget_in_master: b }
1364
1364
  } = He(), { isInitialized: h } = ze(), { setSelectedAccount: m } = Ve(), { selectedDebtPriority: v, setSelectedDebtChartData: x } = P(), {
1365
- isAccountDataLoaded: $,
1366
- loadAccountData: L,
1365
+ isAccountDataLoaded: L,
1366
+ loadAccountData: F,
1367
1367
  detailedAccounts: N,
1368
1368
  visibleDebtAccounts: A
1369
1369
  } = te(), { isAllGoalDataLoaded: E, loadGoalData: Y, monthlyCashFlowProfile: _ } = V(), { debts: p } = ee(), [g, D] = f.useState(!1), [M, B] = f.useState(!1), [K, ce] = f.useState(!1), [U, Se] = f.useState(""), [Ae, de] = f.useState(!1);
1370
1370
  st({
1371
1371
  widgetName: "DebtsWidget",
1372
- isLoaded: E
1372
+ isLoaded: L && E
1373
1373
  });
1374
1374
  const q = f.useMemo(() => {
1375
1375
  const O = _?.extra_payment ?? 0;
1376
1376
  return $e(p, v, O);
1377
1377
  }, [p, v, _]);
1378
1378
  f.useEffect(() => {
1379
- $ || L().finally(), c(S.DEBTS_VIEW);
1379
+ L || F().finally(), c(S.DEBTS_VIEW);
1380
1380
  }, []), f.useEffect(() => {
1381
1381
  h && Y().finally();
1382
1382
  }, [h]);
@@ -1388,7 +1388,7 @@ const Wt = (r) => {
1388
1388
  }, Ie = () => {
1389
1389
  B(!0), c(S.DEBTS_CLICK_PAYDOWN);
1390
1390
  };
1391
- if (!h || !E)
1391
+ if (!h || !L || !E)
1392
1392
  return /* @__PURE__ */ e(ct, {});
1393
1393
  const Me = N.length === 0, ke = A.length === 0, Ne = p.length === 0, X = Me || ke || Ne, Z = Oe(
1394
1394
  d,
@@ -58,7 +58,7 @@ import { ChartsXAxis as Qn } from "@mui/x-charts/ChartsXAxis";
58
58
  import { ChartsYAxis as Zn } from "@mui/x-charts/ChartsYAxis";
59
59
  import { startOfMonth as It } from "date-fns/startOfMonth";
60
60
  import { endOfMonth as At } from "date-fns/endOfMonth";
61
- import { g as Jn, S as eo, b as to } from "../SpendingLegend-Bn3DzGyK.mjs";
61
+ import { g as Jn, S as eo, b as to } from "../SpendingLegend-CxvNOg3c.mjs";
62
62
  import { formatISO as no } from "date-fns/formatISO";
63
63
  import { fromUnixTime as oo } from "date-fns/fromUnixTime";
64
64
  import { subDays as ro } from "date-fns/subDays";
@@ -8,7 +8,7 @@ import y from "@mui/material/Stack";
8
8
  import $ from "@mui/material/Tab";
9
9
  import rt from "@mui/material/Tabs";
10
10
  import { useTheme as _t } from "@mui/material/styles";
11
- import { g as st, a as lt, S as B, b as q } from "../SpendingLegend-Bn3DzGyK.mjs";
11
+ import { g as st, a as lt, S as B, b as q } from "../SpendingLegend-CxvNOg3c.mjs";
12
12
  import { Text as T, Icon as bt } from "@mxenabled/mxui";
13
13
  import { f as k } from "../NumberFormatting--XMeeBfr.mjs";
14
14
  import { u as A, l as R, c as ct, a as P, i as H, g as dt, f as yt } from "../hooks-97sNJ_lf.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mx-cartographer/experiences",
3
- "version": "9.0.10",
3
+ "version": "9.0.12",
4
4
  "description": "Library containing experience widgets",
5
5
  "author": "MX",
6
6
  "license": "MIT",
@@ -1,193 +0,0 @@
1
- import { g as _ } from "./TransactionUtils-BphBJBbU.mjs";
2
- import { C as p } from "./Category-DEKZGLYe.mjs";
3
- import { jsxs as f, Fragment as N, jsx as d } from "react/jsx-runtime";
4
- import T from "react";
5
- import { observer as k } from "mobx-react-lite";
6
- import S from "@mui/material/Box";
7
- import A from "@mui/material/Button";
8
- import h from "@mui/material/Stack";
9
- import { useTheme as M } from "@mui/material/styles";
10
- import { CategoryIcon as G, CategoryIconVariants as O, Text as y, P as $ } from "@mxenabled/mxui";
11
- import { f as b } from "./NumberFormatting--XMeeBfr.mjs";
12
- import { D as j } from "./Donut-SzzfZDHF.mjs";
13
- import { u as R } from "./useAriaLive-MkYebyUR.mjs";
14
- import { u as v } from "./hooks-97sNJ_lf.mjs";
15
- import { u as V } from "./useScreenSize-mWpmnh5w.mjs";
16
- const D = 5, B = (i, l, s, m) => m.reduce((o, n) => {
17
- const r = i.find((u) => u.guid === n.category_guid);
18
- if (!r) return o;
19
- const t = r.parent_guid ?? r.guid, a = i.find((u) => u.guid === t);
20
- if (!a || n.total <= 0) return o;
21
- const c = {
22
- guid: r.guid,
23
- name: r.guid === t ? `${l.parent_category_totals_label_general} ${r.name}` : r.name,
24
- color: _(a.guid, s),
25
- amount: n.total
26
- }, e = o.find((u) => u.guid === t);
27
- return e ? (e.amount += n.total, e.categoryTotals?.push(c)) : o.push({
28
- guid: t,
29
- name: a.name,
30
- color: _(a.guid, s),
31
- categoryTotals: [c],
32
- amount: n.total
33
- }), o;
34
- }, []), nt = (i, l, s, m) => {
35
- const n = B(i, l, s, m).filter(
36
- (e) => e.guid !== p.INCOME && e.guid !== p.INVESTMENTS && e.guid !== p.TRANSFER && e.amount > 0
37
- ).sort((e, u) => u.amount - e.amount), r = n.reduce(
38
- (e, u) => e + u.amount,
39
- 0
40
- ), t = n.length > D ? D : n.length, a = n.slice(0, t), c = a.map((e) => ({
41
- id: e.guid,
42
- color: _(e.guid, s),
43
- label: e.name,
44
- value: e.amount / r * 100
45
- }));
46
- if (n.length > 5) {
47
- const e = n.slice(D), u = e.reduce(
48
- (C, g) => C + g.amount,
49
- 0
50
- );
51
- a.push({
52
- guid: "other",
53
- color: s.palette.categories.others || "",
54
- name: l.saving_goal_other,
55
- categoryTotals: e,
56
- amount: u
57
- }), c.push({
58
- id: "other",
59
- color: s.palette.categories.others || "",
60
- label: l.saving_goal_other,
61
- value: u / r * 100
62
- });
63
- }
64
- return {
65
- categoryData: a,
66
- donutData: c,
67
- totalAmount: r
68
- };
69
- }, et = (i, l, s) => {
70
- const m = i.filter(
71
- (t) => t.guid === p.INCOME || t.parent_guid === p.INCOME
72
- ), o = l.filter((t) => m.some((a) => a.guid === t.category_guid)).sort((t, a) => t.total - a.total).map((t, a) => ({
73
- guid: t.category_guid,
74
- name: i.find((c) => c.guid === t.category_guid)?.name,
75
- color: s[a % s.length],
76
- categoryTotals: [],
77
- amount: Math.abs(t.total)
78
- })), n = o.reduce(
79
- (t, a) => t + a.amount,
80
- 0
81
- ), r = o.map((t) => ({
82
- id: t.guid,
83
- color: t.color,
84
- label: t.name,
85
- value: t.amount / n * 100
86
- }));
87
- return {
88
- categoryData: o,
89
- donutData: r,
90
- totalAmount: n
91
- };
92
- }, P = ({
93
- data: i,
94
- isIncome: l = !1,
95
- onSelected: s,
96
- onViewTransactions: m,
97
- selectedId: o,
98
- size: n = 150,
99
- totalLabel: r,
100
- variant: t = "mini"
101
- }) => {
102
- const { spending: a } = v(), c = M(), { isTablet: e } = V(), { announce: u, ariaLive: C } = R(), g = T.useMemo(
103
- () => o ? i.categoryData.find((x) => x.guid === o) : void 0,
104
- [o]
105
- );
106
- T.useEffect(() => {
107
- if (g) {
108
- const x = b(g.amount, t === "mini" ? "0,0" : "0,0.00");
109
- u(`${g.name}: ${x}`);
110
- }
111
- }, [g, u, t]);
112
- const E = i.donutData.length > 0 ? i.donutData : [{ id: "0", color: c.palette.divider, value: 100 }], I = () => {
113
- m?.(o);
114
- }, w = e ? 32 : 48;
115
- return /* @__PURE__ */ f(N, { children: [
116
- C,
117
- /* @__PURE__ */ d(j, { data: E, onClick: s, selectedId: o, size: n, children: /* @__PURE__ */ d(h, { alignItems: "center", height: "100%", justifyContent: "center", width: "100%", children: /* @__PURE__ */ f(h, { alignItems: "center", justifyContent: "center", minHeight: n, minWidth: n, children: [
118
- g && /* @__PURE__ */ f(
119
- h,
120
- {
121
- alignItems: "center",
122
- gap: t === "mini" ? 0 : 8,
123
- mb: t === "mini" ? 0 : 8,
124
- mt: t === "mini" ? 0 : -16,
125
- sx: t === "mini" ? { gap: 0, mb: 0 } : { gap: { xs: 4, xl: 8 }, mb: { xs: 4, xl: 8 } },
126
- children: [
127
- /* @__PURE__ */ d(S, { "aria-hidden": "true", role: "presentation", children: /* @__PURE__ */ d(
128
- G,
129
- {
130
- categoryGuid: l ? p.INCOME : g.guid,
131
- size: t === "mini" ? 24 : w,
132
- variant: O.Transparent
133
- }
134
- ) }),
135
- /* @__PURE__ */ d(
136
- y,
137
- {
138
- color: "text.secondary",
139
- noWrap: !0,
140
- variant: t === "mini" ? "tiny" : "body1",
141
- children: g ? g.name : r
142
- }
143
- )
144
- ]
145
- }
146
- ),
147
- !g && t === "full" && /* @__PURE__ */ d(y, { bold: !0, color: "text.secondary", sx: { mb: { xs: 4, xl: 8 } }, children: r }),
148
- /* @__PURE__ */ d($, { variant: t === "mini" ? "h2" : "h1", children: g ? b(g.amount, t === "mini" ? "0,0" : "0,0.00") : b(i.totalAmount, t === "mini" ? "0,0" : "0,0.00") }),
149
- !g && t === "mini" && /* @__PURE__ */ d(y, { color: "text.secondary", noWrap: !0, variant: "tiny", children: r }),
150
- t === "full" && /* @__PURE__ */ d(
151
- A,
152
- {
153
- "aria-label": `View ${g?.name || ""} Transactions`,
154
- disabled: i.categoryData.length === 0,
155
- onClick: I,
156
- sx: { mt: { xl: 4, xs: 0 }, zIndex: 1 },
157
- variant: "text",
158
- children: a.view_transactions
159
- }
160
- )
161
- ] }) }) })
162
- ] });
163
- }, at = k(P), rt = ({ data: i, onSelected: l, selectedId: s }) => {
164
- const m = (o, n) => {
165
- (o.key === "Enter" || o.key === " ") && (o.preventDefault(), l(n));
166
- };
167
- return /* @__PURE__ */ d(h, { gap: 8, height: "100%", justifyContent: "center", my: "auto", children: i.categoryData.map((o) => /* @__PURE__ */ f(
168
- h,
169
- {
170
- alignItems: "center",
171
- "aria-label": o.name,
172
- "aria-pressed": o.guid === s,
173
- direction: "row",
174
- gap: 8,
175
- onClick: () => l(o.guid),
176
- onKeyDown: (n) => m(n, o.guid),
177
- role: "button",
178
- sx: { cursor: "pointer", touchAction: "manipulation" },
179
- tabIndex: 0,
180
- children: [
181
- /* @__PURE__ */ d(S, { borderRadius: 4, height: 8, sx: { backgroundColor: o.color }, width: 8 }),
182
- /* @__PURE__ */ d(y, { bold: o.guid === s, variant: "caption", children: o.name })
183
- ]
184
- },
185
- o.guid
186
- )) });
187
- };
188
- export {
189
- at as S,
190
- et as a,
191
- rt as b,
192
- nt as g
193
- };