@toolbox-web/grid 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/all.d.ts +1709 -135
- package/all.js +745 -645
- package/all.js.map +1 -1
- package/index.d.ts +161 -1
- package/index.js +1050 -913
- package/index.js.map +1 -1
- package/lib/plugins/clipboard/index.js +110 -52
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +78 -20
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +163 -95
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/export/index.js +93 -35
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +188 -133
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +69 -11
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +111 -55
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +196 -51
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +104 -46
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +74 -16
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +65 -7
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +117 -59
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/reorder/index.js +103 -45
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js +139 -81
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js +96 -38
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/index.js +108 -47
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js +70 -12
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +82 -24
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +31 -31
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +15 -15
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +2 -2
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +3 -3
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +2 -2
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +2 -2
- 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/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +2 -2
- package/umd/plugins/tree.umd.js.map +1 -1
- package/umd/plugins/visibility.umd.js +1 -1
- package/umd/plugins/visibility.umd.js.map +1 -1
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
const f = {
|
|
2
|
+
expand: "▶",
|
|
3
|
+
collapse: "▼",
|
|
4
|
+
sortAsc: "▲",
|
|
5
|
+
sortDesc: "▼",
|
|
6
|
+
sortNone: "⇅",
|
|
7
|
+
submenuArrow: "▶",
|
|
8
|
+
dragHandle: "⋮⋮"
|
|
9
|
+
};
|
|
10
|
+
class w {
|
|
2
11
|
/** Plugin version - override in subclass if needed */
|
|
3
12
|
version = "1.0.0";
|
|
4
13
|
/** CSS styles to inject into the grid's shadow DOM */
|
|
@@ -97,6 +106,55 @@ class f {
|
|
|
97
106
|
get shadowRoot() {
|
|
98
107
|
return this.grid?.shadowRoot ?? null;
|
|
99
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Get the disconnect signal for event listener cleanup.
|
|
111
|
+
* This signal is aborted when the grid disconnects from the DOM.
|
|
112
|
+
* Use this when adding event listeners that should be cleaned up automatically.
|
|
113
|
+
*
|
|
114
|
+
* Best for:
|
|
115
|
+
* - Document/window-level listeners added in attach()
|
|
116
|
+
* - Listeners on the grid element itself
|
|
117
|
+
* - Any listener that should persist across renders
|
|
118
|
+
*
|
|
119
|
+
* Not needed for:
|
|
120
|
+
* - Listeners on elements created in afterRender() (removed with element)
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* element.addEventListener('click', handler, { signal: this.disconnectSignal });
|
|
124
|
+
* document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
|
|
125
|
+
*/
|
|
126
|
+
get disconnectSignal() {
|
|
127
|
+
return this.grid?.disconnectSignal;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get the grid-level icons configuration.
|
|
131
|
+
* Returns merged icons (user config + defaults).
|
|
132
|
+
*/
|
|
133
|
+
get gridIcons() {
|
|
134
|
+
const e = this.grid?.gridConfig?.icons ?? {};
|
|
135
|
+
return { ...f, ...e };
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Resolve an icon value to string or HTMLElement.
|
|
139
|
+
* Checks plugin config first, then grid-level icons, then defaults.
|
|
140
|
+
*
|
|
141
|
+
* @param iconKey - The icon key in GridIcons (e.g., 'expand', 'collapse')
|
|
142
|
+
* @param pluginOverride - Optional plugin-level override
|
|
143
|
+
* @returns The resolved icon value
|
|
144
|
+
*/
|
|
145
|
+
resolveIcon(e, t) {
|
|
146
|
+
return t !== void 0 ? t : this.gridIcons[e];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Set an icon value on an element.
|
|
150
|
+
* Handles both string (text/HTML) and HTMLElement values.
|
|
151
|
+
*
|
|
152
|
+
* @param element - The element to set the icon on
|
|
153
|
+
* @param icon - The icon value (string or HTMLElement)
|
|
154
|
+
*/
|
|
155
|
+
setIcon(e, t) {
|
|
156
|
+
typeof t == "string" ? e.innerHTML = t : t instanceof HTMLElement && (e.innerHTML = "", e.appendChild(t.cloneNode(!0)));
|
|
157
|
+
}
|
|
100
158
|
/**
|
|
101
159
|
* Log a warning message.
|
|
102
160
|
*/
|
|
@@ -104,7 +162,7 @@ class f {
|
|
|
104
162
|
console.warn(`[tbw-grid:${this.name}] ${e}`);
|
|
105
163
|
}
|
|
106
164
|
}
|
|
107
|
-
function
|
|
165
|
+
function d(s) {
|
|
108
166
|
return {
|
|
109
167
|
startRow: Math.min(s.startRow, s.endRow),
|
|
110
168
|
startCol: Math.min(s.startCol, s.endCol),
|
|
@@ -112,35 +170,35 @@ function h(s) {
|
|
|
112
170
|
endCol: Math.max(s.startCol, s.endCol)
|
|
113
171
|
};
|
|
114
172
|
}
|
|
115
|
-
function
|
|
116
|
-
const e =
|
|
173
|
+
function R(s) {
|
|
174
|
+
const e = d(s);
|
|
117
175
|
return {
|
|
118
176
|
from: { row: e.startRow, col: e.startCol },
|
|
119
177
|
to: { row: e.endRow, col: e.endCol }
|
|
120
178
|
};
|
|
121
179
|
}
|
|
122
|
-
function
|
|
123
|
-
return s.map(
|
|
180
|
+
function h(s) {
|
|
181
|
+
return s.map(R);
|
|
124
182
|
}
|
|
125
|
-
function
|
|
126
|
-
const
|
|
127
|
-
return s >=
|
|
183
|
+
function C(s, e, t) {
|
|
184
|
+
const r = d(t);
|
|
185
|
+
return s >= r.startRow && s <= r.endRow && e >= r.startCol && e <= r.endCol;
|
|
128
186
|
}
|
|
129
187
|
function g(s, e, t) {
|
|
130
|
-
return t.some((
|
|
188
|
+
return t.some((r) => C(s, e, r));
|
|
131
189
|
}
|
|
132
|
-
function
|
|
133
|
-
const e = [], t =
|
|
134
|
-
for (let
|
|
135
|
-
for (let
|
|
136
|
-
e.push({ row:
|
|
190
|
+
function m(s) {
|
|
191
|
+
const e = [], t = d(s);
|
|
192
|
+
for (let r = t.startRow; r <= t.endRow; r++)
|
|
193
|
+
for (let n = t.startCol; n <= t.endCol; n++)
|
|
194
|
+
e.push({ row: r, col: n });
|
|
137
195
|
return e;
|
|
138
196
|
}
|
|
139
|
-
function
|
|
197
|
+
function b(s) {
|
|
140
198
|
const e = /* @__PURE__ */ new Map();
|
|
141
199
|
for (const t of s)
|
|
142
|
-
for (const
|
|
143
|
-
e.set(`${
|
|
200
|
+
for (const r of m(t))
|
|
201
|
+
e.set(`${r.row},${r.col}`, r);
|
|
144
202
|
return [...e.values()];
|
|
145
203
|
}
|
|
146
204
|
function u(s, e) {
|
|
@@ -151,7 +209,7 @@ function u(s, e) {
|
|
|
151
209
|
endCol: e.col
|
|
152
210
|
};
|
|
153
211
|
}
|
|
154
|
-
function
|
|
212
|
+
function A(s, e, t) {
|
|
155
213
|
if (s === "cell" && e.selectedCell)
|
|
156
214
|
return {
|
|
157
215
|
mode: s,
|
|
@@ -163,15 +221,15 @@ function b(s, e, t) {
|
|
|
163
221
|
]
|
|
164
222
|
};
|
|
165
223
|
if (s === "row" && e.selected.size > 0) {
|
|
166
|
-
const
|
|
167
|
-
from: { row:
|
|
168
|
-
to: { row:
|
|
224
|
+
const r = [...e.selected].map((n) => ({
|
|
225
|
+
from: { row: n, col: 0 },
|
|
226
|
+
to: { row: n, col: t - 1 }
|
|
169
227
|
}));
|
|
170
|
-
return { mode: s, ranges:
|
|
228
|
+
return { mode: s, ranges: r };
|
|
171
229
|
}
|
|
172
|
-
return s === "range" && e.ranges.length > 0 ? { mode: s, ranges:
|
|
230
|
+
return s === "range" && e.ranges.length > 0 ? { mode: s, ranges: h(e.ranges) } : { mode: s, ranges: [] };
|
|
173
231
|
}
|
|
174
|
-
class v extends
|
|
232
|
+
class v extends w {
|
|
175
233
|
name = "selection";
|
|
176
234
|
version = "1.0.0";
|
|
177
235
|
get defaultConfig() {
|
|
@@ -197,32 +255,32 @@ class v extends f {
|
|
|
197
255
|
}
|
|
198
256
|
// ===== Event Handlers =====
|
|
199
257
|
onCellClick(e) {
|
|
200
|
-
const { rowIndex: t, colIndex:
|
|
258
|
+
const { rowIndex: t, colIndex: r, originalEvent: n } = e, { mode: o } = this.config;
|
|
201
259
|
if (o === "cell")
|
|
202
|
-
return this.selectedCell = { row: t, col:
|
|
260
|
+
return this.selectedCell = { row: t, col: r }, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
|
|
203
261
|
if (o === "row")
|
|
204
262
|
return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
|
|
205
263
|
if (o === "range") {
|
|
206
|
-
const a =
|
|
264
|
+
const a = n.shiftKey, i = n.ctrlKey || n.metaKey;
|
|
207
265
|
if (a && this.cellAnchor) {
|
|
208
|
-
const
|
|
209
|
-
i ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] =
|
|
266
|
+
const l = u(this.cellAnchor, { row: t, col: r });
|
|
267
|
+
i ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = l : this.ranges.push(l) : this.ranges = [l], this.activeRange = l;
|
|
210
268
|
} else if (i) {
|
|
211
|
-
const
|
|
269
|
+
const l = {
|
|
212
270
|
startRow: t,
|
|
213
|
-
startCol:
|
|
271
|
+
startCol: r,
|
|
214
272
|
endRow: t,
|
|
215
|
-
endCol:
|
|
273
|
+
endCol: r
|
|
216
274
|
};
|
|
217
|
-
this.ranges.push(
|
|
275
|
+
this.ranges.push(l), this.activeRange = l, this.cellAnchor = { row: t, col: r };
|
|
218
276
|
} else {
|
|
219
|
-
const
|
|
277
|
+
const l = {
|
|
220
278
|
startRow: t,
|
|
221
|
-
startCol:
|
|
279
|
+
startCol: r,
|
|
222
280
|
endRow: t,
|
|
223
|
-
endCol:
|
|
281
|
+
endCol: r
|
|
224
282
|
};
|
|
225
|
-
this.ranges = [
|
|
283
|
+
this.ranges = [l], this.activeRange = l, this.cellAnchor = { row: t, col: r };
|
|
226
284
|
}
|
|
227
285
|
return this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
|
|
228
286
|
}
|
|
@@ -233,13 +291,13 @@ class v extends f {
|
|
|
233
291
|
if (e.key === "Escape")
|
|
234
292
|
return t === "cell" ? this.selectedCell = null : t === "row" ? (this.selected.clear(), this.anchor = null) : t === "range" && (this.ranges = [], this.activeRange = null, this.cellAnchor = null), this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
235
293
|
if (t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey)) {
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
294
|
+
const r = this.rows.length, n = this.columns.length;
|
|
295
|
+
if (r > 0 && n > 0) {
|
|
238
296
|
const o = {
|
|
239
297
|
startRow: 0,
|
|
240
298
|
startCol: 0,
|
|
241
|
-
endRow:
|
|
242
|
-
endCol:
|
|
299
|
+
endRow: r - 1,
|
|
300
|
+
endCol: n - 1
|
|
243
301
|
};
|
|
244
302
|
return this.ranges = [o], this.activeRange = o, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
245
303
|
}
|
|
@@ -250,13 +308,13 @@ class v extends f {
|
|
|
250
308
|
if (this.config.mode !== "range" || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0 || e.originalEvent.shiftKey && this.cellAnchor)
|
|
251
309
|
return;
|
|
252
310
|
this.isDragging = !0;
|
|
253
|
-
const t = e.rowIndex,
|
|
254
|
-
this.cellAnchor = { row: t, col:
|
|
311
|
+
const t = e.rowIndex, r = e.colIndex;
|
|
312
|
+
this.cellAnchor = { row: t, col: r }, e.originalEvent.ctrlKey || e.originalEvent.metaKey || (this.ranges = []);
|
|
255
313
|
const o = {
|
|
256
314
|
startRow: t,
|
|
257
|
-
startCol:
|
|
315
|
+
startCol: r,
|
|
258
316
|
endRow: t,
|
|
259
|
-
endCol:
|
|
317
|
+
endCol: r
|
|
260
318
|
};
|
|
261
319
|
return this.ranges.push(o), this.activeRange = o, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
262
320
|
}
|
|
@@ -280,17 +338,17 @@ class v extends f {
|
|
|
280
338
|
e.querySelectorAll(".cell").forEach((o) => {
|
|
281
339
|
o.classList.remove("selected", "top", "bottom", "first", "last");
|
|
282
340
|
});
|
|
283
|
-
const
|
|
284
|
-
if (
|
|
341
|
+
const n = e.querySelectorAll(".data-grid-row");
|
|
342
|
+
if (n.forEach((o) => {
|
|
285
343
|
o.classList.remove("selected", "row-focus");
|
|
286
|
-
}), t === "row" &&
|
|
344
|
+
}), t === "row" && n.forEach((o) => {
|
|
287
345
|
const a = o.querySelector(".cell[data-row]"), i = parseInt(a?.getAttribute("data-row") ?? "-1", 10);
|
|
288
|
-
i >= 0 && this.selected.has(i) && (o.classList.add("selected", "row-focus"), o.querySelectorAll(".cell-focus").forEach((
|
|
346
|
+
i >= 0 && this.selected.has(i) && (o.classList.add("selected", "row-focus"), o.querySelectorAll(".cell-focus").forEach((l) => l.classList.remove("cell-focus")));
|
|
289
347
|
}), t === "range" && this.ranges.length > 0) {
|
|
290
|
-
const o = this.activeRange ?
|
|
348
|
+
const o = this.activeRange ? d(this.activeRange) : null;
|
|
291
349
|
e.querySelectorAll(".cell[data-row][data-col]").forEach((i) => {
|
|
292
|
-
const
|
|
293
|
-
|
|
350
|
+
const l = parseInt(i.getAttribute("data-row") ?? "-1", 10), c = parseInt(i.getAttribute("data-col") ?? "-1", 10);
|
|
351
|
+
l >= 0 && c >= 0 && g(l, c, this.ranges) && (i.classList.add("selected"), i.classList.remove("cell-focus"), o && (l === o.startRow && i.classList.add("top"), l === o.endRow && i.classList.add("bottom"), c === o.startCol && i.classList.add("first"), c === o.endCol && i.classList.add("last")));
|
|
294
352
|
});
|
|
295
353
|
}
|
|
296
354
|
t === "cell" && this.selectedCell && e.querySelectorAll(".cell-focus").forEach((o) => o.classList.remove("cell-focus"));
|
|
@@ -298,8 +356,8 @@ class v extends f {
|
|
|
298
356
|
afterRender() {
|
|
299
357
|
const e = this.shadowRoot;
|
|
300
358
|
if (!e) return;
|
|
301
|
-
const t = e.children[0], { mode:
|
|
302
|
-
this.grid.setAttribute("data-selection-mode",
|
|
359
|
+
const t = e.children[0], { mode: r } = this.config;
|
|
360
|
+
this.grid.setAttribute("data-selection-mode", r), t && t.classList.toggle("selecting", this.isDragging), this.#t();
|
|
303
361
|
}
|
|
304
362
|
/**
|
|
305
363
|
* Called after scroll-triggered row rendering.
|
|
@@ -325,13 +383,13 @@ class v extends f {
|
|
|
325
383
|
* Get all selected cell ranges in public format.
|
|
326
384
|
*/
|
|
327
385
|
getRanges() {
|
|
328
|
-
return
|
|
386
|
+
return h(this.ranges);
|
|
329
387
|
}
|
|
330
388
|
/**
|
|
331
389
|
* Get all selected cells across all ranges.
|
|
332
390
|
*/
|
|
333
391
|
getSelectedCells() {
|
|
334
|
-
return
|
|
392
|
+
return b(this.ranges);
|
|
335
393
|
}
|
|
336
394
|
/**
|
|
337
395
|
* Check if a specific cell is in range selection.
|
|
@@ -356,12 +414,12 @@ class v extends f {
|
|
|
356
414
|
endCol: t.to.col
|
|
357
415
|
})), this.activeRange = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null, this.emit("selection-change", {
|
|
358
416
|
mode: this.config.mode,
|
|
359
|
-
ranges:
|
|
417
|
+
ranges: h(this.ranges)
|
|
360
418
|
}), this.requestAfterRender();
|
|
361
419
|
}
|
|
362
420
|
// ===== Private Helpers =====
|
|
363
421
|
#e() {
|
|
364
|
-
return
|
|
422
|
+
return A(
|
|
365
423
|
this.config.mode,
|
|
366
424
|
{
|
|
367
425
|
selectedCell: this.selectedCell,
|
|
@@ -406,39 +464,39 @@ class v extends f {
|
|
|
406
464
|
}
|
|
407
465
|
`;
|
|
408
466
|
}
|
|
409
|
-
function
|
|
410
|
-
const
|
|
467
|
+
function y(s, e, t, r) {
|
|
468
|
+
const n = new Set(s.selected);
|
|
411
469
|
let o = s.anchor;
|
|
412
470
|
if (t === "single")
|
|
413
|
-
|
|
471
|
+
n.clear(), n.add(e), o = e;
|
|
414
472
|
else if (t === "multiple") {
|
|
415
|
-
const a =
|
|
416
|
-
if (
|
|
417
|
-
const i = Math.min(s.anchor, e),
|
|
418
|
-
for (let c = i; c <=
|
|
419
|
-
|
|
420
|
-
} else a ? (
|
|
421
|
-
}
|
|
422
|
-
return { selected:
|
|
473
|
+
const a = r.ctrlKey || r.metaKey;
|
|
474
|
+
if (r.shiftKey && s.anchor !== null) {
|
|
475
|
+
const i = Math.min(s.anchor, e), l = Math.max(s.anchor, e);
|
|
476
|
+
for (let c = i; c <= l; c++)
|
|
477
|
+
n.add(c);
|
|
478
|
+
} else a ? (n.has(e) ? n.delete(e) : n.add(e), o = e) : (n.clear(), n.add(e), o = e);
|
|
479
|
+
}
|
|
480
|
+
return { selected: n, lastSelected: e, anchor: o };
|
|
423
481
|
}
|
|
424
|
-
function
|
|
482
|
+
function S(s) {
|
|
425
483
|
const e = /* @__PURE__ */ new Set();
|
|
426
484
|
for (let t = 0; t < s; t++)
|
|
427
485
|
e.add(t);
|
|
428
486
|
return e;
|
|
429
487
|
}
|
|
430
|
-
function
|
|
431
|
-
const t = [],
|
|
432
|
-
for (const
|
|
433
|
-
s.has(
|
|
434
|
-
for (const
|
|
435
|
-
e.has(
|
|
436
|
-
return { added: t, removed:
|
|
488
|
+
function I(s, e) {
|
|
489
|
+
const t = [], r = [];
|
|
490
|
+
for (const n of e)
|
|
491
|
+
s.has(n) || t.push(n);
|
|
492
|
+
for (const n of s)
|
|
493
|
+
e.has(n) || r.push(n);
|
|
494
|
+
return { added: t, removed: r };
|
|
437
495
|
}
|
|
438
496
|
export {
|
|
439
497
|
v as SelectionPlugin,
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
498
|
+
I as computeSelectionDiff,
|
|
499
|
+
y as handleRowClick,
|
|
500
|
+
S as selectAll
|
|
443
501
|
};
|
|
444
502
|
//# sourceMappingURL=index.js.map
|