@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.
- package/README.md +1 -1
- package/chunks/grid-detail-panel-CR7YUhdN.js +52 -0
- package/chunks/grid-responsive-card-BB28Zl2O.js +45 -0
- package/chunks/portal-bridge-DLA6Zs11.js +51 -0
- package/chunks/react-column-config-Sb-U7Bq3.js +109 -0
- package/chunks/react-grid-adapter-CzByOnua.js +416 -0
- package/features/editing.js +5 -0
- package/features/filtering.d.ts.map +1 -1
- package/features/filtering.js +55 -45
- package/features/grouping-columns.js +18 -23
- package/features/grouping-rows.js +11 -16
- package/features/index.js +3 -3
- package/features/master-detail.js +18 -0
- package/features/pinned-rows.d.ts.map +1 -1
- package/features/pinned-rows.js +24 -17
- package/features/responsive.js +18 -0
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -1
- package/index.js +438 -895
- package/lib/column-shorthand.d.ts +22 -1
- package/lib/column-shorthand.d.ts.map +1 -1
- package/lib/data-grid.d.ts.map +1 -1
- package/lib/editor-mount-hooks.d.ts +39 -0
- package/lib/editor-mount-hooks.d.ts.map +1 -0
- package/lib/event-props.d.ts +132 -6
- package/lib/event-props.d.ts.map +1 -1
- package/lib/feature-props.d.ts +17 -2
- package/lib/feature-props.d.ts.map +1 -1
- package/lib/portal-bridge.d.ts +11 -0
- package/lib/portal-bridge.d.ts.map +1 -1
- package/lib/portal-manager.d.ts.map +1 -1
- package/lib/react-column-config.d.ts +36 -5
- package/lib/react-column-config.d.ts.map +1 -1
- package/lib/react-grid-adapter.d.ts +111 -14
- package/lib/react-grid-adapter.d.ts.map +1 -1
- package/lib/use-grid-overlay.d.ts +74 -0
- package/lib/use-grid-overlay.d.ts.map +1 -0
- package/package.json +1 -1
- 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` |
|
|
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
|
+
};
|
package/features/editing.js
CHANGED
|
@@ -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;
|
|
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"}
|