@toolbox-web/grid-react 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/chunks/grid-detail-panel-CR7YUhdN.js +52 -0
  3. package/chunks/grid-responsive-card-BB28Zl2O.js +45 -0
  4. package/chunks/portal-bridge-DLA6Zs11.js +51 -0
  5. package/chunks/react-column-config-Sb-U7Bq3.js +109 -0
  6. package/chunks/react-grid-adapter-CzByOnua.js +416 -0
  7. package/features/editing.js +5 -0
  8. package/features/filtering.d.ts.map +1 -1
  9. package/features/filtering.js +55 -45
  10. package/features/grouping-columns.js +18 -23
  11. package/features/grouping-rows.js +11 -16
  12. package/features/index.js +3 -3
  13. package/features/master-detail.js +18 -0
  14. package/features/pinned-rows.d.ts.map +1 -1
  15. package/features/pinned-rows.js +24 -17
  16. package/features/responsive.js +18 -0
  17. package/index.d.ts +2 -0
  18. package/index.d.ts.map +1 -1
  19. package/index.js +438 -895
  20. package/lib/column-shorthand.d.ts +22 -1
  21. package/lib/column-shorthand.d.ts.map +1 -1
  22. package/lib/data-grid.d.ts.map +1 -1
  23. package/lib/editor-mount-hooks.d.ts +39 -0
  24. package/lib/editor-mount-hooks.d.ts.map +1 -0
  25. package/lib/event-props.d.ts +132 -6
  26. package/lib/event-props.d.ts.map +1 -1
  27. package/lib/feature-props.d.ts +17 -2
  28. package/lib/feature-props.d.ts.map +1 -1
  29. package/lib/portal-bridge.d.ts +11 -0
  30. package/lib/portal-bridge.d.ts.map +1 -1
  31. package/lib/portal-manager.d.ts.map +1 -1
  32. package/lib/react-column-config.d.ts +36 -5
  33. package/lib/react-column-config.d.ts.map +1 -1
  34. package/lib/react-grid-adapter.d.ts +111 -14
  35. package/lib/react-grid-adapter.d.ts.map +1 -1
  36. package/lib/use-grid-overlay.d.ts +74 -0
  37. package/lib/use-grid-overlay.d.ts.map +1 -0
  38. package/package.json +1 -1
  39. package/chunks/portal-bridge-DZ4yQkmm.js +0 -42
package/README.md CHANGED
@@ -702,7 +702,7 @@ import type {
702
702
  | `gridConfig` | `GridConfig` | Full configuration object |
703
703
  | `fitMode` | `'stretch' \| 'fit-columns' \| 'auto-fit'` | Column sizing mode |
704
704
  | `customStyles` | `string` | CSS injected via `document.adoptedStyleSheets` |
705
- | `ssr` | `boolean` | Disable features for SSR |
705
+ | `ssr` | `boolean` | **Deprecated** — no-op, will be removed |
706
706
  | `onRowsChange` | `(rows: TRow[]) => void` | Rows changed callback |
707
707
  | `onCellEdit` | `(event: CustomEvent) => void` | Cell edited callback |
708
708
  | `onRowClick` | `(event: CustomEvent) => void` | Row clicked callback |
@@ -0,0 +1,52 @@
1
+ import { jsx as u } from "react/jsx-runtime";
2
+ import { useRef as g, useCallback as m, useEffect as p } from "react";
3
+ const o = /* @__PURE__ */ new WeakMap(), s = /* @__PURE__ */ new Map();
4
+ function x(r) {
5
+ const i = r.querySelector("tbw-grid-detail");
6
+ if (i) {
7
+ const n = o.get(i);
8
+ if (n) return n;
9
+ }
10
+ const d = r.id || r.getAttribute("data-grid-id");
11
+ if (d)
12
+ return s.get(d);
13
+ }
14
+ function b(r) {
15
+ const { children: i, showExpandColumn: d = !0, animation: n = "slide" } = r, l = g(null), f = m(
16
+ (t) => {
17
+ if (l.current = t, !t) return;
18
+ o.set(t, i);
19
+ const e = t.closest("tbw-grid");
20
+ if (e) {
21
+ const a = e.id || e.getAttribute("data-grid-id");
22
+ a && s.set(a, i);
23
+ }
24
+ },
25
+ [i]
26
+ );
27
+ return p(() => () => {
28
+ const t = l.current;
29
+ if (t) {
30
+ o.delete(t);
31
+ const e = t.closest("tbw-grid");
32
+ if (e) {
33
+ const c = e.id || e.getAttribute("data-grid-id");
34
+ c && s.delete(c);
35
+ }
36
+ const a = t.parentNode;
37
+ a && a.contains(t);
38
+ }
39
+ }, []), /* @__PURE__ */ u(
40
+ "tbw-grid-detail",
41
+ {
42
+ ref: f,
43
+ showExpandColumn: d ? void 0 : "false",
44
+ animation: n === !1 ? "false" : n
45
+ }
46
+ );
47
+ }
48
+ b.displayName = "GridDetailPanel";
49
+ export {
50
+ b as G,
51
+ x as g
52
+ };
@@ -0,0 +1,45 @@
1
+ import { jsx as u } from "react/jsx-runtime";
2
+ import { useRef as f, useCallback as l, useEffect as p } from "react";
3
+ const o = /* @__PURE__ */ new WeakMap(), a = /* @__PURE__ */ new Map();
4
+ function w(i) {
5
+ const r = i.querySelector("tbw-grid-responsive-card");
6
+ if (r) {
7
+ const d = o.get(r);
8
+ if (d) return d;
9
+ }
10
+ const s = i.id || i.getAttribute("data-grid-id");
11
+ if (s)
12
+ return a.get(s);
13
+ }
14
+ function R(i) {
15
+ const { children: r, cardRowHeight: s = "auto" } = i, d = f(null), c = l(
16
+ (e) => {
17
+ if (d.current = e, !e) return;
18
+ o.set(e, r);
19
+ const t = e.closest("tbw-grid");
20
+ if (t) {
21
+ const n = t.id || t.getAttribute("data-grid-id");
22
+ n && a.set(n, r);
23
+ }
24
+ },
25
+ [r]
26
+ );
27
+ p(() => () => {
28
+ const e = d.current;
29
+ if (e) {
30
+ o.delete(e);
31
+ const t = e.closest("tbw-grid");
32
+ if (t) {
33
+ const n = t.id || t.getAttribute("data-grid-id");
34
+ n && a.delete(n);
35
+ }
36
+ }
37
+ }, []);
38
+ const g = s === "auto" ? "auto" : String(s);
39
+ return /* @__PURE__ */ u("tbw-grid-responsive-card", { ref: c, cardRowHeight: g });
40
+ }
41
+ R.displayName = "GridResponsiveCard";
42
+ export {
43
+ R as G,
44
+ w as g
45
+ };
@@ -0,0 +1,51 @@
1
+ import { flushSync as d } from "react-dom";
2
+ import { createRoot as p } from "react-dom/client";
3
+ const s = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
4
+ let m = 0;
5
+ function M(e, t) {
6
+ t ? s.set(e, t) : s.delete(e);
7
+ }
8
+ function g(e, t) {
9
+ if (t) return t;
10
+ const n = e.closest("tbw-grid");
11
+ if (n) return n;
12
+ if (s.size === 1) return s.keys().next().value;
13
+ }
14
+ function f(e) {
15
+ const t = i.get(e);
16
+ if (t) {
17
+ try {
18
+ t.unmount();
19
+ } catch {
20
+ }
21
+ i.delete(e);
22
+ }
23
+ }
24
+ function v(e, t, n, o) {
25
+ const r = n ?? `p-${m++}`, c = g(e, o), u = c ? s.get(c) : void 0;
26
+ if (u)
27
+ f(r), c && l.set(r, c), u.renderPortal(r, e, t);
28
+ else {
29
+ let a = i.get(r);
30
+ a || (a = p(e), i.set(r, a)), d(() => a.render(t));
31
+ }
32
+ return r;
33
+ }
34
+ function b(e, t) {
35
+ const n = l.get(e);
36
+ (n ? s.get(n) : void 0)?.removePortal(e, t?.sync), l.delete(e), f(e);
37
+ }
38
+ function x(e) {
39
+ return (t) => {
40
+ const n = e(t);
41
+ if (n == null || n === !1) return null;
42
+ const o = document.createElement("div");
43
+ return o.style.display = "contents", v(o, n), o;
44
+ };
45
+ }
46
+ export {
47
+ v as a,
48
+ x as c,
49
+ b as r,
50
+ M as s
51
+ };
@@ -0,0 +1,109 @@
1
+ import { a as i, r as p } from "./portal-bridge-DLA6Zs11.js";
2
+ const y = [];
3
+ function C(e) {
4
+ y.push(e);
5
+ }
6
+ function R(e, t) {
7
+ const r = [];
8
+ for (const n of y) {
9
+ const o = n({ container: e, gridEl: t });
10
+ o && r.push(o);
11
+ }
12
+ return () => {
13
+ for (const n of r) n();
14
+ };
15
+ }
16
+ const d = /* @__PURE__ */ Symbol("reactProcessed"), s = /* @__PURE__ */ new Map();
17
+ function H(e) {
18
+ const t = e.querySelectorAll(".react-cell-editor, .react-cell-renderer");
19
+ for (const r of t) {
20
+ const n = s.get(r);
21
+ n && (n.unsub?.(), p(n.key, { sync: !0 }), s.delete(r));
22
+ }
23
+ }
24
+ function l(e) {
25
+ const t = document.createElement("div");
26
+ return t.className = e, t.style.display = "contents", t;
27
+ }
28
+ function K(e) {
29
+ return () => {
30
+ const t = e.ownerDocument.activeElement;
31
+ t && e.contains(t) && (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement) && t.blur();
32
+ };
33
+ }
34
+ function E(e) {
35
+ const t = /* @__PURE__ */ new WeakMap();
36
+ return (r) => {
37
+ const n = r.cellEl;
38
+ if (n) {
39
+ const c = t.get(n);
40
+ if (c) {
41
+ if (n.contains(c.container))
42
+ return i(c.container, e(r), c.portalKey), c.container;
43
+ p(c.portalKey, { sync: !0 }), t.delete(n);
44
+ }
45
+ }
46
+ const o = l("react-cell-renderer"), a = i(o, e(r));
47
+ return n && t.set(n, { portalKey: a, container: o }), s.set(o, { key: a }), o;
48
+ };
49
+ }
50
+ function h(e) {
51
+ return (t) => {
52
+ const r = l("react-cell-editor"), o = { key: i(r, e(t)) };
53
+ return s.set(r, o), queueMicrotask(() => {
54
+ const a = r.closest("tbw-grid");
55
+ a && (o.unsub = R(r, a));
56
+ }), r;
57
+ };
58
+ }
59
+ function k(e) {
60
+ return (t) => {
61
+ const r = l("react-header-renderer"), n = i(r, e(t));
62
+ return s.set(r, { key: n }), r;
63
+ };
64
+ }
65
+ function w(e) {
66
+ return (t) => {
67
+ const r = l("react-header-label-renderer"), n = i(r, e(t));
68
+ return s.set(r, { key: n }), r;
69
+ };
70
+ }
71
+ function M(e) {
72
+ return (t) => {
73
+ const r = e(t);
74
+ if (r instanceof HTMLElement || typeof r == "string")
75
+ return r;
76
+ const n = l("react-loading-renderer"), o = i(n, r);
77
+ return s.set(n, { key: o }), n;
78
+ };
79
+ }
80
+ function L(e) {
81
+ if (!e) return;
82
+ if (e[d]) return e;
83
+ if (e.loadingRenderer && typeof e.loadingRenderer == "function") {
84
+ const n = e.loadingRenderer;
85
+ e = {
86
+ ...e,
87
+ loadingRenderer: M(n)
88
+ };
89
+ }
90
+ if (!e.columns) {
91
+ const n = e;
92
+ return n[d] = !0, n;
93
+ }
94
+ const t = e.columns.map((n) => {
95
+ const { renderer: o, editor: a, headerRenderer: c, headerLabelRenderer: f, ...m } = n, u = { ...m };
96
+ return o && (u.renderer = E(o)), a && (u.editor = h(a)), c && (u.headerRenderer = k(c)), f && (u.headerLabelRenderer = w(f)), u;
97
+ }), r = {
98
+ ...e,
99
+ columns: t
100
+ };
101
+ return r[d] = !0, r;
102
+ }
103
+ export {
104
+ H as c,
105
+ K as m,
106
+ R as n,
107
+ L as p,
108
+ C as r
109
+ };
@@ -0,0 +1,416 @@
1
+ import { p as b, n as m, c as K } from "./react-column-config-Sb-U7Bq3.js";
2
+ import { jsx as T } from "react/jsx-runtime";
3
+ import { useRef as k, useCallback as E, useEffect as w } from "react";
4
+ import { a as u, r as g } from "./portal-bridge-DLA6Zs11.js";
5
+ const p = /* @__PURE__ */ new WeakMap(), h = /* @__PURE__ */ new Map();
6
+ function D(o) {
7
+ const e = p.get(o);
8
+ if (e) return e;
9
+ const t = o.id;
10
+ if (t)
11
+ return h.get(t);
12
+ }
13
+ function x(o) {
14
+ const { id: e, title: t, icon: r, tooltip: n, order: s = 100, children: i } = o, l = k(null), y = E(
15
+ (a) => {
16
+ l.current = a, a && (p.set(a, i), e && h.set(e, i));
17
+ },
18
+ [i, e]
19
+ );
20
+ return w(() => () => {
21
+ const a = l.current;
22
+ a && (p.delete(a), e && h.delete(e));
23
+ }, [e]), /* @__PURE__ */ T(
24
+ "tbw-grid-tool-panel",
25
+ {
26
+ ref: y,
27
+ id: e,
28
+ title: t,
29
+ icon: r,
30
+ tooltip: n,
31
+ order: s?.toString()
32
+ }
33
+ );
34
+ }
35
+ let R = null, v = null, P = null;
36
+ function S(o) {
37
+ R = o;
38
+ }
39
+ function W(o) {
40
+ v = o;
41
+ }
42
+ function I(o) {
43
+ P = o;
44
+ }
45
+ const d = /* @__PURE__ */ new WeakMap(), c = /* @__PURE__ */ new Map();
46
+ function N(o, e) {
47
+ const t = o.getAttribute("field"), r = d.get(o) ?? {};
48
+ if (r.renderer = e, d.set(o, r), t) {
49
+ const n = c.get(t) ?? {};
50
+ n.renderer = e, c.set(t, n);
51
+ }
52
+ }
53
+ function j(o, e) {
54
+ const t = o.getAttribute("field"), r = d.get(o) ?? {};
55
+ if (r.editor = e, d.set(o, r), t) {
56
+ const n = c.get(t) ?? {};
57
+ n.editor = e, c.set(t, n);
58
+ }
59
+ }
60
+ function B(o) {
61
+ let e = d.get(o)?.renderer;
62
+ if (!e) {
63
+ const t = o.getAttribute("field");
64
+ t && (e = c.get(t)?.renderer);
65
+ }
66
+ return e;
67
+ }
68
+ function M(o) {
69
+ let e = d.get(o)?.editor;
70
+ if (!e) {
71
+ const t = o.getAttribute("field");
72
+ t && (e = c.get(t)?.editor);
73
+ }
74
+ return e;
75
+ }
76
+ class q {
77
+ /** Portal keys for all managed portals (for cleanup on destroy). */
78
+ allPortalKeys = /* @__PURE__ */ new Set();
79
+ /** Portal keys for editor-specific portals (for per-cell cleanup via releaseCell). */
80
+ editorPortalKeys = /* @__PURE__ */ new Set();
81
+ /** Maps portal keys to their containers (for container-based lookups in releaseCell/unmount). */
82
+ keyToContainer = /* @__PURE__ */ new Map();
83
+ /**
84
+ * Reverse index: container element → portal key. Maintained alongside
85
+ * `keyToContainer` so `releaseCell` can resolve only the containers
86
+ * actually inside the released cell (via `cellEl.querySelectorAll`)
87
+ * instead of scanning every tracked portal — important for grids with
88
+ * many cells, where `releaseCell` runs on every cell teardown.
89
+ */
90
+ containerToKey = /* @__PURE__ */ new WeakMap();
91
+ /**
92
+ * Per-editor `before-edit-close` listener teardown functions, keyed by portal key.
93
+ *
94
+ * The grid's editing plugin emits `before-edit-close` on the host `<tbw-grid>`
95
+ * before tearing down a row's managed editors. React editors commonly write
96
+ * `onBlur={commit}` to flush local state on click-away, but Tab / programmatic
97
+ * row exit rebuilds the cell DOM synchronously without giving the focused
98
+ * input a chance to fire `blur` first.
99
+ *
100
+ * To bridge that gap we call `.blur()` on the focused input inside the editor
101
+ * container as soon as `before-edit-close` fires. The native `.blur()` method
102
+ * is what React's event system actually observes — React 17+ delegates focus
103
+ * events at the root by listening to `focusout` (bubbling) and mapping it to
104
+ * `onBlur`. A bare `dispatchEvent(new FocusEvent('blur'))` would be ignored
105
+ * by React because `blur` does not bubble. Calling the native `.blur()`
106
+ * dispatches the full focus-loss chain (`blur` + `focusout`) and also moves
107
+ * focus off the input — both desirable here since the editor DOM is about to
108
+ * be torn down anyway.
109
+ *
110
+ * Mirrors the Angular adapter's `BaseGridEditor.onBeforeEditClose()` hook.
111
+ * Requires zero per-editor code: any editor with `onBlur={commit}` is
112
+ * automatically covered for Tab commits and programmatic row exit.
113
+ */
114
+ editorBeforeCloseUnsubs = /* @__PURE__ */ new Map();
115
+ typeDefaults = null;
116
+ /**
117
+ * Sets the type defaults map for this adapter.
118
+ * Called by DataGrid when it receives type defaults from context.
119
+ *
120
+ * @internal
121
+ */
122
+ setTypeDefaults(e) {
123
+ this.typeDefaults = e;
124
+ }
125
+ /**
126
+ * FrameworkAdapter.processConfig implementation.
127
+ * Called automatically by the grid's `set gridConfig` setter.
128
+ * Converts React renderer/editor functions to DOM-returning functions.
129
+ */
130
+ processConfig(e) {
131
+ return b(e) ?? e;
132
+ }
133
+ /**
134
+ * Determines if this adapter can handle the given element.
135
+ * Checks if a renderer or editor is registered for this element.
136
+ */
137
+ canHandle(e) {
138
+ const t = e.getAttribute("field");
139
+ let r = d.get(e);
140
+ if (!r && t) {
141
+ const i = c.get(t);
142
+ i && (i.renderer || i.editor) && (r = i, d.set(e, r));
143
+ }
144
+ const n = r?.renderer !== void 0, s = r?.editor !== void 0;
145
+ return r !== void 0 && (n || s);
146
+ }
147
+ /**
148
+ * Creates a view renderer function that renders a React component
149
+ * and returns its container DOM element.
150
+ *
151
+ * Uses a cell cache to reuse portals for performance - instead of
152
+ * creating new portals on each render, we reuse existing ones and
153
+ * update their content.
154
+ *
155
+ * Returns undefined if no renderer is registered for this element,
156
+ * allowing the grid to use its default rendering.
157
+ */
158
+ createRenderer(e) {
159
+ const t = B(e);
160
+ if (!t)
161
+ return;
162
+ const r = e.closest("tbw-grid"), n = /* @__PURE__ */ new WeakMap();
163
+ return (s) => {
164
+ const i = s.cellEl;
165
+ if (i) {
166
+ const a = n.get(i);
167
+ if (a) {
168
+ if (i.contains(a.container))
169
+ return u(a.container, t(s), a.portalKey), a.container;
170
+ g(a.portalKey, { sync: !0 }), this.untrackPortal(a.portalKey), n.delete(i);
171
+ }
172
+ const f = document.createElement("div");
173
+ f.className = "react-cell-renderer", f.style.display = "contents";
174
+ const C = u(
175
+ f,
176
+ t(s),
177
+ void 0,
178
+ r ?? void 0
179
+ );
180
+ return n.set(i, { portalKey: C, container: f }), this.trackPortal(C, f, !1), f;
181
+ }
182
+ const l = document.createElement("div");
183
+ l.className = "react-cell-renderer", l.style.display = "contents";
184
+ const y = u(
185
+ l,
186
+ t(s),
187
+ void 0,
188
+ r ?? void 0
189
+ );
190
+ return this.trackPortal(y, l, !1), l;
191
+ };
192
+ }
193
+ /**
194
+ * Creates an editor spec that renders a React component
195
+ * with commit/cancel callbacks passed as props.
196
+ */
197
+ createEditor(e) {
198
+ const t = M(e);
199
+ if (!t)
200
+ return () => document.createElement("div");
201
+ const r = e.closest("tbw-grid") ?? void 0;
202
+ return (n) => {
203
+ const s = document.createElement("div");
204
+ s.className = "react-cell-editor", s.style.display = "contents";
205
+ const i = u(
206
+ s,
207
+ t(n),
208
+ void 0,
209
+ r
210
+ );
211
+ return this.trackPortal(i, s, !0), r && this.editorBeforeCloseUnsubs.set(i, m(s, r)), s;
212
+ };
213
+ }
214
+ /**
215
+ * Creates a detail renderer function for MasterDetailPlugin.
216
+ * Implementation is installed by `@toolbox-web/grid-react/features/master-detail`
217
+ * via {@link registerDetailRendererBridge}. Returns undefined if the
218
+ * master-detail feature has not been imported, or if no GridDetailPanel
219
+ * was registered for this grid.
220
+ */
221
+ createDetailRenderer(e) {
222
+ return R?.(e, this.bridgeContext);
223
+ }
224
+ /**
225
+ * Framework adapter hook called by MasterDetailPlugin during attach().
226
+ * Parses the <tbw-grid-detail> element and returns a React-based renderer.
227
+ */
228
+ parseDetailElement(e) {
229
+ const t = e.closest("tbw-grid");
230
+ if (t)
231
+ return this.createDetailRenderer(t);
232
+ }
233
+ /**
234
+ * Creates a responsive card renderer function for ResponsivePlugin.
235
+ * Implementation is installed by `@toolbox-web/grid-react/features/responsive`
236
+ * via {@link registerResponsiveCardRendererBridge}. Returns undefined if
237
+ * the responsive feature has not been imported, or if no GridResponsiveCard
238
+ * was registered for this grid.
239
+ */
240
+ createResponsiveCardRenderer(e) {
241
+ return v?.(e, this.bridgeContext);
242
+ }
243
+ /**
244
+ * FrameworkAdapter hook called by ResponsivePlugin during attach().
245
+ * Parses the `<tbw-grid-responsive-card>` element and delegates to
246
+ * {@link createResponsiveCardRenderer}. Needed for parity with the Vue
247
+ * and Angular adapters so ResponsivePlugin's standard lookup path works
248
+ * for React users as well, not just via the imperative
249
+ * `refreshResponsiveCardRenderer` hook in DataGrid.
250
+ */
251
+ parseResponsiveCardElement(e) {
252
+ const t = e.closest("tbw-grid");
253
+ if (t)
254
+ return this.createResponsiveCardRenderer(t);
255
+ }
256
+ /**
257
+ * Creates a tool panel renderer from a light DOM element.
258
+ * Renders React components into tool panel containers.
259
+ */
260
+ createToolPanelRenderer(e) {
261
+ const t = D(e);
262
+ if (!t)
263
+ return;
264
+ const r = e.closest("tbw-grid");
265
+ return (n) => {
266
+ const i = u(n, t({
267
+ grid: r ?? n
268
+ }), void 0, r ?? void 0);
269
+ return this.trackPortal(i, n, !1), () => {
270
+ g(i, { sync: !0 }), this.untrackPortal(i);
271
+ };
272
+ };
273
+ }
274
+ /**
275
+ * Gets type-level defaults from the type defaults map.
276
+ *
277
+ * This enables application-wide type defaults configured via GridTypeProvider.
278
+ * The returned TypeDefault contains renderer/editor functions that render
279
+ * React components into the grid's cells.
280
+ *
281
+ * @example
282
+ * ```tsx
283
+ * // App.tsx
284
+ * const typeDefaults = {
285
+ * country: {
286
+ * renderer: (ctx) => <CountryBadge code={ctx.value} />,
287
+ * editor: (ctx) => <CountrySelect value={ctx.value} onCommit={ctx.commit} />
288
+ * }
289
+ * };
290
+ *
291
+ * <GridTypeProvider defaults={typeDefaults}>
292
+ * <App />
293
+ * </GridTypeProvider>
294
+ *
295
+ * // Any grid with type: 'country' columns will use these components
296
+ * ```
297
+ */
298
+ getTypeDefault(e, t) {
299
+ if (!this.typeDefaults)
300
+ return;
301
+ const r = this.typeDefaults[e];
302
+ if (!r)
303
+ return;
304
+ const n = {
305
+ editorParams: r.editorParams
306
+ };
307
+ return r.renderer && (n.renderer = this.createTypeRenderer(r.renderer, t)), r.editor && (n.editor = this.createTypeEditor(r.editor, t)), r.filterPanelRenderer && P && (n.filterPanelRenderer = P(
308
+ r.filterPanelRenderer,
309
+ t,
310
+ this.bridgeContext
311
+ )), n;
312
+ }
313
+ /**
314
+ * Creates a renderer function from a React render function for type defaults.
315
+ * @internal
316
+ */
317
+ createTypeRenderer(e, t) {
318
+ return (r) => {
319
+ const n = document.createElement("span");
320
+ n.style.display = "contents";
321
+ const s = r.cellEl?.closest("tbw-grid") ?? t, i = u(n, e(r), void 0, s);
322
+ return this.trackPortal(i, n, !1), n;
323
+ };
324
+ }
325
+ /**
326
+ * Creates an editor function from a React render function for type defaults.
327
+ * @internal
328
+ */
329
+ createTypeEditor(e, t) {
330
+ return (r) => {
331
+ const n = document.createElement("span");
332
+ n.style.display = "contents";
333
+ const s = u(n, e(r), void 0, t);
334
+ return this.trackPortal(s, n, !0), n;
335
+ };
336
+ }
337
+ // #region Portal tracking helpers
338
+ /**
339
+ * Stable bridge context handed to feature installers. Bound once per adapter
340
+ * so feature bridges can call `trackPortal` without each invocation creating
341
+ * a fresh closure.
342
+ */
343
+ bridgeContext = {
344
+ trackPortal: (e, t, r) => this.trackPortal(e, t, r)
345
+ };
346
+ /** Register a portal key for lifecycle tracking. */
347
+ trackPortal(e, t, r) {
348
+ this.allPortalKeys.add(e), this.keyToContainer.set(e, t), this.containerToKey.set(t, e), r && this.editorPortalKeys.add(e);
349
+ }
350
+ /** Unregister a portal key from all tracking sets. */
351
+ untrackPortal(e) {
352
+ this.allPortalKeys.delete(e), this.editorPortalKeys.delete(e);
353
+ const t = this.keyToContainer.get(e);
354
+ this.keyToContainer.delete(e), t && this.containerToKey.delete(t);
355
+ const r = this.editorBeforeCloseUnsubs.get(e);
356
+ r && (r(), this.editorBeforeCloseUnsubs.delete(e));
357
+ }
358
+ // #endregion
359
+ /**
360
+ * Clean up all mounted portals.
361
+ * Call this when the grid is unmounted.
362
+ */
363
+ destroy() {
364
+ for (const e of this.allPortalKeys)
365
+ g(e);
366
+ this.allPortalKeys.clear(), this.editorPortalKeys.clear(), this.keyToContainer.clear();
367
+ for (const e of this.editorBeforeCloseUnsubs.values()) e();
368
+ this.editorBeforeCloseUnsubs.clear(), c.clear();
369
+ }
370
+ /**
371
+ * Called when a cell's content is about to be wiped.
372
+ *
373
+ * Destroys editor portals AND renderer portals whose container is inside
374
+ * the cell. Releasing renderers here is critical: the editing pipeline
375
+ * runs `cell.innerHTML = ''` immediately after this returns, which
376
+ * silently detaches React-managed renderer containers from the DOM.
377
+ * If we leave the React root mounted, its fiber tree still believes
378
+ * the now-orphaned children are present — a subsequent React commit
379
+ * (e.g. the user's `onCellCommit` → `setRows`) tries to `removeChild`
380
+ * those gone nodes and throws `NotFoundError` (issue #250).
381
+ *
382
+ * Calling this BEFORE the wipe lets React unmount cleanly while DOM
383
+ * still matches its fiber tree. The `wrapReactRenderer` cache will
384
+ * detect the missing entry on the next render and create a fresh
385
+ * container — see the cache-validation defense in `createRenderer`
386
+ * and `wrapReactRenderer` (`react-column-config.ts`).
387
+ *
388
+ * Also cleans up config-based editor and renderer roots
389
+ * (from processGridConfig/wrapReactEditor/wrapReactRenderer) that
390
+ * bypass the adapter's own portal tracking.
391
+ */
392
+ releaseCell(e) {
393
+ const t = e.querySelectorAll(".react-cell-renderer, .react-cell-editor");
394
+ for (const r of t) {
395
+ const n = this.containerToKey.get(r);
396
+ n && (g(n, { sync: !0 }), this.untrackPortal(n));
397
+ }
398
+ K(e);
399
+ }
400
+ /**
401
+ * Unmount a specific container (called when cell is recycled).
402
+ */
403
+ unmount(e) {
404
+ const t = this.containerToKey.get(e);
405
+ t && (g(t), this.untrackPortal(t));
406
+ }
407
+ }
408
+ export {
409
+ q as G,
410
+ S as a,
411
+ W as b,
412
+ N as c,
413
+ j as d,
414
+ x as e,
415
+ I as r
416
+ };
@@ -1 +1,6 @@
1
1
  import "@toolbox-web/grid/features/editing";
2
+ import { r, m as s } from "../chunks/react-column-config-Sb-U7Bq3.js";
3
+ r(({ container: t, gridEl: e }) => {
4
+ const o = s(t);
5
+ return e.addEventListener("before-edit-close", o), () => e.removeEventListener("before-edit-close", o);
6
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../../../../libs/grid-react/src/features/filtering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAEL,KAAK,SAAS,EAEd,KAAK,WAAW,EAEjB,MAAM,qCAAqC,CAAC;AAmC7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAE9G;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IAEtD;;OAEG;IACH,UAAU,EAAE,MAAM,WAAW,EAAE,CAAC;IAEhC;;;OAGG;IACH,cAAc,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAEjF;;;OAGG;IACH,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAE1D;;;OAGG;IACH,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAE1E;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAE5C;;OAEG;IACH,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAElC;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;IAE9C;;OAEG;IACH,eAAe,EAAE,MAAM,WAAW,EAAE,CAAC;IAErC;;OAEG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAE3C;;OAEG;IACH,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAuHpE"}
1
+ {"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../../../../libs/grid-react/src/features/filtering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAEL,KAAK,SAAS,EAEd,KAAK,WAAW,EAEjB,MAAM,qCAAqC,CAAC;AAyD7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAE9G;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IAEtD;;OAEG;IACH,UAAU,EAAE,MAAM,WAAW,EAAE,CAAC;IAEhC;;;OAGG;IACH,cAAc,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAEjF;;;OAGG;IACH,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAE1D;;;OAGG;IACH,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAE1E;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAE5C;;OAEG;IACH,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAElC;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;IAE9C;;OAEG;IACH,eAAe,EAAE,MAAM,WAAW,EAAE,CAAC;IAErC;;OAEG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAE3C;;OAEG;IACH,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAuHpE"}