flexdesk 0.11.1 → 0.12.1
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 +55 -0
- package/css/flexdesk.css +105 -9
- package/css/overrides.css +29 -9
- package/dist/charts.js +2 -2
- package/dist/{chunk-EHHTKD7B.js → chunk-2LEJQD4H.js} +2 -2
- package/dist/{chunk-5QPGYHBN.js → chunk-CWPMLX67.js} +2 -2
- package/dist/{chunk-6CGH73BC.js → chunk-M2L4XW2U.js} +224 -31
- package/dist/chunk-M2L4XW2U.js.map +7 -0
- package/dist/{chunk-6EZPPN4E.js → chunk-NNFTETK3.js} +8 -4
- package/dist/chunk-NNFTETK3.js.map +7 -0
- package/dist/flexdesk.css +105 -9
- package/dist/flow.js +2 -2
- package/dist/tiles.js +2 -2
- package/dist/widgets.js +3 -3
- package/dist/wm.js +23 -5
- package/dist/wm.js.map +2 -2
- package/package.json +1 -1
- package/src/tiling/content_registry.js +5 -0
- package/src/tiling/tile_renderer.js +45 -3
- package/src/ui/components/data_table.js +266 -31
- package/src/ui/components/modal.js +4 -2
- package/dist/chunk-6CGH73BC.js.map +0 -7
- package/dist/chunk-6EZPPN4E.js.map +0 -7
- /package/dist/{chunk-EHHTKD7B.js.map → chunk-2LEJQD4H.js.map} +0 -0
- /package/dist/{chunk-5QPGYHBN.js.map → chunk-CWPMLX67.js.map} +0 -0
|
@@ -763,8 +763,21 @@ var DataTable = class {
|
|
|
763
763
|
hiddenColumns: null,
|
|
764
764
|
columnChooser: false,
|
|
765
765
|
onColumnsChange: null,
|
|
766
|
+
// STORY-0016. Off — no select column, as in 0.11 — until set.
|
|
767
|
+
selectToggle: false,
|
|
768
|
+
selectMode: false,
|
|
769
|
+
onSelectModeChange: null,
|
|
766
770
|
...config
|
|
767
771
|
};
|
|
772
|
+
{
|
|
773
|
+
const sel = this.config.selectable;
|
|
774
|
+
const asked = !!this.config.selectToggle || !!this.config.selectMode;
|
|
775
|
+
this._gutter = asked && !!sel && sel !== "single";
|
|
776
|
+
if (asked && !this._gutter) {
|
|
777
|
+
console.warn("[DataTable] selectToggle/selectMode need a multi-row `selectable`; ignored.");
|
|
778
|
+
}
|
|
779
|
+
this._selecting = this._gutter && !!this.config.selectMode;
|
|
780
|
+
}
|
|
768
781
|
this._expanded = new Set((this.config.expandedRows || []).map((k) => String(k)));
|
|
769
782
|
this._detailHeights = /* @__PURE__ */ new Map();
|
|
770
783
|
this._source = null;
|
|
@@ -879,8 +892,10 @@ var DataTable = class {
|
|
|
879
892
|
}
|
|
880
893
|
if (blob.colWidths && typeof blob.colWidths === "object") {
|
|
881
894
|
this._colWidths = {};
|
|
895
|
+
const shift = this._lead().select - (Number(blob.colWidthsLead) || 0);
|
|
882
896
|
for (const [k, v] of Object.entries(blob.colWidths)) {
|
|
883
|
-
|
|
897
|
+
const i = Number(k) + shift;
|
|
898
|
+
if (i >= this._lead().select) this._colWidths[i] = v;
|
|
884
899
|
}
|
|
885
900
|
this._colWidthsSig = this._colSig();
|
|
886
901
|
applied = true;
|
|
@@ -906,6 +921,9 @@ var DataTable = class {
|
|
|
906
921
|
sortAscending: this._state.sortAscending,
|
|
907
922
|
filters: [...this._state.filters.entries()],
|
|
908
923
|
colWidths: { ...this._colWidths },
|
|
924
|
+
// STORY-0016. Where the widths start, so a blob read by a table
|
|
925
|
+
// with or without the select column lands on the same columns.
|
|
926
|
+
...this._gutter ? { colWidthsLead: 1 } : {},
|
|
909
927
|
// STORY-0010. Only for a table that asked: one that did not writes
|
|
910
928
|
// the 0.9.1 blob, key for key.
|
|
911
929
|
...this.config.persistPage ? { offset: this._state.offset } : {},
|
|
@@ -935,18 +953,24 @@ var DataTable = class {
|
|
|
935
953
|
/** The cells a drawn row has: the shown columns, and the row number. */
|
|
936
954
|
_domColCount() {
|
|
937
955
|
const n = Math.max(0, (this.config.headers?.length || 0) - this._hidden.size);
|
|
938
|
-
return n +
|
|
956
|
+
return n + this._lead().all;
|
|
957
|
+
}
|
|
958
|
+
/** STORY-0016. The drawn columns in front of the data: the select column
|
|
959
|
+
* (`select`, 0 or 1, always first) and the row number. */
|
|
960
|
+
_lead() {
|
|
961
|
+
const select = this._gutter ? 1 : 0;
|
|
962
|
+
return { select, all: select + (this.config.showRowNumbers ? 1 : 0) };
|
|
939
963
|
}
|
|
940
964
|
/** A data column's drawn index (row number included), or -1 when hidden. */
|
|
941
965
|
_domIdxOf(colIdx) {
|
|
942
966
|
if (this._isHidden(colIdx)) return -1;
|
|
943
|
-
let dom = this.
|
|
967
|
+
let dom = this._lead().all;
|
|
944
968
|
for (const h of this._hidden) if (h < colIdx) dom--;
|
|
945
969
|
return dom + colIdx;
|
|
946
970
|
}
|
|
947
971
|
/** A drawn cell's data column, or null for the row number. */
|
|
948
972
|
_dataIdxOfDom(domIdx) {
|
|
949
|
-
let i = domIdx -
|
|
973
|
+
let i = domIdx - this._lead().all;
|
|
950
974
|
if (i < 0) return null;
|
|
951
975
|
const n = this.config.headers?.length || 0;
|
|
952
976
|
for (let c = 0; c < n; c++) {
|
|
@@ -993,7 +1017,7 @@ var DataTable = class {
|
|
|
993
1017
|
this._setHidden([...next]);
|
|
994
1018
|
if (kept) {
|
|
995
1019
|
const widths = {};
|
|
996
|
-
|
|
1020
|
+
for (let i = 0; i < this._lead().all; i++) if (old[i] != null) widths[i] = old[i];
|
|
997
1021
|
for (let c = 0; c < n; c++) {
|
|
998
1022
|
const from = domBefore[c];
|
|
999
1023
|
const to = this._domIdxOf(c);
|
|
@@ -1039,6 +1063,7 @@ var DataTable = class {
|
|
|
1039
1063
|
* @param {Object} updates - Partial config updates (headers, rows, etc.)
|
|
1040
1064
|
*/
|
|
1041
1065
|
setData(updates) {
|
|
1066
|
+
const keepTicks = updates.rows && this._selecting && typeof this.config.getRowKey === "function" && this._state.selected.size ? new Set(this.getSelection().map((i) => this._rowKey(this.config.rows[i], i)).filter((k) => k !== null)) : null;
|
|
1042
1067
|
if (updates.headers && this._state.filters.size > 0) {
|
|
1043
1068
|
const oldHeaders = this.config.headers;
|
|
1044
1069
|
const newHeaders = updates.headers;
|
|
@@ -1087,9 +1112,15 @@ var DataTable = class {
|
|
|
1087
1112
|
if (Object.prototype.hasOwnProperty.call(updates, "columnTypes") && !updates.rows) {
|
|
1088
1113
|
this._columnTypes = this._detectColumnTypes();
|
|
1089
1114
|
}
|
|
1115
|
+
if (keepTicks) {
|
|
1116
|
+
(this.config.rows || []).forEach((r, i) => {
|
|
1117
|
+
if (keepTicks.has(this._rowKey(r, i))) this._state.selected.add(i);
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1090
1120
|
this._processedRows = null;
|
|
1091
1121
|
this._processedIndexMap = null;
|
|
1092
1122
|
this.render();
|
|
1123
|
+
if (keepTicks) this._notifySelectionChange();
|
|
1093
1124
|
}
|
|
1094
1125
|
/**
|
|
1095
1126
|
* Show / hide a translucent loading overlay over the table body.
|
|
@@ -1414,6 +1445,7 @@ var DataTable = class {
|
|
|
1414
1445
|
headerTable.className = this._tableClassName();
|
|
1415
1446
|
const thead = document.createElement("thead");
|
|
1416
1447
|
const tr = document.createElement("tr");
|
|
1448
|
+
if (this._gutter) tr.appendChild(this._buildSelectHead());
|
|
1417
1449
|
if (showRowNumbers) {
|
|
1418
1450
|
const th = document.createElement("th");
|
|
1419
1451
|
th.className = "num";
|
|
@@ -1922,6 +1954,11 @@ var DataTable = class {
|
|
|
1922
1954
|
const { showRowNumbers } = this.config;
|
|
1923
1955
|
const tr = document.createElement("tr");
|
|
1924
1956
|
tr.className = "twm-data-table__filter-row";
|
|
1957
|
+
if (this._gutter) {
|
|
1958
|
+
const th = document.createElement("th");
|
|
1959
|
+
th.className = "data-table__filter-cell data-table__filter-cell--empty twm-dt-select-cell";
|
|
1960
|
+
tr.appendChild(th);
|
|
1961
|
+
}
|
|
1925
1962
|
if (showRowNumbers) {
|
|
1926
1963
|
const th = document.createElement("th");
|
|
1927
1964
|
th.className = "data-table__filter-cell data-table__filter-cell--empty";
|
|
@@ -2268,7 +2305,7 @@ var DataTable = class {
|
|
|
2268
2305
|
if (!row) return null;
|
|
2269
2306
|
const cells = Array.from(row.children);
|
|
2270
2307
|
const idx = cells.indexOf(cell);
|
|
2271
|
-
return this.
|
|
2308
|
+
return this._dataIdxOfDom(idx);
|
|
2272
2309
|
}
|
|
2273
2310
|
_restoreFilterFocus(colIdx) {
|
|
2274
2311
|
const filterRow = this._wrapperEl?.querySelector(".twm-data-table__filter-row");
|
|
@@ -2740,6 +2777,7 @@ var DataTable = class {
|
|
|
2740
2777
|
table.tabIndex = 0;
|
|
2741
2778
|
const thead = document.createElement("thead");
|
|
2742
2779
|
const headerRow = document.createElement("tr");
|
|
2780
|
+
if (this._gutter) headerRow.appendChild(this._buildSelectHead());
|
|
2743
2781
|
if (showRowNumbers) {
|
|
2744
2782
|
const th = document.createElement("th");
|
|
2745
2783
|
th.className = "num";
|
|
@@ -2898,7 +2936,7 @@ var DataTable = class {
|
|
|
2898
2936
|
const colgroup = document.createElement("colgroup");
|
|
2899
2937
|
for (let i = 0; i < n; i++) {
|
|
2900
2938
|
const col = document.createElement("col");
|
|
2901
|
-
const w = this._colWidths?.[i];
|
|
2939
|
+
const w = i < this._lead().select ? this._selectColWidth() : this._colWidths?.[i];
|
|
2902
2940
|
if (w != null && this._colWidthsSig === this._colSig()) col.style.width = `${w}px`;
|
|
2903
2941
|
colgroup.appendChild(col);
|
|
2904
2942
|
}
|
|
@@ -3306,6 +3344,18 @@ var DataTable = class {
|
|
|
3306
3344
|
* update than it did on load. */
|
|
3307
3345
|
_fillRowCells(tr, row, globalIdx, showRowNumbers) {
|
|
3308
3346
|
tr.replaceChildren();
|
|
3347
|
+
if (this._gutter) {
|
|
3348
|
+
const td = document.createElement("td");
|
|
3349
|
+
td.className = "twm-dt-select-cell";
|
|
3350
|
+
const box = document.createElement("input");
|
|
3351
|
+
box.type = "checkbox";
|
|
3352
|
+
box.className = "twm-dt-select-box";
|
|
3353
|
+
box.tabIndex = -1;
|
|
3354
|
+
box.checked = this._state.selected.has(globalIdx);
|
|
3355
|
+
box.setAttribute("aria-label", "Select row");
|
|
3356
|
+
td.appendChild(box);
|
|
3357
|
+
tr.appendChild(td);
|
|
3358
|
+
}
|
|
3309
3359
|
if (showRowNumbers) {
|
|
3310
3360
|
const td = document.createElement("td");
|
|
3311
3361
|
td.className = "num";
|
|
@@ -3418,7 +3468,7 @@ var DataTable = class {
|
|
|
3418
3468
|
minWidth: td.style.minWidth,
|
|
3419
3469
|
maxWidth: td.style.maxWidth
|
|
3420
3470
|
})) : null;
|
|
3421
|
-
const showRowNumbers = this.config.showRowNumbers !== false && tr.
|
|
3471
|
+
const showRowNumbers = this.config.showRowNumbers !== false && !!tr.querySelector(":scope > td.num");
|
|
3422
3472
|
this._fillRowCells(tr, row, index, showRowNumbers);
|
|
3423
3473
|
if (widths) {
|
|
3424
3474
|
widths.forEach((saved, i) => {
|
|
@@ -4575,6 +4625,8 @@ var DataTable = class {
|
|
|
4575
4625
|
const names = this.config.readonly ? ["twm-preview-table", "twm-preview-table--readonly"] : ["twm-preview-table"];
|
|
4576
4626
|
if (this.config.firstColumn === "plain") names.push("twm-dt--first-plain");
|
|
4577
4627
|
if (this._isClickable()) names.push("twm-dt--clickable");
|
|
4628
|
+
if (this._gutter) names.push("twm-dt--select");
|
|
4629
|
+
if (this._selecting) names.push("twm-dt--selecting");
|
|
4578
4630
|
return names.join(" ");
|
|
4579
4631
|
}
|
|
4580
4632
|
/** `clickable` when it is said; otherwise exactly when rows open. */
|
|
@@ -4658,6 +4710,7 @@ var DataTable = class {
|
|
|
4658
4710
|
const multi = !!sel && sel !== "single";
|
|
4659
4711
|
const fire = (tr, ev) => {
|
|
4660
4712
|
if (!this._wrapperEl || typeof this.config.onRowActivate !== "function") return;
|
|
4713
|
+
if (this._selecting) return;
|
|
4661
4714
|
try {
|
|
4662
4715
|
this.config.onRowActivate(tr.__rowIndex, tr.__row, ev);
|
|
4663
4716
|
} catch (err) {
|
|
@@ -5018,7 +5071,7 @@ var DataTable = class {
|
|
|
5018
5071
|
*/
|
|
5019
5072
|
autoSizeColumn(domIdx, opts = {}) {
|
|
5020
5073
|
const natural = this._measureNaturalWidths({ sample: true });
|
|
5021
|
-
if (!natural || domIdx <
|
|
5074
|
+
if (!natural || domIdx < this._lead().select || domIdx >= natural.length) return false;
|
|
5022
5075
|
this._colWidths[domIdx] = this._autoWidth(natural[domIdx], opts);
|
|
5023
5076
|
this._colWidthsSig = this._colSig();
|
|
5024
5077
|
this._savePersisted();
|
|
@@ -5044,7 +5097,7 @@ var DataTable = class {
|
|
|
5044
5097
|
const natural = this._measureNaturalWidths({ sample: true });
|
|
5045
5098
|
if (!natural) return false;
|
|
5046
5099
|
this._colWidths = {};
|
|
5047
|
-
for (let i =
|
|
5100
|
+
for (let i = this._lead().select; i < natural.length; i++) {
|
|
5048
5101
|
this._colWidths[i] = this._autoWidth(natural[i], opts);
|
|
5049
5102
|
}
|
|
5050
5103
|
this._colWidthsSig = this._colSig();
|
|
@@ -5076,7 +5129,7 @@ var DataTable = class {
|
|
|
5076
5129
|
*/
|
|
5077
5130
|
_allColumnsPinned(n) {
|
|
5078
5131
|
if (!n || this._colWidthsSig !== this._colSig()) return false;
|
|
5079
|
-
for (let i =
|
|
5132
|
+
for (let i = this._lead().select; i < n; i++) {
|
|
5080
5133
|
if (this._colWidths[i] == null) return false;
|
|
5081
5134
|
}
|
|
5082
5135
|
return true;
|
|
@@ -5101,10 +5154,12 @@ var DataTable = class {
|
|
|
5101
5154
|
const wrap = this._tableWrapEl;
|
|
5102
5155
|
const headerWrap = this._headerWrapEl;
|
|
5103
5156
|
const avail = wrap ? wrap.clientWidth : 0;
|
|
5104
|
-
const
|
|
5157
|
+
const lead = this._lead().all;
|
|
5158
|
+
const firstIdx = lead && n > lead ? lead : 0;
|
|
5105
5159
|
const widths = this._fitColumnWidths(natural, avail, {
|
|
5106
5160
|
firstIdx,
|
|
5107
|
-
|
|
5161
|
+
// STORY-0016. The select column is as wide as its controls, always.
|
|
5162
|
+
overrides: this._gutter ? { ...this._colWidths, 0: this._selectColWidth() } : this._colWidths,
|
|
5108
5163
|
fit: this.config.columnFit,
|
|
5109
5164
|
floors: this._filterFloors
|
|
5110
5165
|
});
|
|
@@ -5336,6 +5391,7 @@ var DataTable = class {
|
|
|
5336
5391
|
if (!headRow) return;
|
|
5337
5392
|
[...headRow.children].forEach((th, domIdx) => {
|
|
5338
5393
|
if (th.querySelector(".twm-dt-col-resizer")) return;
|
|
5394
|
+
if (th.classList.contains("twm-dt-select-cell")) return;
|
|
5339
5395
|
th.classList.add("twm-dt-col");
|
|
5340
5396
|
const grip = document.createElement("div");
|
|
5341
5397
|
grip.className = "twm-dt-col-resizer";
|
|
@@ -5508,6 +5564,19 @@ var DataTable = class {
|
|
|
5508
5564
|
if (!(was && (event.metaKey || event.ctrlKey))) selected.add(idx);
|
|
5509
5565
|
else DESELECTING_CLICKS.add(event);
|
|
5510
5566
|
this._state.anchorIndex = selected.size ? idx : null;
|
|
5567
|
+
} else if (this._selecting) {
|
|
5568
|
+
if (event.shiftKey && this._state.anchorIndex != null) {
|
|
5569
|
+
const order = this._processedIndexMap || this.config.rows.map((_, i) => i);
|
|
5570
|
+
const a = order.indexOf(this._state.anchorIndex);
|
|
5571
|
+
const b = order.indexOf(idx);
|
|
5572
|
+
if (a >= 0 && b >= 0) {
|
|
5573
|
+
for (let i = Math.min(a, b); i <= Math.max(a, b); i++) selected.add(order[i]);
|
|
5574
|
+
} else selected.add(idx);
|
|
5575
|
+
} else if (selected.has(idx)) selected.delete(idx);
|
|
5576
|
+
else selected.add(idx);
|
|
5577
|
+
this._state.anchorIndex = idx;
|
|
5578
|
+
this._navCursor = idx;
|
|
5579
|
+
this._markCursor();
|
|
5511
5580
|
} else if (event.shiftKey && this._state.anchorIndex != null) {
|
|
5512
5581
|
const start = Math.min(this._state.anchorIndex, idx);
|
|
5513
5582
|
const end = Math.max(this._state.anchorIndex, idx);
|
|
@@ -5559,7 +5628,7 @@ var DataTable = class {
|
|
|
5559
5628
|
if (!order.length) return;
|
|
5560
5629
|
ev.preventDefault();
|
|
5561
5630
|
const selected = this._state.selected;
|
|
5562
|
-
const cur = this._navCursor != null && selected.has(this._navCursor) ? this._navCursor : this._state.anchorIndex;
|
|
5631
|
+
const cur = this._navCursor != null && (this._selecting || selected.has(this._navCursor)) ? this._navCursor : this._state.anchorIndex;
|
|
5563
5632
|
let pos = order.indexOf(cur);
|
|
5564
5633
|
if (ev.key === "Home") pos = 0;
|
|
5565
5634
|
else if (ev.key === "End") pos = order.length - 1;
|
|
@@ -5568,6 +5637,20 @@ var DataTable = class {
|
|
|
5568
5637
|
const idx = order[pos];
|
|
5569
5638
|
this._navCursor = idx;
|
|
5570
5639
|
const anchorPos = order.indexOf(this._state.anchorIndex);
|
|
5640
|
+
if (this._selecting) {
|
|
5641
|
+
if (ev.shiftKey) {
|
|
5642
|
+
const from = order.indexOf(cur);
|
|
5643
|
+
if (from >= 0) {
|
|
5644
|
+
for (let i = Math.min(from, pos); i <= Math.max(from, pos); i++) selected.add(order[i]);
|
|
5645
|
+
} else selected.add(idx);
|
|
5646
|
+
this._updateRowSelection();
|
|
5647
|
+
this._notifySelectionChange();
|
|
5648
|
+
}
|
|
5649
|
+
this._state.anchorIndex = idx;
|
|
5650
|
+
this._markCursor();
|
|
5651
|
+
this.scrollToRow(idx);
|
|
5652
|
+
return;
|
|
5653
|
+
}
|
|
5571
5654
|
if (ev.shiftKey && selectable !== "single" && anchorPos !== -1) {
|
|
5572
5655
|
const [a, b] = anchorPos <= pos ? [anchorPos, pos] : [pos, anchorPos];
|
|
5573
5656
|
selected.clear();
|
|
@@ -5584,6 +5667,25 @@ var DataTable = class {
|
|
|
5584
5667
|
table.addEventListener("keydown", onNavKey);
|
|
5585
5668
|
this._disposers.push(() => table.removeEventListener("keydown", onNavKey));
|
|
5586
5669
|
}
|
|
5670
|
+
if (this._gutter) {
|
|
5671
|
+
const onSpace = (ev) => {
|
|
5672
|
+
if (!this._selecting || ev.key !== " " || ev.ctrlKey || ev.metaKey || ev.altKey) return;
|
|
5673
|
+
if (isRowControl(ev.target, table)) return;
|
|
5674
|
+
const idx = this._navCursor ?? this._state.anchorIndex;
|
|
5675
|
+
if (idx == null || !this.config.rows[idx]) return;
|
|
5676
|
+
ev.preventDefault();
|
|
5677
|
+
const selected = this._state.selected;
|
|
5678
|
+
if (selected.has(idx)) selected.delete(idx);
|
|
5679
|
+
else selected.add(idx);
|
|
5680
|
+
this._state.anchorIndex = idx;
|
|
5681
|
+
this._updateRowSelection();
|
|
5682
|
+
this._notifySelectionChange();
|
|
5683
|
+
};
|
|
5684
|
+
table.addEventListener("keydown", onSpace);
|
|
5685
|
+
this._disposers.push(() => table.removeEventListener("keydown", onSpace));
|
|
5686
|
+
this._paintSelectHead();
|
|
5687
|
+
this._markCursor();
|
|
5688
|
+
}
|
|
5587
5689
|
if (typeof this.config.onRowActivate === "function") {
|
|
5588
5690
|
this._installActivation(tbody, table);
|
|
5589
5691
|
}
|
|
@@ -5625,7 +5727,7 @@ var DataTable = class {
|
|
|
5625
5727
|
}
|
|
5626
5728
|
event.preventDefault();
|
|
5627
5729
|
event.stopPropagation();
|
|
5628
|
-
if (idx !== void 0 && !this._state.selected.has(idx)) {
|
|
5730
|
+
if (idx !== void 0 && !this._state.selected.has(idx) && !this._selecting) {
|
|
5629
5731
|
this._state.selected.clear();
|
|
5630
5732
|
this._state.selected.add(idx);
|
|
5631
5733
|
this._state.anchorIndex = idx;
|
|
@@ -5650,20 +5752,7 @@ var DataTable = class {
|
|
|
5650
5752
|
event.preventDefault();
|
|
5651
5753
|
} else if (key === "a" && selectable) {
|
|
5652
5754
|
event.preventDefault();
|
|
5653
|
-
this.
|
|
5654
|
-
const indexMap = this._processedIndexMap;
|
|
5655
|
-
if (indexMap) {
|
|
5656
|
-
for (const originalIdx of indexMap) {
|
|
5657
|
-
this._state.selected.add(originalIdx);
|
|
5658
|
-
}
|
|
5659
|
-
} else {
|
|
5660
|
-
for (let i = 0; i < this.config.rows.length; i++) {
|
|
5661
|
-
this._state.selected.add(i);
|
|
5662
|
-
}
|
|
5663
|
-
}
|
|
5664
|
-
this._state.anchorIndex = this.config.rows.length - 1;
|
|
5665
|
-
this._updateRowSelection();
|
|
5666
|
-
this._notifySelectionChange();
|
|
5755
|
+
this._selectAllShown();
|
|
5667
5756
|
} else if (key === "c") {
|
|
5668
5757
|
event.preventDefault();
|
|
5669
5758
|
this.copyToClipboard(event.shiftKey ? "csv" : "tsv");
|
|
@@ -5671,6 +5760,8 @@ var DataTable = class {
|
|
|
5671
5760
|
} else if (event.key === "Escape") {
|
|
5672
5761
|
if (this._state.selected.size) {
|
|
5673
5762
|
this.clearSelection();
|
|
5763
|
+
} else if (this._selecting && this.config.selectToggle) {
|
|
5764
|
+
this.setSelectMode(false);
|
|
5674
5765
|
}
|
|
5675
5766
|
this._hideContextMenu();
|
|
5676
5767
|
}
|
|
@@ -5684,9 +5775,111 @@ var DataTable = class {
|
|
|
5684
5775
|
this._tbodyEl.querySelectorAll("tr").forEach((tr) => {
|
|
5685
5776
|
const idx = tr.__rowIndex;
|
|
5686
5777
|
if (idx !== void 0) {
|
|
5687
|
-
|
|
5778
|
+
const on = this._state.selected.has(idx);
|
|
5779
|
+
tr.classList.toggle("selected", on);
|
|
5780
|
+
const box = this._gutter ? tr.querySelector(":scope > td.twm-dt-select-cell > input") : null;
|
|
5781
|
+
if (box) box.checked = on;
|
|
5688
5782
|
}
|
|
5689
5783
|
});
|
|
5784
|
+
this._paintSelectHead();
|
|
5785
|
+
}
|
|
5786
|
+
/* ── STORY-0016: select mode ─────────────────────────────────────── */
|
|
5787
|
+
/** Whether the table is in select mode. */
|
|
5788
|
+
isSelectMode() {
|
|
5789
|
+
return !!this._selecting;
|
|
5790
|
+
}
|
|
5791
|
+
/**
|
|
5792
|
+
* Turn select mode on or off. The ticks are kept either way (a selection
|
|
5793
|
+
* is a selection); the consumer clears it if leaving means "never mind".
|
|
5794
|
+
* Does nothing on a table without the select column.
|
|
5795
|
+
*
|
|
5796
|
+
* @param {boolean} on
|
|
5797
|
+
* @returns {boolean} whether the mode changed
|
|
5798
|
+
*/
|
|
5799
|
+
setSelectMode(on) {
|
|
5800
|
+
if (!this._gutter || !!on === this._selecting) return false;
|
|
5801
|
+
this._selecting = !!on;
|
|
5802
|
+
this._navCursor = this._selecting ? this._state.anchorIndex : null;
|
|
5803
|
+
if (this._wrapperEl) this.render();
|
|
5804
|
+
try {
|
|
5805
|
+
this.config.onSelectModeChange?.(this._selecting);
|
|
5806
|
+
} catch (err) {
|
|
5807
|
+
console.error("[DataTable] onSelectModeChange threw", err);
|
|
5808
|
+
}
|
|
5809
|
+
return true;
|
|
5810
|
+
}
|
|
5811
|
+
/** The rows the filters let through, on every page, by original index. */
|
|
5812
|
+
_shownIndices() {
|
|
5813
|
+
if (this._isServerSide()) return this.config.rows.map((_, i) => i);
|
|
5814
|
+
this._getProcessedRows();
|
|
5815
|
+
return this._processedIndexMap ? [...this._processedIndexMap] : this.config.rows.map((_, i) => i);
|
|
5816
|
+
}
|
|
5817
|
+
/** Ctrl+A and the select-all box: every row the filters let through. */
|
|
5818
|
+
_selectAllShown() {
|
|
5819
|
+
this._state.selected.clear();
|
|
5820
|
+
for (const i of this._shownIndices()) this._state.selected.add(i);
|
|
5821
|
+
this._state.anchorIndex = this.config.rows.length - 1;
|
|
5822
|
+
this._updateRowSelection();
|
|
5823
|
+
this._notifySelectionChange();
|
|
5824
|
+
}
|
|
5825
|
+
/** The select column's width: its controls, never a drag. */
|
|
5826
|
+
_selectColWidth() {
|
|
5827
|
+
return this._selecting ? this.config.selectToggle ? 56 : 32 : 32;
|
|
5828
|
+
}
|
|
5829
|
+
/** The select column's header: the toggle and, in the mode, select-all. */
|
|
5830
|
+
_buildSelectHead() {
|
|
5831
|
+
const th = document.createElement("th");
|
|
5832
|
+
th.className = "twm-dt-select-cell twm-dt-select-head";
|
|
5833
|
+
if (this._selecting) {
|
|
5834
|
+
const all = document.createElement("input");
|
|
5835
|
+
all.type = "checkbox";
|
|
5836
|
+
all.className = "twm-dt-select-all";
|
|
5837
|
+
all.setAttribute("aria-label", "Select all rows");
|
|
5838
|
+
all.title = "Select all rows";
|
|
5839
|
+
all.addEventListener("click", (ev) => {
|
|
5840
|
+
ev.stopPropagation();
|
|
5841
|
+
const shown = this._shownIndices();
|
|
5842
|
+
const every = shown.length > 0 && shown.every((i) => this._state.selected.has(i));
|
|
5843
|
+
if (every) this.clearSelection();
|
|
5844
|
+
else this._selectAllShown();
|
|
5845
|
+
});
|
|
5846
|
+
th.appendChild(all);
|
|
5847
|
+
}
|
|
5848
|
+
if (this.config.selectToggle) {
|
|
5849
|
+
const btn = document.createElement("button");
|
|
5850
|
+
btn.type = "button";
|
|
5851
|
+
btn.className = "material-symbols-outlined twm-dt-select-toggle";
|
|
5852
|
+
btn.textContent = this._selecting ? "close" : "checklist";
|
|
5853
|
+
btn.setAttribute("aria-pressed", this._selecting ? "true" : "false");
|
|
5854
|
+
const label = this._selecting ? "Stop selecting" : "Select multiple";
|
|
5855
|
+
btn.setAttribute("aria-label", label);
|
|
5856
|
+
btn.title = label;
|
|
5857
|
+
btn.addEventListener("click", (ev) => {
|
|
5858
|
+
ev.stopPropagation();
|
|
5859
|
+
this.setSelectMode(!this._selecting);
|
|
5860
|
+
});
|
|
5861
|
+
th.appendChild(btn);
|
|
5862
|
+
}
|
|
5863
|
+
th.classList.toggle("twm-dt-select-head--on", this._selecting);
|
|
5864
|
+
return th;
|
|
5865
|
+
}
|
|
5866
|
+
/** The select-all box: checked, mixed or clear, as the ticks are. */
|
|
5867
|
+
_paintSelectHead() {
|
|
5868
|
+
if (!this._gutter || !this._wrapperEl) return;
|
|
5869
|
+
const all = this._wrapperEl.querySelector(".twm-dt-select-all");
|
|
5870
|
+
if (!all) return;
|
|
5871
|
+
const shown = this._shownIndices();
|
|
5872
|
+
const n = shown.filter((i) => this._state.selected.has(i)).length;
|
|
5873
|
+
all.checked = n > 0 && n === shown.length;
|
|
5874
|
+
all.indeterminate = n > 0 && n < shown.length;
|
|
5875
|
+
}
|
|
5876
|
+
/** The keyboard's row in select mode, marked so it can be seen. */
|
|
5877
|
+
_markCursor() {
|
|
5878
|
+
if (!this._tbodyEl) return;
|
|
5879
|
+
for (const tr of this._tbodyEl.children) {
|
|
5880
|
+
if (tr.__rowIndex === void 0) continue;
|
|
5881
|
+
tr.classList.toggle("twm-dt-row--cursor", this._selecting && tr.__rowIndex === this._navCursor);
|
|
5882
|
+
}
|
|
5690
5883
|
}
|
|
5691
5884
|
_notifySelectionChange() {
|
|
5692
5885
|
this.config.onSelectionChange?.(this.getSelection());
|
|
@@ -5975,4 +6168,4 @@ export {
|
|
|
5975
6168
|
resolvePaging,
|
|
5976
6169
|
DataTable
|
|
5977
6170
|
};
|
|
5978
|
-
//# sourceMappingURL=chunk-
|
|
6171
|
+
//# sourceMappingURL=chunk-M2L4XW2U.js.map
|