@toolbox-web/grid 0.0.3 → 0.0.5
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 +50 -6
- package/all.js +101 -98
- package/all.js.map +1 -1
- package/index.d.ts +54 -0
- package/index.js +793 -692
- package/index.js.map +1 -1
- package/lib/plugins/clipboard/index.js +55 -35
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +49 -29
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +35 -15
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/export/index.js +52 -32
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +116 -99
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +42 -22
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +20 -0
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +50 -27
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +25 -5
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +20 -0
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +20 -0
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +20 -0
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/reorder/index.js +56 -33
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js +138 -100
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js +20 -0
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/index.js +76 -53
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js +20 -0
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +20 -0
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +4 -1
- package/themes/dg-theme-contrast.css +43 -43
- package/themes/dg-theme-large.css +54 -54
- package/themes/dg-theme-standard.css +19 -19
- package/themes/dg-theme-vibrant.css +16 -16
- package/umd/grid.all.umd.js +24 -24
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +14 -14
- package/umd/grid.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/master-detail.umd.js +2 -2
- package/umd/plugins/master-detail.umd.js.map +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/selection.umd.js +2 -2
- package/umd/plugins/selection.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.map +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class f {
|
|
2
2
|
/** Plugin version - override in subclass if needed */
|
|
3
3
|
version = "1.0.0";
|
|
4
4
|
/** CSS styles to inject into the grid's shadow DOM */
|
|
@@ -97,6 +97,26 @@ class w {
|
|
|
97
97
|
get shadowRoot() {
|
|
98
98
|
return this.grid?.shadowRoot ?? null;
|
|
99
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Get the disconnect signal for event listener cleanup.
|
|
102
|
+
* This signal is aborted when the grid disconnects from the DOM.
|
|
103
|
+
* Use this when adding event listeners that should be cleaned up automatically.
|
|
104
|
+
*
|
|
105
|
+
* Best for:
|
|
106
|
+
* - Document/window-level listeners added in attach()
|
|
107
|
+
* - Listeners on the grid element itself
|
|
108
|
+
* - Any listener that should persist across renders
|
|
109
|
+
*
|
|
110
|
+
* Not needed for:
|
|
111
|
+
* - Listeners on elements created in afterRender() (removed with element)
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* element.addEventListener('click', handler, { signal: this.disconnectSignal });
|
|
115
|
+
* document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
|
|
116
|
+
*/
|
|
117
|
+
get disconnectSignal() {
|
|
118
|
+
return this.grid?.disconnectSignal;
|
|
119
|
+
}
|
|
100
120
|
/**
|
|
101
121
|
* Log a warning message.
|
|
102
122
|
*/
|
|
@@ -104,7 +124,7 @@ class w {
|
|
|
104
124
|
console.warn(`[tbw-grid:${this.name}] ${e}`);
|
|
105
125
|
}
|
|
106
126
|
}
|
|
107
|
-
function
|
|
127
|
+
function h(s) {
|
|
108
128
|
return {
|
|
109
129
|
startRow: Math.min(s.startRow, s.endRow),
|
|
110
130
|
startCol: Math.min(s.startCol, s.endCol),
|
|
@@ -112,38 +132,38 @@ function d(s) {
|
|
|
112
132
|
endCol: Math.max(s.startCol, s.endCol)
|
|
113
133
|
};
|
|
114
134
|
}
|
|
115
|
-
function
|
|
116
|
-
const e =
|
|
135
|
+
function w(s) {
|
|
136
|
+
const e = h(s);
|
|
117
137
|
return {
|
|
118
138
|
from: { row: e.startRow, col: e.startCol },
|
|
119
139
|
to: { row: e.endRow, col: e.endCol }
|
|
120
140
|
};
|
|
121
141
|
}
|
|
122
|
-
function
|
|
123
|
-
return s.map(
|
|
142
|
+
function d(s) {
|
|
143
|
+
return s.map(w);
|
|
124
144
|
}
|
|
125
|
-
function
|
|
126
|
-
const
|
|
127
|
-
return s >=
|
|
145
|
+
function R(s, e, t) {
|
|
146
|
+
const l = h(t);
|
|
147
|
+
return s >= l.startRow && s <= l.endRow && e >= l.startCol && e <= l.endCol;
|
|
128
148
|
}
|
|
129
|
-
function
|
|
130
|
-
return t.some((
|
|
149
|
+
function g(s, e, t) {
|
|
150
|
+
return t.some((l) => R(s, e, l));
|
|
131
151
|
}
|
|
132
|
-
function
|
|
133
|
-
const e = [], t =
|
|
134
|
-
for (let
|
|
135
|
-
for (let
|
|
136
|
-
e.push({ row:
|
|
152
|
+
function C(s) {
|
|
153
|
+
const e = [], t = h(s);
|
|
154
|
+
for (let l = t.startRow; l <= t.endRow; l++)
|
|
155
|
+
for (let r = t.startCol; r <= t.endCol; r++)
|
|
156
|
+
e.push({ row: l, col: r });
|
|
137
157
|
return e;
|
|
138
158
|
}
|
|
139
|
-
function
|
|
159
|
+
function m(s) {
|
|
140
160
|
const e = /* @__PURE__ */ new Map();
|
|
141
161
|
for (const t of s)
|
|
142
|
-
for (const
|
|
143
|
-
e.set(`${
|
|
162
|
+
for (const l of C(t))
|
|
163
|
+
e.set(`${l.row},${l.col}`, l);
|
|
144
164
|
return [...e.values()];
|
|
145
165
|
}
|
|
146
|
-
function
|
|
166
|
+
function u(s, e) {
|
|
147
167
|
return {
|
|
148
168
|
startRow: s.row,
|
|
149
169
|
startCol: s.col,
|
|
@@ -151,7 +171,7 @@ function f(s, e) {
|
|
|
151
171
|
endCol: e.col
|
|
152
172
|
};
|
|
153
173
|
}
|
|
154
|
-
function
|
|
174
|
+
function b(s, e, t) {
|
|
155
175
|
if (s === "cell" && e.selectedCell)
|
|
156
176
|
return {
|
|
157
177
|
mode: s,
|
|
@@ -163,15 +183,15 @@ function A(s, e, t) {
|
|
|
163
183
|
]
|
|
164
184
|
};
|
|
165
185
|
if (s === "row" && e.selected.size > 0) {
|
|
166
|
-
const
|
|
167
|
-
from: { row:
|
|
168
|
-
to: { row:
|
|
186
|
+
const l = [...e.selected].map((r) => ({
|
|
187
|
+
from: { row: r, col: 0 },
|
|
188
|
+
to: { row: r, col: t - 1 }
|
|
169
189
|
}));
|
|
170
|
-
return { mode: s, ranges:
|
|
190
|
+
return { mode: s, ranges: l };
|
|
171
191
|
}
|
|
172
|
-
return s === "range" && e.ranges.length > 0 ? { mode: s, ranges:
|
|
192
|
+
return s === "range" && e.ranges.length > 0 ? { mode: s, ranges: d(e.ranges) } : { mode: s, ranges: [] };
|
|
173
193
|
}
|
|
174
|
-
class
|
|
194
|
+
class v extends f {
|
|
175
195
|
name = "selection";
|
|
176
196
|
version = "1.0.0";
|
|
177
197
|
get defaultConfig() {
|
|
@@ -197,32 +217,32 @@ class p extends w {
|
|
|
197
217
|
}
|
|
198
218
|
// ===== Event Handlers =====
|
|
199
219
|
onCellClick(e) {
|
|
200
|
-
const { rowIndex: t, colIndex:
|
|
201
|
-
if (
|
|
202
|
-
return this.selectedCell = { row: t, col:
|
|
203
|
-
if (
|
|
220
|
+
const { rowIndex: t, colIndex: l, originalEvent: r } = e, { mode: n } = this.config;
|
|
221
|
+
if (n === "cell")
|
|
222
|
+
return this.selectedCell = { row: t, col: l }, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
|
|
223
|
+
if (n === "row")
|
|
204
224
|
return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
|
|
205
|
-
if (
|
|
206
|
-
const
|
|
207
|
-
if (
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
} else if (
|
|
211
|
-
const
|
|
225
|
+
if (n === "range") {
|
|
226
|
+
const a = r.shiftKey, i = r.ctrlKey || r.metaKey;
|
|
227
|
+
if (a && this.cellAnchor) {
|
|
228
|
+
const o = u(this.cellAnchor, { row: t, col: l });
|
|
229
|
+
i ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = o : this.ranges.push(o) : this.ranges = [o], this.activeRange = o;
|
|
230
|
+
} else if (i) {
|
|
231
|
+
const o = {
|
|
212
232
|
startRow: t,
|
|
213
|
-
startCol:
|
|
233
|
+
startCol: l,
|
|
214
234
|
endRow: t,
|
|
215
|
-
endCol:
|
|
235
|
+
endCol: l
|
|
216
236
|
};
|
|
217
|
-
this.ranges.push(
|
|
237
|
+
this.ranges.push(o), this.activeRange = o, this.cellAnchor = { row: t, col: l };
|
|
218
238
|
} else {
|
|
219
|
-
const
|
|
239
|
+
const o = {
|
|
220
240
|
startRow: t,
|
|
221
|
-
startCol:
|
|
241
|
+
startCol: l,
|
|
222
242
|
endRow: t,
|
|
223
|
-
endCol:
|
|
243
|
+
endCol: l
|
|
224
244
|
};
|
|
225
|
-
this.ranges = [
|
|
245
|
+
this.ranges = [o], this.activeRange = o, this.cellAnchor = { row: t, col: l };
|
|
226
246
|
}
|
|
227
247
|
return this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
|
|
228
248
|
}
|
|
@@ -233,15 +253,15 @@ class p extends w {
|
|
|
233
253
|
if (e.key === "Escape")
|
|
234
254
|
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
255
|
if (t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey)) {
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
238
|
-
const
|
|
256
|
+
const l = this.rows.length, r = this.columns.length;
|
|
257
|
+
if (l > 0 && r > 0) {
|
|
258
|
+
const n = {
|
|
239
259
|
startRow: 0,
|
|
240
260
|
startCol: 0,
|
|
241
|
-
endRow:
|
|
242
|
-
endCol:
|
|
261
|
+
endRow: l - 1,
|
|
262
|
+
endCol: r - 1
|
|
243
263
|
};
|
|
244
|
-
return this.ranges = [
|
|
264
|
+
return this.ranges = [n], this.activeRange = n, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
245
265
|
}
|
|
246
266
|
}
|
|
247
267
|
return !1;
|
|
@@ -250,45 +270,63 @@ class p extends w {
|
|
|
250
270
|
if (this.config.mode !== "range" || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0 || e.originalEvent.shiftKey && this.cellAnchor)
|
|
251
271
|
return;
|
|
252
272
|
this.isDragging = !0;
|
|
253
|
-
const t = e.rowIndex,
|
|
254
|
-
this.cellAnchor = { row: t, col:
|
|
255
|
-
const
|
|
273
|
+
const t = e.rowIndex, l = e.colIndex;
|
|
274
|
+
this.cellAnchor = { row: t, col: l }, e.originalEvent.ctrlKey || e.originalEvent.metaKey || (this.ranges = []);
|
|
275
|
+
const n = {
|
|
256
276
|
startRow: t,
|
|
257
|
-
startCol:
|
|
277
|
+
startCol: l,
|
|
258
278
|
endRow: t,
|
|
259
|
-
endCol:
|
|
279
|
+
endCol: l
|
|
260
280
|
};
|
|
261
|
-
return this.ranges.push(
|
|
281
|
+
return this.ranges.push(n), this.activeRange = n, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
262
282
|
}
|
|
263
283
|
onCellMouseMove(e) {
|
|
264
284
|
if (this.config.mode !== "range" || !this.isDragging || !this.cellAnchor || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
|
|
265
|
-
const t =
|
|
285
|
+
const t = u(this.cellAnchor, { row: e.rowIndex, col: e.colIndex });
|
|
266
286
|
return this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = t : this.ranges.push(t), this.activeRange = t, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
267
287
|
}
|
|
268
288
|
onCellMouseUp(e) {
|
|
269
289
|
if (this.config.mode === "range" && this.isDragging)
|
|
270
290
|
return this.isDragging = !1, !0;
|
|
271
291
|
}
|
|
272
|
-
|
|
292
|
+
/**
|
|
293
|
+
* Apply selection classes to visible cells/rows.
|
|
294
|
+
* Shared by afterRender and onScrollRender.
|
|
295
|
+
*/
|
|
296
|
+
#t() {
|
|
273
297
|
const e = this.shadowRoot;
|
|
274
298
|
if (!e) return;
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
299
|
+
const { mode: t } = this.config;
|
|
300
|
+
e.querySelectorAll(".cell").forEach((n) => {
|
|
301
|
+
n.classList.remove("selected", "top", "bottom", "first", "last");
|
|
278
302
|
});
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
}),
|
|
283
|
-
const a =
|
|
284
|
-
|
|
285
|
-
})
|
|
286
|
-
const
|
|
287
|
-
e.querySelectorAll(".cell[data-row][data-col]").forEach((
|
|
288
|
-
const
|
|
289
|
-
|
|
303
|
+
const r = e.querySelectorAll(".data-grid-row");
|
|
304
|
+
if (r.forEach((n) => {
|
|
305
|
+
n.classList.remove("selected", "row-focus");
|
|
306
|
+
}), t === "row" && r.forEach((n) => {
|
|
307
|
+
const a = n.querySelector(".cell[data-row]"), i = parseInt(a?.getAttribute("data-row") ?? "-1", 10);
|
|
308
|
+
i >= 0 && this.selected.has(i) && (n.classList.add("selected", "row-focus"), n.querySelectorAll(".cell-focus").forEach((o) => o.classList.remove("cell-focus")));
|
|
309
|
+
}), t === "range" && this.ranges.length > 0) {
|
|
310
|
+
const n = this.activeRange ? h(this.activeRange) : null;
|
|
311
|
+
e.querySelectorAll(".cell[data-row][data-col]").forEach((i) => {
|
|
312
|
+
const o = parseInt(i.getAttribute("data-row") ?? "-1", 10), c = parseInt(i.getAttribute("data-col") ?? "-1", 10);
|
|
313
|
+
o >= 0 && c >= 0 && g(o, c, this.ranges) && (i.classList.add("selected"), i.classList.remove("cell-focus"), n && (o === n.startRow && i.classList.add("top"), o === n.endRow && i.classList.add("bottom"), c === n.startCol && i.classList.add("first"), c === n.endCol && i.classList.add("last")));
|
|
290
314
|
});
|
|
291
315
|
}
|
|
316
|
+
t === "cell" && this.selectedCell && e.querySelectorAll(".cell-focus").forEach((n) => n.classList.remove("cell-focus"));
|
|
317
|
+
}
|
|
318
|
+
afterRender() {
|
|
319
|
+
const e = this.shadowRoot;
|
|
320
|
+
if (!e) return;
|
|
321
|
+
const t = e.children[0], { mode: l } = this.config;
|
|
322
|
+
this.grid.setAttribute("data-selection-mode", l), t && t.classList.toggle("selecting", this.isDragging), this.#t();
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Called after scroll-triggered row rendering.
|
|
326
|
+
* Reapplies selection classes to recycled DOM elements.
|
|
327
|
+
*/
|
|
328
|
+
onScrollRender() {
|
|
329
|
+
this.#t();
|
|
292
330
|
}
|
|
293
331
|
// ===== Public API =====
|
|
294
332
|
/**
|
|
@@ -307,19 +345,19 @@ class p extends w {
|
|
|
307
345
|
* Get all selected cell ranges in public format.
|
|
308
346
|
*/
|
|
309
347
|
getRanges() {
|
|
310
|
-
return
|
|
348
|
+
return d(this.ranges);
|
|
311
349
|
}
|
|
312
350
|
/**
|
|
313
351
|
* Get all selected cells across all ranges.
|
|
314
352
|
*/
|
|
315
353
|
getSelectedCells() {
|
|
316
|
-
return
|
|
354
|
+
return m(this.ranges);
|
|
317
355
|
}
|
|
318
356
|
/**
|
|
319
357
|
* Check if a specific cell is in range selection.
|
|
320
358
|
*/
|
|
321
359
|
isCellSelected(e, t) {
|
|
322
|
-
return
|
|
360
|
+
return g(e, t, this.ranges);
|
|
323
361
|
}
|
|
324
362
|
/**
|
|
325
363
|
* Clear all selection.
|
|
@@ -338,12 +376,12 @@ class p extends w {
|
|
|
338
376
|
endCol: t.to.col
|
|
339
377
|
})), this.activeRange = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null, this.emit("selection-change", {
|
|
340
378
|
mode: this.config.mode,
|
|
341
|
-
ranges:
|
|
379
|
+
ranges: d(this.ranges)
|
|
342
380
|
}), this.requestAfterRender();
|
|
343
381
|
}
|
|
344
382
|
// ===== Private Helpers =====
|
|
345
383
|
#e() {
|
|
346
|
-
return
|
|
384
|
+
return b(
|
|
347
385
|
this.config.mode,
|
|
348
386
|
{
|
|
349
387
|
selectedCell: this.selectedCell,
|
|
@@ -388,39 +426,39 @@ class p extends w {
|
|
|
388
426
|
}
|
|
389
427
|
`;
|
|
390
428
|
}
|
|
391
|
-
function
|
|
392
|
-
const
|
|
393
|
-
let
|
|
429
|
+
function p(s, e, t, l) {
|
|
430
|
+
const r = new Set(s.selected);
|
|
431
|
+
let n = s.anchor;
|
|
394
432
|
if (t === "single")
|
|
395
|
-
|
|
433
|
+
r.clear(), r.add(e), n = e;
|
|
396
434
|
else if (t === "multiple") {
|
|
397
|
-
const
|
|
398
|
-
if (
|
|
399
|
-
const
|
|
400
|
-
for (let c =
|
|
401
|
-
|
|
402
|
-
} else
|
|
403
|
-
}
|
|
404
|
-
return { selected:
|
|
435
|
+
const a = l.ctrlKey || l.metaKey;
|
|
436
|
+
if (l.shiftKey && s.anchor !== null) {
|
|
437
|
+
const i = Math.min(s.anchor, e), o = Math.max(s.anchor, e);
|
|
438
|
+
for (let c = i; c <= o; c++)
|
|
439
|
+
r.add(c);
|
|
440
|
+
} else a ? (r.has(e) ? r.delete(e) : r.add(e), n = e) : (r.clear(), r.add(e), n = e);
|
|
441
|
+
}
|
|
442
|
+
return { selected: r, lastSelected: e, anchor: n };
|
|
405
443
|
}
|
|
406
|
-
function
|
|
444
|
+
function y(s) {
|
|
407
445
|
const e = /* @__PURE__ */ new Set();
|
|
408
446
|
for (let t = 0; t < s; t++)
|
|
409
447
|
e.add(t);
|
|
410
448
|
return e;
|
|
411
449
|
}
|
|
412
450
|
function S(s, e) {
|
|
413
|
-
const t = [],
|
|
414
|
-
for (const
|
|
415
|
-
s.has(
|
|
416
|
-
for (const
|
|
417
|
-
e.has(
|
|
418
|
-
return { added: t, removed:
|
|
451
|
+
const t = [], l = [];
|
|
452
|
+
for (const r of e)
|
|
453
|
+
s.has(r) || t.push(r);
|
|
454
|
+
for (const r of s)
|
|
455
|
+
e.has(r) || l.push(r);
|
|
456
|
+
return { added: t, removed: l };
|
|
419
457
|
}
|
|
420
458
|
export {
|
|
421
|
-
|
|
459
|
+
v as SelectionPlugin,
|
|
422
460
|
S as computeSelectionDiff,
|
|
423
|
-
|
|
424
|
-
|
|
461
|
+
p as handleRowClick,
|
|
462
|
+
y as selectAll
|
|
425
463
|
};
|
|
426
464
|
//# sourceMappingURL=index.js.map
|