@toolbox-web/grid 0.2.6 → 0.2.7

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 (52) hide show
  1. package/all.d.ts +434 -61
  2. package/all.js +844 -541
  3. package/all.js.map +1 -1
  4. package/index-DG2CZ_Zo.js +3229 -0
  5. package/index-DG2CZ_Zo.js.map +1 -0
  6. package/index.d.ts +210 -6
  7. package/index.js +25 -3194
  8. package/index.js.map +1 -1
  9. package/lib/plugins/clipboard/index.js.map +1 -1
  10. package/lib/plugins/column-virtualization/index.js.map +1 -1
  11. package/lib/plugins/context-menu/index.js.map +1 -1
  12. package/lib/plugins/export/index.js.map +1 -1
  13. package/lib/plugins/filtering/index.js +183 -148
  14. package/lib/plugins/filtering/index.js.map +1 -1
  15. package/lib/plugins/grouping-columns/index.js.map +1 -1
  16. package/lib/plugins/grouping-rows/index.js +116 -82
  17. package/lib/plugins/grouping-rows/index.js.map +1 -1
  18. package/lib/plugins/master-detail/index.js +139 -81
  19. package/lib/plugins/master-detail/index.js.map +1 -1
  20. package/lib/plugins/multi-sort/index.js +17 -17
  21. package/lib/plugins/multi-sort/index.js.map +1 -1
  22. package/lib/plugins/pinned-columns/index.js.map +1 -1
  23. package/lib/plugins/pinned-rows/index.js.map +1 -1
  24. package/lib/plugins/pivot/index.js +369 -337
  25. package/lib/plugins/pivot/index.js.map +1 -1
  26. package/lib/plugins/reorder/index.js +264 -91
  27. package/lib/plugins/reorder/index.js.map +1 -1
  28. package/lib/plugins/selection/index.js.map +1 -1
  29. package/lib/plugins/server-side/index.js.map +1 -1
  30. package/lib/plugins/tree/index.js +180 -169
  31. package/lib/plugins/tree/index.js.map +1 -1
  32. package/lib/plugins/undo-redo/index.js.map +1 -1
  33. package/lib/plugins/visibility/index.js.map +1 -1
  34. package/package.json +1 -1
  35. package/umd/grid.all.umd.js +21 -21
  36. package/umd/grid.all.umd.js.map +1 -1
  37. package/umd/grid.umd.js +12 -12
  38. package/umd/grid.umd.js.map +1 -1
  39. package/umd/plugins/filtering.umd.js +1 -1
  40. package/umd/plugins/filtering.umd.js.map +1 -1
  41. package/umd/plugins/grouping-rows.umd.js +1 -1
  42. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  43. package/umd/plugins/master-detail.umd.js +1 -1
  44. package/umd/plugins/master-detail.umd.js.map +1 -1
  45. package/umd/plugins/multi-sort.umd.js +1 -1
  46. package/umd/plugins/multi-sort.umd.js.map +1 -1
  47. package/umd/plugins/pivot.umd.js +1 -1
  48. package/umd/plugins/pivot.umd.js.map +1 -1
  49. package/umd/plugins/reorder.umd.js +1 -1
  50. package/umd/plugins/reorder.umd.js.map +1 -1
  51. package/umd/plugins/tree.umd.js +1 -1
  52. package/umd/plugins/tree.umd.js.map +1 -1
package/index.js CHANGED
@@ -1,3197 +1,28 @@
1
- const fe = ":root{color-scheme:light dark}:host{--tbw-color-bg: transparent;--tbw-color-panel-bg: light-dark(#eeeeee, #222222);--tbw-color-fg: light-dark(#222222, #eeeeee);--tbw-color-fg-muted: light-dark(#555555, #aaaaaa);--tbw-color-accent: light-dark(#3b82f6, #3b82f6);--tbw-color-accent-fg: light-dark(#ffffff, #000000);--tbw-color-success: light-dark(hsl(122, 39%, 40%), hsl(122, 39%, 49%));--tbw-color-selection: light-dark(#fff7d6, #333333);--tbw-color-row-alt: var(--tbw-color-bg);--tbw-color-row-hover: light-dark(#f0f6ff, #1c1c1c);--tbw-color-header-bg: color-mix(in hsl, var(--tbw-color-panel-bg) 85%, var(--tbw-color-fg));--tbw-color-header-fg: color-mix(in hsl, var(--tbw-color-fg) 75%, var(--tbw-color-panel-bg));--tbw-color-border: light-dark(#d0d0d4, #454545);--tbw-color-border-strong: light-dark(#777777, #adacac);--tbw-color-border-cell: var(--tbw-color-border);--tbw-color-border-header: var(--tbw-color-border);--tbw-color-shadow: light-dark(rgba(0, 0, 0, .1), rgba(0, 0, 0, .3));--tbw-font-family: inherit;--tbw-font-size: inherit;--tbw-font-size-header: var(--tbw-font-size);--tbw-font-weight-header: bold;--tbw-cell-padding-header: 2px 8px;--tbw-cell-padding: 2px 8px;--tbw-cell-padding-input: 2px 6px;--tbw-row-height: 28px;--tbw-header-height: 30px;--tbw-cell-white-space: nowrap;--tbw-border-radius: 4px;--tbw-border-input: 1px solid var(--tbw-color-border-strong);--tbw-border-header: 1px solid var(--tbw-color-border-header);--tbw-row-divider: 1px solid var(--tbw-color-border-cell);--tbw-row-hover-outline: 0;--tbw-color-active-row-bg: var(--tbw-color-selection);--tbw-active-row-outline: 0;--tbw-focus-outline: 2px solid var(--tbw-color-accent);--tbw-focus-outline-offset: -2px;--tbw-focus-background: rgba(from var(--tbw-color-accent) r g b / 12%);--tbw-range-border-color: var(--tbw-color-accent);--tbw-range-selection-bg: rgba(from var(--tbw-range-border-color) r g b / 12%);--tbw-resize-handle-width: 6px;--tbw-resize-handle-color: transparent;--tbw-resize-handle-color-hover: var(--tbw-color-accent);--tbw-resize-handle-border-radius: 0;--tbw-scrollbar-thumb: var(--tbw-color-border-strong);--tbw-scrollbar-track: var(--tbw-color-bg);--tbw-transition-duration: .12s;--tbw-transition-ease: ease;--tbw-editing-bg: var(--tbw-color-selection);--tbw-editing-border: var(--tbw-border-input, 1px solid var(--tbw-color-border-strong));--tbw-padding-editing-input: var(--tbw-cell-padding-input, 2px 6px);--tbw-font-size-editor: inherit;--tbw-sort-indicator-color: var(--tbw-color-fg-muted);--tbw-sort-indicator-active-color: var(--tbw-color-accent);--tbw-header-text-transform: none;--tbw-header-letter-spacing: normal;--tbw-color-header-separator: var(--tbw-color-border-cell);--tbw-checkbox-size: 16px;--tbw-density-scale: 1}:host{position:relative;display:block;width:100%;height:100%;min-height:0;contain:content;font-family:var(--tbw-font-family);font-size:var(--tbw-font-size);background:var(--tbw-color-bg);color:var(--tbw-color-fg);border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);overflow:clip;outline:none}:host,:host *{box-sizing:border-box}:host .header{display:block;flex-shrink:0;z-index:var(--tbw-z-layer-header, 30);background:var(--tbw-color-header-bg);overflow:visible}:host .header-group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-color-header-bg);z-index:var(--tbw-z-layer-header, 30)}:host .header-group-cell{display:flex;align-items:center;justify-content:flex-start;padding:var(--tbw-cell-padding-header, 2px 8px);color:var(--tbw-color-header-group-fg, var(--tbw-color-header-fg));font-weight:var(--tbw-font-weight-header-group, var(--tbw-font-weight-header));justify-content:var(--tbw-align-header-group, var(--tbw-align-header, flex-start))}:host .header-row{display:grid;grid-template-columns:var(--tbw-column-template);color:var(--tbw-color-header-fg);font-size:var(--tbw-font-size-header);min-height:var(--tbw-header-height);border-bottom:var(--tbw-border-header);z-index:var(--tbw-z-layer-header, 30)}:host .header-row>.cell{display:flex;align-items:center;gap:4px;padding:var(--tbw-cell-padding-header, 2px 8px);background-color:var(--tbw-color-header-bg);font-weight:var(--tbw-font-weight-header);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}:host .header-row>.cell>span:first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .header-row>.cell>span[part~=sort-indicator]{flex-shrink:0}:host .header-row>.cell:last-child{border-right:0}:host .header-group-cell:not(:last-child),:host .header-row>.cell.grouped.group-end:not(:last-child){border-right:2px solid var(--tbw-color-border)}:host .tbw-grid-root{display:flex;flex-direction:column;height:100%}:host .rows-body-wrapper{flex:1;min-height:0;display:flex;flex-direction:row;width:100%;min-width:fit-content}:host .rows-body{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:visible}:host .rows-container{display:flex;flex-direction:row;flex:1;min-height:0;overflow:visible}:host .rows-viewport{flex:1;min-width:0;position:relative;display:block;overflow:clip}:host .faux-vscroll{position:sticky;inset-inline-end:0;flex-shrink:0;width:auto;overflow-y:auto;overflow-x:hidden;z-index:var(--tbw-z-layer-header, 30)}:host .faux-vscroll-spacer{width:1px}:host .rows-viewport .rows{position:absolute;top:0;left:0;min-width:100%;will-change:transform;z-index:var(--tbw-z-layer-rows, 1)}:host .data-grid-row{display:grid;grid-template-columns:var(--tbw-column-template);contain:layout style}:host .data-grid-row:has(.editing){background:var(--tbw-editing-bg)}:host .selecting .data-grid-row>.cell{user-select:none}:host .data-grid-row>.cell.selected:focus-visible,:host .data-grid-row>.cell:focus-visible:not(.cell-focus){outline:none}:host .data-grid-row>.cell{display:block;padding:var(--tbw-cell-padding, 2px 8px);border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height);line-height:calc(var(--tbw-row-height) - 5px);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0;white-space:var(--tbw-cell-white-space, nowrap);text-overflow:ellipsis}:host .data-grid-row>.cell>*{overflow:hidden;text-overflow:ellipsis;white-space:inherit;min-width:0}:host .data-grid-row>.cell:last-child{border-right:0}:host .data-grid-row>.cell[data-type=boolean]{text-align:center}:host .data-grid-row>.cell[data-type=boolean] input[type=checkbox]{margin:0;width:var(--tbw-checkbox-size);height:var(--tbw-checkbox-size);vertical-align:middle}:host .data-grid-row>.cell.editing{overflow:hidden;padding:0;display:flex}:host .data-grid-row>.cell.editing input:not([type=checkbox]),:host .data-grid-row>.cell.editing select,:host .data-grid-row>.cell.editing textarea{width:100%;height:100%;max-width:100%;flex:1 1 auto;min-width:0;border:var(--tbw-editing-border);padding:var(--tbw-padding-editing-input);font-size:var(--tbw-font-size-editor)}:host .data-grid-row:nth-child(2n){background:var(--tbw-color-row-alt)}:host .data-grid-row:hover{background:var(--tbw-color-row-hover)}:host .sortable{cursor:pointer;user-select:none}:host .resize-handle{position:absolute;top:0;right:calc(var(--tbw-resize-handle-width) / -2);width:var(--tbw-resize-handle-width);height:100%;cursor:e-resize;user-select:none;touch-action:none;z-index:20;background:var(--tbw-resize-handle-color);transition:background .12s ease;border-radius:var(--tbw-resize-handle-border-radius)}:host .resize-handle:hover{background:var(--tbw-resize-handle-color-hover)}:host .cell-focus,:host .row-focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}:host .group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-color-row-alt);font-weight:500;border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height)}:host .group-row .cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, 2px 8px)}:host .group-row .group-toggle{background:none;border:0;cursor:pointer;padding:0 4px 0 0;font:inherit}:host .group-row .group-count{margin-left:4px;opacity:.7}:host .sticky-left,:host .sticky-right{position:sticky;z-index:25}:host .header-row>.cell.sticky-left,:host .header-row>.cell.sticky-right{background:var(--tbw-color-header-bg);z-index:35}:host .data-grid-row>.cell.sticky-left,:host .data-grid-row>.cell.sticky-right{background:var(--tbw-color-panel-bg)}:host .sticky-left{box-shadow:1px 0 0 var(--tbw-color-border)}:host .sticky-right{box-shadow:-1px 0 0 var(--tbw-color-border)}.grid-container{position:relative;width:100%;height:100%}.grid-placeholder{padding:2rem;text-align:center;color:var(--tbw-color-fg);opacity:.6}:host{--tbw-shell-header-height: 44px;--tbw-shell-header-bg: var(--tbw-color-panel-bg);--tbw-shell-header-border: var(--tbw-color-border);--tbw-shell-title-font-size: 14px;--tbw-shell-title-font-weight: 600;--tbw-tool-panel-width: 280px;--tbw-tool-panel-bg: var(--tbw-color-panel-bg);--tbw-tool-panel-border: var(--tbw-color-border);--tbw-tool-panel-header-height: 40px;--tbw-tool-panel-transition: .2s ease-out;--tbw-toolbar-button-size: 32px;--tbw-toolbar-button-gap: 4px}:host .tbw-grid-root.has-shell{display:flex;flex-direction:column;height:100%}:host .tbw-shell-header{display:flex;align-items:center;gap:8px;min-height:var(--tbw-shell-header-height);padding:0 8px;background:var(--tbw-shell-header-bg);border-bottom:1px solid var(--tbw-shell-header-border);flex-shrink:0}:host .tbw-shell-title{font-size:var(--tbw-shell-title-font-size);font-weight:var(--tbw-shell-title-font-weight);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .tbw-shell-content{flex:1;display:flex;align-items:center;gap:12px;min-width:0;overflow:hidden}:host .tbw-shell-toolbar{display:flex;align-items:center;gap:var(--tbw-toolbar-button-gap);flex-shrink:0}:host .tbw-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;width:var(--tbw-toolbar-button-size);height:var(--tbw-toolbar-button-size);padding:0;border:1px solid transparent;border-radius:var(--tbw-border-radius);background:transparent;color:var(--tbw-color-fg);cursor:pointer;font-size:16px;transition:background var(--tbw-transition-duration) var(--tbw-transition-ease),border-color var(--tbw-transition-duration) var(--tbw-transition-ease)}:host .tbw-toolbar-btn:hover{background:var(--tbw-color-row-hover)}:host .tbw-toolbar-btn:focus-visible{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}:host .tbw-toolbar-btn.active{background:var(--tbw-focus-background);border-color:var(--tbw-color-accent)}:host .tbw-toolbar-btn:disabled{opacity:.5;cursor:not-allowed}:host .tbw-toolbar-separator{width:1px;height:20px;background:var(--tbw-color-border);margin:0 4px}:host .tbw-shell-body{position:relative;display:flex;flex:1;min-height:0;overflow:visible}:host .tbw-grid-content{flex:1;min-width:0;min-height:0;display:flex;flex-direction:row;overflow:hidden}:host .tbw-scroll-area{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow-x:auto;overflow-y:hidden}:host .tbw-tool-panel{position:absolute;top:0;bottom:0;right:0;width:0;overflow:hidden;background:var(--tbw-tool-panel-bg);border-left:1px solid var(--tbw-tool-panel-border);transition:width var(--tbw-tool-panel-transition);display:flex;flex-direction:column;z-index:30;box-shadow:-2px 0 8px var(--tbw-color-shadow)}:host .tbw-tool-panel[data-position=left]{right:auto;left:0;border-left:none;border-right:1px solid var(--tbw-tool-panel-border);box-shadow:2px 0 8px var(--tbw-color-shadow)}:host .tbw-tool-panel.open{width:var(--tbw-tool-panel-width)}:host .tbw-tool-panel-resize{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;background:transparent;z-index:10;transition:background .15s ease}:host .tbw-tool-panel-resize[data-handle-position=left]{left:0}:host .tbw-tool-panel-resize[data-handle-position=right]{right:0}:host .tbw-tool-panel-resize:hover,:host .tbw-tool-panel-resize.resizing{background:var(--tbw-color-accent)}:host .tbw-tool-panel-header{display:flex;align-items:center;justify-content:space-between;min-height:var(--tbw-tool-panel-header-height);padding:0 12px;border-bottom:1px solid var(--tbw-tool-panel-border);flex-shrink:0}:host .tbw-tool-panel-title{font-weight:600;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .tbw-tool-panel-close{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;border-radius:var(--tbw-border-radius);background:transparent;color:var(--tbw-color-fg-muted);cursor:pointer;font-size:14px}:host .tbw-tool-panel-close:hover{background:var(--tbw-color-row-hover);color:var(--tbw-color-fg)}:host .tbw-tool-panel-content{flex:1;overflow:auto}:host .tbw-accordion{display:flex;flex-direction:column;gap:0}:host .tbw-accordion-section{border-bottom:1px solid var(--tbw-tool-panel-border)}:host .tbw-accordion-section:last-child{border-bottom:none}:host .tbw-accordion-header{display:flex;align-items:center;gap:8px;width:100%;padding:10px 12px;border:none;background:transparent;color:var(--tbw-color-fg);font-size:13px;font-weight:600;text-align:left;cursor:pointer;user-select:none}:host .tbw-accordion-header:hover{background:var(--tbw-color-row-hover)}:host .tbw-accordion-section.single .tbw-accordion-header{cursor:default}:host .tbw-accordion-section.single .tbw-accordion-header:hover{background:transparent}:host .tbw-accordion-chevron{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:10px;color:var(--tbw-color-fg-muted);transition:transform .15s ease;flex-shrink:0}:host .tbw-accordion-section.expanded .tbw-accordion-chevron{transform:rotate(90deg)}:host .tbw-accordion-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;flex-shrink:0}:host .tbw-accordion-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .tbw-accordion-content{display:none}:host .tbw-accordion-section.expanded .tbw-accordion-content{display:block}:host .tbw-quick-filter-input{flex:1;max-width:300px;height:28px;padding:0 8px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);color:var(--tbw-color-fg);font-size:13px}:host .tbw-quick-filter-input:focus{outline:none;border-color:var(--tbw-color-accent)}:host .tbw-selection-summary{font-size:13px;color:var(--tbw-color-fg-muted);white-space:nowrap}";
2
- function pe(t) {
3
- const e = /* @__PURE__ */ new Map();
4
- return t._sortState && e.set(t._sortState.field, {
5
- direction: t._sortState.direction === 1 ? "asc" : "desc",
6
- priority: 0
7
- }), e;
8
- }
9
- function ce(t, e) {
10
- const o = t._columns, i = pe(t);
11
- return {
12
- columns: o.map((n, s) => {
13
- const r = {
14
- field: n.field,
15
- order: s,
16
- visible: !0
17
- // If it's in _columns, it's visible (hidden columns are filtered out)
18
- }, l = n;
19
- l.__renderedWidth !== void 0 ? r.width = l.__renderedWidth : n.width !== void 0 && (r.width = typeof n.width == "string" ? parseFloat(n.width) : n.width);
20
- const a = i.get(n.field);
21
- a && (r.sort = a);
22
- for (const d of e)
23
- if (d.getColumnState) {
24
- const f = d.getColumnState(n.field);
25
- f && Object.assign(r, f);
26
- }
27
- return r;
28
- })
29
- };
30
- }
31
- function be(t, e, o, i) {
32
- if (!e.columns || e.columns.length === 0) return;
33
- const n = new Map(e.columns.map((l) => [l.field, l])), s = o.map((l) => {
34
- const a = n.get(l.field);
35
- if (!a) return l;
36
- const d = { ...l };
37
- return a.width !== void 0 && (d.width = a.width, d.__renderedWidth = a.width), a.visible !== void 0 && (d.hidden = !a.visible), d;
38
- });
39
- s.sort((l, a) => {
40
- const d = n.get(l.field)?.order ?? 1 / 0, f = n.get(a.field)?.order ?? 1 / 0;
41
- return d - f;
42
- }), t._columns = s;
43
- const r = e.columns.filter((l) => l.sort !== void 0).sort((l, a) => (l.sort?.priority ?? 0) - (a.sort?.priority ?? 0));
44
- if (r.length > 0) {
45
- const l = r[0];
46
- l.sort && (t._sortState = {
47
- field: l.field,
48
- direction: l.sort.direction === "asc" ? 1 : -1
49
- });
50
- } else
51
- t._sortState = null;
52
- for (const l of i)
53
- if (l.applyColumnState)
54
- for (const a of e.columns)
55
- l.applyColumnState(a.field, a);
56
- }
57
- function we(t, e, o) {
58
- let i = null;
59
- return () => {
60
- i !== null && clearTimeout(i), i = setTimeout(() => {
61
- i = null;
62
- const n = ce(t, e());
63
- o(n);
64
- }, 100);
65
- };
66
- }
67
- const $ = {
68
- STRETCH: "stretch",
69
- FIXED: "fixed"
70
- }, H = {
71
- expand: "▶",
72
- collapse: "▼",
73
- sortAsc: "▲",
74
- sortDesc: "▼",
75
- sortNone: "⇅",
76
- submenuArrow: "▶",
77
- dragHandle: "⋮⋮",
78
- toolPanel: "☰"
79
- };
80
- function ge(t) {
81
- return t == null ? "string" : typeof t == "number" ? "number" : typeof t == "boolean" ? "boolean" : t instanceof Date || typeof t == "string" && /\d{4}-\d{2}-\d{2}/.test(t) && !isNaN(Date.parse(t)) ? "date" : "string";
82
- }
83
- function de(t, e) {
84
- if (e && e.length) {
85
- const s = {};
86
- return e.forEach((r) => {
87
- r.type && (s[r.field] = r.type);
88
- }), { columns: e, typeMap: s };
89
- }
90
- const o = t[0] || {}, i = Object.keys(o).map((s) => {
91
- const r = o[s], l = ge(r);
92
- return { field: s, header: s.charAt(0).toUpperCase() + s.slice(1), type: l };
93
- }), n = {};
94
- return i.forEach((s) => {
95
- n[s.field] = s.type || "string";
96
- }), { columns: i, typeMap: n };
97
- }
98
- const me = /{{\s*([^}]+)\s*}}/g, L = "__DG_EMPTY__", ve = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, _e = /__(proto|defineGetter|defineSetter)|constructor|window|globalThis|global|process|Function|import|eval|Reflect|Proxy|Error|arguments|document|location|cookie|localStorage|sessionStorage|indexedDB|fetch|XMLHttpRequest|WebSocket|Worker|SharedWorker|ServiceWorker|opener|parent|top|frames|self|this\b/, Ee = /* @__PURE__ */ new Set([
99
- "script",
100
- "iframe",
101
- "object",
102
- "embed",
103
- "form",
104
- "input",
105
- "button",
106
- "textarea",
107
- "select",
108
- "link",
109
- "meta",
110
- "base",
111
- "style",
112
- "template",
113
- "slot",
114
- "portal",
115
- "frame",
116
- "frameset",
117
- "applet",
118
- "noscript",
119
- "noembed",
120
- "plaintext",
121
- "xmp",
122
- "listing"
123
- ]), Q = /^on\w+$/i, Ce = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "data", "srcdoc", "xlink:href", "poster", "srcset"]), ye = /^\s*(javascript|vbscript|data|blob):/i;
124
- function F(t) {
125
- if (!t || typeof t != "string") return "";
126
- if (t.indexOf("<") === -1) return t;
127
- const e = document.createElement("template");
128
- return e.innerHTML = t, Se(e.content), e.innerHTML;
129
- }
130
- function Se(t) {
131
- const e = [], o = t.querySelectorAll("*");
132
- for (const i of o) {
133
- const n = i.tagName.toLowerCase();
134
- if (Ee.has(n)) {
135
- e.push(i);
136
- continue;
137
- }
138
- if ((n === "svg" || i.namespaceURI === "http://www.w3.org/2000/svg") && Array.from(i.attributes).some(
139
- (l) => Q.test(l.name) || l.name === "href" || l.name === "xlink:href"
140
- )) {
141
- e.push(i);
142
- continue;
143
- }
144
- const s = [];
145
- for (const r of i.attributes) {
146
- const l = r.name.toLowerCase();
147
- if (Q.test(l)) {
148
- s.push(r.name);
149
- continue;
150
- }
151
- if (Ce.has(l) && ye.test(r.value)) {
152
- s.push(r.name);
153
- continue;
154
- }
155
- if (l === "style" && /expression\s*\(|javascript:|behavior\s*:/i.test(r.value)) {
156
- s.push(r.name);
157
- continue;
158
- }
159
- }
160
- s.forEach((r) => i.removeAttribute(r));
161
- }
162
- e.forEach((i) => i.remove());
163
- }
164
- function ue(t, e) {
165
- if (!t || t.indexOf("{{") === -1) return t;
166
- const o = [], i = t.replace(me, (l, a) => {
167
- const d = Re(a, e);
168
- return o.push({ expr: a.trim(), result: d }), d;
169
- }), n = xe(i), s = o.length && o.every((l) => l.result === "" || l.result === L);
170
- return /Reflect\.|\bProxy\b|ownKeys\(/.test(t) || s ? "" : n;
171
- }
172
- function Re(t, e) {
173
- if (t = (t || "").trim(), !t || /\b(Reflect|Proxy|ownKeys)\b/.test(t)) return L;
174
- if (t === "value") return e.value == null ? L : String(e.value);
175
- if (t.startsWith("row.") && !/[()?]/.test(t) && !t.includes(":")) {
176
- const i = t.slice(4), n = e.row ? e.row[i] : void 0;
177
- return n == null ? L : String(n);
178
- }
179
- if (t.length > 80 || !ve.test(t) || _e.test(t)) return L;
180
- const o = t.match(/\./g);
181
- if (o && o.length > 1) return L;
182
- try {
183
- const n = new Function("value", "row", `return (${t});`)(e.value, e.row), s = n == null ? "" : String(n);
184
- return /Reflect|Proxy|ownKeys/.test(s) ? L : s || L;
185
- } catch {
186
- return L;
187
- }
188
- }
189
- function xe(t) {
190
- return t && t.replace(new RegExp(L, "g"), "").replace(/Reflect\.[^<>{}\s]+/g, "").replace(/\bProxy\b/g, "").replace(/ownKeys\([^)]*\)/g, "");
191
- }
192
- function Ae(t) {
193
- if (/Reflect|Proxy|ownKeys/.test(t.textContent || "")) {
194
- if (Array.from(t.childNodes).forEach((e) => {
195
- e.nodeType === Node.TEXT_NODE && /Reflect|Proxy|ownKeys/.test(e.textContent || "") && (e.textContent = "");
196
- }), /Reflect|Proxy|ownKeys/.test(t.textContent || "")) {
197
- if (/Reflect|Proxy|ownKeys/.test(t.textContent || ""))
198
- for (; t.firstChild; ) t.removeChild(t.firstChild);
199
- t.textContent = (t.textContent || "").replace(/Reflect|Proxy|ownKeys/g, "");
200
- }
201
- (t.textContent || "").trim().length === 0 && (t.textContent = "");
202
- }
203
- }
204
- function ee(t) {
205
- const e = /Reflect\.|\bProxy\b|ownKeys\(/.test(t), o = (i) => e ? "" : ue(t, i);
206
- return o.__blocked = e, o;
207
- }
208
- function Te(t) {
209
- return Array.from(t.querySelectorAll("tbw-grid-column")).map((o) => {
210
- const i = o.getAttribute("field") || "";
211
- if (!i) return null;
212
- const n = o.getAttribute("type") || void 0, r = n && (/* @__PURE__ */ new Set(["number", "string", "date", "boolean", "select", "typeahead"])).has(n) ? n : void 0, l = o.getAttribute("header") || void 0, a = o.hasAttribute("sortable"), d = o.hasAttribute("editable"), f = { field: i, type: r, header: l, sortable: a, editable: d };
213
- o.hasAttribute("resizable") && (f.resizable = !0), o.hasAttribute("sizable") && (f.resizable = !0);
214
- const h = o.getAttribute("options");
215
- h && (f.options = h.split(",").map((b) => {
216
- const [w, v] = b.includes(":") ? b.split(":") : [b.trim(), b.trim()];
217
- return { value: w.trim(), label: v?.trim() || w.trim() };
218
- }));
219
- const p = o.querySelector("tbw-grid-column-view"), c = o.querySelector("tbw-grid-column-editor"), u = o.querySelector("tbw-grid-column-header");
220
- return p && (f.__viewTemplate = p), c && (f.__editorTemplate = c), u && (f.__headerTemplate = u), f;
221
- }).filter((o) => !!o);
222
- }
223
- function Le(t, e) {
224
- if ((!t || !t.length) && (!e || !e.length)) return [];
225
- if (!t || !t.length) return e || [];
226
- if (!e || !e.length) return t;
227
- const o = {};
228
- e.forEach((n) => o[n.field] = n);
229
- const i = t.map((n) => {
230
- const s = o[n.field];
231
- if (!s) return n;
232
- const r = { ...n };
233
- return s.header && !r.header && (r.header = s.header), s.type && !r.type && (r.type = s.type), r.sortable = n.sortable || s.sortable, (n.resizable === !0 || s.resizable === !0) && (r.resizable = !0), r.editable = n.editable || s.editable, s.__viewTemplate && (r.__viewTemplate = s.__viewTemplate), s.__editorTemplate && (r.__editorTemplate = s.__editorTemplate), s.__headerTemplate && (r.__headerTemplate = s.__headerTemplate), delete o[n.field], r;
234
- });
235
- return Object.keys(o).forEach((n) => i.push(o[n])), i;
236
- }
237
- function Y(t, e) {
238
- try {
239
- t.part?.add?.(e);
240
- } catch {
241
- }
242
- const o = t.getAttribute("part");
243
- o ? o.split(/\s+/).includes(e) || t.setAttribute("part", o + " " + e) : t.setAttribute("part", e);
244
- }
245
- function Pe(t) {
246
- t.__lightDomColumnsCache || (t.__originalColumnNodes = Array.from(
247
- t.querySelectorAll("tbw-grid-column")
248
- ), t.__lightDomColumnsCache = t.__originalColumnNodes.length ? Te(t) : []);
249
- const e = t.__lightDomColumnsCache, o = Le(t._columns, e);
250
- o.forEach((n) => {
251
- n.__viewTemplate && !n.__compiledView && (n.__compiledView = ee(n.__viewTemplate.innerHTML)), n.__editorTemplate && !n.__compiledEditor && (n.__compiledEditor = ee(n.__editorTemplate.innerHTML));
252
- });
253
- const { columns: i } = de(t._rows, o);
254
- t._columns = i;
255
- }
256
- function te(t) {
257
- const e = t.effectiveConfig?.fitMode || t.fitMode || $.STRETCH;
258
- if (e !== $.STRETCH && e !== $.FIXED || t.__didInitialAutoSize || !t.isConnected) return;
259
- const o = t._headerRowEl?.children || [];
260
- if (!o.length) return;
261
- let i = !1;
262
- t._visibleColumns.forEach((n, s) => {
263
- if (n.width) return;
264
- const r = o[s];
265
- let l = r ? r.scrollWidth : 0;
266
- for (const a of t._rowPool) {
267
- const d = a.children[s];
268
- if (d) {
269
- const f = d.scrollWidth;
270
- f > l && (l = f);
271
- }
272
- }
273
- l > 0 && (n.width = l + 2, n.__autoSized = !0, i = !0);
274
- }), i && z(t), t.__didInitialAutoSize = !0;
275
- }
276
- function z(t) {
277
- (t.effectiveConfig?.fitMode || t.fitMode || $.STRETCH) === $.STRETCH ? t._gridTemplate = t._visibleColumns.map((o) => {
278
- if (o.width) return `${o.width}px`;
279
- const i = o.minWidth;
280
- return i != null ? `minmax(${i}px, 1fr)` : "1fr";
281
- }).join(" ").trim() : t._gridTemplate = t._visibleColumns.map((o) => o.width ? `${o.width}px` : "max-content").join(" "), t.style.setProperty("--tbw-column-template", t._gridTemplate);
282
- }
283
- function He(t) {
284
- switch (t.type) {
285
- case "number":
286
- return (e) => {
287
- const o = document.createElement("input");
288
- return o.type = "number", o.value = e.value != null ? String(e.value) : "", o.addEventListener("blur", () => e.commit(o.value === "" ? null : Number(o.value))), o.addEventListener("keydown", (i) => {
289
- i.key === "Enter" && e.commit(o.value === "" ? null : Number(o.value)), i.key === "Escape" && e.cancel();
290
- }), o.focus(), o;
291
- };
292
- case "boolean":
293
- return (e) => {
294
- const o = document.createElement("input");
295
- return o.type = "checkbox", o.checked = !!e.value, o.addEventListener("change", () => e.commit(o.checked)), o.focus(), o;
296
- };
297
- case "date":
298
- return (e) => {
299
- const o = document.createElement("input");
300
- return o.type = "date", e.value instanceof Date && (o.valueAsDate = e.value), o.addEventListener("change", () => e.commit(o.valueAsDate)), o.addEventListener("keydown", (i) => {
301
- i.key === "Escape" && e.cancel();
302
- }), o.focus(), o;
303
- };
304
- case "select":
305
- case "typeahead":
306
- return (e) => {
307
- const o = document.createElement("select");
308
- e.column.multi && (o.multiple = !0), (typeof e.column.options == "function" ? e.column.options() : e.column.options || []).forEach((s) => {
309
- const r = document.createElement("option");
310
- r.value = String(s.value), r.textContent = s.label, (e.column.multi && Array.isArray(e.value) && e.value.includes(s.value) || !e.column.multi && e.value === s.value) && (r.selected = !0), o.appendChild(r);
311
- });
312
- const n = () => {
313
- if (e.column.multi) {
314
- const s = [];
315
- Array.from(o.selectedOptions).forEach((r) => {
316
- s.push(r.value);
317
- }), e.commit(s);
318
- } else
319
- e.commit(o.value);
320
- };
321
- return o.addEventListener("change", n), o.addEventListener("blur", n), o.addEventListener("keydown", (s) => {
322
- s.key === "Escape" && e.cancel();
323
- }), o.focus(), o;
324
- };
325
- default:
326
- return (e) => {
327
- const o = document.createElement("input");
328
- return o.type = "text", o.value = e.value != null ? String(e.value) : "", o.addEventListener("blur", () => e.commit(o.value)), o.addEventListener("keydown", (i) => {
329
- i.key === "Enter" && e.commit(o.value), i.key === "Escape" && e.cancel();
330
- }), o.focus(), o;
331
- };
332
- }
333
- }
334
- function ke(t, e) {
335
- if (t._dispatchKeyDown?.(e))
336
- return;
337
- const o = t._rows.length - 1, i = t._visibleColumns.length - 1, n = t._activeEditRows !== void 0 && t._activeEditRows !== -1, r = t._visibleColumns[t._focusCol]?.type, l = e.composedPath ? e.composedPath() : [], a = l && l.length ? l[0] : e.target, d = (f) => {
338
- if (!f) return !1;
339
- const h = f.tagName;
340
- return !!(h === "INPUT" || h === "SELECT" || h === "TEXTAREA" || f.isContentEditable);
341
- };
342
- if (!(d(a) && (e.key === "Home" || e.key === "End")) && !(d(a) && (e.key === "ArrowUp" || e.key === "ArrowDown") && a.tagName === "INPUT" && a.type === "number") && !(d(a) && (e.key === "ArrowLeft" || e.key === "ArrowRight")) && !(d(a) && (e.key === "Enter" || e.key === "Escape")) && !(n && (r === "select" || r === "typeahead") && (e.key === "ArrowDown" || e.key === "ArrowUp"))) {
343
- switch (e.key) {
344
- case "Tab": {
345
- e.preventDefault(), !e.shiftKey ? t._focusCol < i ? t._focusCol += 1 : (typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow < o && (t._focusRow += 1, t._focusCol = 0)) : t._focusCol > 0 ? t._focusCol -= 1 : t._focusRow > 0 && (typeof t.commitActiveRowEdit == "function" && t._activeEditRows === t._focusRow && t.commitActiveRowEdit(), t._focusRow -= 1, t._focusCol = i), M(t);
346
- return;
347
- }
348
- case "ArrowDown":
349
- n && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = Math.min(o, t._focusRow + 1), e.preventDefault();
350
- break;
351
- case "ArrowUp":
352
- n && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = Math.max(0, t._focusRow - 1), e.preventDefault();
353
- break;
354
- case "ArrowRight":
355
- t._focusCol = Math.min(i, t._focusCol + 1), e.preventDefault();
356
- break;
357
- case "ArrowLeft":
358
- t._focusCol = Math.max(0, t._focusCol - 1), e.preventDefault();
359
- break;
360
- case "Home":
361
- (e.ctrlKey || e.metaKey) && (n && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = 0), t._focusCol = 0, e.preventDefault(), M(t, { forceScrollLeft: !0 });
362
- return;
363
- case "End":
364
- (e.ctrlKey || e.metaKey) && (n && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = o), t._focusCol = i, e.preventDefault(), M(t, { forceScrollRight: !0 });
365
- return;
366
- case "PageDown":
367
- t._focusRow = Math.min(o, t._focusRow + 20), e.preventDefault();
368
- break;
369
- case "PageUp":
370
- t._focusRow = Math.max(0, t._focusRow - 20), e.preventDefault();
371
- break;
372
- case "Enter":
373
- return typeof t.beginBulkEdit == "function" ? t.beginBulkEdit(t._focusRow) : t.dispatchEvent(
374
- new CustomEvent("activate-cell", { detail: { row: t._focusRow, col: t._focusCol } })
375
- ), M(t);
376
- default:
377
- return;
378
- }
379
- M(t);
380
- }
381
- }
382
- function M(t, e) {
383
- if (t._virtualization?.enabled) {
384
- const { rowHeight: r, container: l, viewportEl: a } = t._virtualization, d = l, f = a?.clientHeight ?? d?.clientHeight ?? 0;
385
- if (d && f > 0) {
386
- const h = t._focusRow * r;
387
- h < d.scrollTop ? d.scrollTop = h : h + r > d.scrollTop + f && (d.scrollTop = h - f + r);
388
- }
389
- }
390
- t._activeEditRows !== void 0 && t._activeEditRows !== -1 || t.refreshVirtualWindow(!1), Array.from(t._bodyEl.querySelectorAll(".cell-focus")).forEach((r) => r.classList.remove("cell-focus")), Array.from(t._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((r) => {
391
- r.setAttribute("aria-selected", "false");
392
- });
393
- const i = t._focusRow, n = t._virtualization.start ?? 0, s = t._virtualization.end ?? t._rows.length;
394
- if (i >= n && i < s) {
395
- const r = t._bodyEl.querySelectorAll(".data-grid-row")[i - n], l = r?.children[t._focusCol];
396
- if (l) {
397
- l.classList.add("cell-focus"), l.setAttribute("aria-selected", "true");
398
- const a = t.shadowRoot?.querySelector(".tbw-scroll-area");
399
- if (a && l)
400
- if (e?.forceScrollLeft)
401
- a.scrollLeft = 0;
402
- else if (e?.forceScrollRight)
403
- a.scrollLeft = a.scrollWidth - a.clientWidth;
404
- else {
405
- const d = t._getHorizontalScrollOffsets?.(r ?? void 0, l) ?? { left: 0, right: 0 };
406
- if (!d.skipScroll) {
407
- const f = l.getBoundingClientRect(), h = a.getBoundingClientRect(), p = f.left - h.left + a.scrollLeft, c = p + f.width, u = a.scrollLeft + d.left, b = a.scrollLeft + a.clientWidth - d.right;
408
- p < u ? a.scrollLeft = p - d.left : c > b && (a.scrollLeft = c - a.clientWidth + d.right);
409
- }
410
- }
411
- if (t._activeEditRows !== void 0 && t._activeEditRows !== -1 && l.classList.contains("editing")) {
412
- const d = l.querySelector(
413
- 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])'
414
- );
415
- if (d && document.activeElement !== d)
416
- try {
417
- d.focus();
418
- } catch {
419
- }
420
- } else if (!l.contains(document.activeElement)) {
421
- l.hasAttribute("tabindex") || l.setAttribute("tabindex", "-1");
422
- try {
423
- l.focus({ preventScroll: !0 });
424
- } catch {
425
- }
426
- }
427
- }
428
- }
429
- }
430
- const Oe = "__cellDisplayCache", Me = "__cellCacheEpoch";
431
- function j(t) {
432
- t[Oe] = void 0, t[Me] = void 0, t.__hasSpecialColumns = void 0;
433
- }
434
- function ze(t, e, o, i, n) {
435
- const s = Math.max(0, o - e), r = t._bodyEl, l = t._visibleColumns, a = l.length;
436
- let d = t.__cachedHeaderRowCount;
437
- for (d === void 0 && (d = t.shadowRoot?.querySelector(".header-group-row") ? 2 : 1, t.__cachedHeaderRowCount = d); t._rowPool.length < s; ) {
438
- const h = document.createElement("div");
439
- h.className = "data-grid-row", h.setAttribute("role", "row"), h.addEventListener("click", (p) => oe(t, p, h, !1)), h.addEventListener("dblclick", (p) => oe(t, p, h, !0)), t._rowPool.push(h);
440
- }
441
- if (t._rowPool.length > s) {
442
- for (let h = s; h < t._rowPool.length; h++) {
443
- const p = t._rowPool[h];
444
- p.parentNode === r && p.remove();
445
- }
446
- t._rowPool.length = s;
447
- }
448
- const f = n && t.__hasRenderRowPlugins !== !1;
449
- for (let h = 0; h < s; h++) {
450
- const p = e + h, c = t._rows[p], u = t._rowPool[h];
451
- if (u.setAttribute("aria-rowindex", String(p + d + 1)), f && n(c, u, p)) {
452
- u.__epoch = i, u.__rowDataRef = c, u.parentNode !== r && r.appendChild(u);
453
- continue;
454
- }
455
- const b = u.__epoch, w = u.__rowDataRef, v = u.children.length, R = b === i && v === a, E = w !== c;
456
- let g = !1;
457
- if (R && E) {
458
- for (let _ = 0; _ < a; _++)
459
- if (l[_].externalView && !u.querySelector(`.cell[data-col="${_}"] [data-external-view]`)) {
460
- g = !0;
461
- break;
462
- }
463
- }
464
- if (!R || g) {
465
- const _ = u.querySelector(".cell.editing"), y = t._activeEditRows === p;
466
- if (_ && !y)
467
- u.__isCustomRow && (u.className = "data-grid-row", u.setAttribute("role", "row"), u.__isCustomRow = !1), N(t, u, c, p), u.__epoch = i, u.__rowDataRef = c;
468
- else if (_ && y)
469
- U(t, u, c, p), u.__rowDataRef = c;
470
- else if (u.__isCustomRow && (u.className = "data-grid-row", u.setAttribute("role", "row"), u.__isCustomRow = !1), N(t, u, c, p), u.__epoch = i, u.__rowDataRef = c, y) {
471
- const x = u.children;
472
- for (let A = 0; A < x.length; A++) {
473
- const P = t._visibleColumns[A];
474
- P && P.editable && k(t, c, p, P, x[A]);
475
- }
476
- }
477
- } else if (E) {
478
- const _ = u.querySelector(".cell.editing"), y = t._activeEditRows === p;
479
- if (_ && !y)
480
- N(t, u, c, p), u.__epoch = i, u.__rowDataRef = c;
481
- else if (U(t, u, c, p), u.__rowDataRef = c, y && !_) {
482
- const x = u.children;
483
- for (let A = 0; A < x.length; A++) {
484
- const P = t._visibleColumns[A];
485
- P && P.editable && k(t, c, p, P, x[A]);
486
- }
487
- }
488
- } else {
489
- const _ = u.querySelector(".cell.editing"), y = t._activeEditRows === p;
490
- if (_ && !y)
491
- N(t, u, c, p), u.__epoch = i, u.__rowDataRef = c;
492
- else if (U(t, u, c, p), y && !_) {
493
- const x = u.children;
494
- for (let A = 0; A < x.length; A++) {
495
- const P = t._visibleColumns[A];
496
- P && P.editable && k(t, c, p, P, x[A]);
497
- }
498
- }
499
- }
500
- const m = t._changedRowIndices.has(p), C = u.classList.contains("changed");
501
- m !== C && u.classList.toggle("changed", m), u.parentNode !== r && r.appendChild(u);
502
- }
503
- }
504
- function U(t, e, o, i) {
505
- const n = e.children, s = t._visibleColumns, r = s.length, l = n.length, a = r < l ? r : l, d = t._focusRow, f = t._focusCol;
506
- let h = t.__hasSpecialColumns;
507
- if (h === void 0) {
508
- h = !1;
509
- for (let c = 0; c < r; c++) {
510
- const u = s[c];
511
- if (u.__viewTemplate || u.__compiledView || u.viewRenderer || u.externalView || u.format || u.type === "date" || u.type === "boolean") {
512
- h = !0;
513
- break;
514
- }
515
- }
516
- t.__hasSpecialColumns = h;
517
- }
518
- const p = String(i);
519
- if (!h) {
520
- for (let c = 0; c < a; c++) {
521
- const u = n[c], b = o[s[c].field];
522
- u.textContent = b == null ? "" : String(b), u.getAttribute("data-row") !== p && u.setAttribute("data-row", p);
523
- const w = d === i && f === c, v = u.classList.contains("cell-focus");
524
- w !== v && (u.classList.toggle("cell-focus", w), u.setAttribute("aria-selected", String(w)));
525
- }
526
- return;
527
- }
528
- for (let c = 0; c < a; c++)
529
- if (s[c].externalView && !n[c].querySelector("[data-external-view]")) {
530
- N(t, e, o, i);
531
- return;
532
- }
533
- for (let c = 0; c < a; c++) {
534
- const u = s[c], b = n[c];
535
- b.getAttribute("data-row") !== p && b.setAttribute("data-row", p);
536
- const w = d === i && f === c, v = b.classList.contains("cell-focus");
537
- if (w !== v && (b.classList.toggle("cell-focus", w), b.setAttribute("aria-selected", String(w))), b.classList.contains("editing")) continue;
538
- if (u.viewRenderer) {
539
- const E = o[u.field], g = u.viewRenderer({ row: o, value: E, field: u.field, column: u });
540
- typeof g == "string" ? b.innerHTML = F(g) : g ? (b.innerHTML = "", b.appendChild(g)) : b.textContent = E == null ? "" : String(E);
541
- continue;
542
- }
543
- if (u.__viewTemplate || u.__compiledView || u.externalView)
544
- continue;
545
- const S = o[u.field];
546
- let R;
547
- if (u.format)
548
- try {
549
- const E = u.format(S, o);
550
- R = E == null ? "" : String(E);
551
- } catch {
552
- R = S == null ? "" : String(S);
553
- }
554
- else if (u.type === "date") {
555
- if (S == null || S === "")
556
- R = "";
557
- else if (S instanceof Date)
558
- R = isNaN(S.getTime()) ? "" : S.toLocaleDateString();
559
- else {
560
- const E = new Date(S);
561
- R = isNaN(E.getTime()) ? "" : E.toLocaleDateString();
562
- }
563
- b.textContent = R;
564
- } else if (u.type === "boolean") {
565
- const E = !!S;
566
- b.innerHTML = `<span role="checkbox" aria-checked="${E}" aria-label="${E}">${E ? "&#x1F5F9;" : "&#9744;"}</span>`;
567
- } else
568
- R = S == null ? "" : String(S), b.textContent = R;
569
- }
570
- }
571
- function N(t, e, o, i) {
572
- e.innerHTML = "";
573
- const n = t._visibleColumns, s = n.length, r = t._focusRow, l = t._focusCol, a = t.effectiveConfig?.editOn || t.editOn, d = t, f = document.createDocumentFragment();
574
- for (let h = 0; h < s; h++) {
575
- const p = n[h], c = document.createElement("div");
576
- c.className = "cell", Y(c, "cell"), c.setAttribute("role", "gridcell"), c.setAttribute("aria-colindex", String(h + 1)), c.setAttribute("data-col", String(h)), c.setAttribute("data-row", String(i)), c.setAttribute("data-field", p.field), p.type, p.type && c.setAttribute("data-type", p.type);
577
- let u = o[p.field];
578
- const b = p.format;
579
- if (b)
580
- try {
581
- u = b(u, o);
582
- } catch {
583
- }
584
- const w = p.__compiledView, v = p.__viewTemplate, S = p.viewRenderer, R = p.externalView;
585
- let E = !1;
586
- if (S) {
587
- const g = S({ row: o, value: u, field: p.field, column: p });
588
- typeof g == "string" ? (c.innerHTML = F(g), E = !0) : g ? c.appendChild(g) : c.textContent = u == null ? "" : String(u);
589
- } else if (R) {
590
- const g = R, m = document.createElement("div");
591
- m.setAttribute("data-external-view", ""), m.setAttribute("data-field", p.field), c.appendChild(m);
592
- const C = { row: o, value: u, field: p.field, column: p };
593
- if (g.mount)
594
- try {
595
- g.mount({ placeholder: m, context: C, spec: g });
596
- } catch {
597
- }
598
- else
599
- queueMicrotask(() => {
600
- try {
601
- d.dispatchEvent(
602
- new CustomEvent("mount-external-view", {
603
- bubbles: !0,
604
- composed: !0,
605
- detail: { placeholder: m, spec: g, context: C }
606
- })
607
- );
608
- } catch {
609
- }
610
- });
611
- m.setAttribute("data-mounted", "");
612
- } else if (w) {
613
- const g = w({ row: o, value: u, field: p.field, column: p }), m = w.__blocked;
614
- c.innerHTML = m ? "" : F(g), E = !0, m && (c.textContent = "", c.setAttribute("data-blocked-template", ""));
615
- } else if (v) {
616
- const g = v.innerHTML;
617
- /Reflect\.|\bProxy\b|ownKeys\(/.test(g) ? (c.textContent = "", c.setAttribute("data-blocked-template", "")) : (c.innerHTML = F(ue(g, { row: o, value: u })), E = !0);
618
- } else if (p.type === "date")
619
- if (u == null || u === "")
620
- c.textContent = "";
621
- else {
622
- let g = null;
623
- if (u instanceof Date) g = u;
624
- else if (typeof u == "number" || typeof u == "string") {
625
- const m = new Date(u);
626
- isNaN(m.getTime()) || (g = m);
627
- }
628
- c.textContent = g ? g.toLocaleDateString() : "";
629
- }
630
- else if (p.type === "boolean") {
631
- const g = !!u;
632
- c.innerHTML = `<span role="checkbox" aria-checked="${g}" aria-label="${g}">${g ? "&#x1F5F9;" : "&#9744;"}</span>`;
633
- } else
634
- c.textContent = u == null ? "" : String(u);
635
- if (E) {
636
- Ae(c);
637
- const g = c.textContent || "";
638
- /Proxy|Reflect\.ownKeys/.test(g) && (c.textContent = g.replace(/Proxy|Reflect\.ownKeys/g, "").trim(), /Proxy|Reflect\.ownKeys/.test(c.textContent || "") && (c.textContent = ""));
639
- }
640
- c.hasAttribute("data-blocked-template") && (c.textContent || "").trim().length && (c.textContent = ""), p.editable ? (c.tabIndex = 0, c.addEventListener("mousedown", () => {
641
- if (c.classList.contains("editing")) return;
642
- const g = Number(c.getAttribute("data-row")), m = Number(c.getAttribute("data-col"));
643
- isNaN(g) || isNaN(m) || (t._focusRow = g, t._focusCol = m, M(t));
644
- }), a === "click" ? c.addEventListener("click", (g) => {
645
- if (c.classList.contains("editing")) return;
646
- g.stopPropagation();
647
- const m = Number(c.getAttribute("data-row")), C = Number(c.getAttribute("data-col"));
648
- if (isNaN(m) || isNaN(C)) return;
649
- const _ = t._rows[m], y = t._visibleColumns[C];
650
- !_ || !y || (t._focusRow = m, t._focusCol = C, k(t, _, m, y, c));
651
- }) : c.addEventListener("dblclick", (g) => {
652
- g.stopPropagation();
653
- const m = Number(c.getAttribute("data-row"));
654
- if (isNaN(m)) return;
655
- const C = t._rows[m];
656
- if (!C) return;
657
- B(t, m, C);
658
- const _ = t.findRenderedRowElement?.(m);
659
- if (_) {
660
- const y = _.children;
661
- for (let x = 0; x < y.length; x++) {
662
- const A = t._visibleColumns[x];
663
- A && A.editable && k(t, C, m, A, y[x]);
664
- }
665
- }
666
- }), c.addEventListener("keydown", (g) => {
667
- const m = Number(c.getAttribute("data-row")), C = Number(c.getAttribute("data-col"));
668
- if (isNaN(m) || isNaN(C)) return;
669
- const _ = t._rows[m], y = t._visibleColumns[C];
670
- if (!(!_ || !y)) {
671
- if ((y.type === "select" || y.type === "typeahead") && !c.classList.contains("editing") && g.key === "Enter") {
672
- g.preventDefault(), t._activeEditRows !== m && B(t, m, _), k(t, _, m, y, c), setTimeout(() => {
673
- const x = c.querySelector("select");
674
- try {
675
- x?.showPicker?.();
676
- } catch {
677
- }
678
- x?.focus();
679
- }, 0);
680
- return;
681
- }
682
- if (y.type === "boolean" && g.key === " " && !c.classList.contains("editing")) {
683
- g.preventDefault(), t._activeEditRows !== m && B(t, m, _);
684
- const x = !_[y.field];
685
- J(t, m, y, x, _), c.innerHTML = `<span role="checkbox" aria-checked="${x}" aria-label="${x}">${x ? "&#x1F5F9;" : "&#9744;"}</span>`;
686
- return;
687
- }
688
- if (g.key === "Enter" && !c.classList.contains("editing")) {
689
- g.preventDefault(), g.stopPropagation(), t._focusRow = m, t._focusCol = C, typeof t.beginBulkEdit == "function" ? t.beginBulkEdit(m) : k(t, _, m, y, c);
690
- return;
691
- }
692
- if (g.key === "F2" && !c.classList.contains("editing")) {
693
- g.preventDefault(), k(t, _, m, y, c);
694
- return;
695
- }
696
- }
697
- })) : p.type === "boolean" && (c.hasAttribute("tabindex") || (c.tabIndex = 0)), r === i && l === h ? (c.classList.add("cell-focus"), c.setAttribute("aria-selected", "true")) : c.setAttribute("aria-selected", "false"), f.appendChild(c);
698
- }
699
- e.appendChild(f);
700
- }
701
- function oe(t, e, o, i) {
702
- if (e.target?.closest(".resize-handle")) return;
703
- const n = o.querySelector(".cell[data-row]");
704
- if (!n) return;
705
- const s = Number(n.getAttribute("data-row"));
706
- if (isNaN(s)) return;
707
- const r = t._rows[s];
708
- if (!r || t._dispatchRowClick?.(e, s, r, o))
709
- return;
710
- const l = e.target?.closest(".cell[data-col]");
711
- if (l) {
712
- if (l.classList.contains("editing")) return;
713
- const d = Number(l.getAttribute("data-col"));
714
- if (!isNaN(d)) {
715
- if (t._dispatchCellClick?.(e, s, d, l))
716
- return;
717
- t._focusRow = s, t._focusCol = d, M(t);
718
- }
719
- }
720
- if (o.querySelector(".cell.editing")) {
721
- const d = o.querySelectorAll(".cell.editing");
722
- if (!i) return;
723
- d.forEach((f) => f.classList.remove("editing"));
724
- }
725
- const a = t.effectiveConfig?.editOn || t.editOn || "doubleClick";
726
- if (a === "click" || a === "doubleClick" && i) B(t, s, r);
727
- else return;
728
- Array.from(o.children).forEach((d, f) => {
729
- const h = t._visibleColumns[f];
730
- h && h.editable && k(t, r, s, h, d);
731
- }), l && queueMicrotask(() => {
732
- const d = o.querySelector(`.cell[data-col="${t._focusCol}"]`);
733
- if (d?.classList.contains("editing")) {
734
- const f = d.querySelector(
735
- 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])'
736
- );
737
- try {
738
- f?.focus();
739
- } catch {
740
- }
741
- }
742
- });
743
- }
744
- function Z(t) {
745
- return !(t === "__proto__" || t === "constructor" || t === "prototype");
746
- }
747
- function B(t, e, o) {
748
- t._activeEditRows !== e && (t._rowEditSnapshots.set(e, { ...o }), t._activeEditRows = e);
749
- }
750
- function D(t, e, o) {
751
- if (t._activeEditRows !== e) return;
752
- const i = t._rowEditSnapshots.get(e), n = t._rows[e], s = t.findRenderedRowElement?.(e);
753
- if (!o && s && n && s.querySelectorAll(".cell.editing").forEach((l) => {
754
- const a = Number(l.getAttribute("data-col"));
755
- if (isNaN(a)) return;
756
- const d = t._visibleColumns[a];
757
- if (!d) return;
758
- const f = l.querySelector("input,textarea,select");
759
- if (f) {
760
- let h;
761
- f instanceof HTMLInputElement && f.type === "checkbox" ? h = f.checked : (h = f.value, d.type === "number" && h !== "" && (h = Number(h))), n[d.field] !== h && J(t, e, d, h, n);
762
- }
763
- }), o && i && n)
764
- Object.keys(i).forEach((r) => n[r] = i[r]), t._changedRowIndices.delete(e), j(t);
765
- else if (!o) {
766
- const r = t._changedRowIndices.has(e);
767
- t.dispatchEvent(
768
- new CustomEvent("row-commit", {
769
- detail: {
770
- rowIndex: e,
771
- row: n,
772
- changed: r,
773
- changedRows: t.changedRows,
774
- changedRowIndices: t.changedRowIndices
775
- }
776
- })
777
- );
778
- }
779
- t._rowEditSnapshots.delete(e), t._activeEditRows = -1, s && (N(t, s, t._rows[e], e), t._changedRowIndices.has(e) ? s.classList.add("changed") : s.classList.remove("changed")), queueMicrotask(() => {
780
- try {
781
- const r = t._focusRow, l = t._focusCol, a = t.findRenderedRowElement?.(r);
782
- if (a) {
783
- Array.from(t._bodyEl.querySelectorAll(".cell-focus")).forEach(
784
- (f) => f.classList.remove("cell-focus")
785
- );
786
- const d = a.querySelector(`.cell[data-row="${r}"][data-col="${l}"]`);
787
- d && (d.classList.add("cell-focus"), d.setAttribute("aria-selected", "true"), d.hasAttribute("tabindex") || d.setAttribute("tabindex", "-1"), d.focus({ preventScroll: !0 }));
788
- }
789
- } catch {
790
- }
791
- });
792
- }
793
- function J(t, e, o, i, n) {
794
- const s = o.field;
795
- if (!Z(s) || n[s] === i) return;
796
- n[s] = i;
797
- const l = !t._changedRowIndices.has(e);
798
- t._changedRowIndices.add(e);
799
- const a = t.findRenderedRowElement?.(e);
800
- a && a.classList.add("changed"), t.dispatchEvent(
801
- new CustomEvent("cell-commit", {
802
- detail: {
803
- row: n,
804
- field: s,
805
- value: i,
806
- rowIndex: e,
807
- changedRows: t.changedRows,
808
- changedRowIndices: t.changedRowIndices,
809
- firstTimeForRow: l
810
- }
811
- })
812
- );
813
- }
814
- function k(t, e, o, i, n) {
815
- if (!i.editable || (t._activeEditRows !== o && B(t, o, e), n.classList.contains("editing"))) return;
816
- const s = Z(i.field) ? e[i.field] : void 0;
817
- n.classList.add("editing");
818
- let r = !1;
819
- const l = (c) => {
820
- r || t._activeEditRows === -1 || J(t, o, i, c, e);
821
- }, a = () => {
822
- r = !0, e[i.field] = Z(i.field) ? s : void 0;
823
- const c = n.querySelector("input,textarea,select");
824
- c && (typeof HTMLInputElement < "u" && c instanceof HTMLInputElement && c.type === "checkbox" ? c.checked = !!s : "value" in c && (c.value = s ?? ""));
825
- }, d = document.createElement("div");
826
- d.style.display = "contents", n.innerHTML = "", n.appendChild(d), d.addEventListener("keydown", (c) => {
827
- c.key === "Enter" && (c.stopPropagation(), c.preventDefault(), r = !0, D(t, o, !1)), c.key === "Escape" && (c.stopPropagation(), c.preventDefault(), a(), D(t, o, !0));
828
- });
829
- const f = i.__editorTemplate, h = i.editor || (f ? "template" : He(i)), p = s;
830
- if (h === "template" && f) {
831
- const c = f.cloneNode(!0), u = i.__compiledEditor;
832
- u ? c.innerHTML = u({ row: e, value: s, field: i.field, column: i }) : c.querySelectorAll("*").forEach((w) => {
833
- w.childNodes.length === 1 && w.firstChild?.nodeType === Node.TEXT_NODE && (w.textContent = w.textContent?.replace(/{{\s*value\s*}}/g, s == null ? "" : String(s)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (v, S) => {
834
- const R = e[S];
835
- return R == null ? "" : String(R);
836
- }) || "");
837
- });
838
- const b = c.querySelector("input,textarea,select");
839
- if (b) {
840
- const w = typeof HTMLInputElement < "u";
841
- w && b instanceof HTMLInputElement && b.type === "checkbox" ? b.checked = !!s : "value" in b && (b.value = s ?? ""), b.addEventListener("blur", () => {
842
- const v = w && b instanceof HTMLInputElement && b.type === "checkbox" ? b.checked : b.value;
843
- l(v);
844
- }), b.addEventListener("keydown", (v) => {
845
- if (v.key === "Enter") {
846
- v.stopPropagation(), v.preventDefault(), r = !0;
847
- const S = w && b instanceof HTMLInputElement && b.type === "checkbox" ? b.checked : b.value;
848
- l(S), D(t, o, !1);
849
- }
850
- v.key === "Escape" && (v.stopPropagation(), v.preventDefault(), a(), D(t, o, !0));
851
- }), w && b instanceof HTMLInputElement && b.type === "checkbox" && b.addEventListener("change", () => {
852
- const v = b.checked;
853
- l(v);
854
- }), setTimeout(() => b.focus(), 0);
855
- }
856
- d.appendChild(c);
857
- } else if (typeof h == "string") {
858
- const c = document.createElement(h);
859
- c.value = p, c.addEventListener("change", () => l(c.value)), d.appendChild(c);
860
- } else if (typeof h == "function") {
861
- const c = h({ row: e, value: p, field: i.field, column: i, commit: l, cancel: a });
862
- typeof c == "string" ? d.innerHTML = c : d.appendChild(c);
863
- } else if (h && typeof h == "object") {
864
- const c = document.createElement("div");
865
- c.setAttribute("data-external-editor", ""), c.setAttribute("data-field", i.field), d.appendChild(c);
866
- const u = { row: e, value: p, field: i.field, column: i, commit: l, cancel: a };
867
- if (h.mount)
868
- try {
869
- h.mount({ placeholder: c, context: u, spec: h });
870
- } catch {
871
- }
872
- else
873
- t.dispatchEvent(
874
- new CustomEvent("mount-external-editor", { detail: { placeholder: c, spec: h, context: u } })
875
- );
876
- }
877
- }
878
- function ne(t, e) {
879
- !t._sortState || t._sortState.field !== e.field ? (t._sortState || (t.__originalOrder = t._rows.slice()), ie(t, e, 1)) : t._sortState.direction === 1 ? ie(t, e, -1) : (t._sortState = null, t.__rowRenderEpoch++, t._rowPool.forEach((i) => i.__epoch = -1), t._rows = t.__originalOrder.slice(), q(t), t._headerRowEl?.querySelectorAll('[role="columnheader"].sortable')?.forEach((i) => {
880
- i.getAttribute("aria-sort") ? (i.getAttribute("aria-sort") === "ascending" || i.getAttribute("aria-sort") === "descending") && (t._sortState || i.setAttribute("aria-sort", "none")) : i.setAttribute("aria-sort", "none");
881
- }), t.refreshVirtualWindow(!0), t.dispatchEvent(
882
- new CustomEvent("sort-change", { detail: { field: e.field, direction: 0 } })
883
- ), t.requestStateChange?.());
884
- }
885
- function ie(t, e, o) {
886
- t._sortState = { field: e.field, direction: o };
887
- const i = e.sortComparator || ((n, s) => n == null && s == null ? 0 : n == null ? -1 : s == null || n > s ? 1 : n < s ? -1 : 0);
888
- t._rows.sort((n, s) => i(n[e.field], s[e.field], n, s) * o), t.__rowRenderEpoch++, t._rowPool.forEach((n) => n.__epoch = -1), q(t), t.refreshVirtualWindow(!0), t.dispatchEvent(
889
- new CustomEvent("sort-change", { detail: { field: e.field, direction: o } })
890
- ), t.requestStateChange?.();
891
- }
892
- function De(t, e) {
893
- typeof e == "string" ? t.textContent = e : e instanceof HTMLElement && (t.innerHTML = "", t.appendChild(e.cloneNode(!0)));
894
- }
895
- function q(t) {
896
- t._headerRowEl = t.findHeaderRow();
897
- const e = t._headerRowEl;
898
- e.innerHTML = "", t._visibleColumns.forEach((o, i) => {
899
- const n = document.createElement("div");
900
- n.className = "cell", Y(n, "header-cell"), n.setAttribute("role", "columnheader"), n.setAttribute("aria-colindex", String(i + 1)), n.setAttribute("data-field", o.field), n.setAttribute("data-col", String(i));
901
- const s = o.__headerTemplate;
902
- if (s) Array.from(s.childNodes).forEach((r) => n.appendChild(r.cloneNode(!0)));
903
- else {
904
- const r = o.header || o.field, l = document.createElement("span");
905
- l.textContent = r, n.appendChild(l);
906
- }
907
- if (o.sortable) {
908
- n.classList.add("sortable"), n.tabIndex = 0;
909
- const r = document.createElement("span");
910
- Y(r, "sort-indicator"), r.style.opacity = "0.6";
911
- const l = t._sortState?.field === o.field ? t._sortState.direction : 0, a = { ...H, ...t.icons }, d = l === 1 ? a.sortAsc : l === -1 ? a.sortDesc : a.sortNone;
912
- De(r, d), n.appendChild(r), n.setAttribute("aria-sort", l === 0 ? "none" : l === 1 ? "ascending" : "descending"), n.addEventListener("click", (f) => {
913
- t._resizeController?.isResizing || t._dispatchHeaderClick?.(f, i, n) || ne(t, o);
914
- }), n.addEventListener("keydown", (f) => {
915
- if (f.key === "Enter" || f.key === " ") {
916
- if (f.preventDefault(), t._dispatchHeaderClick?.(f, i, n)) return;
917
- ne(t, o);
918
- }
919
- });
920
- }
921
- if (o.resizable) {
922
- n.style.position = "relative";
923
- const r = document.createElement("div");
924
- r.className = "resize-handle", r.setAttribute("aria-hidden", "true"), r.addEventListener("mousedown", (l) => {
925
- l.stopPropagation(), l.preventDefault(), t._resizeController.start(l, i, n);
926
- }), r.addEventListener("dblclick", (l) => {
927
- l.stopPropagation(), l.preventDefault(), t._resizeController.resetColumn(i);
928
- }), n.appendChild(r);
929
- }
930
- e.appendChild(n);
931
- }), e.querySelectorAll(".cell.sortable").forEach((o) => {
932
- o.getAttribute("aria-sort") || o.setAttribute("aria-sort", "none");
933
- }), e.children.length > 0 ? (e.setAttribute("role", "row"), e.setAttribute("aria-rowindex", "1")) : (e.removeAttribute("role"), e.removeAttribute("aria-rowindex"));
934
- }
935
- function Ne(t) {
936
- let e = null, o = null, i = null, n = null;
937
- const s = (a) => {
938
- if (!e) return;
939
- const d = a.clientX - e.startX, f = Math.max(40, e.startWidth + d), h = t._visibleColumns[e.colIndex];
940
- h.width = f, h.__userResized = !0, h.__renderedWidth = f, o == null && (o = requestAnimationFrame(() => {
941
- o = null, t.updateTemplate?.();
942
- })), t.dispatchEvent(
943
- new CustomEvent("column-resize", { detail: { field: h.field, width: f } })
944
- );
945
- };
946
- let r = !1;
947
- const l = () => {
948
- const a = e !== null;
949
- a && (r = !0, requestAnimationFrame(() => {
950
- r = !1;
951
- })), window.removeEventListener("mousemove", s), window.removeEventListener("mouseup", l), i !== null && (document.documentElement.style.cursor = i, i = null), n !== null && (document.body.style.userSelect = n, n = null), e = null, a && t.requestStateChange && t.requestStateChange();
952
- };
953
- return {
954
- get isResizing() {
955
- return e !== null || r;
956
- },
957
- start(a, d, f) {
958
- a.preventDefault();
959
- const h = f.getBoundingClientRect();
960
- e = { startX: a.clientX, colIndex: d, startWidth: h.width }, window.addEventListener("mousemove", s), window.addEventListener("mouseup", l), i === null && (i = document.documentElement.style.cursor), document.documentElement.style.cursor = "e-resize", n === null && (n = document.body.style.userSelect), document.body.style.userSelect = "none";
961
- },
962
- resetColumn(a) {
963
- const d = t._visibleColumns[a];
964
- d && (d.__userResized = !1, d.__renderedWidth = void 0, d.width = d.__originalWidth, t.updateTemplate?.(), t.requestStateChange?.(), t.dispatchEvent(
965
- new CustomEvent("column-resize-reset", { detail: { field: d.field, width: d.width } })
966
- ));
967
- },
968
- dispose() {
969
- l();
970
- }
971
- };
972
- }
973
- function V(t) {
974
- return t ? typeof t == "string" ? t : t.outerHTML : "";
975
- }
976
- function qe() {
977
- return {
978
- toolPanels: /* @__PURE__ */ new Map(),
979
- headerContents: /* @__PURE__ */ new Map(),
980
- toolbarButtons: /* @__PURE__ */ new Map(),
981
- lightDomButtons: [],
982
- lightDomHeaderContent: [],
983
- isPanelOpen: !1,
984
- expandedSections: /* @__PURE__ */ new Set(),
985
- headerContentCleanups: /* @__PURE__ */ new Map(),
986
- panelCleanups: /* @__PURE__ */ new Map(),
987
- toolbarButtonCleanups: /* @__PURE__ */ new Map(),
988
- // Deprecated - kept for backward compatibility
989
- activePanel: null,
990
- activePanelCleanup: null
991
- };
992
- }
993
- function Be(t, e) {
994
- return !!(t?.header?.title || t?.header?.toolbarButtons?.length || e.toolPanels.size > 0 || e.headerContents.size > 0 || e.toolbarButtons.size > 0 || e.lightDomButtons.length > 0 || e.lightDomHeaderContent.length > 0);
995
- }
996
- function Ie(t, e, o = "☰") {
997
- const i = t?.header?.title ?? "", n = !!i, s = V(o), r = t?.header?.toolbarButtons ?? [], l = r.length > 0, a = e.toolbarButtons.size > 0, d = e.lightDomButtons.length > 0, f = e.toolPanels.size > 0, p = (l || a || d) && f, c = [...r].sort((w, v) => (w.order ?? 100) - (v.order ?? 100)), u = [...e.toolbarButtons.values()].sort((w, v) => (w.order ?? 100) - (v.order ?? 100));
998
- let b = "";
999
- for (const w of c)
1000
- w.icon && w.action && (b += `<button class="tbw-toolbar-btn" data-btn="${w.id}" title="${w.label}" aria-label="${w.label}"${w.disabled ? " disabled" : ""}>${w.icon}</button>`);
1001
- for (const w of u)
1002
- w.icon && w.action && (b += `<button class="tbw-toolbar-btn" data-btn="${w.id}" title="${w.label}" aria-label="${w.label}"${w.disabled ? " disabled" : ""}>${w.icon}</button>`);
1003
- for (const w of c)
1004
- (w.element || w.render) && (b += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${w.id}"></div>`);
1005
- for (const w of u)
1006
- (w.element || w.render) && (b += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${w.id}"></div>`);
1007
- if (d && (b += '<slot name="toolbar"></slot>'), p && (b += '<div class="tbw-toolbar-separator"></div>'), f) {
1008
- const w = e.isPanelOpen;
1009
- b += `<button class="tbw-toolbar-btn${w ? " active" : ""}" data-panel-toggle title="Settings" aria-label="Toggle settings panel" aria-pressed="${w}" aria-controls="tbw-tool-panel">${s}</button>`;
1010
- }
1011
- return `
1012
- <div class="tbw-shell-header" part="shell-header" role="presentation">
1013
- ${n ? `<div class="tbw-shell-title">${i}</div>` : ""}
1014
- <div class="tbw-shell-content" part="shell-content" role="presentation">
1015
- <slot name="header-content"></slot>
1016
- </div>
1017
- <div class="tbw-shell-toolbar" part="shell-toolbar" role="presentation">
1018
- ${b}
1019
- </div>
1020
- </div>
1021
- `;
1022
- }
1023
- function $e(t, e, o, i) {
1024
- const n = t?.toolPanel?.position ?? "right", s = e.toolPanels.size > 0, r = e.isPanelOpen, l = V(i?.expand ?? H.expand), a = V(i?.collapse ?? H.collapse), d = [...e.toolPanels.values()].sort((u, b) => (u.order ?? 100) - (b.order ?? 100)), f = d.length === 1;
1025
- let h = "";
1026
- for (const u of d) {
1027
- const b = e.expandedSections.has(u.id), w = u.icon ? `<span class="tbw-accordion-icon">${u.icon}</span>` : "", v = f ? "" : `<span class="tbw-accordion-chevron">${b ? a : l}</span>`;
1028
- h += `
1029
- <div class="${`tbw-accordion-section${b ? " expanded" : ""}${f ? " single" : ""}`}" data-section="${u.id}">
1030
- <button class="tbw-accordion-header" aria-expanded="${b}" aria-controls="tbw-section-${u.id}"${f ? ' aria-disabled="true"' : ""}>
1031
- ${w}
1032
- <span class="tbw-accordion-title">${u.title}</span>
1033
- ${v}
1034
- </button>
1035
- <div class="tbw-accordion-content" id="tbw-section-${u.id}" role="presentation"></div>
1036
- </div>
1037
- `;
1038
- }
1039
- const c = s ? `
1040
- <aside class="tbw-tool-panel${r ? " open" : ""}" part="tool-panel" data-position="${n}" role="presentation" id="tbw-tool-panel">
1041
- <div class="tbw-tool-panel-resize" data-resize-handle data-handle-position="${n === "left" ? "right" : "left"}" aria-hidden="true"></div>
1042
- <div class="tbw-tool-panel-content" role="presentation">
1043
- <div class="tbw-accordion">
1044
- ${h}
1045
- </div>
1046
- </div>
1047
- </aside>
1048
- ` : "";
1049
- return n === "left" ? `
1050
- <div class="tbw-shell-body">
1051
- ${c}
1052
- <div class="tbw-grid-content">
1053
- ${o}
1054
- </div>
1055
- </div>
1056
- ` : `
1057
- <div class="tbw-shell-body">
1058
- <div class="tbw-grid-content">
1059
- ${o}
1060
- </div>
1061
- ${c}
1062
- </div>
1063
- `;
1064
- }
1065
- function se(t, e) {
1066
- const o = t.querySelector("tbw-grid-header");
1067
- if (!o) return;
1068
- o.style.display = "none";
1069
- const i = o.querySelectorAll("tbw-grid-header-content");
1070
- e.lightDomHeaderContent = Array.from(i), e.lightDomHeaderContent.forEach((s) => {
1071
- s.setAttribute("slot", "header-content");
1072
- });
1073
- const n = o.querySelectorAll("tbw-grid-tool-button");
1074
- e.lightDomButtons = Array.from(n), e.lightDomButtons.sort((s, r) => {
1075
- const l = parseInt(s.getAttribute("order") ?? "100", 10), a = parseInt(r.getAttribute("order") ?? "100", 10);
1076
- return l - a;
1077
- }), e.lightDomButtons.forEach((s) => {
1078
- s.setAttribute("slot", "toolbar");
1079
- });
1080
- }
1081
- function We(t, e, o, i) {
1082
- const n = t.querySelector(".tbw-shell-toolbar");
1083
- n && n.addEventListener("click", (r) => {
1084
- const l = r.target;
1085
- if (l.closest("[data-panel-toggle]")) {
1086
- i.onPanelToggle();
1087
- return;
1088
- }
1089
- const d = l.closest("[data-btn]");
1090
- if (d) {
1091
- const f = d.getAttribute("data-btn");
1092
- f && i.onToolbarButtonClick(f);
1093
- }
1094
- });
1095
- const s = t.querySelector(".tbw-accordion");
1096
- s && s.addEventListener("click", (r) => {
1097
- const a = r.target.closest(".tbw-accordion-header");
1098
- if (a) {
1099
- const f = a.closest("[data-section]")?.getAttribute("data-section");
1100
- f && i.onSectionToggle(f);
1101
- }
1102
- });
1103
- }
1104
- function Ve(t, e, o) {
1105
- const i = t.querySelector(".tbw-tool-panel"), n = t.querySelector("[data-resize-handle]"), s = t.querySelector(".tbw-shell-body");
1106
- if (!i || !n || !s)
1107
- return () => {
1108
- };
1109
- const r = e?.toolPanel?.position ?? "right", l = 200;
1110
- let a = 0, d = 0, f = 0, h = !1;
1111
- const p = (b) => {
1112
- if (!h) return;
1113
- b.preventDefault();
1114
- const w = r === "left" ? b.clientX - a : a - b.clientX, v = Math.min(f, Math.max(l, d + w));
1115
- i.style.width = `${v}px`;
1116
- }, c = () => {
1117
- if (!h) return;
1118
- h = !1, n.classList.remove("resizing"), i.style.transition = "", document.body.style.cursor = "", document.body.style.userSelect = "";
1119
- const b = i.getBoundingClientRect().width;
1120
- o(b), document.removeEventListener("mousemove", p), document.removeEventListener("mouseup", c);
1121
- }, u = (b) => {
1122
- b.preventDefault(), h = !0, a = b.clientX, d = i.getBoundingClientRect().width, f = s.getBoundingClientRect().width - 20, n.classList.add("resizing"), i.style.transition = "none", document.body.style.cursor = "col-resize", document.body.style.userSelect = "none", document.addEventListener("mousemove", p), document.addEventListener("mouseup", c);
1123
- };
1124
- return n.addEventListener("mousedown", u), () => {
1125
- n.removeEventListener("mousedown", u), document.removeEventListener("mousemove", p), document.removeEventListener("mouseup", c);
1126
- };
1127
- }
1128
- function Ge(t, e, o) {
1129
- const i = [...e?.header?.toolbarButtons ?? [], ...o.toolbarButtons.values()];
1130
- for (const n of i) {
1131
- const s = t.querySelector(`[data-btn-slot="${n.id}"]`);
1132
- if (!s) continue;
1133
- const r = o.toolbarButtonCleanups.get(n.id);
1134
- if (r && (r(), o.toolbarButtonCleanups.delete(n.id)), n.element)
1135
- s.appendChild(n.element);
1136
- else if (n.render) {
1137
- const l = n.render(s);
1138
- l && o.toolbarButtonCleanups.set(n.id, l);
1139
- }
1140
- }
1141
- }
1142
- function he(t, e) {
1143
- const o = t.querySelector(".tbw-shell-content");
1144
- if (!o) return;
1145
- const i = [...e.headerContents.values()].sort((s, r) => (s.order ?? 100) - (r.order ?? 100)), n = o.querySelector('slot[name="header-content"]');
1146
- for (const s of i) {
1147
- const r = e.headerContentCleanups.get(s.id);
1148
- r && (r(), e.headerContentCleanups.delete(s.id));
1149
- let l = o.querySelector(`[data-header-content="${s.id}"]`);
1150
- l || (l = document.createElement("div"), l.setAttribute("data-header-content", s.id), n ? o.insertBefore(l, n) : o.appendChild(l));
1151
- const a = s.render(l);
1152
- a && e.headerContentCleanups.set(s.id, a);
1153
- }
1154
- }
1155
- function Fe(t, e, o) {
1156
- if (!e.isPanelOpen) return;
1157
- const i = V(o?.expand ?? H.expand), n = V(o?.collapse ?? H.collapse);
1158
- for (const [s, r] of e.toolPanels) {
1159
- const l = e.expandedSections.has(s), a = t.querySelector(`[data-section="${s}"]`), d = a?.querySelector(".tbw-accordion-content");
1160
- if (!a || !d) continue;
1161
- a.classList.toggle("expanded", l);
1162
- const f = a.querySelector(".tbw-accordion-header");
1163
- f && f.setAttribute("aria-expanded", String(l));
1164
- const h = a.querySelector(".tbw-accordion-chevron");
1165
- if (h && (h.innerHTML = l ? n : i), l) {
1166
- if (d.children.length === 0) {
1167
- const p = r.render(d);
1168
- p && e.panelCleanups.set(s, p);
1169
- }
1170
- } else {
1171
- const p = e.panelCleanups.get(s);
1172
- p && (p(), e.panelCleanups.delete(s)), d.innerHTML = "";
1173
- }
1174
- }
1175
- }
1176
- function re(t, e) {
1177
- const o = t.querySelector("[data-panel-toggle]");
1178
- o && (o.classList.toggle("active", e.isPanelOpen), o.setAttribute("aria-pressed", String(e.isPanelOpen)));
1179
- }
1180
- function le(t, e) {
1181
- const o = t.querySelector(".tbw-tool-panel");
1182
- o && (o.classList.toggle("open", e.isPanelOpen), e.isPanelOpen || (o.style.width = ""));
1183
- }
1184
- function Ue(t, e) {
1185
- const o = [];
1186
- for (const i of t?.header?.toolbarButtons ?? [])
1187
- o.push({
1188
- id: i.id,
1189
- label: i.label,
1190
- disabled: i.disabled ?? !1,
1191
- source: "config"
1192
- });
1193
- for (const i of e.toolbarButtons.values())
1194
- o.push({
1195
- id: i.id,
1196
- label: i.label,
1197
- disabled: i.disabled ?? !1,
1198
- source: "config"
1199
- });
1200
- for (let i = 0; i < e.lightDomButtons.length; i++) {
1201
- const s = e.lightDomButtons[i].querySelector("button");
1202
- o.push({
1203
- id: `light-dom-${i}`,
1204
- label: s?.getAttribute("title") ?? s?.getAttribute("aria-label") ?? "",
1205
- disabled: s?.disabled ?? !1,
1206
- source: "light-dom"
1207
- });
1208
- }
1209
- for (const i of e.toolPanels.values())
1210
- o.push({
1211
- id: `panel-toggle-${i.id}`,
1212
- label: i.tooltip ?? i.title,
1213
- disabled: !1,
1214
- source: "panel-toggle",
1215
- panelId: i.id
1216
- });
1217
- return o;
1218
- }
1219
- function Xe(t) {
1220
- for (const e of t.headerContentCleanups.values())
1221
- e();
1222
- t.headerContentCleanups.clear(), t.activePanelCleanup && (t.activePanelCleanup(), t.activePanelCleanup = null);
1223
- for (const e of t.toolbarButtonCleanups.values())
1224
- e();
1225
- t.toolbarButtonCleanups.clear(), t.activePanel && t.toolPanels.get(t.activePanel)?.onClose?.(), t.toolPanels.clear(), t.headerContents.clear(), t.toolbarButtons.clear(), t.lightDomButtons = [], t.lightDomHeaderContent = [], t.activePanel = null;
1226
- }
1227
- function Ke(t, e) {
1228
- let o = !1;
1229
- const i = {
1230
- get isInitialized() {
1231
- return o;
1232
- },
1233
- setInitialized(n) {
1234
- o = n;
1235
- },
1236
- get isPanelOpen() {
1237
- return t.isPanelOpen;
1238
- },
1239
- get activePanel() {
1240
- return t.isPanelOpen && t.expandedSections.size > 0 ? [...t.expandedSections][0] : null;
1241
- },
1242
- get expandedSections() {
1243
- return [...t.expandedSections];
1244
- },
1245
- openToolPanel() {
1246
- if (t.isPanelOpen) return;
1247
- if (t.toolPanels.size === 0) {
1248
- console.warn("[tbw-grid] No tool panels registered");
1249
- return;
1250
- }
1251
- if (t.isPanelOpen = !0, t.expandedSections.size === 0 && t.toolPanels.size > 0) {
1252
- const r = [...t.toolPanels.values()].sort((l, a) => (l.order ?? 100) - (a.order ?? 100))[0];
1253
- r && t.expandedSections.add(r.id);
1254
- }
1255
- const n = e.getShadow();
1256
- re(n, t), le(n, t), Fe(n, t, e.getAccordionIcons()), e.emit("tool-panel-open", { sections: i.expandedSections });
1257
- },
1258
- closeToolPanel() {
1259
- if (!t.isPanelOpen) return;
1260
- for (const s of t.panelCleanups.values())
1261
- s();
1262
- t.panelCleanups.clear(), t.activePanelCleanup && (t.activePanelCleanup(), t.activePanelCleanup = null);
1263
- for (const s of t.toolPanels.values())
1264
- s.onClose?.();
1265
- t.isPanelOpen = !1;
1266
- const n = e.getShadow();
1267
- re(n, t), le(n, t), e.emit("tool-panel-close", {});
1268
- },
1269
- toggleToolPanel() {
1270
- t.isPanelOpen ? i.closeToolPanel() : i.openToolPanel();
1271
- },
1272
- toggleToolPanelSection(n) {
1273
- const s = t.toolPanels.get(n);
1274
- if (!s) {
1275
- console.warn(`[tbw-grid] Tool panel section "${n}" not found`);
1276
- return;
1277
- }
1278
- if (t.toolPanels.size === 1)
1279
- return;
1280
- const r = e.getShadow(), l = t.expandedSections.has(n);
1281
- if (l) {
1282
- const a = t.panelCleanups.get(n);
1283
- a && (a(), t.panelCleanups.delete(n)), s.onClose?.(), t.expandedSections.delete(n), X(r, n, !1);
1284
- } else {
1285
- for (const [a, d] of t.toolPanels)
1286
- if (a !== n && t.expandedSections.has(a)) {
1287
- const f = t.panelCleanups.get(a);
1288
- f && (f(), t.panelCleanups.delete(a)), d.onClose?.(), t.expandedSections.delete(a), X(r, a, !1);
1289
- const h = r.querySelector(`[data-section="${a}"] .tbw-accordion-content`);
1290
- h && (h.innerHTML = "");
1291
- }
1292
- t.expandedSections.add(n), X(r, n, !0), Ye(r, t, n);
1293
- }
1294
- e.emit("tool-panel-section-toggle", { id: n, expanded: !l });
1295
- },
1296
- getToolPanels() {
1297
- return [...t.toolPanels.values()];
1298
- },
1299
- registerToolPanel(n) {
1300
- if (t.toolPanels.has(n.id)) {
1301
- console.warn(`[tbw-grid] Tool panel "${n.id}" already registered`);
1302
- return;
1303
- }
1304
- t.toolPanels.set(n.id, n), o && e.refreshShellHeader();
1305
- },
1306
- unregisterToolPanel(n) {
1307
- if (t.expandedSections.has(n)) {
1308
- const s = t.panelCleanups.get(n);
1309
- s && (s(), t.panelCleanups.delete(n)), t.expandedSections.delete(n);
1310
- }
1311
- t.toolPanels.delete(n), o && e.refreshShellHeader();
1312
- },
1313
- getHeaderContents() {
1314
- return [...t.headerContents.values()];
1315
- },
1316
- registerHeaderContent(n) {
1317
- if (t.headerContents.has(n.id)) {
1318
- console.warn(`[tbw-grid] Header content "${n.id}" already registered`);
1319
- return;
1320
- }
1321
- t.headerContents.set(n.id, n), o && he(e.getShadow(), t);
1322
- },
1323
- unregisterHeaderContent(n) {
1324
- const s = t.headerContentCleanups.get(n);
1325
- s && (s(), t.headerContentCleanups.delete(n)), t.headerContents.get(n)?.onDestroy?.(), t.headerContents.delete(n), e.getShadow().querySelector(`[data-header-content="${n}"]`)?.remove();
1326
- },
1327
- getToolbarButtons() {
1328
- return Ue(e.getShellConfig(), t);
1329
- },
1330
- registerToolbarButton(n) {
1331
- if (t.toolbarButtons.has(n.id)) {
1332
- console.warn(`[tbw-grid] Toolbar button "${n.id}" already registered`);
1333
- return;
1334
- }
1335
- t.toolbarButtons.set(n.id, n), o && e.refreshShellHeader();
1336
- },
1337
- unregisterToolbarButton(n) {
1338
- const s = t.toolbarButtonCleanups.get(n);
1339
- s && (s(), t.toolbarButtonCleanups.delete(n)), t.toolbarButtons.delete(n), o && e.refreshShellHeader();
1340
- },
1341
- setToolbarButtonDisabled(n, s) {
1342
- const r = t.toolbarButtons.get(n);
1343
- r && (r.disabled = s);
1344
- const l = e.getShadow().querySelector(`[data-btn="${n}"]`);
1345
- l && (l.disabled = s);
1346
- }
1347
- };
1348
- return i;
1349
- }
1350
- function X(t, e, o) {
1351
- const i = t.querySelector(`[data-section="${e}"]`);
1352
- i && i.classList.toggle("expanded", o);
1353
- }
1354
- function Ye(t, e, o) {
1355
- const i = e.toolPanels.get(o);
1356
- if (!i?.render) return;
1357
- const n = t.querySelector(`[data-section="${o}"] .tbw-accordion-content`);
1358
- if (!n) return;
1359
- const s = i.render(n);
1360
- s && e.panelCleanups.set(o, s);
1361
- }
1362
- class je {
1363
- constructor(e) {
1364
- this.grid = e;
1365
- }
1366
- /** Plugin instances in order of attachment */
1367
- plugins = [];
1368
- /** Map from plugin class to instance for fast lookup */
1369
- pluginMap = /* @__PURE__ */ new Map();
1370
- /** Cell renderers registered by plugins */
1371
- cellRenderers = /* @__PURE__ */ new Map();
1372
- /** Header renderers registered by plugins */
1373
- headerRenderers = /* @__PURE__ */ new Map();
1374
- /** Cell editors registered by plugins */
1375
- cellEditors = /* @__PURE__ */ new Map();
1376
- /**
1377
- * Attach all plugins from the config.
1378
- */
1379
- attachAll(e) {
1380
- for (const o of e)
1381
- this.attach(o);
1382
- }
1383
- /**
1384
- * Attach a plugin to this grid.
1385
- */
1386
- attach(e) {
1387
- if (this.pluginMap.set(e.constructor, e), this.plugins.push(e), e.cellRenderers)
1388
- for (const [o, i] of Object.entries(e.cellRenderers))
1389
- this.cellRenderers.set(o, i);
1390
- if (e.headerRenderers)
1391
- for (const [o, i] of Object.entries(e.headerRenderers))
1392
- this.headerRenderers.set(o, i);
1393
- if (e.cellEditors)
1394
- for (const [o, i] of Object.entries(e.cellEditors))
1395
- this.cellEditors.set(o, i);
1396
- e.attach(this.grid);
1397
- }
1398
- /**
1399
- * Detach all plugins and clean up.
1400
- */
1401
- detachAll() {
1402
- for (let e = this.plugins.length - 1; e >= 0; e--)
1403
- this.plugins[e].detach();
1404
- this.plugins = [], this.pluginMap.clear(), this.cellRenderers.clear(), this.headerRenderers.clear(), this.cellEditors.clear();
1405
- }
1406
- /**
1407
- * Get a plugin instance by its class.
1408
- */
1409
- getPlugin(e) {
1410
- return this.pluginMap.get(e);
1411
- }
1412
- /**
1413
- * Get a plugin instance by its name.
1414
- */
1415
- getPluginByName(e) {
1416
- return this.plugins.find((o) => o.name === e);
1417
- }
1418
- /**
1419
- * Check if a plugin is attached.
1420
- */
1421
- hasPlugin(e) {
1422
- return this.pluginMap.has(e);
1423
- }
1424
- /**
1425
- * Get all attached plugins.
1426
- */
1427
- getAll() {
1428
- return this.plugins;
1429
- }
1430
- /**
1431
- * Get a cell renderer by type name.
1432
- */
1433
- getCellRenderer(e) {
1434
- return this.cellRenderers.get(e);
1435
- }
1436
- /**
1437
- * Get a header renderer by type name.
1438
- */
1439
- getHeaderRenderer(e) {
1440
- return this.headerRenderers.get(e);
1441
- }
1442
- /**
1443
- * Get a cell editor by type name.
1444
- */
1445
- getCellEditor(e) {
1446
- return this.cellEditors.get(e);
1447
- }
1448
- /**
1449
- * Get all CSS styles from all plugins.
1450
- */
1451
- getAllStyles() {
1452
- return this.plugins.filter((e) => e.styles).map((e) => e.styles).join(`
1453
- `);
1454
- }
1455
- // #region Hook execution methods
1456
- /**
1457
- * Execute processRows hook on all plugins.
1458
- */
1459
- processRows(e) {
1460
- let o = [...e];
1461
- for (const i of this.plugins)
1462
- i.processRows && (o = i.processRows(o));
1463
- return o;
1464
- }
1465
- /**
1466
- * Execute processColumns hook on all plugins.
1467
- */
1468
- processColumns(e) {
1469
- let o = [...e];
1470
- for (const i of this.plugins)
1471
- i.processColumns && (o = i.processColumns(o));
1472
- return o;
1473
- }
1474
- /**
1475
- * Execute beforeRender hook on all plugins.
1476
- */
1477
- beforeRender() {
1478
- for (const e of this.plugins)
1479
- e.beforeRender?.();
1480
- }
1481
- /**
1482
- * Execute afterRender hook on all plugins.
1483
- */
1484
- afterRender() {
1485
- for (const e of this.plugins)
1486
- e.afterRender?.();
1487
- }
1488
- /**
1489
- * Execute onScrollRender hook on all plugins.
1490
- * Called after scroll-triggered row rendering for lightweight visual state updates.
1491
- */
1492
- onScrollRender() {
1493
- for (const e of this.plugins)
1494
- e.onScrollRender?.();
1495
- }
1496
- /**
1497
- * Get total extra height contributed by plugins (e.g., expanded detail rows).
1498
- * Used to adjust scrollbar height calculations.
1499
- */
1500
- getExtraHeight() {
1501
- let e = 0;
1502
- for (const o of this.plugins)
1503
- typeof o.getExtraHeight == "function" && (e += o.getExtraHeight());
1504
- return e;
1505
- }
1506
- /**
1507
- * Get extra height from plugins that appears before a given row index.
1508
- * Used by virtualization to correctly position the scroll window.
1509
- */
1510
- getExtraHeightBefore(e) {
1511
- let o = 0;
1512
- for (const i of this.plugins)
1513
- typeof i.getExtraHeightBefore == "function" && (o += i.getExtraHeightBefore(e));
1514
- return o;
1515
- }
1516
- /**
1517
- * Adjust the virtualization start index based on plugin needs.
1518
- * Returns the minimum start index from all plugins.
1519
- */
1520
- adjustVirtualStart(e, o, i) {
1521
- let n = e;
1522
- for (const s of this.plugins)
1523
- if (typeof s.adjustVirtualStart == "function") {
1524
- const r = s.adjustVirtualStart(e, o, i);
1525
- r < n && (n = r);
1526
- }
1527
- return n;
1528
- }
1529
- /**
1530
- * Execute renderRow hook on all plugins.
1531
- * Returns true if any plugin handled the row.
1532
- */
1533
- renderRow(e, o, i) {
1534
- for (const n of this.plugins)
1535
- if (n.renderRow?.(e, o, i))
1536
- return !0;
1537
- return !1;
1538
- }
1539
- /**
1540
- * Query all plugins with a generic query and collect responses.
1541
- * This enables inter-plugin communication without the core knowing plugin-specific concepts.
1542
- *
1543
- * Common query types are defined in PLUGIN_QUERIES, but plugins can define their own.
1544
- *
1545
- * @param query - The query object containing type and context
1546
- * @returns Array of non-undefined responses from plugins
1547
- */
1548
- queryPlugins(e) {
1549
- const o = [];
1550
- for (const i of this.plugins) {
1551
- const n = i.onPluginQuery?.(e);
1552
- n !== void 0 && o.push(n);
1553
- }
1554
- return o;
1555
- }
1556
- /**
1557
- * Execute onKeyDown hook on all plugins.
1558
- * Returns true if any plugin handled the event.
1559
- */
1560
- onKeyDown(e) {
1561
- for (const o of this.plugins)
1562
- if (o.onKeyDown?.(e))
1563
- return !0;
1564
- return !1;
1565
- }
1566
- /**
1567
- * Execute onCellClick hook on all plugins.
1568
- * Returns true if any plugin handled the event.
1569
- */
1570
- onCellClick(e) {
1571
- for (const o of this.plugins)
1572
- if (o.onCellClick?.(e))
1573
- return !0;
1574
- return !1;
1575
- }
1576
- /**
1577
- * Execute onRowClick hook on all plugins.
1578
- * Returns true if any plugin handled the event.
1579
- */
1580
- onRowClick(e) {
1581
- for (const o of this.plugins)
1582
- if (o.onRowClick?.(e))
1583
- return !0;
1584
- return !1;
1585
- }
1586
- /**
1587
- * Execute onHeaderClick hook on all plugins.
1588
- * Returns true if any plugin handled the event.
1589
- */
1590
- onHeaderClick(e) {
1591
- for (const o of this.plugins)
1592
- if (o.onHeaderClick?.(e))
1593
- return !0;
1594
- return !1;
1595
- }
1596
- /**
1597
- * Execute onScroll hook on all plugins.
1598
- */
1599
- onScroll(e) {
1600
- for (const o of this.plugins)
1601
- o.onScroll?.(e);
1602
- }
1603
- /**
1604
- * Execute onCellMouseDown hook on all plugins.
1605
- * Returns true if any plugin handled the event.
1606
- */
1607
- onCellMouseDown(e) {
1608
- for (const o of this.plugins)
1609
- if (o.onCellMouseDown?.(e))
1610
- return !0;
1611
- return !1;
1612
- }
1613
- /**
1614
- * Execute onCellMouseMove hook on all plugins.
1615
- * Returns true if any plugin handled the event.
1616
- */
1617
- onCellMouseMove(e) {
1618
- for (const o of this.plugins)
1619
- if (o.onCellMouseMove?.(e))
1620
- return !0;
1621
- return !1;
1622
- }
1623
- /**
1624
- * Execute onCellMouseUp hook on all plugins.
1625
- * Returns true if any plugin handled the event.
1626
- */
1627
- onCellMouseUp(e) {
1628
- for (const o of this.plugins)
1629
- if (o.onCellMouseUp?.(e))
1630
- return !0;
1631
- return !1;
1632
- }
1633
- // #endregion
1634
- // #region Scroll Boundary Hooks
1635
- /**
1636
- * Collect horizontal scroll boundary offsets from all plugins.
1637
- * Combines offsets from all plugins that report them.
1638
- *
1639
- * @param rowEl - The row element (optional, for calculating widths from rendered cells)
1640
- * @param focusedCell - The currently focused cell element (optional, to determine if scrolling should be skipped)
1641
- * @returns Combined left and right pixel offsets, plus skipScroll if any plugin requests it
1642
- */
1643
- getHorizontalScrollOffsets(e, o) {
1644
- let i = 0, n = 0, s = !1;
1645
- for (const r of this.plugins) {
1646
- const l = r.getHorizontalScrollOffsets?.(e, o);
1647
- l && (i += l.left, n += l.right, l.skipScroll && (s = !0));
1648
- }
1649
- return { left: i, right: n, skipScroll: s };
1650
- }
1651
- // #endregion
1652
- // #region Shell Integration Hooks
1653
- /**
1654
- * Collect tool panels from all plugins.
1655
- * Returns panels sorted by order (ascending).
1656
- */
1657
- getToolPanels() {
1658
- const e = [];
1659
- for (const o of this.plugins) {
1660
- const i = o.getToolPanel?.();
1661
- i && e.push({ plugin: o, panel: i });
1662
- }
1663
- return e.sort((o, i) => (o.panel.order ?? 0) - (i.panel.order ?? 0));
1664
- }
1665
- /**
1666
- * Collect header contents from all plugins.
1667
- * Returns contents sorted by order (ascending).
1668
- */
1669
- getHeaderContents() {
1670
- const e = [];
1671
- for (const o of this.plugins) {
1672
- const i = o.getHeaderContent?.();
1673
- i && e.push({ plugin: o, content: i });
1674
- }
1675
- return e.sort((o, i) => (o.content.order ?? 0) - (i.content.order ?? 0));
1676
- }
1677
- // #endregion
1678
- }
1679
- class W extends HTMLElement {
1680
- // TODO: Rename to 'data-grid' when migration is complete
1681
- static tagName = "tbw-grid";
1682
- static version = "0.2.6";
1683
- // ---------------- Observed Attributes ----------------
1684
- static get observedAttributes() {
1685
- return ["rows", "columns", "grid-config", "fit-mode", "edit-on"];
1686
- }
1687
- #o;
1688
- #O = !1;
1689
- // ---------------- Ready Promise ----------------
1690
- #I;
1691
- #$;
1692
- // #region Input Properties
1693
- // These backing fields store raw user input. They are merged into
1694
- // #effectiveConfig by #mergeEffectiveConfig(). Never read directly
1695
- // for rendering logic - always use effectiveConfig or derived state.
1696
- #r = [];
1697
- #l;
1698
- #g;
1699
- #C;
1700
- #y;
1701
- // #endregion
1702
- // #region Single Source of Truth
1703
- // All input sources converge here. This is the canonical config
1704
- // that all rendering and logic should read from.
1705
- #t = {};
1706
- #p = !1;
1707
- #b = 0;
1708
- #S = null;
1709
- #R = !1;
1710
- // Cached flag for plugin scroll handlers
1711
- #M;
1712
- // Cached hook to avoid closures
1713
- #x = !1;
1714
- #A = null;
1715
- #T = null;
1716
- #L = null;
1717
- #P = null;
1718
- #m = null;
1719
- #v = null;
1720
- #_ = null;
1721
- #d = 0;
1722
- #u = 0;
1723
- #w = 0;
1724
- #a;
1725
- #E;
1726
- // ---------------- Plugin System ----------------
1727
- #e;
1728
- // ---------------- Column State ----------------
1729
- #z;
1730
- #h;
1731
- // ---------------- Shell State ----------------
1732
- #i = qe();
1733
- #n;
1734
- #H;
1735
- // #endregion
1736
- // #region Derived State
1737
- // _rows: result of applying plugin processRows hooks
1738
- _rows = [];
1739
- // _baseColumns: columns before plugin transformation (analogous to #rows for row processing)
1740
- // This is the source of truth for processColumns - plugins transform these
1741
- #D = [];
1742
- // _columns is a getter/setter that operates on effectiveConfig.columns
1743
- // This ensures effectiveConfig.columns is the single source of truth for columns
1744
- // _columns always contains ALL columns (including hidden)
1745
- get _columns() {
1746
- return this.#t.columns ?? [];
1747
- }
1748
- set _columns(e) {
1749
- this.#t.columns = e;
1750
- }
1751
- // visibleColumns returns only visible columns for rendering
1752
- // This is what header/row rendering should use
1753
- get _visibleColumns() {
1754
- return this._columns.filter((e) => !e.hidden);
1755
- }
1756
- // #endregion
1757
- // #region Runtime State (Plugin-accessible)
1758
- // DOM references
1759
- _headerRowEl;
1760
- _bodyEl;
1761
- _rowPool = [];
1762
- _resizeController;
1763
- // Virtualization & scroll state
1764
- _virtualization = {
1765
- enabled: !0,
1766
- rowHeight: 28,
1767
- bypassThreshold: 24,
1768
- start: 0,
1769
- end: 0,
1770
- container: null,
1771
- viewportEl: null,
1772
- totalHeightEl: null
1773
- };
1774
- // Focus & navigation
1775
- _focusRow = 0;
1776
- _focusCol = 0;
1777
- // Sort state
1778
- _sortState = null;
1779
- // Edit state
1780
- _activeEditRows = -1;
1781
- _rowEditSnapshots = /* @__PURE__ */ new Map();
1782
- _changedRowIndices = /* @__PURE__ */ new Set();
1783
- // Layout
1784
- _gridTemplate = "";
1785
- // #endregion
1786
- // #region Implementation Details (Internal only)
1787
- __rowRenderEpoch = 0;
1788
- __didInitialAutoSize = !1;
1789
- __lightDomColumnsCache;
1790
- __originalColumnNodes;
1791
- __originalOrder = [];
1792
- // #endregion
1793
- // ---------------- Public API Props (getters/setters) ----------------
1794
- // Getters return the EFFECTIVE value (after merging), not the raw input.
1795
- // This is what consumers and plugins need - the current resolved state.
1796
- // Setters update input properties which trigger re-merge into effectiveConfig.
1797
- get rows() {
1798
- return this._rows;
1799
- }
1800
- set rows(e) {
1801
- const o = this.#r;
1802
- this.#r = e, o !== e && this.#ee();
1803
- }
1804
- /**
1805
- * Get the original unfiltered/unprocessed rows.
1806
- * Use this when you need access to all source data regardless of active filters.
1807
- */
1808
- get sourceRows() {
1809
- return this.#r;
1810
- }
1811
- get columns() {
1812
- return [...this._columns];
1813
- }
1814
- set columns(e) {
1815
- const o = this.#l;
1816
- this.#l = e, o !== e && this.#te();
1817
- }
1818
- get gridConfig() {
1819
- return this.#t;
1820
- }
1821
- set gridConfig(e) {
1822
- const o = this.#g;
1823
- this.#g = e, o !== e && this.#oe();
1824
- }
1825
- get fitMode() {
1826
- return this.#t.fitMode ?? "stretch";
1827
- }
1828
- set fitMode(e) {
1829
- const o = this.#C;
1830
- this.#C = e, o !== e && this.#J();
1831
- }
1832
- get editOn() {
1833
- return this.#t.editOn;
1834
- }
1835
- set editOn(e) {
1836
- const o = this.#y;
1837
- this.#y = e, o !== e && this.#Q();
1838
- }
1839
- /**
1840
- * Effective config accessor for internal modules and plugins.
1841
- * Returns the merged config (single source of truth) before plugin processing.
1842
- * Use this when you need the raw merged config (e.g., for column definitions including hidden).
1843
- * @internal Plugin API
1844
- */
1845
- get effectiveConfig() {
1846
- return this.#t;
1847
- }
1848
- /**
1849
- * Get the disconnect signal for event listener cleanup.
1850
- * This signal is aborted when the grid disconnects from the DOM.
1851
- * Plugins and internal code can use this for automatic listener cleanup.
1852
- * @internal Plugin API
1853
- * @example
1854
- * element.addEventListener('click', handler, { signal: this.grid.disconnectSignal });
1855
- */
1856
- get disconnectSignal() {
1857
- return this.#a || (this.#a = new AbortController()), this.#a.signal;
1858
- }
1859
- constructor() {
1860
- super(), this.#o = this.attachShadow({ mode: "open" }), this.#K(), this.#I = new Promise((e) => this.#$ = e), this.#n = Ke(this.#i, {
1861
- getShadow: () => this.#o,
1862
- getShellConfig: () => this.#t?.shell,
1863
- getAccordionIcons: () => ({
1864
- expand: this.#t?.icons?.expand ?? H.expand,
1865
- collapse: this.#t?.icons?.collapse ?? H.collapse
1866
- }),
1867
- emit: (e, o) => this.#s(e, o),
1868
- refreshShellHeader: () => this.refreshShellHeader()
1869
- });
1870
- }
1871
- #K() {
1872
- const e = new CSSStyleSheet();
1873
- e.replaceSync(fe), this.#o.adoptedStyleSheets = [e];
1874
- }
1875
- // ---------------- Plugin System ----------------
1876
- /**
1877
- * Get a plugin instance by its class.
1878
- * Used by plugins for inter-plugin communication.
1879
- * @internal Plugin API
1880
- */
1881
- getPlugin(e) {
1882
- return this.#e?.getPlugin(e);
1883
- }
1884
- /**
1885
- * Get a plugin instance by its name.
1886
- * Used for loose coupling between plugins (avoids static imports).
1887
- * @internal Plugin API
1888
- */
1889
- getPluginByName(e) {
1890
- return this.#e?.getPluginByName(e);
1891
- }
1892
- /**
1893
- * Request a full re-render of the grid.
1894
- * Called by plugins when they need the grid to update.
1895
- * Note: This does NOT reset plugin state - just re-processes rows/columns and renders.
1896
- * @internal Plugin API
1897
- */
1898
- requestRender() {
1899
- this.#k(), this.#N(), q(this), z(this), this.refreshVirtualWindow(!0);
1900
- }
1901
- /**
1902
- * Update the grid's column template CSS.
1903
- * Called by resize controller during column resize operations.
1904
- * @internal
1905
- */
1906
- updateTemplate() {
1907
- z(this);
1908
- }
1909
- /**
1910
- * Request a lightweight style update without rebuilding DOM.
1911
- * Called by plugins when they only need to update CSS classes/styles.
1912
- * This runs all plugin afterRender hooks without rebuilding row/column DOM.
1913
- * @internal Plugin API
1914
- */
1915
- requestAfterRender() {
1916
- this.#e?.afterRender();
1917
- }
1918
- /**
1919
- * Initialize plugin system with instances from config.
1920
- * Plugins are class instances passed in gridConfig.plugins[].
1921
- */
1922
- #W() {
1923
- this.#e = new je(this);
1924
- const e = this.#t?.plugins, o = Array.isArray(e) ? e : [];
1925
- this.#e.attachAll(o);
1926
- }
1927
- /**
1928
- * Inject all plugin styles into the shadow DOM.
1929
- * Must be called after #render() since innerHTML wipes existing content.
1930
- */
1931
- #V() {
1932
- const e = this.#e?.getAllStyles() ?? "";
1933
- if (e) {
1934
- const o = document.createElement("style");
1935
- o.setAttribute("data-plugin", "all"), o.textContent = e, this.#o.appendChild(o);
1936
- }
1937
- }
1938
- /**
1939
- * Update plugins when grid config changes.
1940
- * With class-based plugins, we need to detach old and attach new.
1941
- */
1942
- #G() {
1943
- this.#e && this.#e.detachAll(), this.#W(), this.#V(), this.#R = this.#e?.getAll().some((e) => e.onScroll) ?? !1;
1944
- }
1945
- /**
1946
- * Clean up plugin states when grid disconnects.
1947
- */
1948
- #Y() {
1949
- this.#e?.detachAll();
1950
- }
1951
- /**
1952
- * Collect tool panels and header content from all plugins.
1953
- * Called after plugins are attached but before render.
1954
- */
1955
- #j() {
1956
- if (!this.#e) return;
1957
- const e = this.#e.getToolPanels();
1958
- for (const { panel: i } of e)
1959
- this.#i.toolPanels.has(i.id) || this.#i.toolPanels.set(i.id, i);
1960
- const o = this.#e.getHeaderContents();
1961
- for (const { content: i } of o)
1962
- this.#i.headerContents.has(i.id) || this.#i.headerContents.set(i.id, i);
1963
- }
1964
- // ---------------- Lifecycle ----------------
1965
- connectedCallback() {
1966
- this.hasAttribute("tabindex") || (this.tabIndex = 0), this.hasAttribute("version") || this.setAttribute("version", W.version), this._rows = Array.isArray(this.#r) ? [...this.#r] : [], this.#a?.abort(), this.#a = new AbortController(), this.#f(), this.#W(), this.#j(), this.#O || (this.#X(), this.#V(), this.#O = !0), this.#F();
1967
- }
1968
- disconnectedCallback() {
1969
- this.#Y(), Xe(this.#i), this.#n.setInitialized(!1), this.#H?.(), this.#H = void 0, this.#a && (this.#a.abort(), this.#a = void 0), this._resizeController && this._resizeController.dispose(), this.#E && (this.#E.disconnect(), this.#E = void 0), this.#p = !1;
1970
- }
1971
- /**
1972
- * Handle HTML attribute changes.
1973
- * Only processes attribute values when SET (non-null).
1974
- * Removing an attribute does NOT clear JS-set properties.
1975
- */
1976
- attributeChangedCallback(e, o, i) {
1977
- if (o === i || !i || i === "null" || i === "undefined") return;
1978
- const s = {
1979
- rows: "rows",
1980
- columns: "columns",
1981
- "grid-config": "gridConfig",
1982
- "fit-mode": "fitMode",
1983
- "edit-on": "editOn"
1984
- }[e];
1985
- if (s)
1986
- if (e === "rows" || e === "columns" || e === "grid-config")
1987
- try {
1988
- this[s] = JSON.parse(i);
1989
- } catch {
1990
- console.warn(`[tbw-grid] Invalid JSON for '${e}' attribute:`, i);
1991
- }
1992
- else
1993
- this[s] = i;
1994
- }
1995
- #F() {
1996
- const o = this.#o.querySelector(".tbw-grid-content") ?? this.#o.querySelector(".tbw-grid-root");
1997
- if (this._headerRowEl = o?.querySelector(".header-row"), this._virtualization.totalHeightEl = o?.querySelector(".faux-vscroll-spacer"), this._virtualization.viewportEl = o?.querySelector(".rows-viewport"), this._bodyEl = o?.querySelector(".rows"), this.#n.isInitialized) {
1998
- he(this.#o, this.#i), Ge(this.#o, this.#t?.shell, this.#i);
1999
- const l = this.#t?.shell?.toolPanel?.defaultOpen;
2000
- l && this.#i.toolPanels.has(l) && (this.openToolPanel(), this.#i.expandedSections.add(l));
2001
- }
2002
- this.setAttribute("data-upgraded", ""), this.#p = !0;
2003
- const i = this.disconnectSignal;
2004
- this._resizeController = Ne(this), this.#c(), this.addEventListener("keydown", (l) => ke(this, l), { signal: i }), document.addEventListener(
2005
- "keydown",
2006
- (l) => {
2007
- l.key === "Escape" && this._activeEditRows !== -1 && D(this, this._activeEditRows, !0);
2008
- },
2009
- { capture: !0, signal: i }
2010
- ), document.addEventListener(
2011
- "mousedown",
2012
- (l) => {
2013
- if (this._activeEditRows === -1) return;
2014
- const a = this.findRenderedRowElement(this._activeEditRows);
2015
- !a || (l.composedPath && l.composedPath() || []).includes(a) || D(this, this._activeEditRows, !1);
2016
- },
2017
- { signal: i }
2018
- );
2019
- const n = o?.querySelector(".faux-vscroll"), s = o?.querySelector(".rows");
2020
- if (this._virtualization.container = n ?? this, this.#R = this.#e?.getAll().some((l) => l.onScroll) ?? !1, n && s) {
2021
- n.addEventListener(
2022
- "scroll",
2023
- () => {
2024
- if (!this._virtualization.enabled && !this.#R) return;
2025
- const d = n.scrollTop, f = this._virtualization.rowHeight, h = Math.floor(d / f), p = h - h % 2, c = -(d - p * f);
2026
- s.style.transform = `translateY(${c}px)`, this.#S = d, this.#b || (this.#b = requestAnimationFrame(() => {
2027
- this.#b = 0, this.#S !== null && (this.#ne(this.#S), this.#S = null);
2028
- }));
2029
- },
2030
- { passive: !0, signal: i }
2031
- );
2032
- const l = this.#o.querySelector(".tbw-grid-content"), a = this.#o.querySelector(".tbw-scroll-area");
2033
- l && (l.addEventListener(
2034
- "wheel",
2035
- (d) => {
2036
- const f = d.shiftKey || Math.abs(d.deltaX) > Math.abs(d.deltaY);
2037
- if (f && a) {
2038
- const h = d.shiftKey ? d.deltaY : d.deltaX, { scrollLeft: p, scrollWidth: c, clientWidth: u } = a;
2039
- (h > 0 && p < c - u || h < 0 && p > 0) && (d.preventDefault(), a.scrollLeft += h);
2040
- } else if (!f) {
2041
- const { scrollTop: h, scrollHeight: p, clientHeight: c } = n;
2042
- (d.deltaY > 0 && h < p - c || d.deltaY < 0 && h > 0) && (d.preventDefault(), n.scrollTop += d.deltaY);
2043
- }
2044
- },
2045
- { passive: !1, signal: i }
2046
- ), l.addEventListener(
2047
- "touchstart",
2048
- (d) => {
2049
- d.touches.length === 1 && (this.#w && (cancelAnimationFrame(this.#w), this.#w = 0), this.#A = d.touches[0].clientY, this.#T = d.touches[0].clientX, this.#m = d.touches[0].clientY, this.#v = d.touches[0].clientX, this.#_ = performance.now(), this.#L = n.scrollTop, this.#P = a?.scrollLeft ?? 0, this.#d = 0, this.#u = 0);
2050
- },
2051
- { passive: !0, signal: i }
2052
- ), l.addEventListener(
2053
- "touchmove",
2054
- (d) => {
2055
- if (d.touches.length === 1 && this.#A !== null && this.#T !== null && this.#L !== null && this.#P !== null) {
2056
- const f = d.touches[0].clientY, h = d.touches[0].clientX, p = performance.now(), c = this.#A - f, u = this.#T - h;
2057
- if (this.#_ !== null && this.#m !== null && this.#v !== null) {
2058
- const g = p - this.#_;
2059
- g > 0 && (this.#d = (this.#m - f) / g, this.#u = (this.#v - h) / g);
2060
- }
2061
- this.#m = f, this.#v = h, this.#_ = p;
2062
- const { scrollTop: b, scrollHeight: w, clientHeight: v } = n, S = w - v, R = c > 0 && b < S || c < 0 && b > 0;
2063
- let E = !1;
2064
- if (a) {
2065
- const { scrollLeft: g, scrollWidth: m, clientWidth: C } = a, _ = m - C;
2066
- E = u > 0 && g < _ || u < 0 && g > 0;
2067
- }
2068
- R && (n.scrollTop = this.#L + c), E && a && (a.scrollLeft = this.#P + u), (R || E) && d.preventDefault();
2069
- }
2070
- },
2071
- { passive: !1, signal: i }
2072
- ), l.addEventListener(
2073
- "touchend",
2074
- () => {
2075
- (Math.abs(this.#d) > 0.1 || Math.abs(this.#u) > 0.1) && this.#ie(n, a), this.#A = null, this.#T = null, this.#L = null, this.#P = null, this.#m = null, this.#v = null, this.#_ = null;
2076
- },
2077
- { passive: !0, signal: i }
2078
- ));
2079
- }
2080
- this.#o.addEventListener("mousedown", (l) => this.#se(l), { signal: i }), document.addEventListener("mousemove", (l) => this.#re(l), { signal: i }), document.addEventListener("mouseup", (l) => this.#le(l), { signal: i }), this._virtualization.enabled && requestAnimationFrame(() => this.refreshVirtualWindow(!0));
2081
- const r = this.#t.rowHeight;
2082
- r && r > 0 ? this._virtualization.rowHeight = r : requestAnimationFrame(() => {
2083
- const l = this._bodyEl?.querySelector(".data-grid-row");
2084
- if (l) {
2085
- const a = l.getBoundingClientRect().height;
2086
- a > 0 && (this._virtualization.rowHeight = a, this.refreshVirtualWindow(!0));
2087
- }
2088
- }), this._virtualization.viewportEl && (this.#E = new ResizeObserver(() => {
2089
- this.#b || (this.#b = requestAnimationFrame(() => {
2090
- this.#b = 0, this.refreshVirtualWindow(!0), M(this);
2091
- }));
2092
- }), this.#E.observe(this._virtualization.viewportEl)), queueMicrotask(() => this.#Z()), requestAnimationFrame(() => requestAnimationFrame(() => this.#$?.()));
2093
- }
2094
- // ---------------- Event Emitters ----------------
2095
- #s(e, o) {
2096
- this.dispatchEvent(new CustomEvent(e, { detail: o, bubbles: !0, composed: !0 }));
2097
- }
2098
- _emitCellCommit(e) {
2099
- this.#s("cell-commit", e);
2100
- }
2101
- _emitRowCommit(e) {
2102
- this.#s("row-commit", e);
2103
- }
2104
- _emitSortChange(e) {
2105
- this.#s("sort-change", e);
2106
- }
2107
- _emitColumnResize(e) {
2108
- this.#s("column-resize", e);
2109
- }
2110
- _emitActivateCell(e) {
2111
- this.#s("activate-cell", e);
2112
- }
2113
- /** Update ARIA selection attributes on rendered rows/cells */
2114
- #Z() {
2115
- this._bodyEl?.querySelectorAll(".data-grid-row")?.forEach((o, i) => {
2116
- const n = i === this._focusRow;
2117
- o.setAttribute("aria-selected", String(n)), o.querySelectorAll(".cell").forEach((s, r) => {
2118
- s.setAttribute("aria-selected", String(n && r === this._focusCol));
2119
- });
2120
- });
2121
- }
2122
- // ---------------- Watch Handlers ----------------
2123
- #J() {
2124
- if (!this.#p) return;
2125
- this.#f(), this.#t.fitMode === "fixed" ? (this.__didInitialAutoSize = !1, te(this)) : (this._columns.forEach((o) => {
2126
- !o.__userResized && o.__autoSized && delete o.width;
2127
- }), z(this));
2128
- }
2129
- #Q() {
2130
- this.#p && (this.#f(), this._rowPool.length = 0, this._bodyEl && (this._bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.refreshVirtualWindow(!0));
2131
- }
2132
- #ee() {
2133
- this._rows = Array.isArray(this.#r) ? [...this.#r] : [], this.#k(), !this.#l || Array.isArray(this.#l) && this.#l.length === 0 ? this.#c() : this.refreshVirtualWindow(!0);
2134
- }
2135
- #te() {
2136
- j(this), this.#p && (this.#f(), this.#c());
2137
- }
2138
- #oe() {
2139
- this.#p && (this.#f(), this.#G(), this.#k(), this.#N(), q(this), z(this), this.refreshVirtualWindow(!0));
2140
- }
2141
- #N() {
2142
- if (this.#e) {
2143
- const e = this.#D.length > 0 ? this.#D : this._columns, o = e.filter((s) => !s.hidden), i = e.filter((s) => s.hidden), n = this.#e.processColumns([...o]);
2144
- if (n !== o) {
2145
- const s = new Map(n.map((l, a) => [l.field, { col: l, order: a }]));
2146
- if (!o.some((l) => s.has(l.field)) && n.length > 0)
2147
- this._columns = [...n, ...i];
2148
- else {
2149
- const l = e.map((a) => {
2150
- if (a.hidden) return a;
2151
- const d = s.get(a.field);
2152
- return d ? d.col : a;
2153
- });
2154
- this._columns = l;
2155
- }
2156
- } else
2157
- this._columns = [...e];
2158
- }
2159
- }
2160
- /** Recompute row model via plugin hooks (grouping, tree, filtering, etc.). */
2161
- #k() {
2162
- j(this);
2163
- const e = Array.isArray(this.#r) ? [...this.#r] : [], o = this.#e?.processRows(e) ?? e;
2164
- this._rows = o;
2165
- }
2166
- /**
2167
- * Build the canonical effective configuration by merging all input sources.
2168
- *
2169
- * This is the **single source of truth** for the grid's configuration.
2170
- * All inputs (gridConfig, light DOM, individual props) converge here.
2171
- *
2172
- * **Precedence (lowest → highest):**
2173
- * 1. `gridConfig` property - base config object
2174
- * 2. Light DOM `<tbw-grid-column>` elements - declarative columns
2175
- * 3. `columns` property - programmatic columns override
2176
- * 4. Inferred columns - auto-detected from row data
2177
- * 5. Individual props (`fitMode`, `editOn`) - convenience overrides
2178
- *
2179
- * After this method runs:
2180
- * - `#effectiveConfig` contains the merged result
2181
- * - `_columns` is NOT set here (done by #getColumnConfiguration + #processColumns)
2182
- * - Plugins receive config via their attach() method
2183
- */
2184
- #f() {
2185
- const e = this.#g ? { ...this.#g } : {};
2186
- let o = Array.isArray(e.columns) ? [...e.columns] : [];
2187
- const i = (this.__lightDomColumnsCache || []).map((n) => ({
2188
- ...n
2189
- }));
2190
- if (i.length) {
2191
- const n = {};
2192
- o.forEach((s) => n[s.field] = s), i.forEach((s) => {
2193
- const r = n[s.field];
2194
- r ? (s.header && !r.header && (r.header = s.header), s.type && !r.type && (r.type = s.type), r.sortable = r.sortable || s.sortable, s.resizable && (r.resizable = !0), s.editable && (r.editable = !0)) : (o.push(s), n[s.field] = s);
2195
- });
2196
- }
2197
- if (this.#l && this.#l.length && (o = [...this.#l]), (!o || o.length === 0) && this._rows.length && (o = de(this._rows).columns), o.length) {
2198
- o.forEach((r) => {
2199
- r.sortable === void 0 && (r.sortable = !0), r.resizable === void 0 && (r.resizable = !0);
2200
- const l = r;
2201
- l.__originalWidth === void 0 && typeof r.width == "number" && (l.__originalWidth = r.width);
2202
- });
2203
- const n = this.#t.columns;
2204
- n?.some((r) => r.__compiledView || r.__compiledEditor) ? e.columns = n : e.columns = o;
2205
- } else {
2206
- const n = this.#t.columns;
2207
- n?.some((s) => s.__compiledView || s.__compiledEditor) && (e.columns = n);
2208
- }
2209
- this.#C && (e.fitMode = this.#C), e.fitMode || (e.fitMode = "stretch"), this.#y && (e.editOn = this.#y), e.rowHeight && e.rowHeight > 0 && (this._virtualization.rowHeight = e.rowHeight), e.columnState && !this.#h && (this.#h = e.columnState), this.#t = e, e.fitMode === "fixed" && this._columns.forEach((n) => {
2210
- n.width == null && (n.width = 80);
2211
- });
2212
- }
2213
- // ---------------- Delegate Wrappers ----------------
2214
- #q(e, o, i = this.__rowRenderEpoch) {
2215
- this.#M || (this.#M = (n, s, r) => this.#e?.renderRow(n, s, r) ?? !1), ze(this, e, o, i, this.#M);
2216
- }
2217
- // ---------------- Core Helpers ----------------
2218
- #c() {
2219
- if (!this.isConnected || !this._headerRowEl || !this._bodyEl)
2220
- return;
2221
- const e = this.#g?.columns || this.#l || [];
2222
- if (e.length) {
2223
- const i = new Map(this._columns.filter((s) => s.hidden).map((s) => [s.field, !0])), n = e.map((s) => ({
2224
- ...s,
2225
- hidden: i.get(s.field) ?? s.hidden
2226
- }));
2227
- this._columns = n;
2228
- }
2229
- if (Pe(this), this.#f(), this.#G(), this.#D = [...this._columns], this.#k(), this.#N(), this.#h) {
2230
- const i = this.#h;
2231
- this.#h = void 0, this.#U(i);
2232
- }
2233
- q(this), z(this), this.refreshVirtualWindow(!0), this.#t.fitMode === "fixed" && !this.__didInitialAutoSize && requestAnimationFrame(() => te(this)), this._bodyEl && (this._bodyEl.style.display = "", this._bodyEl.style.gridTemplateColumns = ""), queueMicrotask(() => this.#e?.afterRender());
2234
- }
2235
- /** Internal method to apply column state without triggering setup loop */
2236
- #U(e) {
2237
- const o = this.#t.columns ?? [], i = this.#e?.getAll() ?? [];
2238
- be(this, e, o, i);
2239
- for (const n of e.columns) {
2240
- const s = o.find((r) => r.field === n.field);
2241
- s && (s.hidden = !n.visible);
2242
- }
2243
- }
2244
- #ne(e) {
2245
- if (this.refreshVirtualWindow(!1), this.#e?.onScrollRender(), this.#R) {
2246
- const o = this._virtualization.container, i = {
2247
- scrollTop: e,
2248
- scrollLeft: o?.scrollLeft ?? 0,
2249
- scrollHeight: o?.scrollHeight ?? 0,
2250
- scrollWidth: o?.scrollWidth ?? 0,
2251
- clientHeight: o?.clientHeight ?? 0,
2252
- clientWidth: o?.clientWidth ?? 0,
2253
- originalEvent: new Event("scroll")
2254
- };
2255
- this.#e?.onScroll(i);
2256
- }
2257
- }
2258
- /**
2259
- * Find the header row element in the shadow DOM.
2260
- * Used by plugins that need to access header cells for styling or measurement.
2261
- * @internal Plugin API
2262
- */
2263
- findHeaderRow() {
2264
- return this.#o.querySelector(".header-row");
2265
- }
2266
- /**
2267
- * Find a rendered row element by its data row index.
2268
- * Returns null if the row is not currently rendered (virtualized out of view).
2269
- * Used by plugins that need to access specific row elements for styling or measurement.
2270
- * @internal Plugin API
2271
- * @param rowIndex - The data row index (not the DOM position)
2272
- */
2273
- findRenderedRowElement(e) {
2274
- return Array.from(this._bodyEl.querySelectorAll(".data-grid-row")).find((o) => {
2275
- const i = o.querySelector(".cell[data-row]");
2276
- return i && Number(i.getAttribute("data-row")) === e;
2277
- }) || null;
2278
- }
2279
- /**
2280
- * Dispatch a cell click event to the plugin system.
2281
- * Returns true if any plugin handled the event.
2282
- */
2283
- _dispatchCellClick(e, o, i, n) {
2284
- const s = this._rows[o], r = this._columns[i];
2285
- if (!s || !r) return !1;
2286
- const l = {
2287
- row: s,
2288
- rowIndex: o,
2289
- colIndex: i,
2290
- field: r.field,
2291
- value: s[r.field],
2292
- cellEl: n,
2293
- originalEvent: e
2294
- };
2295
- return this.#e?.onCellClick(l) ?? !1;
2296
- }
2297
- /**
2298
- * Dispatch a row click event to the plugin system.
2299
- * Returns true if any plugin handled the event.
2300
- */
2301
- _dispatchRowClick(e, o, i, n) {
2302
- if (!i) return !1;
2303
- const s = {
2304
- rowIndex: o,
2305
- row: i,
2306
- rowEl: n,
2307
- originalEvent: e
2308
- };
2309
- return this.#e?.onRowClick(s) ?? !1;
2310
- }
2311
- /**
2312
- * Dispatch a header click event to the plugin system.
2313
- * Returns true if any plugin handled the event.
2314
- */
2315
- _dispatchHeaderClick(e, o, i) {
2316
- const n = this._columns[o];
2317
- if (!n) return !1;
2318
- const s = {
2319
- colIndex: o,
2320
- field: n.field,
2321
- column: n,
2322
- headerEl: i,
2323
- originalEvent: e
2324
- };
2325
- return this.#e?.onHeaderClick(s) ?? !1;
2326
- }
2327
- /**
2328
- * Dispatch a keyboard event to the plugin system.
2329
- * Returns true if any plugin handled the event.
2330
- */
2331
- _dispatchKeyDown(e) {
2332
- return this.#e?.onKeyDown(e) ?? !1;
2333
- }
2334
- /**
2335
- * Get horizontal scroll boundary offsets from plugins.
2336
- * Used by keyboard navigation to ensure focused cells are fully visible
2337
- * when plugins like pinned columns obscure part of the scroll area.
2338
- */
2339
- _getHorizontalScrollOffsets(e, o) {
2340
- return this.#e?.getHorizontalScrollOffsets(e, o) ?? { left: 0, right: 0 };
2341
- }
2342
- /**
2343
- * Query all plugins with a generic query and collect responses.
2344
- * This enables inter-plugin communication without the core knowing plugin-specific concepts.
2345
- * @internal Plugin API
2346
- *
2347
- * @example
2348
- * // Check if any plugin vetoes moving a column
2349
- * const responses = grid.queryPlugins<boolean>({ type: PLUGIN_QUERIES.CAN_MOVE_COLUMN, context: column });
2350
- * const canMove = !responses.includes(false);
2351
- */
2352
- queryPlugins(e) {
2353
- return this.#e?.queryPlugins(e) ?? [];
2354
- }
2355
- /**
2356
- * Build a CellMouseEvent from a native MouseEvent.
2357
- * Extracts cell/row information from the event target.
2358
- */
2359
- #B(e, o) {
2360
- let i = null;
2361
- const n = e.composedPath?.();
2362
- if (n && n.length > 0 ? i = n[0] : i = e.target, i && !this.#o.contains(i)) {
2363
- const u = this.#o.elementFromPoint(e.clientX, e.clientY);
2364
- u && (i = u);
2365
- }
2366
- const s = i?.closest?.("[data-col]"), r = i?.closest?.(".data-grid-row"), l = i?.closest?.(".header-row");
2367
- let a, d, f, h, p, c;
2368
- return s && (a = parseInt(s.getAttribute("data-row") ?? "-1", 10), d = parseInt(s.getAttribute("data-col") ?? "-1", 10), a >= 0 && d >= 0 && (f = this._rows[a], c = this._columns[d], h = c?.field, p = f && h ? f[h] : void 0)), {
2369
- type: o,
2370
- row: f,
2371
- rowIndex: a !== void 0 && a >= 0 ? a : void 0,
2372
- colIndex: d !== void 0 && d >= 0 ? d : void 0,
2373
- field: h,
2374
- value: p,
2375
- column: c,
2376
- originalEvent: e,
2377
- cellElement: s ?? void 0,
2378
- rowElement: r ?? void 0,
2379
- isHeader: !!l,
2380
- cell: a !== void 0 && d !== void 0 && a >= 0 && d >= 0 ? { row: a, col: d } : void 0
2381
- };
2382
- }
2383
- /**
2384
- * Apply momentum scrolling animation after touch release.
2385
- * Decelerates smoothly until velocity drops below threshold.
2386
- */
2387
- #ie(e, o) {
2388
- const s = () => {
2389
- this.#d *= 0.95, this.#u *= 0.95;
2390
- const r = this.#d * 16, l = this.#u * 16;
2391
- Math.abs(this.#d) > 0.01 && (e.scrollTop += r), Math.abs(this.#u) > 0.01 && o && (o.scrollLeft += l), Math.abs(this.#d) > 0.01 || Math.abs(this.#u) > 0.01 ? this.#w = requestAnimationFrame(s) : this.#w = 0;
2392
- };
2393
- this.#w = requestAnimationFrame(s);
2394
- }
2395
- /**
2396
- * Handle mousedown events and dispatch to plugin system.
2397
- */
2398
- #se(e) {
2399
- const o = this.#B(e, "mousedown");
2400
- (this.#e?.onCellMouseDown(o) ?? !1) && (this.#x = !0);
2401
- }
2402
- /**
2403
- * Handle mousemove events (only when dragging).
2404
- */
2405
- #re(e) {
2406
- if (!this.#x) return;
2407
- const o = this.#B(e, "mousemove");
2408
- this.#e?.onCellMouseMove(o);
2409
- }
2410
- /**
2411
- * Handle mouseup events.
2412
- */
2413
- #le(e) {
2414
- if (!this.#x) return;
2415
- const o = this.#B(e, "mouseup");
2416
- this.#e?.onCellMouseUp(o), this.#x = !1;
2417
- }
2418
- // API consumed by internal utils (rows.ts)
2419
- get changedRows() {
2420
- return Array.from(this._changedRowIndices).map((e) => this._rows[e]);
2421
- }
2422
- get changedRowIndices() {
2423
- return Array.from(this._changedRowIndices);
2424
- }
2425
- async resetChangedRows(e) {
2426
- this._changedRowIndices.clear(), e || this.#s("changed-rows-reset", { rows: this.changedRows, indices: this.changedRowIndices }), this._rowPool.forEach((o) => o.classList.remove("changed"));
2427
- }
2428
- async beginBulkEdit(e) {
2429
- if (!this._columns.some((s) => s.editable)) return;
2430
- const i = this._rows[e];
2431
- B(this, e, i);
2432
- const n = this.findRenderedRowElement?.(e);
2433
- n && (Array.from(n.children).forEach((s, r) => {
2434
- const l = this._visibleColumns[r];
2435
- if (l?.editable) {
2436
- const a = s;
2437
- a.classList.contains("editing") || k(this, i, e, l, a);
2438
- }
2439
- }), queueMicrotask(() => {
2440
- const s = n.querySelector(`.cell[data-col="${this._focusCol}"]`);
2441
- if (s?.classList.contains("editing")) {
2442
- const r = s.querySelector(
2443
- 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])'
2444
- );
2445
- try {
2446
- r?.focus();
2447
- } catch {
2448
- }
2449
- }
2450
- }));
2451
- }
2452
- async commitActiveRowEdit() {
2453
- this._activeEditRows !== -1 && D(this, this._activeEditRows, !1);
2454
- }
2455
- async ready() {
2456
- return this.#I;
2457
- }
2458
- async forceLayout() {
2459
- this.#c(), await new Promise((e) => requestAnimationFrame(() => requestAnimationFrame(e)));
2460
- }
2461
- /** Public method: returns a frozen snapshot of the merged effective configuration */
2462
- async getConfig() {
2463
- return Object.freeze({ ...this.#t || {} });
2464
- }
2465
- // ---------------- Column Visibility API ----------------
2466
- /**
2467
- * Set the visibility of a column.
2468
- * @param field - The field name of the column
2469
- * @param visible - Whether the column should be visible
2470
- * @returns True if visibility was changed, false if column not found or locked
2471
- */
2472
- setColumnVisible(e, o) {
2473
- const i = this.#t.columns, n = i?.find((l) => l.field === e);
2474
- if (!n || !o && n.lockVisible || !o && (i ?? []).filter((a) => !a.hidden && a.field !== e).length === 0)
2475
- return !1;
2476
- const s = !!n.hidden, r = !o;
2477
- return s !== r ? (n.hidden = r, this.#s("column-visibility", {
2478
- field: e,
2479
- visible: o,
2480
- visibleColumns: (i ?? []).filter((l) => !l.hidden).map((l) => l.field)
2481
- }), this._rowPool.length = 0, this._bodyEl && (this._bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.#c(), this.requestStateChange(), !0) : !1;
2482
- }
2483
- /**
2484
- * Toggle the visibility of a column.
2485
- * @param field - The field name of the column
2486
- * @returns True if visibility was toggled, false if column not found or locked
2487
- */
2488
- toggleColumnVisibility(e) {
2489
- const n = !!this.#t.columns?.find((s) => s.field === e)?.hidden;
2490
- return this.setColumnVisible(e, n);
2491
- }
2492
- /**
2493
- * Check if a column is currently visible.
2494
- * @param field - The field name of the column
2495
- * @returns True if visible, false if hidden or not found
2496
- */
2497
- isColumnVisible(e) {
2498
- const i = this.#t.columns?.find((n) => n.field === e);
2499
- return i ? !i.hidden : !1;
2500
- }
2501
- /**
2502
- * Show all columns.
2503
- */
2504
- showAllColumns() {
2505
- const e = this.#t.columns;
2506
- e?.some((i) => i.hidden) && (e?.forEach((i) => {
2507
- i.hidden = !1;
2508
- }), this.#s("column-visibility", {
2509
- visibleColumns: (e ?? []).map((i) => i.field)
2510
- }), this._rowPool.length = 0, this._bodyEl && (this._bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.#c(), this.requestStateChange());
2511
- }
2512
- /**
2513
- * Get list of all column fields (including hidden).
2514
- * Returns columns reflecting current display order (after reordering).
2515
- * Hidden columns are interleaved at their original relative positions.
2516
- * @returns Array of all field names with their visibility status
2517
- */
2518
- getAllColumns() {
2519
- return (this.#t.columns ?? []).map((o) => ({
2520
- field: o.field,
2521
- header: o.header || o.field,
2522
- visible: !o.hidden,
2523
- lockVisible: o.lockVisible
2524
- }));
2525
- }
2526
- /**
2527
- * Reorder columns according to the specified field order.
2528
- * This directly updates _columns in place without going through processColumns.
2529
- * @param order - Array of field names in the desired order
2530
- */
2531
- setColumnOrder(e) {
2532
- if (!e.length) return;
2533
- const o = new Map(this._columns.map((n) => [n.field, n])), i = [];
2534
- for (const n of e) {
2535
- const s = o.get(n);
2536
- s && (i.push(s), o.delete(n));
2537
- }
2538
- for (const n of o.values())
2539
- i.push(n);
2540
- this._columns = i, q(this), z(this), this.refreshVirtualWindow(!0);
2541
- }
2542
- /**
2543
- * Get the current column order as an array of field names.
2544
- * @returns Array of field names in display order
2545
- */
2546
- getColumnOrder() {
2547
- return this._columns.map((e) => e.field);
2548
- }
2549
- // ---------------- Column State API ----------------
2550
- /**
2551
- * Get the current column state, including order, width, visibility, sort, and plugin state.
2552
- * Returns a serializable object suitable for localStorage or database storage.
2553
- */
2554
- getColumnState() {
2555
- const e = this.#e?.getAll() ?? [];
2556
- return ce(this, e);
2557
- }
2558
- /**
2559
- * Set the column state, restoring order, width, visibility, sort, and plugin state.
2560
- * Use this to restore previously saved column state.
2561
- */
2562
- set columnState(e) {
2563
- e && (this.#h = e, this.#O && this.#ae(e));
2564
- }
2565
- /**
2566
- * Get the current column state.
2567
- */
2568
- get columnState() {
2569
- return this.getColumnState();
2570
- }
2571
- /**
2572
- * Apply column state internally.
2573
- */
2574
- #ae(e) {
2575
- (this.#t.columns ?? []).forEach((i) => {
2576
- i.hidden = !1;
2577
- }), this.#U(e), this.#c();
2578
- }
2579
- /**
2580
- * Request a state change event to be emitted.
2581
- * Called internally after resize, reorder, visibility, or sort changes.
2582
- * Plugins should call this after changing their state.
2583
- * The event is debounced to avoid excessive events during drag operations.
2584
- * @internal Plugin API
2585
- */
2586
- requestStateChange() {
2587
- this.#z || (this.#z = we(
2588
- this,
2589
- () => this.#e?.getAll() ?? [],
2590
- (e) => this.#s("column-state-change", e)
2591
- )), this.#z();
2592
- }
2593
- /**
2594
- * Reset column state to initial configuration.
2595
- * Clears all user modifications (order, width, visibility, sort).
2596
- */
2597
- resetColumnState() {
2598
- this.#h = void 0, (this.#t.columns ?? []).forEach((i) => {
2599
- i.hidden = !1;
2600
- }), this._sortState = null, this.__originalOrder = [], this.#f(), this.#c();
2601
- const o = this.#e?.getAll() ?? [];
2602
- for (const i of o)
2603
- if (i.applyColumnState)
2604
- for (const n of this._columns)
2605
- i.applyColumnState(n.field, {
2606
- field: n.field,
2607
- order: 0,
2608
- visible: !0
2609
- });
2610
- this.requestStateChange();
2611
- }
2612
- // ---------------- Shell / Tool Panel API ----------------
2613
- // These methods delegate to ShellController for implementation.
2614
- // The controller encapsulates all tool panel logic while grid.ts
2615
- // exposes the public API surface.
2616
- /** Check if the tool panel is currently open. */
2617
- get isToolPanelOpen() {
2618
- return this.#n.isPanelOpen;
2619
- }
2620
- /**
2621
- * Get the currently active tool panel ID, or null if none is open.
2622
- * @deprecated Use isToolPanelOpen and expandedToolPanelSections instead.
2623
- */
2624
- get activeToolPanel() {
2625
- return this.#n.activePanel;
2626
- }
2627
- /** Get the IDs of expanded accordion sections. */
2628
- get expandedToolPanelSections() {
2629
- return this.#n.expandedSections;
2630
- }
2631
- /** Open the tool panel (accordion view with all registered panels). */
2632
- openToolPanel() {
2633
- this.#n.openToolPanel();
2634
- }
2635
- /** Close the tool panel. */
2636
- closeToolPanel() {
2637
- this.#n.closeToolPanel();
2638
- }
2639
- /** Toggle the tool panel open/closed. */
2640
- toggleToolPanel() {
2641
- this.#n.toggleToolPanel();
2642
- }
2643
- /** Toggle an accordion section expanded/collapsed. */
2644
- toggleToolPanelSection(e) {
2645
- this.#n.toggleToolPanelSection(e);
2646
- }
2647
- /** Get registered tool panel definitions. */
2648
- getToolPanels() {
2649
- return this.#n.getToolPanels();
2650
- }
2651
- /** Register a custom tool panel (without creating a plugin). */
2652
- registerToolPanel(e) {
2653
- this.#n.registerToolPanel(e);
2654
- }
2655
- /** Unregister a custom tool panel. */
2656
- unregisterToolPanel(e) {
2657
- this.#n.unregisterToolPanel(e);
2658
- }
2659
- /** Get registered header content definitions. */
2660
- getHeaderContents() {
2661
- return this.#n.getHeaderContents();
2662
- }
2663
- /** Register custom header content (without creating a plugin). */
2664
- registerHeaderContent(e) {
2665
- this.#n.registerHeaderContent(e);
2666
- }
2667
- /** Unregister custom header content. */
2668
- unregisterHeaderContent(e) {
2669
- this.#n.unregisterHeaderContent(e);
2670
- }
2671
- /** Get all registered toolbar buttons. */
2672
- getToolbarButtons() {
2673
- return this.#n.getToolbarButtons();
2674
- }
2675
- /** Register a custom toolbar button programmatically. */
2676
- registerToolbarButton(e) {
2677
- this.#n.registerToolbarButton(e);
2678
- }
2679
- /** Unregister a custom toolbar button. */
2680
- unregisterToolbarButton(e) {
2681
- this.#n.unregisterToolbarButton(e);
2682
- }
2683
- /** Enable/disable a toolbar button by ID. */
2684
- setToolbarButtonDisabled(e, o) {
2685
- this.#n.setToolbarButtonDisabled(e, o);
2686
- }
2687
- /**
2688
- * Re-parse light DOM shell elements and refresh shell header.
2689
- * Call this after dynamically modifying <tbw-grid-header> children.
2690
- */
2691
- refreshShellHeader() {
2692
- se(this, this.#i), this.#X(), this.#F();
2693
- }
2694
- // ---------------- Virtual Window ----------------
2695
- /**
2696
- * Core virtualization routine. Chooses between bypass (small datasets), grouped window rendering,
2697
- * or standard row window rendering.
2698
- * @internal Plugin API
2699
- */
2700
- refreshVirtualWindow(e = !1) {
2701
- if (!this._bodyEl) return;
2702
- const o = this._rows.length;
2703
- if (!this._virtualization.enabled) {
2704
- this.#q(0, o), this.#e?.afterRender();
2705
- return;
2706
- }
2707
- if (this._rows.length <= this._virtualization.bypassThreshold) {
2708
- if (this._virtualization.start = 0, this._virtualization.end = o, this._bodyEl.style.transform = "translateY(0px)", this.#q(0, o, this.__rowRenderEpoch), this._virtualization.totalHeightEl) {
2709
- const C = this.#o.querySelector(".tbw-scroll-area"), _ = C ? C.offsetHeight - C.clientHeight : 0;
2710
- this._virtualization.totalHeightEl.style.height = `${o * this._virtualization.rowHeight + _}px`;
2711
- }
2712
- const m = this.#o.querySelector(".rows-body");
2713
- m?.setAttribute("aria-rowcount", String(o)), m?.setAttribute("aria-colcount", String(this._visibleColumns.length)), this.#e?.afterRender();
2714
- return;
2715
- }
2716
- const i = this._virtualization.container ?? this, s = (this._virtualization.viewportEl ?? i).clientHeight, r = this._virtualization.rowHeight, l = i.scrollTop;
2717
- let a = Math.floor(l / r), d = 0;
2718
- const f = 10;
2719
- for (; d < f; ) {
2720
- const m = this.#e?.getExtraHeightBefore?.(a) ?? 0, C = Math.floor((l - m) / r);
2721
- if (C >= a || C < 0) break;
2722
- a = C, d++;
2723
- }
2724
- a = a - a % 2, a < 0 && (a = 0);
2725
- const h = this.#e?.adjustVirtualStart(a, l, r);
2726
- h !== void 0 && h < a && (a = h, a = a - a % 2, a < 0 && (a = 0));
2727
- const p = Math.ceil(s / r) + 3;
2728
- let c = a + p;
2729
- c > o && (c = o), this._virtualization.start = a, this._virtualization.end = c;
2730
- const b = this.#o.querySelector(".tbw-footer")?.offsetHeight ?? 0, w = this.#e?.getExtraHeight() ?? 0, v = this.#o.querySelector(".tbw-scroll-area"), S = v ? v.offsetHeight - v.clientHeight : 0;
2731
- this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${o * r + r + b + w + S}px`);
2732
- const R = this.#e?.getExtraHeightBefore?.(a) ?? 0, E = -(l - a * r - R);
2733
- this._bodyEl.style.transform = `translateY(${E}px)`, this.#q(a, c, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch);
2734
- const g = this.#o.querySelector(".rows-body");
2735
- g?.setAttribute("aria-rowcount", String(o)), g?.setAttribute("aria-colcount", String(this._visibleColumns.length)), e && this.#e?.afterRender();
2736
- }
2737
- // ---------------- Render ----------------
2738
- #X() {
2739
- se(this, this.#i);
2740
- const e = this.#t?.shell, o = Be(e, this.#i), i = `
2741
- <div class="tbw-scroll-area">
2742
- <div class="rows-body-wrapper">
2743
- <div class="rows-body" role="grid">
2744
- <div class="header">
2745
- <div class="header-row" part="header-row"></div>
2746
- </div>
2747
- <div class="rows-container">
2748
- <div class="rows-viewport">
2749
- <div class="rows"></div>
2750
- </div>
2751
- </div>
2752
- </div>
2753
- </div>
2754
- </div>
2755
- <div class="faux-vscroll">
2756
- <div class="faux-vscroll-spacer"></div>
2757
- </div>
2758
- `;
2759
- if (o) {
2760
- const n = this.#t?.icons?.toolPanel ?? H.toolPanel, s = {
2761
- expand: this.#t?.icons?.expand ?? H.expand,
2762
- collapse: this.#t?.icons?.collapse ?? H.collapse
2763
- }, r = Ie(e, this.#i, n), l = $e(e, this.#i, i, s);
2764
- this.#o.innerHTML = `
2765
- <div class="tbw-grid-root has-shell">
2766
- ${r}
2767
- ${l}
2768
- </div>
2769
- `, this.#ce(), this.#n.setInitialized(!0);
2770
- } else
2771
- this.#o.innerHTML = `
2772
- <div class="tbw-grid-root">
2773
- <div class="tbw-grid-content">
2774
- ${i}
2775
- </div>
2776
- </div>
2777
- `;
2778
- }
2779
- /**
2780
- * Set up shell event listeners after render.
2781
- */
2782
- #ce() {
2783
- We(this.#o, this.#t?.shell, this.#i, {
2784
- onPanelToggle: () => this.toggleToolPanel(),
2785
- onSectionToggle: (e) => this.toggleToolPanelSection(e),
2786
- onToolbarButtonClick: (e) => this.#de(e)
2787
- }), this.#H?.(), this.#H = Ve(this.#o, this.#t?.shell, (e) => {
2788
- this.style.setProperty("--tbw-tool-panel-width", `${e}px`);
2789
- });
2790
- }
2791
- /**
2792
- * Handle toolbar button click (for config buttons with action).
2793
- */
2794
- #de(e) {
2795
- const i = (this.#t?.shell?.header?.toolbarButtons ?? []).find((s) => s.id === e);
2796
- if (i?.action) {
2797
- i.action();
2798
- return;
2799
- }
2800
- const n = this.#i.toolbarButtons.get(e);
2801
- n?.action && n.action();
2802
- }
2803
- }
2804
- customElements.get(W.tagName) || customElements.define(W.tagName, W);
2805
- const Je = {
2806
- /** Ask if a column can be moved. Context: ColumnConfig. Response: boolean | undefined */
2807
- CAN_MOVE_COLUMN: "canMoveColumn",
2808
- /** Get context menu items. Context: ContextMenuParams. Response: ContextMenuItem[] */
2809
- GET_CONTEXT_MENU_ITEMS: "getContextMenuItems"
2810
- };
2811
- class Qe {
2812
- /** Plugin version - override in subclass if needed */
2813
- version = "1.0.0";
2814
- /** CSS styles to inject into the grid's shadow DOM */
2815
- styles;
2816
- /** Custom cell renderers keyed by type name */
2817
- cellRenderers;
2818
- /** Custom header renderers keyed by type name */
2819
- headerRenderers;
2820
- /** Custom cell editors keyed by type name */
2821
- cellEditors;
2822
- /** The grid instance this plugin is attached to */
2823
- grid;
2824
- /** Plugin configuration - merged with defaults in attach() */
2825
- config;
2826
- /** User-provided configuration from constructor */
2827
- userConfig;
2828
- /**
2829
- * Default configuration - subclasses should override this getter.
2830
- * Note: This must be a getter (not property initializer) for proper inheritance
2831
- * since property initializers run after parent constructor.
2832
- */
2833
- get defaultConfig() {
2834
- return {};
2835
- }
2836
- constructor(e = {}) {
2837
- this.userConfig = e;
2838
- }
2839
- /**
2840
- * Called when the plugin is attached to a grid.
2841
- * Override to set up event listeners, initialize state, etc.
2842
- */
2843
- attach(e) {
2844
- this.grid = e, this.config = { ...this.defaultConfig, ...this.userConfig };
2845
- }
2846
- /**
2847
- * Called when the plugin is detached from a grid.
2848
- * Override to clean up event listeners, timers, etc.
2849
- */
2850
- detach() {
2851
- }
2852
- /**
2853
- * Get another plugin instance from the same grid.
2854
- * Use for inter-plugin communication.
2855
- */
2856
- getPlugin(e) {
2857
- return this.grid?.getPlugin(e);
2858
- }
2859
- /**
2860
- * Emit a custom event from the grid.
2861
- */
2862
- emit(e, o) {
2863
- this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: o, bubbles: !0 }));
2864
- }
2865
- /**
2866
- * Request a re-render of the grid.
2867
- */
2868
- requestRender() {
2869
- this.grid?.requestRender?.();
2870
- }
2871
- /**
2872
- * Request a lightweight style update without rebuilding DOM.
2873
- * Use this instead of requestRender() when only CSS classes need updating.
2874
- */
2875
- requestAfterRender() {
2876
- this.grid?.requestAfterRender?.();
2877
- }
2878
- /**
2879
- * Get the current rows from the grid.
2880
- */
2881
- get rows() {
2882
- return this.grid?.rows ?? [];
2883
- }
2884
- /**
2885
- * Get the original unfiltered/unprocessed rows from the grid.
2886
- * Use this when you need all source data regardless of active filters.
2887
- */
2888
- get sourceRows() {
2889
- return this.grid?.sourceRows ?? [];
2890
- }
2891
- /**
2892
- * Get the current columns from the grid.
2893
- */
2894
- get columns() {
2895
- return this.grid?.columns ?? [];
2896
- }
2897
- /**
2898
- * Get only visible columns from the grid (excludes hidden).
2899
- * Use this for rendering that needs to match the grid template.
2900
- */
2901
- get visibleColumns() {
2902
- return this.grid?._visibleColumns ?? [];
2903
- }
2904
- /**
2905
- * Get the shadow root of the grid.
2906
- */
2907
- get shadowRoot() {
2908
- return this.grid?.shadowRoot ?? null;
2909
- }
2910
- /**
2911
- * Get the disconnect signal for event listener cleanup.
2912
- * This signal is aborted when the grid disconnects from the DOM.
2913
- * Use this when adding event listeners that should be cleaned up automatically.
2914
- *
2915
- * Best for:
2916
- * - Document/window-level listeners added in attach()
2917
- * - Listeners on the grid element itself
2918
- * - Any listener that should persist across renders
2919
- *
2920
- * Not needed for:
2921
- * - Listeners on elements created in afterRender() (removed with element)
2922
- *
2923
- * @example
2924
- * element.addEventListener('click', handler, { signal: this.disconnectSignal });
2925
- * document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
2926
- */
2927
- get disconnectSignal() {
2928
- return this.grid?.disconnectSignal;
2929
- }
2930
- /**
2931
- * Get the grid-level icons configuration.
2932
- * Returns merged icons (user config + defaults).
2933
- */
2934
- get gridIcons() {
2935
- const e = this.grid?.gridConfig?.icons ?? {};
2936
- return { ...H, ...e };
2937
- }
2938
- /**
2939
- * Resolve an icon value to string or HTMLElement.
2940
- * Checks plugin config first, then grid-level icons, then defaults.
2941
- *
2942
- * @param iconKey - The icon key in GridIcons (e.g., 'expand', 'collapse')
2943
- * @param pluginOverride - Optional plugin-level override
2944
- * @returns The resolved icon value
2945
- */
2946
- resolveIcon(e, o) {
2947
- return o !== void 0 ? o : this.gridIcons[e];
2948
- }
2949
- /**
2950
- * Set an icon value on an element.
2951
- * Handles both string (text/HTML) and HTMLElement values.
2952
- *
2953
- * @param element - The element to set the icon on
2954
- * @param icon - The icon value (string or HTMLElement)
2955
- */
2956
- setIcon(e, o) {
2957
- typeof o == "string" ? e.innerHTML = o : o instanceof HTMLElement && (e.innerHTML = "", e.appendChild(o.cloneNode(!0)));
2958
- }
2959
- /**
2960
- * Log a warning message.
2961
- */
2962
- warn(e) {
2963
- console.warn(`[tbw-grid:${this.name}] ${e}`);
2964
- }
2965
- // #endregion
2966
- }
2967
- const T = {
2968
- // ─── Core Structure ───────────────────────────────────────────────
2969
- ROOT: "tbw-grid-root",
2970
- HEADER: "header",
2971
- HEADER_ROW: "header-row",
2972
- HEADER_CELL: "header-cell",
2973
- // Body structure
2974
- ROWS_VIEWPORT: "rows-viewport",
2975
- ROWS_SPACER: "rows-spacer",
2976
- ROWS_CONTAINER: "rows",
2977
- // Row elements
2978
- DATA_ROW: "data-row",
2979
- GROUP_ROW: "group-row",
2980
- // Cell elements
2981
- DATA_CELL: "data-cell",
2982
- // ─── Core States ──────────────────────────────────────────────────
2983
- SELECTED: "selected",
2984
- FOCUSED: "focused",
2985
- EDITING: "editing",
2986
- EXPANDED: "expanded",
2987
- COLLAPSED: "collapsed",
2988
- DRAGGING: "dragging",
2989
- RESIZING: "resizing",
2990
- // Sorting (core feature)
2991
- SORTABLE: "sortable",
2992
- SORTED_ASC: "sorted-asc",
2993
- SORTED_DESC: "sorted-desc",
2994
- // Visibility
2995
- HIDDEN: "hidden",
2996
- // ─── Shared Classes (used by plugins, styled by core CSS) ────────
2997
- // These are defined here because core CSS provides the base styling.
2998
- // Plugins apply these classes; core CSS defines how they look.
2999
- // Sticky positioning (PinnedColumnsPlugin applies, core CSS styles)
3000
- STICKY_LEFT: "sticky-left",
3001
- STICKY_RIGHT: "sticky-right",
3002
- // Pinned rows (PinnedRowsPlugin applies, core CSS styles)
3003
- PINNED_TOP: "pinned-top",
3004
- PINNED_BOTTOM: "pinned-bottom",
3005
- // Tree structure (TreePlugin applies, core CSS styles)
3006
- TREE_TOGGLE: "tree-toggle",
3007
- TREE_INDENT: "tree-indent",
3008
- // Grouping (GroupingRowsPlugin applies, core CSS styles)
3009
- GROUP_TOGGLE: "group-toggle",
3010
- GROUP_LABEL: "group-label",
3011
- GROUP_COUNT: "group-count",
3012
- // Selection (SelectionPlugin applies, core CSS styles)
3013
- RANGE_SELECTION: "range-selection",
3014
- SELECTION_OVERLAY: "selection-overlay"
3015
- }, G = {
3016
- // ─── Core Attributes ──────────────────────────────────────────────
3017
- ROW_INDEX: "data-row-index",
3018
- COL_INDEX: "data-col-index",
3019
- FIELD: "data-field",
3020
- // ─── Shared Attributes (used by plugins) ──────────────────────────
3021
- GROUP_KEY: "data-group-key",
3022
- // GroupingRowsPlugin
3023
- TREE_LEVEL: "data-tree-level",
3024
- // TreePlugin
3025
- STICKY: "data-sticky"
3026
- // PinnedColumnsPlugin
3027
- }, et = {
3028
- ROOT: `.${T.ROOT}`,
3029
- HEADER: `.${T.HEADER}`,
3030
- HEADER_ROW: `.${T.HEADER_ROW}`,
3031
- HEADER_CELL: `.${T.HEADER_CELL}`,
3032
- ROWS_VIEWPORT: `.${T.ROWS_VIEWPORT}`,
3033
- ROWS_CONTAINER: `.${T.ROWS_CONTAINER}`,
3034
- DATA_ROW: `.${T.DATA_ROW}`,
3035
- DATA_CELL: `.${T.DATA_CELL}`,
3036
- GROUP_ROW: `.${T.GROUP_ROW}`,
3037
- // By data attribute
3038
- ROW_BY_INDEX: (t) => `.${T.DATA_ROW}[${G.ROW_INDEX}="${t}"]`,
3039
- CELL_BY_FIELD: (t) => `.${T.DATA_CELL}[${G.FIELD}="${t}"]`,
3040
- CELL_AT: (t, e) => `.${T.DATA_ROW}[${G.ROW_INDEX}="${t}"] .${T.DATA_CELL}[${G.COL_INDEX}="${e}"]`,
3041
- // State selectors
3042
- SELECTED_ROWS: `.${T.DATA_ROW}.${T.SELECTED}`,
3043
- EDITING_CELL: `.${T.DATA_CELL}.${T.EDITING}`
3044
- }, tt = {
3045
- // Colors
3046
- COLOR_BG: "--tbw-color-bg",
3047
- COLOR_FG: "--tbw-color-fg",
3048
- COLOR_FG_MUTED: "--tbw-color-fg-muted",
3049
- COLOR_BORDER: "--tbw-color-border",
3050
- COLOR_ACCENT: "--tbw-color-accent",
3051
- COLOR_HEADER_BG: "--tbw-color-header-bg",
3052
- COLOR_HEADER_FG: "--tbw-color-header-fg",
3053
- COLOR_SELECTION: "--tbw-color-selection",
3054
- COLOR_ROW_HOVER: "--tbw-color-row-hover",
3055
- COLOR_ROW_ALT: "--tbw-color-row-alt",
3056
- // Sizing
3057
- ROW_HEIGHT: "--tbw-row-height",
3058
- HEADER_HEIGHT: "--tbw-header-height",
3059
- CELL_PADDING: "--tbw-cell-padding",
3060
- // Typography
3061
- FONT_FAMILY: "--tbw-font-family",
3062
- FONT_SIZE: "--tbw-font-size",
3063
- // Borders
3064
- BORDER_RADIUS: "--tbw-border-radius",
3065
- FOCUS_OUTLINE: "--tbw-focus-outline"
3066
- }, ot = {
3067
- CELL_COMMIT: "cell-commit",
3068
- ROW_COMMIT: "row-commit",
3069
- CHANGED_ROWS_RESET: "changed-rows-reset",
3070
- MOUNT_EXTERNAL_VIEW: "mount-external-view",
3071
- MOUNT_EXTERNAL_EDITOR: "mount-external-editor",
3072
- SORT_CHANGE: "sort-change",
3073
- COLUMN_RESIZE: "column-resize",
3074
- ACTIVATE_CELL: "activate-cell",
3075
- GROUP_TOGGLE: "group-toggle",
3076
- COLUMN_STATE_CHANGE: "column-state-change"
3077
- }, nt = {
3078
- // Selection plugin
3079
- SELECTION_CHANGE: "selection-change",
3080
- // Tree plugin
3081
- TREE_EXPAND: "tree-expand",
3082
- // Filtering plugin
3083
- FILTER_CHANGE: "filter-change",
3084
- // Sorting plugin
3085
- SORT_MODEL_CHANGE: "sort-model-change",
3086
- // Export plugin
3087
- EXPORT_START: "export-start",
3088
- EXPORT_COMPLETE: "export-complete",
3089
- // Clipboard plugin
3090
- CLIPBOARD_COPY: "clipboard-copy",
3091
- CLIPBOARD_PASTE: "clipboard-paste",
3092
- // Context menu plugin
3093
- CONTEXT_MENU_OPEN: "context-menu-open",
3094
- CONTEXT_MENU_CLOSE: "context-menu-close",
3095
- // Undo/Redo plugin
3096
- HISTORY_CHANGE: "history-change",
3097
- // Server-side plugin
3098
- SERVER_LOADING: "server-loading",
3099
- SERVER_ERROR: "server-error",
3100
- // Visibility plugin
3101
- COLUMN_VISIBILITY_CHANGE: "column-visibility-change",
3102
- // Reorder plugin
3103
- COLUMN_REORDER: "column-reorder",
3104
- // Master-detail plugin
3105
- DETAIL_EXPAND: "detail-expand",
3106
- // Grouping rows plugin
3107
- GROUP_EXPAND: "group-expand"
3108
- }, K = {
3109
- sum: (t, e) => t.reduce((o, i) => o + (Number(i[e]) || 0), 0),
3110
- avg: (t, e) => {
3111
- const o = t.reduce((i, n) => i + (Number(n[e]) || 0), 0);
3112
- return t.length ? o / t.length : 0;
3113
- },
3114
- count: (t) => t.length,
3115
- min: (t, e) => Math.min(...t.map((o) => Number(o[e]) || 1 / 0)),
3116
- max: (t, e) => Math.max(...t.map((o) => Number(o[e]) || -1 / 0)),
3117
- first: (t, e) => t[0]?.[e],
3118
- last: (t, e) => t[t.length - 1]?.[e]
3119
- }, I = /* @__PURE__ */ new Map(), O = {
3120
- /**
3121
- * Register a custom aggregator function.
3122
- */
3123
- register(t, e) {
3124
- I.set(t, e);
3125
- },
3126
- /**
3127
- * Unregister a custom aggregator function.
3128
- */
3129
- unregister(t) {
3130
- I.delete(t);
3131
- },
3132
- /**
3133
- * Get an aggregator function by reference.
3134
- */
3135
- get(t) {
3136
- if (t !== void 0)
3137
- return typeof t == "function" ? t : I.get(t) ?? K[t];
3138
- },
3139
- /**
3140
- * Run an aggregator on a set of rows.
3141
- */
3142
- run(t, e, o, i) {
3143
- const n = this.get(t);
3144
- return n ? n(e, o, i) : void 0;
3145
- },
3146
- /**
3147
- * Check if an aggregator exists.
3148
- */
3149
- has(t) {
3150
- return I.has(t) || t in K;
3151
- },
3152
- /**
3153
- * List all available aggregator names.
3154
- */
3155
- list() {
3156
- return [...Object.keys(K), ...I.keys()];
3157
- }
3158
- }, ae = {
3159
- sum: (t) => t.reduce((e, o) => e + o, 0),
3160
- avg: (t) => t.length ? t.reduce((e, o) => e + o, 0) / t.length : 0,
3161
- count: (t) => t.length,
3162
- min: (t) => t.length ? Math.min(...t) : 0,
3163
- max: (t) => t.length ? Math.max(...t) : 0,
3164
- first: (t) => t[0] ?? 0,
3165
- last: (t) => t[t.length - 1] ?? 0
3166
- };
3167
- function Ze(t) {
3168
- return ae[t] ?? ae.sum;
3169
- }
3170
- function it(t, e) {
3171
- return Ze(t)(e);
3172
- }
3173
- const st = O.register.bind(O), rt = O.unregister.bind(O), lt = O.get.bind(O), at = O.run.bind(O), ct = O.list.bind(O);
1
+ import { B as s, k as g, D as e, i as t, b as i, F as o, o as n, G as l, p as u, b as A, q as G, P as d, j as E, c as I, d as D, m, n as S, g as C, a as F, l as N, f as P, r as _, h as U, u as b } from "./index-DG2CZ_Zo.js";
3174
2
  export {
3175
- Qe as BaseGridPlugin,
3176
- H as DEFAULT_GRID_ICONS,
3177
- ot as DGEvents,
3178
- W as DataGridElement,
3179
- $ as FitModeEnum,
3180
- tt as GridCSSVars,
3181
- T as GridClasses,
3182
- G as GridDataAttrs,
3183
- W as GridElement,
3184
- et as GridSelectors,
3185
- Je as PLUGIN_QUERIES,
3186
- nt as PluginEvents,
3187
- je as PluginManager,
3188
- O as aggregatorRegistry,
3189
- lt as getAggregator,
3190
- Ze as getValueAggregator,
3191
- ct as listAggregators,
3192
- st as registerAggregator,
3193
- at as runAggregator,
3194
- it as runValueAggregator,
3195
- rt as unregisterAggregator
3
+ s as BaseGridPlugin,
4
+ g as DEFAULT_ANIMATION_CONFIG,
5
+ e as DEFAULT_GRID_ICONS,
6
+ t as DGEvents,
7
+ i as DataGridElement,
8
+ o as FitModeEnum,
9
+ n as GridCSSVars,
10
+ l as GridClasses,
11
+ u as GridDataAttrs,
12
+ A as GridElement,
13
+ G as GridSelectors,
14
+ d as PLUGIN_QUERIES,
15
+ E as PluginEvents,
16
+ I as PluginManager,
17
+ D as aggregatorRegistry,
18
+ m as builtInSort,
19
+ S as defaultComparator,
20
+ C as getAggregator,
21
+ F as getValueAggregator,
22
+ N as listAggregators,
23
+ P as registerAggregator,
24
+ _ as runAggregator,
25
+ U as runValueAggregator,
26
+ b as unregisterAggregator
3196
27
  };
3197
28
  //# sourceMappingURL=index.js.map