@object-ui/plugin-tree 17.1.0 → 17.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,151 @@
1
1
  # @object-ui/plugin-tree
2
2
 
3
+ ## 17.3.0
4
+
5
+ ### Patch Changes
6
+
7
+ - aa36e60: Localize the record-detail headings that `ObjectKanban`, `ObjectTree` and
8
+ `ObjectView` build themselves (objectui#3459)
9
+
10
+ #3426 / PR #3457 keyed `ListView` and `ObjectGrid`; a repo-wide grep found the
11
+ same pattern in three more hosts, each string-building an English heading in
12
+ TypeScript so the surrounding drawer/panel was fully localized with one English
13
+ phrase on top of it.
14
+
15
+ - `packages/plugin-kanban/src/ObjectKanban.tsx` — the object-derived heading of
16
+ the card-detail drawer
17
+ - `packages/plugin-tree/src/ObjectTree.tsx` — the bare literal
18
+ `"Record Details"` handed to `NavigationOverlay`
19
+ - `packages/plugin-view/src/ObjectView.tsx` — `` `${objectLabel} Detail` `` on
20
+ the `mode: 'split'` panel
21
+
22
+ All three are user-reachable, each verified by a test that drives the real
23
+ interaction (render the block, click a card/row, read the heading), not by
24
+ inspection:
25
+
26
+ - `object-kanban` is a public page block whose `navigation` config DEFAULTS to
27
+ `{ mode: 'drawer' }`, so a board needs no authoring at all to open this
28
+ drawer on card click;
29
+ - `object-tree` needs `navigation: { mode: 'drawer' }` authored explicitly, and
30
+ every row's click is wired to `navigation.handleClick`;
31
+ - `object-view` declares `navigation` as an authorable input and maps
32
+ `mode: 'split'` onto the branch that renders this heading.
33
+
34
+ ## What changed
35
+
36
+ Each call site now keys its heading through the existing `detail.*` pair —
37
+ `detail.recordDetailWithLabel` (`'{{label}} Detail'`) where an object label is
38
+ available, `detail.recordDetail` where none is. No new locale keys: both
39
+ already ship in all ten packs from #3457, and reusing them keeps one heading on
40
+ one control instead of minting per-plugin twins that drift.
41
+
42
+ Each plugin gains its own English defaults map, which is what
43
+ `createSafeTranslation` falls back to with no `I18nProvider` mounted;
44
+ `@object-ui/plugin-tree` gains a dependency on `@object-ui/i18n` for it.
45
+
46
+ ## Visible English change
47
+
48
+ One, deliberate: the tree overlay's heading goes from the plural
49
+ `Record Details` to the singular `Record Detail` — the spelling the whole
50
+ `detail.*` family, including `NavigationOverlay`'s own default, already uses.
51
+ The maintainer ruled on normalizing the stray plurals rather than minting a
52
+ plural key; a repo-wide grep confirmed no `e2e/` spec and no unit test
53
+ addressed the old string.
54
+
55
+ Every other branch is byte-identical in English (`Contacts Detail`,
56
+ `Support cases Detail`, `Contacts Detail`), with and without a provider —
57
+ pinned by a provider-less test file per plugin, kept separate because
58
+ `initReactI18next` registers its instance as a module global that outlives
59
+ `cleanup()`.
60
+
61
+ The kanban's other former plural (`'Card Details'`) is NOT a visible change: it
62
+ sat on a branch that fires only when the board has no `objectName`, while the
63
+ drawer consuming it returns `null` on that very condition. It is keyed anyway
64
+ so the literal cannot leak if that guard ever relaxes, and it deliberately has
65
+ no test — an assertion there would pass because nothing renders.
66
+
67
+ - Updated dependencies [18cd432]
68
+ - Updated dependencies [532cf8b]
69
+ - Updated dependencies [680080a]
70
+ - Updated dependencies [a7651e6]
71
+ - Updated dependencies [d915c47]
72
+ - Updated dependencies [b71fc92]
73
+ - Updated dependencies [65516ba]
74
+ - Updated dependencies [94c5b7c]
75
+ - Updated dependencies [ca0fa8f]
76
+ - Updated dependencies [34595eb]
77
+ - Updated dependencies [3889ffb]
78
+ - Updated dependencies [5781fb1]
79
+ - Updated dependencies [7e2406a]
80
+ - Updated dependencies [9e9e9a9]
81
+ - Updated dependencies [56409c2]
82
+ - Updated dependencies [042e09d]
83
+ - Updated dependencies [9cbcbf4]
84
+ - Updated dependencies [85c4c9c]
85
+ - Updated dependencies [fd54c3e]
86
+ - Updated dependencies [4eeb932]
87
+ - Updated dependencies [5c856ec]
88
+ - Updated dependencies [23018cc]
89
+ - Updated dependencies [53811d1]
90
+ - Updated dependencies [68b6a28]
91
+ - Updated dependencies [0554e88]
92
+ - Updated dependencies [d915c47]
93
+ - Updated dependencies [f44d872]
94
+ - Updated dependencies [28b2e65]
95
+ - Updated dependencies [509104a]
96
+ - Updated dependencies [825bbe3]
97
+ - Updated dependencies [6195841]
98
+ - Updated dependencies [5dd0127]
99
+ - Updated dependencies [06632e9]
100
+ - Updated dependencies [a415684]
101
+ - Updated dependencies [a4cff5b]
102
+ - Updated dependencies [175bd79]
103
+ - Updated dependencies [5af2852]
104
+ - Updated dependencies [f833d3a]
105
+ - Updated dependencies [a6ec93d]
106
+ - Updated dependencies [2a9513d]
107
+ - Updated dependencies [71be406]
108
+ - Updated dependencies [d22ae31]
109
+ - Updated dependencies [c7ed4c3]
110
+ - Updated dependencies [2409e1d]
111
+ - Updated dependencies [789fe3e]
112
+ - Updated dependencies [8d8094a]
113
+ - @object-ui/core@17.3.0
114
+ - @object-ui/components@17.3.0
115
+ - @object-ui/types@17.3.0
116
+ - @object-ui/i18n@17.3.0
117
+ - @object-ui/react@17.3.0
118
+
119
+ ## 17.2.0
120
+
121
+ ### Patch Changes
122
+
123
+ - Updated dependencies [4ae0ac4]
124
+ - Updated dependencies [696e3c1]
125
+ - Updated dependencies [bca45cc]
126
+ - Updated dependencies [a889e31]
127
+ - Updated dependencies [09d30a4]
128
+ - Updated dependencies [4bf612c]
129
+ - Updated dependencies [335041c]
130
+ - Updated dependencies [b414983]
131
+ - Updated dependencies [256f8cc]
132
+ - Updated dependencies [d9668a7]
133
+ - Updated dependencies [cb82705]
134
+ - Updated dependencies [f572849]
135
+ - Updated dependencies [f6e8d78]
136
+ - Updated dependencies [ea96284]
137
+ - Updated dependencies [d3584c6]
138
+ - Updated dependencies [a8ad6c0]
139
+ - Updated dependencies [444457c]
140
+ - Updated dependencies [850033c]
141
+ - Updated dependencies [022e4c3]
142
+ - Updated dependencies [009e25d]
143
+ - Updated dependencies [726b89c]
144
+ - @object-ui/types@17.2.0
145
+ - @object-ui/components@17.2.0
146
+ - @object-ui/core@17.2.0
147
+ - @object-ui/react@17.2.0
148
+
3
149
  ## 17.1.0
4
150
 
5
151
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"ObjectTree.d.ts","sourceRoot":"","sources":["../src/ObjectTree.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,kBAAkB,CAAC;AAM7D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,sEAAsE;IACtE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6KD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAoQhD,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ObjectTree.d.ts","sourceRoot":"","sources":["../src/ObjectTree.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,kBAAkB,CAAC;AA+B7D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,sEAAsE;IACtE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6KD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgRhD,CAAC;AAEF,eAAe,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -2,10 +2,12 @@ import { useEffect as e, useMemo as t, useState as n } from "react";
2
2
  import { ComponentRegistry as r, buildExpandFields as i, columnIdentity as a, extractRecords as o } from "@object-ui/core";
3
3
  import { useNavigationOverlay as s, useSafeFieldLabel as c, useSchemaContext as l } from "@object-ui/react";
4
4
  import { NavigationOverlay as u, cn as d } from "@object-ui/components";
5
- import { ChevronDown as f, ChevronRight as p } from "lucide-react";
6
- import { jsx as m, jsxs as h } from "react/jsx-runtime";
5
+ import { createSafeTranslation as f } from "@object-ui/i18n";
6
+ import { ChevronDown as p, ChevronRight as m } from "lucide-react";
7
+ import { jsx as h, jsxs as g } from "react/jsx-runtime";
7
8
  //#region src/ObjectTree.tsx
8
- function g(e) {
9
+ var _ = f({ "detail.recordDetail": "Record Detail" }, "detail.recordDetail");
10
+ function v(e) {
9
11
  return e.data ? e.data : e.staticData ? {
10
12
  provider: "value",
11
13
  items: e.staticData
@@ -14,19 +16,19 @@ function g(e) {
14
16
  object: e.objectName
15
17
  } : null;
16
18
  }
17
- function _(e) {
19
+ function y(e) {
18
20
  return a(e) || (e && typeof e == "object" ? e.key : void 0) || void 0;
19
21
  }
20
- function v(e) {
22
+ function b(e) {
21
23
  let t = e.tree || e.filter?.tree || {}, n = Array.isArray(e.fields) ? e.fields : Array.isArray(t.fields) ? t.fields : [];
22
24
  return {
23
- parentField: _(e.parentField ?? t.parentField),
24
- labelField: _(e.labelField ?? t.labelField ?? e.titleField) ?? "name",
25
- fields: n.map(_).filter((e) => !!e),
25
+ parentField: y(e.parentField ?? t.parentField),
26
+ labelField: y(e.labelField ?? t.labelField ?? e.titleField) ?? "name",
27
+ fields: n.map(y).filter((e) => !!e),
26
28
  defaultExpandedDepth: e.defaultExpandedDepth ?? t.defaultExpandedDepth
27
29
  };
28
30
  }
29
- function y(e, t) {
31
+ function x(e, t) {
30
32
  let n = e?.fields;
31
33
  if (!n || typeof n != "object") return;
32
34
  let r;
@@ -37,11 +39,11 @@ function y(e, t) {
37
39
  }
38
40
  return r;
39
41
  }
40
- function b(e) {
42
+ function S(e) {
41
43
  let t = e?.id ?? e?._id;
42
44
  return t == null ? void 0 : String(t);
43
45
  }
44
- function x(e, t) {
46
+ function C(e, t) {
45
47
  if (!t) return;
46
48
  let n = e?.[t];
47
49
  if (n != null) {
@@ -52,10 +54,10 @@ function x(e, t) {
52
54
  return String(n);
53
55
  }
54
56
  }
55
- function S(e, t) {
57
+ function w(e, t) {
56
58
  let n = /* @__PURE__ */ new Map(), r = [];
57
59
  for (let t of e) {
58
- let e = b(t);
60
+ let e = S(t);
59
61
  e != null && (n.set(e, {
60
62
  id: e,
61
63
  record: t,
@@ -65,7 +67,7 @@ function S(e, t) {
65
67
  }
66
68
  let i = [];
67
69
  for (let e of r) {
68
- let r = n.get(e), a = x(r.record, t), o = a == null ? void 0 : n.get(a);
70
+ let r = n.get(e), a = C(r.record, t), o = a == null ? void 0 : n.get(a);
69
71
  o && o !== r ? o.children.push(r) : i.push(r);
70
72
  }
71
73
  let a = (e, t) => {
@@ -73,32 +75,32 @@ function S(e, t) {
73
75
  };
74
76
  return a(i, 0), i;
75
77
  }
76
- function C(e, t) {
78
+ function T(e, t) {
77
79
  let n = [], r = (e) => {
78
80
  for (let i of e) n.push(i), i.children.length > 0 && t.has(i.id) && r(i.children);
79
81
  };
80
82
  return r(e), n;
81
83
  }
82
- function w(e, t) {
84
+ function E(e, t) {
83
85
  let n = /* @__PURE__ */ new Set(), r = (e) => {
84
86
  for (let i of e) i.children.length !== 0 && (t == null || i.depth < t) && (n.add(i.id), r(i.children));
85
87
  };
86
88
  return r(e), n;
87
89
  }
88
- function T(e) {
90
+ function D(e) {
89
91
  return e == null ? "" : String(typeof e == "object" ? e.name ?? e.label ?? e.id ?? e._id ?? "" : e);
90
92
  }
91
- var E = ({ schema: r, dataSource: a, className: l, onRowClick: _, ...b }) => {
92
- let [x, E] = n([]), [D, O] = n(!0), [k, A] = n(null), [j, M] = n(null), N = t(() => g(r), [r]), P = Array.isArray(b.data) || Array.isArray(r.data) || N?.provider === "value";
93
+ var O = ({ schema: r, dataSource: a, className: l, onRowClick: f, ...y }) => {
94
+ let [S, C] = n([]), [O, k] = n(!0), [A, j] = n(null), [M, N] = n(null), P = t(() => v(r), [r]), F = Array.isArray(y.data) || Array.isArray(r.data) || P?.provider === "value";
93
95
  e(() => {
94
96
  let e = !1;
95
- return P || (async () => {
97
+ return F || (async () => {
96
98
  try {
97
99
  if (!a || typeof a.getObjectSchema != "function") return;
98
- let t = N?.provider === "object" ? N.object : r.objectName;
100
+ let t = P?.provider === "object" ? P.object : r.objectName;
99
101
  if (!t) return;
100
102
  let n = await a.getObjectSchema(t);
101
- e || M(n);
103
+ e || N(n);
102
104
  } catch (e) {
103
105
  console.error("[ObjectTree] Failed to fetch object schema:", e);
104
106
  }
@@ -108,142 +110,142 @@ var E = ({ schema: r, dataSource: a, className: l, onRowClick: _, ...b }) => {
108
110
  }, [
109
111
  r.objectName,
110
112
  a,
111
- N,
112
- P
113
+ P,
114
+ F
113
115
  ]), e(() => {
114
116
  let e = !1;
115
117
  return (async () => {
116
118
  try {
117
- if (O(!0), A(null), N?.provider === "object" && a && typeof a.find == "function") {
118
- let t = i(j?.fields), n = await a.find(N.object, {
119
+ if (k(!0), j(null), P?.provider === "object" && a && typeof a.find == "function") {
120
+ let t = i(M?.fields), n = await a.find(P.object, {
119
121
  $filter: r.filter,
120
122
  ...t.length > 0 ? { $expand: t } : {}
121
123
  });
122
- e || (E(o(n)), O(!1));
124
+ e || (C(o(n)), k(!1));
123
125
  return;
124
126
  }
125
- let t = b.data ?? r.data;
127
+ let t = y.data ?? r.data;
126
128
  if (Array.isArray(t)) {
127
- e || (E(t), O(!1));
129
+ e || (C(t), k(!1));
128
130
  return;
129
131
  }
130
- if (N?.provider === "value") {
131
- e || (E(N.items ?? []), O(!1));
132
+ if (P?.provider === "value") {
133
+ e || (C(P.items ?? []), k(!1));
132
134
  return;
133
135
  }
134
- e || (E([]), O(!1));
136
+ e || (C([]), k(!1));
135
137
  } catch (t) {
136
- e || (A(t), O(!1));
138
+ e || (j(t), k(!1));
137
139
  }
138
140
  })(), () => {
139
141
  e = !0;
140
142
  };
141
143
  }, [
142
- N,
144
+ P,
143
145
  a,
144
146
  r.filter,
145
- j,
146
- b.data
147
+ M,
148
+ y.data
147
149
  ]);
148
- let F = t(() => v(r), [r]), I = t(() => F.parentField ?? y(j, r.objectName), [
149
- F.parentField,
150
- j,
150
+ let I = t(() => b(r), [r]), L = t(() => I.parentField ?? x(M, r.objectName), [
151
+ I.parentField,
152
+ M,
151
153
  r.objectName
152
- ]), L = t(() => S(x, I), [x, I]), [R, z] = n(/* @__PURE__ */ new Set());
154
+ ]), R = t(() => w(S, L), [S, L]), [z, B] = n(/* @__PURE__ */ new Set());
153
155
  e(() => {
154
- z(w(L, F.defaultExpandedDepth));
155
- }, [L, F.defaultExpandedDepth]);
156
- let B = (e) => z((t) => {
156
+ B(E(R, I.defaultExpandedDepth));
157
+ }, [R, I.defaultExpandedDepth]);
158
+ let V = (e) => B((t) => {
157
159
  let n = new Set(t);
158
160
  return n.has(e) ? n.delete(e) : n.add(e), n;
159
- }), V = t(() => C(L, R), [L, R]), H = c(), U = (N?.provider === "object" ? N.object : void 0) ?? r.objectName, W = (e) => {
160
- let t = j?.fields?.[e]?.label || e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
161
- return U ? H.fieldLabel(U, e, t) : t;
162
- }, G = s({
161
+ }), H = t(() => T(R, z), [R, z]), U = c(), W = (P?.provider === "object" ? P.object : void 0) ?? r.objectName, G = (e) => {
162
+ let t = M?.fields?.[e]?.label || e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
163
+ return W ? U.fieldLabel(W, e, t) : t;
164
+ }, K = s({
163
165
  navigation: r.navigation,
164
166
  objectName: r.objectName,
165
- onRowClick: _
166
- });
167
- return k ? /* @__PURE__ */ m("div", {
167
+ onRowClick: f
168
+ }), { t: q } = _();
169
+ return A ? /* @__PURE__ */ h("div", {
168
170
  className: d("flex items-center justify-center h-40 text-destructive", l),
169
- children: /* @__PURE__ */ h("p", { children: ["Failed to load tree: ", k.message] })
170
- }) : D ? /* @__PURE__ */ m("div", {
171
+ children: /* @__PURE__ */ g("p", { children: ["Failed to load tree: ", A.message] })
172
+ }) : O ? /* @__PURE__ */ h("div", {
171
173
  className: d("flex items-center justify-center h-40 text-muted-foreground", l),
172
- children: /* @__PURE__ */ m("p", { children: "Loading…" })
173
- }) : x.length === 0 ? /* @__PURE__ */ m("div", {
174
+ children: /* @__PURE__ */ h("p", { children: "Loading…" })
175
+ }) : S.length === 0 ? /* @__PURE__ */ h("div", {
174
176
  className: d("flex items-center justify-center h-40 text-muted-foreground", l),
175
- children: /* @__PURE__ */ m("p", { children: "No records" })
176
- }) : /* @__PURE__ */ h("div", {
177
+ children: /* @__PURE__ */ h("p", { children: "No records" })
178
+ }) : /* @__PURE__ */ g("div", {
177
179
  className: d("w-full overflow-auto", l),
178
180
  "data-testid": "object-tree",
179
- children: [/* @__PURE__ */ h("table", {
181
+ children: [/* @__PURE__ */ g("table", {
180
182
  className: "w-full border-collapse text-sm",
181
- children: [/* @__PURE__ */ m("thead", { children: /* @__PURE__ */ h("tr", {
183
+ children: [/* @__PURE__ */ h("thead", { children: /* @__PURE__ */ g("tr", {
182
184
  className: "border-b text-left text-muted-foreground",
183
- children: [/* @__PURE__ */ m("th", {
185
+ children: [/* @__PURE__ */ h("th", {
184
186
  className: "px-3 py-2 font-medium",
185
- children: W(F.labelField)
186
- }), F.fields.filter((e) => e !== F.labelField).map((e) => /* @__PURE__ */ m("th", {
187
+ children: G(I.labelField)
188
+ }), I.fields.filter((e) => e !== I.labelField).map((e) => /* @__PURE__ */ h("th", {
187
189
  className: "px-3 py-2 font-medium",
188
- children: W(e)
190
+ children: G(e)
189
191
  }, e))]
190
- }) }), /* @__PURE__ */ m("tbody", { children: V.map((e) => {
191
- let t = e.children.length > 0, n = R.has(e.id);
192
- return /* @__PURE__ */ h("tr", {
192
+ }) }), /* @__PURE__ */ h("tbody", { children: H.map((e) => {
193
+ let t = e.children.length > 0, n = z.has(e.id);
194
+ return /* @__PURE__ */ g("tr", {
193
195
  className: "border-b hover:bg-accent/50 cursor-pointer",
194
196
  "data-testid": "object-tree-row",
195
197
  "data-depth": e.depth,
196
- onClick: (t) => G.handleClick(e.record, t),
197
- children: [/* @__PURE__ */ m("td", {
198
+ onClick: (t) => K.handleClick(e.record, t),
199
+ children: [/* @__PURE__ */ h("td", {
198
200
  className: "px-3 py-2",
199
- children: /* @__PURE__ */ h("div", {
201
+ children: /* @__PURE__ */ g("div", {
200
202
  className: "flex items-center gap-1",
201
203
  style: { paddingLeft: `${e.depth * 20}px` },
202
- children: [t ? /* @__PURE__ */ m("button", {
204
+ children: [t ? /* @__PURE__ */ h("button", {
203
205
  type: "button",
204
206
  "aria-label": n ? "Collapse" : "Expand",
205
207
  className: "flex h-5 w-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted",
206
208
  onClick: (t) => {
207
- t.stopPropagation(), B(e.id);
209
+ t.stopPropagation(), V(e.id);
208
210
  },
209
- children: m(n ? f : p, { className: "h-4 w-4" })
210
- }) : /* @__PURE__ */ m("span", { className: "inline-block h-5 w-5" }), /* @__PURE__ */ m("span", {
211
+ children: h(n ? p : m, { className: "h-4 w-4" })
212
+ }) : /* @__PURE__ */ h("span", { className: "inline-block h-5 w-5" }), /* @__PURE__ */ h("span", {
211
213
  className: "truncate",
212
- children: T(e.record[F.labelField]) || "—"
214
+ children: D(e.record[I.labelField]) || "—"
213
215
  })]
214
216
  })
215
- }), F.fields.filter((e) => e !== F.labelField).map((t) => /* @__PURE__ */ m("td", {
217
+ }), I.fields.filter((e) => e !== I.labelField).map((t) => /* @__PURE__ */ h("td", {
216
218
  className: "px-3 py-2 text-muted-foreground",
217
- children: T(e.record[t])
219
+ children: D(e.record[t])
218
220
  }, t))]
219
221
  }, e.id);
220
222
  }) })]
221
- }), G.isOverlay && /* @__PURE__ */ m(u, {
222
- ...G,
223
- title: "Record Details",
224
- children: (e) => /* @__PURE__ */ m("div", {
223
+ }), K.isOverlay && /* @__PURE__ */ h(u, {
224
+ ...K,
225
+ title: q("detail.recordDetail"),
226
+ children: (e) => /* @__PURE__ */ h("div", {
225
227
  className: "space-y-3",
226
- children: Object.entries(e).map(([e, t]) => /* @__PURE__ */ h("div", {
228
+ children: Object.entries(e).map(([e, t]) => /* @__PURE__ */ g("div", {
227
229
  className: "flex flex-col",
228
- children: [/* @__PURE__ */ m("span", {
230
+ children: [/* @__PURE__ */ h("span", {
229
231
  className: "text-xs font-medium text-muted-foreground uppercase tracking-wide",
230
232
  children: e.replace(/_/g, " ")
231
- }), /* @__PURE__ */ m("span", {
233
+ }), /* @__PURE__ */ h("span", {
232
234
  className: "text-sm",
233
- children: T(t) || "—"
235
+ children: D(t) || "—"
234
236
  })]
235
237
  }, e))
236
238
  })
237
239
  })]
238
240
  });
239
- }, D = ({ schema: e, ...t }) => {
241
+ }, k = ({ schema: e, ...t }) => {
240
242
  let { dataSource: n } = l() || {};
241
- return /* @__PURE__ */ m(E, {
243
+ return /* @__PURE__ */ h(O, {
242
244
  schema: e,
243
245
  dataSource: n,
244
246
  ...t
245
247
  });
246
- }, O = [{
248
+ }, A = [{
247
249
  name: "objectName",
248
250
  type: "string",
249
251
  label: "Object Name",
@@ -254,16 +256,16 @@ var E = ({ schema: r, dataSource: a, className: l, onRowClick: _, ...b }) => {
254
256
  label: "Tree Config",
255
257
  description: "parentField, labelField, fields, defaultExpandedDepth"
256
258
  }];
257
- r.register("object-tree", D, {
259
+ r.register("object-tree", k, {
258
260
  namespace: "plugin-tree",
259
261
  label: "Object Tree",
260
262
  category: "view",
261
- inputs: O
262
- }), r.register("tree", D, {
263
+ inputs: A
264
+ }), r.register("tree", k, {
263
265
  namespace: "view",
264
266
  label: "Tree View",
265
267
  category: "view",
266
- inputs: O
268
+ inputs: A
267
269
  });
268
270
  //#endregion
269
- export { E as ObjectTree, D as ObjectTreeRenderer };
271
+ export { O as ObjectTree, k as ObjectTreeRenderer };
@@ -1 +1 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("@object-ui/core"),require("@object-ui/react"),require("@object-ui/components"),require("lucide-react"),require("react/jsx-runtime")):typeof define==`function`&&define.amd?define([`exports`,`react`,`@object-ui/core`,`@object-ui/react`,`@object-ui/components`,`lucide-react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ObjectUIPluginTree={},e.React,e.ObjectUICore,e.ObjectUIReact,e.ObjectUIComponents,e.LucideReact,e.react_jsx_runtime))})(this,function(e,t,n,r,i,a,o){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var s=Object.create,c=Object.defineProperty,l=Object.getOwnPropertyDescriptor,u=Object.getOwnPropertyNames,d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty,p=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=u(t),a=0,o=i.length,s;a<o;a++)s=i[a],!f.call(e,s)&&s!==n&&c(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=l(t,s))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:s(d(e)),p(t||!e||!e.__esModule?c(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);function m(e){return e.data?e.data:e.staticData?{provider:`value`,items:e.staticData}:e.objectName?{provider:`object`,object:e.objectName}:null}function h(e){return(0,n.columnIdentity)(e)||(e&&typeof e==`object`?e.key:void 0)||void 0}function g(e){let t=e.tree||e.filter?.tree||{},n=Array.isArray(e.fields)?e.fields:Array.isArray(t.fields)?t.fields:[];return{parentField:h(e.parentField??t.parentField),labelField:h(e.labelField??t.labelField??e.titleField)??`name`,fields:n.map(h).filter(e=>!!e),defaultExpandedDepth:e.defaultExpandedDepth??t.defaultExpandedDepth}}function _(e,t){let n=e?.fields;if(!n||typeof n!=`object`)return;let r;for(let[e,i]of Object.entries(n)){if(i?.type===`tree`)return e;let n=i?.reference||i?.reference_to||i?.referenceTo;!r&&(i?.type===`lookup`||i?.type===`master_detail`)&&n&&t&&n===t&&(r=e)}return r}function v(e){let t=e?.id??e?._id;return t==null?void 0:String(t)}function y(e,t){if(!t)return;let n=e?.[t];if(n!=null){if(typeof n==`object`){let e=n.id??n._id;return e==null?void 0:String(e)}return String(n)}}function b(e,t){let n=new Map,r=[];for(let t of e){let e=v(t);e!=null&&(n.set(e,{id:e,record:t,depth:0,children:[]}),r.push(e))}let i=[];for(let e of r){let r=n.get(e),a=y(r.record,t),o=a==null?void 0:n.get(a);o&&o!==r?o.children.push(r):i.push(r)}let a=(e,t)=>{for(let n of e)n.depth=t,a(n.children,t+1)};return a(i,0),i}function x(e,t){let n=[],r=e=>{for(let i of e)n.push(i),i.children.length>0&&t.has(i.id)&&r(i.children)};return r(e),n}function S(e,t){let n=new Set,r=e=>{for(let i of e)i.children.length!==0&&(t==null||i.depth<t)&&(n.add(i.id),r(i.children))};return r(e),n}function C(e){return e==null?``:String(typeof e==`object`?e.name??e.label??e.id??e._id??``:e)}var w=({schema:e,dataSource:s,className:c,onRowClick:l,...u})=>{let[d,f]=(0,t.useState)([]),[p,h]=(0,t.useState)(!0),[v,y]=(0,t.useState)(null),[w,T]=(0,t.useState)(null),E=(0,t.useMemo)(()=>m(e),[e]),D=Array.isArray(u.data)||Array.isArray(e.data)||E?.provider===`value`;(0,t.useEffect)(()=>{let t=!1;return D||(async()=>{try{if(!s||typeof s.getObjectSchema!=`function`)return;let n=E?.provider===`object`?E.object:e.objectName;if(!n)return;let r=await s.getObjectSchema(n);t||T(r)}catch(e){console.error(`[ObjectTree] Failed to fetch object schema:`,e)}})(),()=>{t=!0}},[e.objectName,s,E,D]),(0,t.useEffect)(()=>{let t=!1;return(async()=>{try{if(h(!0),y(null),E?.provider===`object`&&s&&typeof s.find==`function`){let r=(0,n.buildExpandFields)(w?.fields),i=await s.find(E.object,{$filter:e.filter,...r.length>0?{$expand:r}:{}});t||(f((0,n.extractRecords)(i)),h(!1));return}let r=u.data??e.data;if(Array.isArray(r)){t||(f(r),h(!1));return}if(E?.provider===`value`){t||(f(E.items??[]),h(!1));return}t||(f([]),h(!1))}catch(e){t||(y(e),h(!1))}})(),()=>{t=!0}},[E,s,e.filter,w,u.data]);let O=(0,t.useMemo)(()=>g(e),[e]),k=(0,t.useMemo)(()=>O.parentField??_(w,e.objectName),[O.parentField,w,e.objectName]),A=(0,t.useMemo)(()=>b(d,k),[d,k]),[j,M]=(0,t.useState)(new Set);(0,t.useEffect)(()=>{M(S(A,O.defaultExpandedDepth))},[A,O.defaultExpandedDepth]);let N=e=>M(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),P=(0,t.useMemo)(()=>x(A,j),[A,j]),F=(0,r.useSafeFieldLabel)(),I=(E?.provider===`object`?E.object:void 0)??e.objectName,L=e=>{let t=w?.fields?.[e]?.label||e.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase());return I?F.fieldLabel(I,e,t):t},R=(0,r.useNavigationOverlay)({navigation:e.navigation,objectName:e.objectName,onRowClick:l});return v?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-destructive`,c),children:(0,o.jsxs)(`p`,{children:[`Failed to load tree: `,v.message]})}):p?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,o.jsx)(`p`,{children:`Loading…`})}):d.length===0?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,o.jsx)(`p`,{children:`No records`})}):(0,o.jsxs)(`div`,{className:(0,i.cn)(`w-full overflow-auto`,c),"data-testid":`object-tree`,children:[(0,o.jsxs)(`table`,{className:`w-full border-collapse text-sm`,children:[(0,o.jsx)(`thead`,{children:(0,o.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,o.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:L(O.labelField)}),O.fields.filter(e=>e!==O.labelField).map(e=>(0,o.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:L(e)},e))]})}),(0,o.jsx)(`tbody`,{children:P.map(e=>{let t=e.children.length>0,n=j.has(e.id);return(0,o.jsxs)(`tr`,{className:`border-b hover:bg-accent/50 cursor-pointer`,"data-testid":`object-tree-row`,"data-depth":e.depth,onClick:t=>R.handleClick(e.record,t),children:[(0,o.jsx)(`td`,{className:`px-3 py-2`,children:(0,o.jsxs)(`div`,{className:`flex items-center gap-1`,style:{paddingLeft:`${e.depth*20}px`},children:[t?(0,o.jsx)(`button`,{type:`button`,"aria-label":n?`Collapse`:`Expand`,className:`flex h-5 w-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted`,onClick:t=>{t.stopPropagation(),N(e.id)},children:n?(0,o.jsx)(a.ChevronDown,{className:`h-4 w-4`}):(0,o.jsx)(a.ChevronRight,{className:`h-4 w-4`})}):(0,o.jsx)(`span`,{className:`inline-block h-5 w-5`}),(0,o.jsx)(`span`,{className:`truncate`,children:C(e.record[O.labelField])||`—`})]})}),O.fields.filter(e=>e!==O.labelField).map(t=>(0,o.jsx)(`td`,{className:`px-3 py-2 text-muted-foreground`,children:C(e.record[t])},t))]},e.id)})})]}),R.isOverlay&&(0,o.jsx)(i.NavigationOverlay,{...R,title:`Record Details`,children:e=>(0,o.jsx)(`div`,{className:`space-y-3`,children:Object.entries(e).map(([e,t])=>(0,o.jsxs)(`div`,{className:`flex flex-col`,children:[(0,o.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:e.replace(/_/g,` `)}),(0,o.jsx)(`span`,{className:`text-sm`,children:C(t)||`—`})]},e))})})]})},T=({schema:e,...t})=>{let{dataSource:n}=(0,r.useSchemaContext)()||{};return(0,o.jsx)(w,{schema:e,dataSource:n,...t})},E=[{name:`objectName`,type:`string`,label:`Object Name`,required:!0},{name:`tree`,type:`object`,label:`Tree Config`,description:`parentField, labelField, fields, defaultExpandedDepth`}];n.ComponentRegistry.register(`object-tree`,T,{namespace:`plugin-tree`,label:`Object Tree`,category:`view`,inputs:E}),n.ComponentRegistry.register(`tree`,T,{namespace:`view`,label:`Tree View`,category:`view`,inputs:E}),e.ObjectTree=w,e.ObjectTreeRenderer=T});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("@object-ui/core"),require("@object-ui/react"),require("@object-ui/components"),require("@object-ui/i18n"),require("lucide-react"),require("react/jsx-runtime")):typeof define==`function`&&define.amd?define([`exports`,`react`,`@object-ui/core`,`@object-ui/react`,`@object-ui/components`,`@object-ui/i18n`,`lucide-react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ObjectUIPluginTree={},e.React,e.ObjectUICore,e.ObjectUIReact,e.ObjectUIComponents,e.ObjectUII18n,e.LucideReact,e.react_jsx_runtime))})(this,function(e,t,n,r,i,a,o,s){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var c=Object.create,l=Object.defineProperty,u=Object.getOwnPropertyDescriptor,d=Object.getOwnPropertyNames,f=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty,m=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=d(t),a=0,o=i.length,s;a<o;a++)s=i[a],!p.call(e,s)&&s!==n&&l(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=u(t,s))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:c(f(e)),m(t||!e||!e.__esModule||!p.call(e,`default`)?l(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);var h=(0,a.createSafeTranslation)({"detail.recordDetail":`Record Detail`},`detail.recordDetail`);function g(e){return e.data?e.data:e.staticData?{provider:`value`,items:e.staticData}:e.objectName?{provider:`object`,object:e.objectName}:null}function _(e){return(0,n.columnIdentity)(e)||(e&&typeof e==`object`?e.key:void 0)||void 0}function v(e){let t=e.tree||e.filter?.tree||{},n=Array.isArray(e.fields)?e.fields:Array.isArray(t.fields)?t.fields:[];return{parentField:_(e.parentField??t.parentField),labelField:_(e.labelField??t.labelField??e.titleField)??`name`,fields:n.map(_).filter(e=>!!e),defaultExpandedDepth:e.defaultExpandedDepth??t.defaultExpandedDepth}}function y(e,t){let n=e?.fields;if(!n||typeof n!=`object`)return;let r;for(let[e,i]of Object.entries(n)){if(i?.type===`tree`)return e;let n=i?.reference||i?.reference_to||i?.referenceTo;!r&&(i?.type===`lookup`||i?.type===`master_detail`)&&n&&t&&n===t&&(r=e)}return r}function b(e){let t=e?.id??e?._id;return t==null?void 0:String(t)}function x(e,t){if(!t)return;let n=e?.[t];if(n!=null){if(typeof n==`object`){let e=n.id??n._id;return e==null?void 0:String(e)}return String(n)}}function S(e,t){let n=new Map,r=[];for(let t of e){let e=b(t);e!=null&&(n.set(e,{id:e,record:t,depth:0,children:[]}),r.push(e))}let i=[];for(let e of r){let r=n.get(e),a=x(r.record,t),o=a==null?void 0:n.get(a);o&&o!==r?o.children.push(r):i.push(r)}let a=(e,t)=>{for(let n of e)n.depth=t,a(n.children,t+1)};return a(i,0),i}function C(e,t){let n=[],r=e=>{for(let i of e)n.push(i),i.children.length>0&&t.has(i.id)&&r(i.children)};return r(e),n}function w(e,t){let n=new Set,r=e=>{for(let i of e)i.children.length!==0&&(t==null||i.depth<t)&&(n.add(i.id),r(i.children))};return r(e),n}function T(e){return e==null?``:String(typeof e==`object`?e.name??e.label??e.id??e._id??``:e)}var E=({schema:e,dataSource:a,className:c,onRowClick:l,...u})=>{let[d,f]=(0,t.useState)([]),[p,m]=(0,t.useState)(!0),[_,b]=(0,t.useState)(null),[x,E]=(0,t.useState)(null),D=(0,t.useMemo)(()=>g(e),[e]),O=Array.isArray(u.data)||Array.isArray(e.data)||D?.provider===`value`;(0,t.useEffect)(()=>{let t=!1;return O||(async()=>{try{if(!a||typeof a.getObjectSchema!=`function`)return;let n=D?.provider===`object`?D.object:e.objectName;if(!n)return;let r=await a.getObjectSchema(n);t||E(r)}catch(e){console.error(`[ObjectTree] Failed to fetch object schema:`,e)}})(),()=>{t=!0}},[e.objectName,a,D,O]),(0,t.useEffect)(()=>{let t=!1;return(async()=>{try{if(m(!0),b(null),D?.provider===`object`&&a&&typeof a.find==`function`){let r=(0,n.buildExpandFields)(x?.fields),i=await a.find(D.object,{$filter:e.filter,...r.length>0?{$expand:r}:{}});t||(f((0,n.extractRecords)(i)),m(!1));return}let r=u.data??e.data;if(Array.isArray(r)){t||(f(r),m(!1));return}if(D?.provider===`value`){t||(f(D.items??[]),m(!1));return}t||(f([]),m(!1))}catch(e){t||(b(e),m(!1))}})(),()=>{t=!0}},[D,a,e.filter,x,u.data]);let k=(0,t.useMemo)(()=>v(e),[e]),A=(0,t.useMemo)(()=>k.parentField??y(x,e.objectName),[k.parentField,x,e.objectName]),j=(0,t.useMemo)(()=>S(d,A),[d,A]),[M,N]=(0,t.useState)(new Set);(0,t.useEffect)(()=>{N(w(j,k.defaultExpandedDepth))},[j,k.defaultExpandedDepth]);let P=e=>N(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),F=(0,t.useMemo)(()=>C(j,M),[j,M]),I=(0,r.useSafeFieldLabel)(),L=(D?.provider===`object`?D.object:void 0)??e.objectName,R=e=>{let t=x?.fields?.[e]?.label||e.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase());return L?I.fieldLabel(L,e,t):t},z=(0,r.useNavigationOverlay)({navigation:e.navigation,objectName:e.objectName,onRowClick:l}),{t:B}=h();return _?(0,s.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-destructive`,c),children:(0,s.jsxs)(`p`,{children:[`Failed to load tree: `,_.message]})}):p?(0,s.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,s.jsx)(`p`,{children:`Loading…`})}):d.length===0?(0,s.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,s.jsx)(`p`,{children:`No records`})}):(0,s.jsxs)(`div`,{className:(0,i.cn)(`w-full overflow-auto`,c),"data-testid":`object-tree`,children:[(0,s.jsxs)(`table`,{className:`w-full border-collapse text-sm`,children:[(0,s.jsx)(`thead`,{children:(0,s.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,s.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:R(k.labelField)}),k.fields.filter(e=>e!==k.labelField).map(e=>(0,s.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:R(e)},e))]})}),(0,s.jsx)(`tbody`,{children:F.map(e=>{let t=e.children.length>0,n=M.has(e.id);return(0,s.jsxs)(`tr`,{className:`border-b hover:bg-accent/50 cursor-pointer`,"data-testid":`object-tree-row`,"data-depth":e.depth,onClick:t=>z.handleClick(e.record,t),children:[(0,s.jsx)(`td`,{className:`px-3 py-2`,children:(0,s.jsxs)(`div`,{className:`flex items-center gap-1`,style:{paddingLeft:`${e.depth*20}px`},children:[t?(0,s.jsx)(`button`,{type:`button`,"aria-label":n?`Collapse`:`Expand`,className:`flex h-5 w-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted`,onClick:t=>{t.stopPropagation(),P(e.id)},children:n?(0,s.jsx)(o.ChevronDown,{className:`h-4 w-4`}):(0,s.jsx)(o.ChevronRight,{className:`h-4 w-4`})}):(0,s.jsx)(`span`,{className:`inline-block h-5 w-5`}),(0,s.jsx)(`span`,{className:`truncate`,children:T(e.record[k.labelField])||`—`})]})}),k.fields.filter(e=>e!==k.labelField).map(t=>(0,s.jsx)(`td`,{className:`px-3 py-2 text-muted-foreground`,children:T(e.record[t])},t))]},e.id)})})]}),z.isOverlay&&(0,s.jsx)(i.NavigationOverlay,{...z,title:B(`detail.recordDetail`),children:e=>(0,s.jsx)(`div`,{className:`space-y-3`,children:Object.entries(e).map(([e,t])=>(0,s.jsxs)(`div`,{className:`flex flex-col`,children:[(0,s.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:e.replace(/_/g,` `)}),(0,s.jsx)(`span`,{className:`text-sm`,children:T(t)||`—`})]},e))})})]})},D=({schema:e,...t})=>{let{dataSource:n}=(0,r.useSchemaContext)()||{};return(0,s.jsx)(E,{schema:e,dataSource:n,...t})},O=[{name:`objectName`,type:`string`,label:`Object Name`,required:!0},{name:`tree`,type:`object`,label:`Tree Config`,description:`parentField, labelField, fields, defaultExpandedDepth`}];n.ComponentRegistry.register(`object-tree`,D,{namespace:`plugin-tree`,label:`Object Tree`,category:`view`,inputs:O}),n.ComponentRegistry.register(`tree`,D,{namespace:`view`,label:`Tree View`,category:`view`,inputs:O}),e.ObjectTree=E,e.ObjectTreeRenderer=D});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/plugin-tree",
3
- "version": "17.1.0",
3
+ "version": "17.3.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Tree / tree-grid visualization plugin for Object UI",
@@ -24,23 +24,24 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@objectstack/spec": "^17.0.0-rc.0",
28
- "lucide-react": "^1.25.0",
29
- "@object-ui/components": "17.1.0",
30
- "@object-ui/core": "17.1.0",
31
- "@object-ui/react": "17.1.0",
32
- "@object-ui/types": "17.1.0"
27
+ "@objectstack/spec": "^17.0.0-rc.2",
28
+ "lucide-react": "^1.28.0",
29
+ "@object-ui/components": "17.3.0",
30
+ "@object-ui/core": "17.3.0",
31
+ "@object-ui/i18n": "17.3.0",
32
+ "@object-ui/react": "17.3.0",
33
+ "@object-ui/types": "17.3.0"
33
34
  },
34
35
  "peerDependencies": {
35
36
  "react": "^18.0.0 || ^19.0.0",
36
37
  "react-dom": "^18.0.0 || ^19.0.0"
37
38
  },
38
39
  "devDependencies": {
39
- "@types/react": "19.2.17",
40
- "@types/react-dom": "19.2.3",
41
- "@vitejs/plugin-react": "^6.0.4",
40
+ "@types/react": "19.2.18",
41
+ "@types/react-dom": "19.2.4",
42
+ "@vitejs/plugin-react": "^6.0.5",
42
43
  "typescript": "^6.0.3",
43
- "vite": "^8.1.5",
44
+ "vite": "^8.2.0",
44
45
  "vite-plugin-dts": "^5.0.3"
45
46
  },
46
47
  "keywords": [