@toolbox-web/grid 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/all.js +694 -525
- package/all.js.map +1 -1
- package/index.js +1468 -1449
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +2 -1
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/sanitize.d.ts.map +1 -1
- package/lib/core/internal/validate-config.d.ts.map +1 -1
- package/lib/core/types.d.ts +9 -1
- package/lib/core/types.d.ts.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/ContextMenuPlugin.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/editors.d.ts.map +1 -1
- package/lib/plugins/editing/index.d.ts +1 -1
- package/lib/plugins/editing/index.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +187 -170
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/editing/types.d.ts +44 -0
- package/lib/plugins/editing/types.d.ts.map +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +9 -9
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +8 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/index.js +59 -60
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +7 -0
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
- package/lib/plugins/master-detail/index.js +185 -145
- package/lib/plugins/master-detail/index.js.map +1 -1
- 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.map +1 -1
- package/lib/plugins/print/index.js.map +1 -1
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/responsive/index.js +40 -39
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/row-reorder/index.js.map +1 -1
- package/lib/plugins/selection/SelectionPlugin.d.ts +51 -0
- package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
- package/lib/plugins/selection/index.js +325 -131
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/selection/types.d.ts +18 -0
- package/lib/plugins/selection/types.d.ts.map +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- 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/public.d.ts +2 -0
- package/public.d.ts.map +1 -1
- package/themes/dg-theme-bootstrap.css +192 -8
- package/themes/dg-theme-material.css +243 -0
- package/umd/grid.all.umd.js +43 -43
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +19 -19
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +1 -1
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +1 -1
- package/umd/plugins/editing.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-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.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/selection.umd.js +2 -2
- package/umd/plugins/selection.umd.js.map +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
function
|
|
2
|
-
if (!
|
|
3
|
-
const e =
|
|
1
|
+
function R(n) {
|
|
2
|
+
if (!n) return -1;
|
|
3
|
+
const e = n.getAttribute("data-row");
|
|
4
4
|
if (e) return parseInt(e, 10);
|
|
5
|
-
const t =
|
|
5
|
+
const t = n.closest(".data-grid-row");
|
|
6
6
|
if (!t) return -1;
|
|
7
7
|
const s = t.parentElement;
|
|
8
8
|
if (!s) return -1;
|
|
@@ -11,10 +11,10 @@ function S(r) {
|
|
|
11
11
|
if (i[l] === t) return l;
|
|
12
12
|
return -1;
|
|
13
13
|
}
|
|
14
|
-
function
|
|
15
|
-
|
|
14
|
+
function C(n) {
|
|
15
|
+
n && n.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
|
|
16
16
|
}
|
|
17
|
-
const
|
|
17
|
+
const p = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', A = {
|
|
18
18
|
expand: "▶",
|
|
19
19
|
collapse: "▼",
|
|
20
20
|
sortAsc: "▲",
|
|
@@ -23,11 +23,11 @@ const R = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
|
|
|
23
23
|
submenuArrow: "▶",
|
|
24
24
|
dragHandle: "⋮⋮",
|
|
25
25
|
toolPanel: "☰",
|
|
26
|
-
filter:
|
|
27
|
-
filterActive:
|
|
26
|
+
filter: p,
|
|
27
|
+
filterActive: p,
|
|
28
28
|
print: "🖨️"
|
|
29
29
|
};
|
|
30
|
-
class
|
|
30
|
+
class k {
|
|
31
31
|
/**
|
|
32
32
|
* Plugin dependencies - declare other plugins this one requires.
|
|
33
33
|
*
|
|
@@ -317,7 +317,7 @@ class v {
|
|
|
317
317
|
*/
|
|
318
318
|
get gridIcons() {
|
|
319
319
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
320
|
-
return { ...
|
|
320
|
+
return { ...A, ...e };
|
|
321
321
|
}
|
|
322
322
|
// #region Animation Helpers
|
|
323
323
|
/**
|
|
@@ -393,65 +393,69 @@ class v {
|
|
|
393
393
|
}
|
|
394
394
|
// #endregion
|
|
395
395
|
}
|
|
396
|
-
|
|
397
|
-
|
|
396
|
+
const E = "__tbw_expander";
|
|
397
|
+
function I(n) {
|
|
398
|
+
return n.field === E;
|
|
398
399
|
}
|
|
399
|
-
function
|
|
400
|
+
function f(n) {
|
|
401
|
+
return n.meta?.utility === !0;
|
|
402
|
+
}
|
|
403
|
+
function g(n) {
|
|
400
404
|
return {
|
|
401
|
-
startRow: Math.min(
|
|
402
|
-
startCol: Math.min(
|
|
403
|
-
endRow: Math.max(
|
|
404
|
-
endCol: Math.max(
|
|
405
|
+
startRow: Math.min(n.startRow, n.endRow),
|
|
406
|
+
startCol: Math.min(n.startCol, n.endCol),
|
|
407
|
+
endRow: Math.max(n.startRow, n.endRow),
|
|
408
|
+
endCol: Math.max(n.startCol, n.endCol)
|
|
405
409
|
};
|
|
406
410
|
}
|
|
407
|
-
function
|
|
408
|
-
const e =
|
|
411
|
+
function v(n) {
|
|
412
|
+
const e = g(n);
|
|
409
413
|
return {
|
|
410
414
|
from: { row: e.startRow, col: e.startCol },
|
|
411
415
|
to: { row: e.endRow, col: e.endCol }
|
|
412
416
|
};
|
|
413
417
|
}
|
|
414
|
-
function
|
|
415
|
-
return
|
|
418
|
+
function y(n) {
|
|
419
|
+
return n.map(v);
|
|
416
420
|
}
|
|
417
|
-
function
|
|
418
|
-
const s =
|
|
419
|
-
return
|
|
421
|
+
function _(n, e, t) {
|
|
422
|
+
const s = g(t);
|
|
423
|
+
return n >= s.startRow && n <= s.endRow && e >= s.startCol && e <= s.endCol;
|
|
420
424
|
}
|
|
421
|
-
function
|
|
422
|
-
return t.some((s) =>
|
|
425
|
+
function q(n, e, t) {
|
|
426
|
+
return t.some((s) => _(n, e, s));
|
|
423
427
|
}
|
|
424
|
-
function
|
|
425
|
-
const e = [], t =
|
|
428
|
+
function K(n) {
|
|
429
|
+
const e = [], t = g(n);
|
|
426
430
|
for (let s = t.startRow; s <= t.endRow; s++)
|
|
427
431
|
for (let i = t.startCol; i <= t.endCol; i++)
|
|
428
432
|
e.push({ row: s, col: i });
|
|
429
433
|
return e;
|
|
430
434
|
}
|
|
431
|
-
function
|
|
435
|
+
function M(n) {
|
|
432
436
|
const e = /* @__PURE__ */ new Map();
|
|
433
|
-
for (const t of
|
|
434
|
-
for (const s of
|
|
437
|
+
for (const t of n)
|
|
438
|
+
for (const s of K(t))
|
|
435
439
|
e.set(`${s.row},${s.col}`, s);
|
|
436
440
|
return [...e.values()];
|
|
437
441
|
}
|
|
438
|
-
function
|
|
442
|
+
function m(n, e) {
|
|
439
443
|
return {
|
|
440
|
-
startRow:
|
|
441
|
-
startCol:
|
|
444
|
+
startRow: n.row,
|
|
445
|
+
startCol: n.col,
|
|
442
446
|
endRow: e.row,
|
|
443
447
|
endCol: e.col
|
|
444
448
|
};
|
|
445
449
|
}
|
|
446
|
-
function
|
|
447
|
-
const t =
|
|
450
|
+
function b(n, e) {
|
|
451
|
+
const t = g(n), s = g(e);
|
|
448
452
|
return t.startRow === s.startRow && t.startCol === s.startCol && t.endRow === s.endRow && t.endCol === s.endCol;
|
|
449
453
|
}
|
|
450
|
-
const
|
|
451
|
-
function
|
|
452
|
-
if (
|
|
454
|
+
const F = '@layer tbw-plugins{tbw-grid.selecting .data-grid-row>.cell{-webkit-user-select:none;user-select:none}tbw-grid:has(.selection){-webkit-user-select:none;user-select:none}tbw-grid[data-has-focus] .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%));outline:none;position:relative}tbw-grid[data-has-focus] .data-grid-row.row-focus:after{content:"";position:absolute;inset:0;pointer-events:none;border:0 solid var(--tbw-range-border-color, var(--tbw-color-accent));border-top-width:2px;border-bottom-width:2px;z-index:1}tbw-grid[data-has-focus] .data-grid-row.row-focus+.data-grid-row.row-focus:after{border-top-width:0}tbw-grid[data-has-focus] .data-grid-row.row-focus:has(+.data-grid-row.row-focus):after{border-bottom-width:0}tbw-grid[data-selection-mode=row] .cell-focus,tbw-grid[data-selection-mode=row] .row-focus,tbw-grid[data-selection-mode=range] .cell-focus{outline:none}tbw-grid .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg);position:relative}tbw-grid .data-grid-row>.cell.selected:after{content:"";position:absolute;inset:0;pointer-events:none;border:0 solid var(--tbw-range-border-color);z-index:1}tbw-grid .data-grid-row>.cell.selected.top:after{border-top-width:2px}tbw-grid .data-grid-row>.cell.selected.bottom:after{border-bottom-width:2px}tbw-grid .data-grid-row>.cell.selected.first:after{border-left-width:2px}tbw-grid .data-grid-row>.cell.selected.last:after{border-right-width:2px}tbw-grid .data-grid-row[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row[data-selectable=false].row-focus{background-color:var(--tbw-color-row-alt)}tbw-grid .data-grid-row>.cell[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row>.cell[data-selectable=false].selected{background-color:var(--tbw-selection-warning-bg, rgba(from var(--tbw-color-error) r g b / 50%))}tbw-grid .tbw-selection-summary{font-size:var(--tbw-font-size-sm, .8125rem);color:var(--tbw-color-fg-muted);white-space:nowrap}tbw-grid .data-grid-row>.cell[data-field=__tbw_checkbox],tbw-grid .header-row>.cell[data-field=__tbw_checkbox]{text-align:center;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center}tbw-grid .tbw-select-row-checkbox{pointer-events:none;margin:0;cursor:pointer}tbw-grid .tbw-checkbox-header{display:flex;justify-content:center;align-items:center;height:100%}tbw-grid .tbw-select-all-checkbox{margin:0;cursor:pointer}}', S = "__tbw_checkbox";
|
|
455
|
+
function D(n, e, t) {
|
|
456
|
+
if (n === "cell" && e.selectedCell)
|
|
453
457
|
return {
|
|
454
|
-
mode:
|
|
458
|
+
mode: n,
|
|
455
459
|
ranges: [
|
|
456
460
|
{
|
|
457
461
|
from: { row: e.selectedCell.row, col: e.selectedCell.col },
|
|
@@ -459,16 +463,16 @@ function _(r, e, t) {
|
|
|
459
463
|
}
|
|
460
464
|
]
|
|
461
465
|
};
|
|
462
|
-
if (
|
|
463
|
-
const s = [...e.selected].
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
return {
|
|
468
|
-
}
|
|
469
|
-
return
|
|
466
|
+
if (n === "row" && e.selected.size > 0) {
|
|
467
|
+
const s = [...e.selected].sort((o, h) => o - h), i = [];
|
|
468
|
+
let l = s[0], r = l;
|
|
469
|
+
for (let o = 1; o < s.length; o++)
|
|
470
|
+
s[o] === r + 1 ? r = s[o] : (i.push({ from: { row: l, col: 0 }, to: { row: r, col: t - 1 } }), l = s[o], r = l);
|
|
471
|
+
return i.push({ from: { row: l, col: 0 }, to: { row: r, col: t - 1 } }), { mode: n, ranges: i };
|
|
472
|
+
}
|
|
473
|
+
return n === "range" && e.ranges.length > 0 ? { mode: n, ranges: y(e.ranges) } : { mode: n, ranges: [] };
|
|
470
474
|
}
|
|
471
|
-
class
|
|
475
|
+
class L extends k {
|
|
472
476
|
/**
|
|
473
477
|
* Plugin manifest - declares queries and configuration validation rules.
|
|
474
478
|
* @internal
|
|
@@ -489,7 +493,7 @@ class D extends v {
|
|
|
489
493
|
/** @internal */
|
|
490
494
|
name = "selection";
|
|
491
495
|
/** @internal */
|
|
492
|
-
styles =
|
|
496
|
+
styles = F;
|
|
493
497
|
/** @internal */
|
|
494
498
|
get defaultConfig() {
|
|
495
499
|
return {
|
|
@@ -512,6 +516,12 @@ class D extends v {
|
|
|
512
516
|
pendingKeyboardUpdate = null;
|
|
513
517
|
/** Cell selection state (cell mode) */
|
|
514
518
|
selectedCell = null;
|
|
519
|
+
/** Last synced focus row — used to detect when grid focus moves so selection follows */
|
|
520
|
+
lastSyncedFocusRow = -1;
|
|
521
|
+
/** Last synced focus col (cell mode) */
|
|
522
|
+
lastSyncedFocusCol = -1;
|
|
523
|
+
/** True when selection was explicitly set (click/keyboard) — prevents #syncSelectionToFocus from overwriting */
|
|
524
|
+
explicitSelection = !1;
|
|
515
525
|
// #endregion
|
|
516
526
|
// #region Private Helpers - Selection Enabled Check
|
|
517
527
|
/**
|
|
@@ -563,42 +573,58 @@ class D extends v {
|
|
|
563
573
|
}
|
|
564
574
|
/** @internal */
|
|
565
575
|
detach() {
|
|
566
|
-
this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.isDragging = !1, this.selectedCell = null, this.pendingKeyboardUpdate = null;
|
|
576
|
+
this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.isDragging = !1, this.selectedCell = null, this.pendingKeyboardUpdate = null, this.lastSyncedFocusRow = -1, this.lastSyncedFocusCol = -1;
|
|
567
577
|
}
|
|
568
578
|
/**
|
|
569
579
|
* Clear selection without emitting an event.
|
|
570
580
|
* Used when selection is invalidated by external changes (filtering, grouping, etc.)
|
|
571
581
|
*/
|
|
572
582
|
clearSelectionSilent() {
|
|
573
|
-
this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.selectedCell = null, this.lastSelected = null, this.anchor = null, this.requestAfterRender();
|
|
583
|
+
this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.selectedCell = null, this.lastSelected = null, this.anchor = null, this.lastSyncedFocusRow = -1, this.lastSyncedFocusCol = -1, this.requestAfterRender();
|
|
574
584
|
}
|
|
575
585
|
// #endregion
|
|
576
586
|
// #region Event Handlers
|
|
577
587
|
/** @internal */
|
|
578
588
|
onCellClick(e) {
|
|
579
589
|
if (!this.isSelectionEnabled()) return !1;
|
|
580
|
-
const { rowIndex: t, colIndex: s, originalEvent: i } = e, { mode: l, triggerOn:
|
|
581
|
-
if (i.type !==
|
|
590
|
+
const { rowIndex: t, colIndex: s, originalEvent: i } = e, { mode: l, triggerOn: r = "click" } = this.config;
|
|
591
|
+
if (i.type !== r)
|
|
582
592
|
return !1;
|
|
583
|
-
const o = this.columns[s],
|
|
593
|
+
const o = this.columns[s], h = o && f(o);
|
|
584
594
|
if (l === "cell") {
|
|
585
|
-
if (
|
|
595
|
+
if (h || !this.isCellSelectable(t, s))
|
|
586
596
|
return !1;
|
|
587
597
|
const a = this.selectedCell;
|
|
588
598
|
return a && a.row === t && a.col === s || (this.selectedCell = { row: t, col: s }, this.emit("selection-change", this.#e()), this.requestAfterRender()), !1;
|
|
589
599
|
}
|
|
590
|
-
if (l === "row")
|
|
591
|
-
|
|
600
|
+
if (l === "row") {
|
|
601
|
+
if (!this.isRowSelectable(t))
|
|
602
|
+
return !1;
|
|
603
|
+
const a = i.shiftKey, d = i.ctrlKey || i.metaKey, c = o?.meta?.checkboxColumn === !0;
|
|
604
|
+
if (a && this.anchor !== null) {
|
|
605
|
+
const u = Math.min(this.anchor, t), x = Math.max(this.anchor, t);
|
|
606
|
+
d || this.selected.clear();
|
|
607
|
+
for (let w = u; w <= x; w++)
|
|
608
|
+
this.isRowSelectable(w) && this.selected.add(w);
|
|
609
|
+
} else if (d || c)
|
|
610
|
+
this.selected.has(t) ? this.selected.delete(t) : this.selected.add(t), this.anchor = t;
|
|
611
|
+
else {
|
|
612
|
+
if (this.selected.size === 1 && this.selected.has(t))
|
|
613
|
+
return !1;
|
|
614
|
+
this.selected.clear(), this.selected.add(t), this.anchor = t;
|
|
615
|
+
}
|
|
616
|
+
return this.lastSelected = t, this.explicitSelection = !0, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
|
|
617
|
+
}
|
|
592
618
|
if (l === "range") {
|
|
593
|
-
if (
|
|
619
|
+
if (h || !this.isCellSelectable(t, s))
|
|
594
620
|
return !1;
|
|
595
|
-
const a = i.shiftKey,
|
|
621
|
+
const a = i.shiftKey, d = i.ctrlKey || i.metaKey;
|
|
596
622
|
if (a && this.cellAnchor) {
|
|
597
|
-
const c =
|
|
598
|
-
if (
|
|
623
|
+
const c = m(this.cellAnchor, { row: t, col: s }), u = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null;
|
|
624
|
+
if (u && b(u, c))
|
|
599
625
|
return !1;
|
|
600
|
-
|
|
601
|
-
} else if (
|
|
626
|
+
d ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = c : this.ranges.push(c) : this.ranges = [c], this.activeRange = c;
|
|
627
|
+
} else if (d) {
|
|
602
628
|
const c = {
|
|
603
629
|
startRow: t,
|
|
604
630
|
startCol: s,
|
|
@@ -613,7 +639,7 @@ class D extends v {
|
|
|
613
639
|
endRow: t,
|
|
614
640
|
endCol: s
|
|
615
641
|
};
|
|
616
|
-
if (this.ranges.length === 1 &&
|
|
642
|
+
if (this.ranges.length === 1 && b(this.ranges[0], c))
|
|
617
643
|
return !1;
|
|
618
644
|
this.ranges = [c], this.activeRange = c, this.cellAnchor = { row: t, col: s };
|
|
619
645
|
}
|
|
@@ -629,99 +655,200 @@ class D extends v {
|
|
|
629
655
|
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;
|
|
630
656
|
if (t === "cell" && i)
|
|
631
657
|
return queueMicrotask(() => {
|
|
632
|
-
const l = this.grid._focusRow,
|
|
633
|
-
this.isCellSelectable(l,
|
|
658
|
+
const l = this.grid._focusRow, r = this.grid._focusCol;
|
|
659
|
+
this.isCellSelectable(l, r) ? this.selectedCell = { row: l, col: r } : this.selectedCell = null, this.emit("selection-change", this.#e()), this.requestAfterRender();
|
|
634
660
|
}), !1;
|
|
635
|
-
if (t === "row"
|
|
636
|
-
|
|
637
|
-
const l =
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
startRow: 0,
|
|
650
|
-
startCol: 0,
|
|
651
|
-
endRow: l - 1,
|
|
652
|
-
endCol: n - 1
|
|
653
|
-
};
|
|
654
|
-
return this.ranges = [o], this.activeRange = o, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
|
|
661
|
+
if (t === "row") {
|
|
662
|
+
if (e.key === "ArrowUp" || e.key === "ArrowDown") {
|
|
663
|
+
const l = e.shiftKey;
|
|
664
|
+
return l && this.anchor === null && (this.anchor = this.grid._focusRow), queueMicrotask(() => {
|
|
665
|
+
const r = this.grid._focusRow;
|
|
666
|
+
if (l && this.anchor !== null) {
|
|
667
|
+
this.selected.clear();
|
|
668
|
+
const o = Math.min(this.anchor, r), h = Math.max(this.anchor, r);
|
|
669
|
+
for (let a = o; a <= h; a++)
|
|
670
|
+
this.isRowSelectable(a) && this.selected.add(a);
|
|
671
|
+
} else
|
|
672
|
+
this.isRowSelectable(r) ? (this.selected.clear(), this.selected.add(r), this.anchor = r) : this.selected.clear();
|
|
673
|
+
this.lastSelected = r, this.explicitSelection = !0, this.emit("selection-change", this.#e()), this.requestAfterRender();
|
|
674
|
+
}), !1;
|
|
655
675
|
}
|
|
676
|
+
if (e.key === "a" && (e.ctrlKey || e.metaKey))
|
|
677
|
+
return e.preventDefault(), e.stopPropagation(), this.selectAll(), !0;
|
|
656
678
|
}
|
|
657
|
-
|
|
679
|
+
if (t === "range" && i) {
|
|
680
|
+
const l = e.key === "Tab", r = e.shiftKey && !l;
|
|
681
|
+
return r && !this.cellAnchor && (this.cellAnchor = { row: this.grid._focusRow, col: this.grid._focusCol }), this.pendingKeyboardUpdate = { shiftKey: r }, queueMicrotask(() => this.requestAfterRender()), !1;
|
|
682
|
+
}
|
|
683
|
+
return t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey) ? (e.preventDefault(), e.stopPropagation(), this.selectAll(), !0) : !1;
|
|
658
684
|
}
|
|
659
685
|
/** @internal */
|
|
660
686
|
onCellMouseDown(e) {
|
|
661
687
|
if (!this.isSelectionEnabled() || this.config.mode !== "range" || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
|
|
662
688
|
const t = this.columns[e.colIndex];
|
|
663
|
-
if (t &&
|
|
689
|
+
if (t && f(t) || !this.isCellSelectable(e.rowIndex, e.colIndex) || e.originalEvent.shiftKey && this.cellAnchor)
|
|
664
690
|
return;
|
|
665
691
|
this.isDragging = !0;
|
|
666
|
-
const s = e.rowIndex, i = e.colIndex, l = e.originalEvent.ctrlKey || e.originalEvent.metaKey,
|
|
692
|
+
const s = e.rowIndex, i = e.colIndex, l = e.originalEvent.ctrlKey || e.originalEvent.metaKey, r = {
|
|
667
693
|
startRow: s,
|
|
668
694
|
startCol: i,
|
|
669
695
|
endRow: s,
|
|
670
696
|
endCol: i
|
|
671
697
|
};
|
|
672
|
-
return !l && this.ranges.length === 1 &&
|
|
698
|
+
return !l && this.ranges.length === 1 && b(this.ranges[0], r) ? (this.cellAnchor = { row: s, col: i }, !0) : (this.cellAnchor = { row: s, col: i }, l || (this.ranges = []), this.ranges.push(r), this.activeRange = r, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0);
|
|
673
699
|
}
|
|
674
700
|
/** @internal */
|
|
675
701
|
onCellMouseMove(e) {
|
|
676
702
|
if (!this.isSelectionEnabled() || this.config.mode !== "range" || !this.isDragging || !this.cellAnchor || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
|
|
677
703
|
let t = e.colIndex;
|
|
678
704
|
const s = this.columns[t];
|
|
679
|
-
if (s &&
|
|
680
|
-
const
|
|
681
|
-
|
|
705
|
+
if (s && f(s)) {
|
|
706
|
+
const r = this.columns.findIndex((o) => !f(o));
|
|
707
|
+
r >= 0 && (t = r);
|
|
682
708
|
}
|
|
683
|
-
const i =
|
|
684
|
-
return l &&
|
|
709
|
+
const i = m(this.cellAnchor, { row: e.rowIndex, col: t }), l = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null;
|
|
710
|
+
return l && b(l, i) || (this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = i : this.ranges.push(i), this.activeRange = i, this.emit("selection-change", this.#e()), this.requestAfterRender()), !0;
|
|
685
711
|
}
|
|
686
712
|
/** @internal */
|
|
687
713
|
onCellMouseUp(e) {
|
|
688
714
|
if (this.isSelectionEnabled() && this.config.mode === "range" && this.isDragging)
|
|
689
715
|
return this.isDragging = !1, !0;
|
|
690
716
|
}
|
|
717
|
+
// #region Checkbox Column
|
|
691
718
|
/**
|
|
692
|
-
*
|
|
693
|
-
*
|
|
719
|
+
* Inject checkbox column when `checkbox: true` and mode is `'row'`.
|
|
720
|
+
* @internal
|
|
721
|
+
*/
|
|
722
|
+
processColumns(e) {
|
|
723
|
+
if (this.config.checkbox && this.config.mode === "row") {
|
|
724
|
+
if (e.some((l) => l.field === S))
|
|
725
|
+
return e;
|
|
726
|
+
const t = this.#t(), s = e.findIndex(I), i = s >= 0 ? s + 1 : 0;
|
|
727
|
+
return [...e.slice(0, i), t, ...e.slice(i)];
|
|
728
|
+
}
|
|
729
|
+
return e;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Create the checkbox utility column configuration.
|
|
694
733
|
*/
|
|
695
734
|
#t() {
|
|
735
|
+
return {
|
|
736
|
+
field: S,
|
|
737
|
+
header: "",
|
|
738
|
+
width: 32,
|
|
739
|
+
resizable: !1,
|
|
740
|
+
sortable: !1,
|
|
741
|
+
meta: {
|
|
742
|
+
lockPosition: !0,
|
|
743
|
+
suppressMovable: !0,
|
|
744
|
+
utility: !0,
|
|
745
|
+
checkboxColumn: !0
|
|
746
|
+
},
|
|
747
|
+
headerRenderer: () => {
|
|
748
|
+
const e = document.createElement("div");
|
|
749
|
+
e.className = "tbw-checkbox-header";
|
|
750
|
+
const t = document.createElement("input");
|
|
751
|
+
return t.type = "checkbox", t.className = "tbw-select-all-checkbox", t.addEventListener("click", (s) => {
|
|
752
|
+
s.stopPropagation(), s.target.checked ? this.selectAll() : this.clearSelection();
|
|
753
|
+
}), e.appendChild(t), e;
|
|
754
|
+
},
|
|
755
|
+
renderer: (e) => {
|
|
756
|
+
const t = document.createElement("input");
|
|
757
|
+
t.type = "checkbox", t.className = "tbw-select-row-checkbox";
|
|
758
|
+
const s = e.cellEl;
|
|
759
|
+
if (s) {
|
|
760
|
+
const i = parseInt(s.getAttribute("data-row") ?? "-1", 10);
|
|
761
|
+
i >= 0 && (t.checked = this.selected.has(i));
|
|
762
|
+
}
|
|
763
|
+
return t;
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Update checkbox checked states to reflect current selection.
|
|
769
|
+
* Called from #applySelectionClasses.
|
|
770
|
+
*/
|
|
771
|
+
#i(e) {
|
|
772
|
+
e.querySelectorAll(".tbw-select-row-checkbox").forEach((i) => {
|
|
773
|
+
const l = i.closest(".cell"), r = l ? R(l) : -1;
|
|
774
|
+
r >= 0 && (i.checked = this.selected.has(r));
|
|
775
|
+
});
|
|
776
|
+
const s = e.querySelector(".tbw-select-all-checkbox");
|
|
777
|
+
if (s) {
|
|
778
|
+
const i = this.rows.length;
|
|
779
|
+
let l = 0;
|
|
780
|
+
if (this.config.isSelectable)
|
|
781
|
+
for (let h = 0; h < i; h++)
|
|
782
|
+
this.isRowSelectable(h) && l++;
|
|
783
|
+
else
|
|
784
|
+
l = i;
|
|
785
|
+
const r = l > 0 && this.selected.size >= l, o = this.selected.size > 0;
|
|
786
|
+
s.checked = r, s.indeterminate = o && !r;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
// #endregion
|
|
790
|
+
/**
|
|
791
|
+
* Sync selection state to the grid's current focus position.
|
|
792
|
+
* In row mode, keeps `selected` in sync with `_focusRow`.
|
|
793
|
+
* In cell mode, keeps `selectedCell` in sync with `_focusRow`/`_focusCol`.
|
|
794
|
+
* Only updates when the focus has changed since the last sync.
|
|
795
|
+
* Skips when `explicitSelection` is set (click/keyboard set selection directly).
|
|
796
|
+
*/
|
|
797
|
+
#r(e) {
|
|
798
|
+
const t = this.grid._focusRow, s = this.grid._focusCol;
|
|
799
|
+
if (e === "row") {
|
|
800
|
+
if (this.explicitSelection) {
|
|
801
|
+
this.explicitSelection = !1, this.lastSyncedFocusRow = t;
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
t !== this.lastSyncedFocusRow && (this.lastSyncedFocusRow = t, this.isRowSelectable(t) && (!this.selected.has(t) || this.selected.size !== 1) && (this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.anchor = t, this.emit("selection-change", this.#e())));
|
|
805
|
+
}
|
|
806
|
+
if (e === "cell") {
|
|
807
|
+
if (this.explicitSelection) {
|
|
808
|
+
this.explicitSelection = !1, this.lastSyncedFocusRow = t, this.lastSyncedFocusCol = s;
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
if ((t !== this.lastSyncedFocusRow || s !== this.lastSyncedFocusCol) && (this.lastSyncedFocusRow = t, this.lastSyncedFocusCol = s, this.isCellSelectable(t, s))) {
|
|
812
|
+
const i = this.selectedCell;
|
|
813
|
+
(!i || i.row !== t || i.col !== s) && (this.selectedCell = { row: t, col: s }, this.emit("selection-change", this.#e()));
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Apply CSS selection classes to row/cell elements.
|
|
819
|
+
* Shared by afterRender and onScrollRender.
|
|
820
|
+
*/
|
|
821
|
+
#s() {
|
|
696
822
|
const e = this.gridElement;
|
|
697
823
|
if (!e) return;
|
|
698
824
|
const { mode: t } = this.config, s = !!this.config.isSelectable;
|
|
699
|
-
e.querySelectorAll(".cell").forEach((
|
|
700
|
-
|
|
825
|
+
e.querySelectorAll(".cell").forEach((r) => {
|
|
826
|
+
r.classList.remove("selected", "top", "bottom", "first", "last"), s && r.removeAttribute("data-selectable");
|
|
701
827
|
});
|
|
702
828
|
const l = e.querySelectorAll(".data-grid-row");
|
|
703
|
-
if (l.forEach((
|
|
704
|
-
|
|
705
|
-
}), t === "row" && (
|
|
706
|
-
const o =
|
|
707
|
-
|
|
708
|
-
})), (t === "cell" || t === "range") && s && e.querySelectorAll(".cell[data-row][data-col]").forEach((o) => {
|
|
709
|
-
const
|
|
710
|
-
|
|
829
|
+
if (l.forEach((r) => {
|
|
830
|
+
r.classList.remove("selected", "row-focus"), s && r.removeAttribute("data-selectable");
|
|
831
|
+
}), t === "row" && (C(e), l.forEach((r) => {
|
|
832
|
+
const o = r.querySelector(".cell[data-row]"), h = R(o);
|
|
833
|
+
h >= 0 && (s && !this.isRowSelectable(h) && r.setAttribute("data-selectable", "false"), this.selected.has(h) && r.classList.add("selected", "row-focus"));
|
|
834
|
+
}), this.config.checkbox && this.#i(e)), (t === "cell" || t === "range") && s && e.querySelectorAll(".cell[data-row][data-col]").forEach((o) => {
|
|
835
|
+
const h = parseInt(o.getAttribute("data-row") ?? "-1", 10), a = parseInt(o.getAttribute("data-col") ?? "-1", 10);
|
|
836
|
+
h >= 0 && a >= 0 && (this.isCellSelectable(h, a) || o.setAttribute("data-selectable", "false"));
|
|
711
837
|
}), t === "range" && this.ranges.length > 0) {
|
|
712
|
-
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
838
|
+
C(e);
|
|
839
|
+
const r = this.ranges.map(g), o = (a, d) => {
|
|
840
|
+
for (const c of r)
|
|
841
|
+
if (a >= c.startRow && a <= c.endRow && d >= c.startCol && d <= c.endCol)
|
|
842
|
+
return !0;
|
|
843
|
+
return !1;
|
|
844
|
+
};
|
|
845
|
+
e.querySelectorAll(".cell[data-row][data-col]").forEach((a) => {
|
|
846
|
+
const d = parseInt(a.getAttribute("data-row") ?? "-1", 10), c = parseInt(a.getAttribute("data-col") ?? "-1", 10);
|
|
847
|
+
if (d >= 0 && c >= 0) {
|
|
848
|
+
const u = this.columns[c];
|
|
849
|
+
if (u && f(u))
|
|
719
850
|
return;
|
|
720
|
-
|
|
721
|
-
h === n.startRow && a.classList.add("top"), h === n.endRow && a.classList.add("bottom");
|
|
722
|
-
const A = Math.max(n.startCol, o);
|
|
723
|
-
c === A && a.classList.add("first"), c === n.endCol && a.classList.add("last");
|
|
724
|
-
}
|
|
851
|
+
o(d, c) && (a.classList.add("selected"), o(d - 1, c) || a.classList.add("top"), o(d + 1, c) || a.classList.add("bottom"), o(d, c - 1) || a.classList.add("first"), o(d, c + 1) || a.classList.add("last"));
|
|
725
852
|
}
|
|
726
853
|
});
|
|
727
854
|
}
|
|
@@ -735,14 +862,14 @@ class D extends v {
|
|
|
735
862
|
if (this.pendingKeyboardUpdate && s === "range") {
|
|
736
863
|
const { shiftKey: i } = this.pendingKeyboardUpdate;
|
|
737
864
|
this.pendingKeyboardUpdate = null;
|
|
738
|
-
const l = this.grid._focusRow,
|
|
865
|
+
const l = this.grid._focusRow, r = this.grid._focusCol;
|
|
739
866
|
if (i && this.cellAnchor) {
|
|
740
|
-
const o =
|
|
867
|
+
const o = m(this.cellAnchor, { row: l, col: r });
|
|
741
868
|
this.ranges = [o], this.activeRange = o;
|
|
742
|
-
} else i || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: l, col:
|
|
869
|
+
} else i || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: l, col: r });
|
|
743
870
|
this.emit("selection-change", this.#e());
|
|
744
871
|
}
|
|
745
|
-
this.grid.setAttribute("data-selection-mode", s), t && t.classList.toggle("selecting", this.isDragging), this.#
|
|
872
|
+
this.#r(s), this.grid.setAttribute("data-selection-mode", s), t && t.classList.toggle("selecting", this.isDragging), this.#s();
|
|
746
873
|
}
|
|
747
874
|
/**
|
|
748
875
|
* Called after scroll-triggered row rendering.
|
|
@@ -750,7 +877,7 @@ class D extends v {
|
|
|
750
877
|
* @internal
|
|
751
878
|
*/
|
|
752
879
|
onScrollRender() {
|
|
753
|
-
this.isSelectionEnabled() && this.#
|
|
880
|
+
this.isSelectionEnabled() && this.#s();
|
|
754
881
|
}
|
|
755
882
|
// #endregion
|
|
756
883
|
// #region Public API
|
|
@@ -780,13 +907,80 @@ class D extends v {
|
|
|
780
907
|
* Get all selected cells across all ranges.
|
|
781
908
|
*/
|
|
782
909
|
getSelectedCells() {
|
|
783
|
-
return
|
|
910
|
+
return M(this.ranges);
|
|
784
911
|
}
|
|
785
912
|
/**
|
|
786
913
|
* Check if a specific cell is in range selection.
|
|
787
914
|
*/
|
|
788
915
|
isCellSelected(e, t) {
|
|
789
|
-
return
|
|
916
|
+
return q(e, t, this.ranges);
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Select all selectable rows (row mode) or all cells (range mode).
|
|
920
|
+
*
|
|
921
|
+
* In row mode, selects every row where `isSelectable` returns true (or all rows if no callback).
|
|
922
|
+
* In range mode, creates a single range spanning all rows and columns.
|
|
923
|
+
* Has no effect in cell mode.
|
|
924
|
+
*
|
|
925
|
+
* @example
|
|
926
|
+
* ```ts
|
|
927
|
+
* const plugin = grid.getPlugin(SelectionPlugin);
|
|
928
|
+
* plugin.selectAll(); // Selects everything in current mode
|
|
929
|
+
* ```
|
|
930
|
+
*/
|
|
931
|
+
selectAll() {
|
|
932
|
+
const { mode: e } = this.config;
|
|
933
|
+
if (e === "row") {
|
|
934
|
+
this.selected.clear();
|
|
935
|
+
for (let t = 0; t < this.rows.length; t++)
|
|
936
|
+
this.isRowSelectable(t) && this.selected.add(t);
|
|
937
|
+
this.explicitSelection = !0, this.emit("selection-change", this.#e()), this.requestAfterRender();
|
|
938
|
+
} else if (e === "range") {
|
|
939
|
+
const t = this.rows.length, s = this.columns.length;
|
|
940
|
+
if (t > 0 && s > 0) {
|
|
941
|
+
const i = {
|
|
942
|
+
startRow: 0,
|
|
943
|
+
startCol: 0,
|
|
944
|
+
endRow: t - 1,
|
|
945
|
+
endCol: s - 1
|
|
946
|
+
};
|
|
947
|
+
this.ranges = [i], this.activeRange = i, this.emit("selection-change", this.#e()), this.requestAfterRender();
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Select specific rows by index (row mode only).
|
|
953
|
+
* Replaces the current selection with the provided row indices.
|
|
954
|
+
* Indices that are out of bounds or fail the `isSelectable` check are ignored.
|
|
955
|
+
*
|
|
956
|
+
* @param indices - Array of row indices to select
|
|
957
|
+
*
|
|
958
|
+
* @example
|
|
959
|
+
* ```ts
|
|
960
|
+
* const plugin = grid.getPlugin(SelectionPlugin);
|
|
961
|
+
* plugin.selectRows([0, 2, 4]); // Select rows 0, 2, and 4
|
|
962
|
+
* ```
|
|
963
|
+
*/
|
|
964
|
+
selectRows(e) {
|
|
965
|
+
if (this.config.mode === "row") {
|
|
966
|
+
this.selected.clear();
|
|
967
|
+
for (const t of e)
|
|
968
|
+
t >= 0 && t < this.rows.length && this.isRowSelectable(t) && this.selected.add(t);
|
|
969
|
+
this.anchor = e.length > 0 ? e[e.length - 1] : null, this.explicitSelection = !0, this.emit("selection-change", this.#e()), this.requestAfterRender();
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* Get the indices of all selected rows (convenience for row mode).
|
|
974
|
+
* Returns indices sorted in ascending order.
|
|
975
|
+
*
|
|
976
|
+
* @example
|
|
977
|
+
* ```ts
|
|
978
|
+
* const plugin = grid.getPlugin(SelectionPlugin);
|
|
979
|
+
* const rows = plugin.getSelectedRowIndices(); // [0, 2, 4]
|
|
980
|
+
* ```
|
|
981
|
+
*/
|
|
982
|
+
getSelectedRowIndices() {
|
|
983
|
+
return [...this.selected].sort((e, t) => e - t);
|
|
790
984
|
}
|
|
791
985
|
/**
|
|
792
986
|
* Clear all selection.
|
|
@@ -805,13 +999,13 @@ class D extends v {
|
|
|
805
999
|
endCol: t.to.col
|
|
806
1000
|
})), this.activeRange = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null, this.emit("selection-change", {
|
|
807
1001
|
mode: this.config.mode,
|
|
808
|
-
ranges:
|
|
1002
|
+
ranges: y(this.ranges)
|
|
809
1003
|
}), this.requestAfterRender();
|
|
810
1004
|
}
|
|
811
1005
|
// #endregion
|
|
812
1006
|
// #region Private Helpers
|
|
813
1007
|
#e() {
|
|
814
|
-
return
|
|
1008
|
+
return D(
|
|
815
1009
|
this.config.mode,
|
|
816
1010
|
{
|
|
817
1011
|
selectedCell: this.selectedCell,
|
|
@@ -824,6 +1018,6 @@ class D extends v {
|
|
|
824
1018
|
// #endregion
|
|
825
1019
|
}
|
|
826
1020
|
export {
|
|
827
|
-
|
|
1021
|
+
L as SelectionPlugin
|
|
828
1022
|
};
|
|
829
1023
|
//# sourceMappingURL=index.js.map
|