@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.
- package/all.d.ts +434 -61
- package/all.js +844 -541
- package/all.js.map +1 -1
- package/index-DG2CZ_Zo.js +3229 -0
- package/index-DG2CZ_Zo.js.map +1 -0
- package/index.d.ts +210 -6
- package/index.js +25 -3194
- package/index.js.map +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +183 -148
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +116 -82
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +139 -81
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +17 -17
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +369 -337
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/reorder/index.js +264 -91
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/index.js +180 -169
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +21 -21
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +12 -12
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- 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 ? "🗹" : "☐"}</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 ? "🗹" : "☐"}</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 ? "🗹" : "☐"}</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
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
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
|