@iyulab/flex-table 0.13.0 → 0.15.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/dist/export/export.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { ColumnDefinition, DataRow } from '../models/types.js';
|
|
2
|
-
export type ExportFormat = 'csv' | 'tsv' | 'json';
|
|
2
|
+
export type ExportFormat = 'csv' | 'tsv' | 'json' | 'xlsx';
|
|
3
3
|
/**
|
|
4
4
|
* Export data to the specified format.
|
|
5
|
+
* Returns string for text formats (csv/tsv/json) or Uint8Array for xlsx.
|
|
5
6
|
*/
|
|
6
|
-
export declare function exportData(data: DataRow[], columns: ColumnDefinition[], format: ExportFormat): string;
|
|
7
|
+
export declare function exportData(data: DataRow[], columns: ColumnDefinition[], format: ExportFormat): string | Uint8Array;
|
|
7
8
|
/**
|
|
8
9
|
* Trigger a file download in the browser.
|
|
9
10
|
*/
|
|
10
|
-
export declare function downloadFile(content: string, filename: string, mimeType: string): void;
|
|
11
|
+
export declare function downloadFile(content: string | Uint8Array, filename: string, mimeType: string): void;
|
|
11
12
|
export declare function getExportMimeType(format: ExportFormat): string;
|
|
12
13
|
export declare function getExportExtension(format: ExportFormat): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal XLSX writer — no external dependencies.
|
|
3
|
+
* Generates OOXML (.xlsx) files using ZIP STORE method (no compression).
|
|
4
|
+
* Supports string, number, boolean, and date cell types.
|
|
5
|
+
*/
|
|
6
|
+
import type { ColumnDefinition, DataRow } from '../models/types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Build an XLSX file as a Uint8Array.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildXlsx(data: DataRow[], columns: ColumnDefinition[]): Uint8Array;
|
|
@@ -174,6 +174,14 @@ var s = t`
|
|
|
174
174
|
|
|
175
175
|
.ft-body { position: relative; }
|
|
176
176
|
|
|
177
|
+
.ft-frozen-rows {
|
|
178
|
+
display: block;
|
|
179
|
+
position: sticky;
|
|
180
|
+
z-index: 3;
|
|
181
|
+
border-bottom: 2px solid var(--ft-active-color);
|
|
182
|
+
background: var(--ft-bg);
|
|
183
|
+
}
|
|
184
|
+
|
|
177
185
|
.ft-row {
|
|
178
186
|
display: block;
|
|
179
187
|
position: absolute;
|
|
@@ -353,7 +361,7 @@ var s = t`
|
|
|
353
361
|
position: absolute;
|
|
354
362
|
top: 100%;
|
|
355
363
|
left: 0;
|
|
356
|
-
min-width:
|
|
364
|
+
min-width: 200px;
|
|
357
365
|
background: var(--ft-bg);
|
|
358
366
|
border: 1px solid var(--ft-border-color);
|
|
359
367
|
border-radius: 4px;
|
|
@@ -407,6 +415,51 @@ var s = t`
|
|
|
407
415
|
color: var(--ft-text-color);
|
|
408
416
|
}
|
|
409
417
|
|
|
418
|
+
.ft-filter-mode-row {
|
|
419
|
+
display: flex;
|
|
420
|
+
gap: 4px;
|
|
421
|
+
margin-bottom: 4px;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.ft-filter-mode-select {
|
|
425
|
+
flex: 1;
|
|
426
|
+
padding: 3px 6px;
|
|
427
|
+
font: inherit;
|
|
428
|
+
font-size: 12px;
|
|
429
|
+
border: 1px solid var(--ft-border-color);
|
|
430
|
+
border-radius: 3px;
|
|
431
|
+
color: var(--ft-text-color);
|
|
432
|
+
background: var(--ft-editor-bg);
|
|
433
|
+
cursor: pointer;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.ft-num-cond-row {
|
|
437
|
+
display: flex;
|
|
438
|
+
gap: 4px;
|
|
439
|
+
margin-bottom: 4px;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.ft-num-op-select {
|
|
443
|
+
flex: 0 0 44px;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.ft-num-cond-input {
|
|
447
|
+
flex: 1;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.ft-filter-empty-row {
|
|
451
|
+
margin-top: 6px;
|
|
452
|
+
padding-top: 6px;
|
|
453
|
+
border-top: 1px solid var(--ft-border-color);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.ft-filter-empty-row label {
|
|
457
|
+
display: block;
|
|
458
|
+
font-size: 11px;
|
|
459
|
+
color: var(--ft-sort-indicator-color);
|
|
460
|
+
margin-bottom: 3px;
|
|
461
|
+
}
|
|
462
|
+
|
|
410
463
|
/* --- Row Selection (Checkbox) --- */
|
|
411
464
|
|
|
412
465
|
.ft-checkbox-header,
|
|
@@ -519,6 +572,42 @@ var s = t`
|
|
|
519
572
|
color: white;
|
|
520
573
|
}
|
|
521
574
|
|
|
575
|
+
/* Body context menu */
|
|
576
|
+
.ft-body-context-menu {
|
|
577
|
+
background: var(--ft-editor-bg, #fff);
|
|
578
|
+
border: 1px solid var(--ft-border-color);
|
|
579
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.16);
|
|
580
|
+
min-width: 180px;
|
|
581
|
+
border-radius: 4px;
|
|
582
|
+
overflow: hidden;
|
|
583
|
+
padding: 4px 0;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.ft-context-menu-item {
|
|
587
|
+
padding: 6px 14px;
|
|
588
|
+
cursor: pointer;
|
|
589
|
+
font-size: var(--ft-font-size, 14px);
|
|
590
|
+
color: var(--ft-text-color);
|
|
591
|
+
white-space: nowrap;
|
|
592
|
+
user-select: none;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
.ft-context-menu-item:hover {
|
|
596
|
+
background: var(--ft-selection-bg);
|
|
597
|
+
color: var(--ft-active-color);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.ft-context-menu-item.ft-context-menu-danger:hover {
|
|
601
|
+
background: #fdd;
|
|
602
|
+
color: #c0392b;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.ft-context-menu-separator {
|
|
606
|
+
height: 1px;
|
|
607
|
+
background: var(--ft-border-color);
|
|
608
|
+
margin: 4px 0;
|
|
609
|
+
}
|
|
610
|
+
|
|
522
611
|
/* Find / Replace panel */
|
|
523
612
|
.ft-find-panel {
|
|
524
613
|
position: sticky;
|
|
@@ -866,13 +955,13 @@ function S(e, t, n) {
|
|
|
866
955
|
if (c && l) continue;
|
|
867
956
|
if (c) return 1;
|
|
868
957
|
if (l) return -1;
|
|
869
|
-
let u =
|
|
958
|
+
let u = ee(t, s, i.get(a) ?? "text");
|
|
870
959
|
if (u !== 0) return o === "asc" ? u : -u;
|
|
871
960
|
}
|
|
872
961
|
return n - r;
|
|
873
962
|
}), r;
|
|
874
963
|
}
|
|
875
|
-
function
|
|
964
|
+
function ee(e, t, n) {
|
|
876
965
|
switch (n) {
|
|
877
966
|
case "number": {
|
|
878
967
|
let n = Number(e), r = Number(t);
|
|
@@ -887,7 +976,7 @@ function C(e, t, n) {
|
|
|
887
976
|
default: return String(e).localeCompare(String(t));
|
|
888
977
|
}
|
|
889
978
|
}
|
|
890
|
-
function
|
|
979
|
+
function te(e, t, n) {
|
|
891
980
|
let r = e.find((e) => e.key === t);
|
|
892
981
|
return n ? r ? r.direction === "asc" ? e.map((e) => e.key === t ? {
|
|
893
982
|
...e,
|
|
@@ -905,7 +994,7 @@ function w(e, t, n) {
|
|
|
905
994
|
}
|
|
906
995
|
//#endregion
|
|
907
996
|
//#region src/core/filtering.ts
|
|
908
|
-
function
|
|
997
|
+
function ne(e, t, n) {
|
|
909
998
|
if (t.length === 0) return Array.from({ length: e.length }, (e, t) => t);
|
|
910
999
|
let r = [];
|
|
911
1000
|
for (let i = 0; i < e.length; i++) {
|
|
@@ -924,9 +1013,9 @@ function T(e, t, n) {
|
|
|
924
1013
|
}
|
|
925
1014
|
//#endregion
|
|
926
1015
|
//#region src/core/undo.ts
|
|
927
|
-
var
|
|
1016
|
+
var C = 100, w = class {
|
|
928
1017
|
constructor() {
|
|
929
|
-
this._undoStack = [], this._redoStack = [], this._maxSize =
|
|
1018
|
+
this._undoStack = [], this._redoStack = [], this._maxSize = C;
|
|
930
1019
|
}
|
|
931
1020
|
get maxSize() {
|
|
932
1021
|
return this._maxSize;
|
|
@@ -963,7 +1052,7 @@ var E = 100, D = class {
|
|
|
963
1052
|
};
|
|
964
1053
|
//#endregion
|
|
965
1054
|
//#region src/clipboard/clipboard.ts
|
|
966
|
-
function
|
|
1055
|
+
function T(e, t, n) {
|
|
967
1056
|
let r = [];
|
|
968
1057
|
for (let i = n.startRow; i <= n.endRow; i++) {
|
|
969
1058
|
let a = e[i], o = [];
|
|
@@ -975,7 +1064,7 @@ function O(e, t, n) {
|
|
|
975
1064
|
}
|
|
976
1065
|
return r.join("\n");
|
|
977
1066
|
}
|
|
978
|
-
function
|
|
1067
|
+
function E(e) {
|
|
979
1068
|
let t = e.replace(/\r\n/g, "\n").replace(/\r/g, "\n"), n = [], r = [], i = 0, a = t.length;
|
|
980
1069
|
for (; i <= a;) {
|
|
981
1070
|
if (i === a) {
|
|
@@ -1004,7 +1093,7 @@ function k(e) {
|
|
|
1004
1093
|
}
|
|
1005
1094
|
return n;
|
|
1006
1095
|
}
|
|
1007
|
-
function
|
|
1096
|
+
function D(e, t) {
|
|
1008
1097
|
if (e === "") return null;
|
|
1009
1098
|
switch (t.type) {
|
|
1010
1099
|
case "number": {
|
|
@@ -1016,24 +1105,122 @@ function A(e, t) {
|
|
|
1016
1105
|
}
|
|
1017
1106
|
}
|
|
1018
1107
|
//#endregion
|
|
1108
|
+
//#region src/export/xlsx-writer.ts
|
|
1109
|
+
var re = (() => {
|
|
1110
|
+
let e = new Uint32Array(256);
|
|
1111
|
+
for (let t = 0; t < 256; t++) {
|
|
1112
|
+
let n = t;
|
|
1113
|
+
for (let e = 0; e < 8; e++) n = n & 1 ? 3988292384 ^ n >>> 1 : n >>> 1;
|
|
1114
|
+
e[t] = n;
|
|
1115
|
+
}
|
|
1116
|
+
return e;
|
|
1117
|
+
})();
|
|
1118
|
+
function ie(e) {
|
|
1119
|
+
let t = 4294967295;
|
|
1120
|
+
for (let n = 0; n < e.length; n++) t = re[(t ^ e[n]) & 255] ^ t >>> 8;
|
|
1121
|
+
return (t ^ 4294967295) >>> 0;
|
|
1122
|
+
}
|
|
1123
|
+
var O = new TextEncoder();
|
|
1124
|
+
function k(e) {
|
|
1125
|
+
let t = [], n = [], r = 0;
|
|
1126
|
+
for (let i of e) {
|
|
1127
|
+
let e = O.encode(i.name), a = ie(i.data), o = i.data.length, s = new ArrayBuffer(30 + e.length), c = new DataView(s);
|
|
1128
|
+
c.setUint32(0, 67324752, !0), c.setUint16(4, 20, !0), c.setUint16(6, 0, !0), c.setUint16(8, 0, !0), c.setUint16(10, 0, !0), c.setUint16(12, 33, !0), c.setUint32(14, a, !0), c.setUint32(18, o, !0), c.setUint32(22, o, !0), c.setUint16(26, e.length, !0), c.setUint16(28, 0, !0), new Uint8Array(s, 30).set(e), t.push(new Uint8Array(s)), t.push(i.data);
|
|
1129
|
+
let l = new ArrayBuffer(46 + e.length), u = new DataView(l);
|
|
1130
|
+
u.setUint32(0, 33639248, !0), u.setUint16(4, 20, !0), u.setUint16(6, 20, !0), u.setUint16(8, 0, !0), u.setUint16(10, 0, !0), u.setUint16(12, 0, !0), u.setUint16(14, 33, !0), u.setUint32(16, a, !0), u.setUint32(20, o, !0), u.setUint32(24, o, !0), u.setUint16(28, e.length, !0), u.setUint16(30, 0, !0), u.setUint16(32, 0, !0), u.setUint16(34, 0, !0), u.setUint16(36, 0, !0), u.setUint32(38, 0, !0), u.setUint32(42, r, !0), new Uint8Array(l, 46).set(e), n.push(new Uint8Array(l)), r += 30 + e.length + o;
|
|
1131
|
+
}
|
|
1132
|
+
let i = A(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
|
|
1133
|
+
return o.setUint32(0, 101010256, !0), o.setUint16(4, 0, !0), o.setUint16(6, 0, !0), o.setUint16(8, e.length, !0), o.setUint16(10, e.length, !0), o.setUint32(12, i.length, !0), o.setUint32(16, r, !0), o.setUint16(20, 0, !0), A([
|
|
1134
|
+
...t,
|
|
1135
|
+
i,
|
|
1136
|
+
new Uint8Array(a)
|
|
1137
|
+
]);
|
|
1138
|
+
}
|
|
1139
|
+
function A(e) {
|
|
1140
|
+
let t = e.reduce((e, t) => e + t.length, 0), n = new Uint8Array(t), r = 0;
|
|
1141
|
+
for (let t of e) n.set(t, r), r += t.length;
|
|
1142
|
+
return n;
|
|
1143
|
+
}
|
|
1144
|
+
function j(e) {
|
|
1145
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1146
|
+
}
|
|
1147
|
+
function ae(e) {
|
|
1148
|
+
let t = "";
|
|
1149
|
+
for (e++; e > 0;) t = String.fromCharCode(64 + (e % 26 || 26)) + t, e = Math.floor((e - 1) / 26);
|
|
1150
|
+
return t;
|
|
1151
|
+
}
|
|
1152
|
+
function M(e, t) {
|
|
1153
|
+
return ae(t) + (e + 1);
|
|
1154
|
+
}
|
|
1155
|
+
function N(e) {
|
|
1156
|
+
let t = Date.UTC(1899, 11, 30);
|
|
1157
|
+
return (e.getTime() - t) / 864e5;
|
|
1158
|
+
}
|
|
1159
|
+
var P = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>\n <Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>\n <Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>\n</Types>", F = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>\n</Relationships>", I = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <sheets><sheet name=\"Sheet1\" sheetId=\"1\" r:id=\"rId1\"/></sheets>\n</workbook>", L = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>", R = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">\n <numFmts count=\"1\"><numFmt numFmtId=\"164\" formatCode=\"yyyy-mm-dd\"/></numFmts>\n <fonts count=\"2\">\n <font><sz val=\"11\"/><name val=\"Calibri\"/></font>\n <font><sz val=\"11\"/><b/><name val=\"Calibri\"/></font>\n </fonts>\n <fills count=\"2\">\n <fill><patternFill patternType=\"none\"/></fill>\n <fill><patternFill patternType=\"gray125\"/></fill>\n </fills>\n <borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>\n <cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>\n <cellXfs count=\"3\">\n <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>\n <xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>\n <xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>\n </cellXfs>\n</styleSheet>";
|
|
1160
|
+
function z(e, t) {
|
|
1161
|
+
let n = [], r = t.map((e, t) => `<c r="${M(0, t)}" t="str" s="2"><v>${j(e.header)}</v></c>`);
|
|
1162
|
+
return n.push(`<row r="1">${r.join("")}</row>`), e.forEach((e, r) => {
|
|
1163
|
+
let i = t.map((t, n) => {
|
|
1164
|
+
let i = M(r + 1, n), a = e[t.key];
|
|
1165
|
+
if (a == null) return `<c r="${i}" t="str"><v></v></c>`;
|
|
1166
|
+
let o = t.type ?? "text";
|
|
1167
|
+
return o === "number" && typeof a == "number" ? `<c r="${i}"><v>${a}</v></c>` : (o === "date" || o === "datetime") && a instanceof Date ? `<c r="${i}" s="1"><v>${N(a).toFixed(6)}</v></c>` : o === "boolean" ? `<c r="${i}" t="b"><v>${+!!a}</v></c>` : `<c r="${i}" t="str"><v>${j(String(a))}</v></c>`;
|
|
1168
|
+
});
|
|
1169
|
+
n.push(`<row r="${r + 2}">${i.join("")}</row>`);
|
|
1170
|
+
}), `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
1171
|
+
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
|
1172
|
+
<sheetData>${n.join("")}</sheetData>
|
|
1173
|
+
</worksheet>`;
|
|
1174
|
+
}
|
|
1175
|
+
function B(e, t) {
|
|
1176
|
+
let n = z(e, t);
|
|
1177
|
+
return k([
|
|
1178
|
+
{
|
|
1179
|
+
name: "[Content_Types].xml",
|
|
1180
|
+
data: O.encode(P)
|
|
1181
|
+
},
|
|
1182
|
+
{
|
|
1183
|
+
name: "_rels/.rels",
|
|
1184
|
+
data: O.encode(F)
|
|
1185
|
+
},
|
|
1186
|
+
{
|
|
1187
|
+
name: "xl/workbook.xml",
|
|
1188
|
+
data: O.encode(I)
|
|
1189
|
+
},
|
|
1190
|
+
{
|
|
1191
|
+
name: "xl/_rels/workbook.xml.rels",
|
|
1192
|
+
data: O.encode(L)
|
|
1193
|
+
},
|
|
1194
|
+
{
|
|
1195
|
+
name: "xl/worksheets/sheet1.xml",
|
|
1196
|
+
data: O.encode(n)
|
|
1197
|
+
},
|
|
1198
|
+
{
|
|
1199
|
+
name: "xl/styles.xml",
|
|
1200
|
+
data: O.encode(R)
|
|
1201
|
+
}
|
|
1202
|
+
]);
|
|
1203
|
+
}
|
|
1204
|
+
//#endregion
|
|
1019
1205
|
//#region src/export/export.ts
|
|
1020
|
-
function
|
|
1206
|
+
function V(e, t, n) {
|
|
1021
1207
|
switch (n) {
|
|
1022
|
-
case "csv": return
|
|
1023
|
-
case "tsv": return
|
|
1024
|
-
case "json": return
|
|
1208
|
+
case "csv": return U(e, t, ",");
|
|
1209
|
+
case "tsv": return U(e, t, " ");
|
|
1210
|
+
case "json": return G(e, t);
|
|
1211
|
+
case "xlsx": return B(e, t);
|
|
1025
1212
|
}
|
|
1026
1213
|
}
|
|
1027
|
-
function
|
|
1214
|
+
function H(e, t) {
|
|
1028
1215
|
return e == null ? "" : (t.type === "date" || t.type === "datetime") && e instanceof Date ? e.toISOString() : String(e);
|
|
1029
1216
|
}
|
|
1030
|
-
function
|
|
1031
|
-
return [t.map((e) =>
|
|
1217
|
+
function U(e, t, n) {
|
|
1218
|
+
return [t.map((e) => W(e.header, n)).join(n), ...e.map((e) => t.map((t) => W(H(e[t.key], t), n)).join(n))].join("\n");
|
|
1032
1219
|
}
|
|
1033
|
-
function
|
|
1220
|
+
function W(e, t) {
|
|
1034
1221
|
return e.includes(t) || e.includes("\"") || e.includes("\n") || e.includes("\r") ? "\"" + e.replace(/"/g, "\"\"") + "\"" : e;
|
|
1035
1222
|
}
|
|
1036
|
-
function
|
|
1223
|
+
function G(e, t) {
|
|
1037
1224
|
let n = e.map((e) => {
|
|
1038
1225
|
let n = {};
|
|
1039
1226
|
for (let r of t) {
|
|
@@ -1044,28 +1231,30 @@ function F(e, t) {
|
|
|
1044
1231
|
});
|
|
1045
1232
|
return JSON.stringify(n, null, 2);
|
|
1046
1233
|
}
|
|
1047
|
-
function
|
|
1234
|
+
function K(e, t, n) {
|
|
1048
1235
|
let r = new Blob([e], { type: n }), i = URL.createObjectURL(r), a = document.createElement("a");
|
|
1049
1236
|
a.href = i, a.download = t, a.style.display = "none", document.body.appendChild(a), a.click(), document.body.removeChild(a), setTimeout(() => URL.revokeObjectURL(i), 100);
|
|
1050
1237
|
}
|
|
1051
|
-
var
|
|
1238
|
+
var q = {
|
|
1052
1239
|
csv: "text/csv;charset=utf-8",
|
|
1053
1240
|
tsv: "text/tab-separated-values;charset=utf-8",
|
|
1054
|
-
json: "application/json;charset=utf-8"
|
|
1055
|
-
|
|
1241
|
+
json: "application/json;charset=utf-8",
|
|
1242
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
1243
|
+
}, oe = {
|
|
1056
1244
|
csv: ".csv",
|
|
1057
1245
|
tsv: ".tsv",
|
|
1058
|
-
json: ".json"
|
|
1246
|
+
json: ".json",
|
|
1247
|
+
xlsx: ".xlsx"
|
|
1059
1248
|
};
|
|
1060
|
-
function
|
|
1061
|
-
return
|
|
1249
|
+
function se(e) {
|
|
1250
|
+
return q[e];
|
|
1062
1251
|
}
|
|
1063
|
-
function
|
|
1064
|
-
return
|
|
1252
|
+
function ce(e) {
|
|
1253
|
+
return oe[e];
|
|
1065
1254
|
}
|
|
1066
1255
|
//#endregion
|
|
1067
1256
|
//#region \0@oxc-project+runtime@0.130.0/helpers/decorate.js
|
|
1068
|
-
function
|
|
1257
|
+
function J(e, t, n, r) {
|
|
1069
1258
|
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
1070
1259
|
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
1071
1260
|
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
@@ -1073,9 +1262,16 @@ function V(e, t, n, r) {
|
|
|
1073
1262
|
}
|
|
1074
1263
|
//#endregion
|
|
1075
1264
|
//#region src/flex-table.ts
|
|
1076
|
-
var
|
|
1265
|
+
var Y = {
|
|
1266
|
+
eq: "=",
|
|
1267
|
+
neq: "≠",
|
|
1268
|
+
gt: ">",
|
|
1269
|
+
lt: "<",
|
|
1270
|
+
gte: "≥",
|
|
1271
|
+
lte: "≤"
|
|
1272
|
+
}, X = 120, Z = 40, le = 32, Q = 5, $ = class extends e {
|
|
1077
1273
|
constructor(...e) {
|
|
1078
|
-
super(...e), this.columns = [], this.data = [], this.rowHeight =
|
|
1274
|
+
super(...e), this.columns = [], this.data = [], this.rowHeight = le, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.selectable = !1, this.dataMode = "client", this.footerData = null, this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new y(), this._editing = new b(), this._rowSelection = new x(), this._undo = new w(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._colDrag = null, this._colDragIndicatorLeft = null, this._fillDrag = null, this._rowDrag = null, this._rowDragIndicatorY = null, this._findState = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._invalidCells = /* @__PURE__ */ new Map(), this._textFilterState = /* @__PURE__ */ new Map(), this._numberFilterState = /* @__PURE__ */ new Map(), this._dateFilterState = /* @__PURE__ */ new Map(), this._emptyFilterState = /* @__PURE__ */ new Map();
|
|
1079
1275
|
}
|
|
1080
1276
|
static {
|
|
1081
1277
|
this.styles = s;
|
|
@@ -1384,12 +1580,12 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1384
1580
|
if (!t) return "";
|
|
1385
1581
|
let n = this.visibleColumns.slice(t.startCol, t.endCol + 1), r = [];
|
|
1386
1582
|
for (let e = t.startRow; e <= t.endRow; e++) r.push(this.data[this._toDataIndex(e)]);
|
|
1387
|
-
return
|
|
1583
|
+
return V(r, n, e);
|
|
1388
1584
|
}
|
|
1389
|
-
return
|
|
1585
|
+
return V(this._sortedIndices.map((e) => this.data[e]), this.visibleColumns, e);
|
|
1390
1586
|
}
|
|
1391
1587
|
exportToFile(e, t) {
|
|
1392
|
-
|
|
1588
|
+
K(this.exportToString(e), t ?? `export${ce(e)}`, se(e));
|
|
1393
1589
|
}
|
|
1394
1590
|
_getSelectedDataRows() {
|
|
1395
1591
|
let e = this._selection.getEffectiveRange();
|
|
@@ -1402,8 +1598,8 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1402
1598
|
return this._columnWidths.get(e);
|
|
1403
1599
|
}
|
|
1404
1600
|
_getColWidth(e) {
|
|
1405
|
-
let t = this._columnWidths.get(e.key) ?? e.width ??
|
|
1406
|
-
return Math.max(t, e.minWidth ??
|
|
1601
|
+
let t = this._columnWidths.get(e.key) ?? e.width ?? X;
|
|
1602
|
+
return Math.max(t, e.minWidth ?? Z);
|
|
1407
1603
|
}
|
|
1408
1604
|
get headerHeight() {
|
|
1409
1605
|
return this.rowHeight + 8;
|
|
@@ -1411,14 +1607,20 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1411
1607
|
get _visibleRowCount() {
|
|
1412
1608
|
return this._sortedIndices.length;
|
|
1413
1609
|
}
|
|
1610
|
+
get _frozenRowCount() {
|
|
1611
|
+
return Math.min(this.frozenRows, this._visibleRowCount);
|
|
1612
|
+
}
|
|
1613
|
+
get frozenRowsHeight() {
|
|
1614
|
+
return this._frozenRowCount * this.rowHeight;
|
|
1615
|
+
}
|
|
1414
1616
|
get totalBodyHeight() {
|
|
1415
|
-
return this._visibleRowCount * this.rowHeight;
|
|
1617
|
+
return Math.max(0, this._visibleRowCount - this._frozenRowCount) * this.rowHeight;
|
|
1416
1618
|
}
|
|
1417
1619
|
get visibleRange() {
|
|
1418
|
-
let e = Math.max(0, this._scrollTop - this.headerHeight),
|
|
1620
|
+
let e = this._frozenRowCount, t = Math.max(0, this._scrollTop - this.headerHeight - this.frozenRowsHeight), n = e + Math.floor(t / this.rowHeight), r = Math.max(e, n - Q), i = Math.ceil(this._viewportHeight / this.rowHeight);
|
|
1419
1621
|
return {
|
|
1420
|
-
start:
|
|
1421
|
-
end: Math.min(this._visibleRowCount,
|
|
1622
|
+
start: r,
|
|
1623
|
+
end: Math.min(this._visibleRowCount, n + i + Q)
|
|
1422
1624
|
};
|
|
1423
1625
|
}
|
|
1424
1626
|
connectedCallback() {
|
|
@@ -1451,13 +1653,13 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1451
1653
|
i = r;
|
|
1452
1654
|
break;
|
|
1453
1655
|
}
|
|
1454
|
-
i = Math.max(0, i -
|
|
1656
|
+
i = Math.max(0, i - Q);
|
|
1455
1657
|
let a = e.length;
|
|
1456
1658
|
for (let e = i; e < t.length; e++) if (t[e] > r) {
|
|
1457
1659
|
a = e;
|
|
1458
1660
|
break;
|
|
1459
1661
|
}
|
|
1460
|
-
return a = Math.min(e.length, a +
|
|
1662
|
+
return a = Math.min(e.length, a + Q), {
|
|
1461
1663
|
start: i,
|
|
1462
1664
|
end: a
|
|
1463
1665
|
};
|
|
@@ -1473,7 +1675,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1473
1675
|
this._filteredIndices = Array.from({ length: this.data.length }, (e, t) => t), this._sortedIndices = this._filteredIndices;
|
|
1474
1676
|
return;
|
|
1475
1677
|
}
|
|
1476
|
-
if (this._filteredIndices =
|
|
1678
|
+
if (this._filteredIndices = ne(this.data, this._filters, (e, t, n) => {
|
|
1477
1679
|
this.dispatchEvent(new CustomEvent("filter-error", {
|
|
1478
1680
|
detail: {
|
|
1479
1681
|
error: e,
|
|
@@ -1506,17 +1708,19 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1506
1708
|
this._scrollTop = this.scrollTop, this._scrollLeft = this.scrollLeft;
|
|
1507
1709
|
}
|
|
1508
1710
|
_onDocumentClick() {
|
|
1509
|
-
this._openFilterKey &&= null, this._headerMenu &&= null;
|
|
1711
|
+
this._openFilterKey &&= null, this._headerMenu &&= null, this._bodyContextMenu &&= null;
|
|
1510
1712
|
}
|
|
1511
1713
|
_onContextMenu(e) {
|
|
1512
1714
|
let t = e.composedPath().find((e) => e instanceof HTMLElement && e.classList.contains("ft-cell"));
|
|
1513
1715
|
if (!t) return;
|
|
1716
|
+
e.preventDefault();
|
|
1514
1717
|
let n = t.parentElement;
|
|
1515
1718
|
if (!n || !n.classList.contains("ft-row")) return;
|
|
1516
1719
|
let r = parseInt(t.dataset.colIndex ?? "-1", 10), i = n.style.top, a = Math.round(parseInt(i, 10) / this.rowHeight);
|
|
1517
1720
|
if (r < 0 || a < 0) return;
|
|
1518
1721
|
let o = this._toDataIndex(a), s = this.visibleColumns[r];
|
|
1519
|
-
|
|
1722
|
+
if (!s) return;
|
|
1723
|
+
let c = new CustomEvent("context-menu", {
|
|
1520
1724
|
detail: {
|
|
1521
1725
|
x: e.clientX,
|
|
1522
1726
|
y: e.clientY,
|
|
@@ -1527,7 +1731,17 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1527
1731
|
rowData: this.data[o]
|
|
1528
1732
|
},
|
|
1529
1733
|
bubbles: !0,
|
|
1530
|
-
composed: !0
|
|
1734
|
+
composed: !0,
|
|
1735
|
+
cancelable: !0
|
|
1736
|
+
});
|
|
1737
|
+
this.dispatchEvent(c), this.showContextMenu && !c.defaultPrevented && (this._bodyContextMenu = {
|
|
1738
|
+
rowIndex: a,
|
|
1739
|
+
colIndex: r,
|
|
1740
|
+
dataIndex: o,
|
|
1741
|
+
x: e.clientX,
|
|
1742
|
+
y: e.clientY
|
|
1743
|
+
}, requestAnimationFrame(() => {
|
|
1744
|
+
document.addEventListener("click", this._onDocumentClick, { once: !0 });
|
|
1531
1745
|
}));
|
|
1532
1746
|
}
|
|
1533
1747
|
_onCellClickEvent(e, t, n) {
|
|
@@ -1600,7 +1814,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1600
1814
|
}
|
|
1601
1815
|
let t = this.shadowRoot?.querySelector(".ft-editor");
|
|
1602
1816
|
if (t) {
|
|
1603
|
-
let n =
|
|
1817
|
+
let n = D(t.value, e);
|
|
1604
1818
|
this._applyEdit(n);
|
|
1605
1819
|
} else this._cancelEdit();
|
|
1606
1820
|
}
|
|
@@ -1793,7 +2007,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1793
2007
|
e.preventDefault();
|
|
1794
2008
|
let n = t[this._activeCell.col];
|
|
1795
2009
|
if (!n) return !0;
|
|
1796
|
-
let r = this._columnWidths.get(n.key) ?? n.width ??
|
|
2010
|
+
let r = this._columnWidths.get(n.key) ?? n.width ?? X, i = e.key === "ArrowRight" ? 20 : -20, a = n.minWidth ?? Z, o = Math.max(a, r + i);
|
|
1797
2011
|
return this._columnWidths.set(n.key, o), this.requestUpdate(), this.dispatchEvent(new CustomEvent("column-resize", {
|
|
1798
2012
|
detail: {
|
|
1799
2013
|
key: n.key,
|
|
@@ -1822,7 +2036,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1822
2036
|
async _handleCopy(e) {
|
|
1823
2037
|
let t = this._selection.getEffectiveRange();
|
|
1824
2038
|
if (!t) return;
|
|
1825
|
-
let n = this.visibleColumns, r =
|
|
2039
|
+
let n = this.visibleColumns, r = T(this._sortedIndices.map((e) => this.data[e]), n, t);
|
|
1826
2040
|
try {
|
|
1827
2041
|
await navigator.clipboard.writeText(r);
|
|
1828
2042
|
} catch (e) {
|
|
@@ -1848,7 +2062,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1848
2062
|
if (!this._activeCell) return;
|
|
1849
2063
|
let e = await this._readClipboardText();
|
|
1850
2064
|
if (e == null) return;
|
|
1851
|
-
let t =
|
|
2065
|
+
let t = E(e);
|
|
1852
2066
|
if (t.length === 0) return;
|
|
1853
2067
|
let n = this._expandRowsForPaste(this._activeCell.row, t.length), r = this._applyPasteData(this._activeCell, t);
|
|
1854
2068
|
if (r.length > 0 || n.length > 0) {
|
|
@@ -1906,7 +2120,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1906
2120
|
for (let a = 0; a < t[i].length; a++) {
|
|
1907
2121
|
let s = e.col + a;
|
|
1908
2122
|
if (s >= n.length) break;
|
|
1909
|
-
let c = n[s], l = this.data[o][c.key], u =
|
|
2123
|
+
let c = n[s], l = this.data[o][c.key], u = D(t[i][a], c);
|
|
1910
2124
|
this.data[o][c.key] = u, r.push({
|
|
1911
2125
|
row: o,
|
|
1912
2126
|
col: s,
|
|
@@ -1971,7 +2185,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
1971
2185
|
for (let r = e.startCol + 1; r <= e.endCol; r++) {
|
|
1972
2186
|
let e = t[r];
|
|
1973
2187
|
if (!e || !this._isCellEditable(e)) continue;
|
|
1974
|
-
let a =
|
|
2188
|
+
let a = D(o == null ? "" : String(o), e);
|
|
1975
2189
|
n.push({
|
|
1976
2190
|
row: i,
|
|
1977
2191
|
key: e.key,
|
|
@@ -2045,7 +2259,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2045
2259
|
_scrollToActiveCell() {
|
|
2046
2260
|
if (!this._activeCell) return;
|
|
2047
2261
|
let e = this._activeCell.row * this.rowHeight + this.headerHeight, t = e + this.rowHeight;
|
|
2048
|
-
e < this.scrollTop + this.headerHeight ? this.scrollTop = e - this.headerHeight : t > this.scrollTop + this.clientHeight && (this.scrollTop = t - this.clientHeight);
|
|
2262
|
+
this._activeCell.row < this._frozenRowCount || (e < this.scrollTop + this.headerHeight + this.frozenRowsHeight ? this.scrollTop = e - this.headerHeight - this.frozenRowsHeight : t > this.scrollTop + this.clientHeight && (this.scrollTop = t - this.clientHeight));
|
|
2049
2263
|
let n = this.visibleColumns, r = this._activeCell.col, i = this._colLeftOffsets[r] ?? 0, a = i + this._getColWidth(n[r]);
|
|
2050
2264
|
i < this.scrollLeft ? this.scrollLeft = i : a > this.scrollLeft + this.clientWidth && (this.scrollLeft = a - this.clientWidth);
|
|
2051
2265
|
}
|
|
@@ -2062,7 +2276,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2062
2276
|
this._selectColumn(n);
|
|
2063
2277
|
return;
|
|
2064
2278
|
}
|
|
2065
|
-
t.sortable !== !1 && (this._sortCriteria =
|
|
2279
|
+
t.sortable !== !1 && (this._sortCriteria = te(this._sortCriteria, t.key, e.shiftKey), this.dataMode !== "server" && this._recomputeView(), this.requestUpdate(), this.dispatchEvent(new CustomEvent("sort-change", {
|
|
2066
2280
|
detail: { criteria: [...this._sortCriteria] },
|
|
2067
2281
|
bubbles: !0,
|
|
2068
2282
|
composed: !0
|
|
@@ -2194,6 +2408,89 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2194
2408
|
</div>
|
|
2195
2409
|
` : r;
|
|
2196
2410
|
}
|
|
2411
|
+
_renderBodyContextMenu() {
|
|
2412
|
+
if (!this._bodyContextMenu) return r;
|
|
2413
|
+
let { colIndex: e, dataIndex: t, x: i, y: a } = this._bodyContextMenu, o = this.visibleColumns[e];
|
|
2414
|
+
if (!o) return r;
|
|
2415
|
+
let s = this.data[t]?.[o.key], c = this._filters.some((e) => e.key === o.key), l = () => {
|
|
2416
|
+
this._bodyContextMenu = null;
|
|
2417
|
+
};
|
|
2418
|
+
return n`
|
|
2419
|
+
<div class="ft-body-context-menu" style="position: fixed; left: ${i + 200 > window.innerWidth ? i - 200 : i}px; top: ${a + 280 > window.innerHeight ? a - 280 : a}px; z-index: 200;"
|
|
2420
|
+
@mousedown=${(e) => e.stopPropagation()}>
|
|
2421
|
+
<div class="ft-context-menu-item"
|
|
2422
|
+
@click=${() => {
|
|
2423
|
+
this._handleCopy(!1), l();
|
|
2424
|
+
}}>
|
|
2425
|
+
Copy
|
|
2426
|
+
</div>
|
|
2427
|
+
<div class="ft-context-menu-separator"></div>
|
|
2428
|
+
<div class="ft-context-menu-item"
|
|
2429
|
+
@click=${() => {
|
|
2430
|
+
this.addRow(void 0, t), l();
|
|
2431
|
+
}}>
|
|
2432
|
+
Insert row above
|
|
2433
|
+
</div>
|
|
2434
|
+
<div class="ft-context-menu-item"
|
|
2435
|
+
@click=${() => {
|
|
2436
|
+
this.addRow(void 0, t + 1), l();
|
|
2437
|
+
}}>
|
|
2438
|
+
Insert row below
|
|
2439
|
+
</div>
|
|
2440
|
+
<div class="ft-context-menu-item ft-context-menu-danger"
|
|
2441
|
+
@click=${() => {
|
|
2442
|
+
this.deleteRows([t]), l();
|
|
2443
|
+
}}>
|
|
2444
|
+
Delete row
|
|
2445
|
+
</div>
|
|
2446
|
+
<div class="ft-context-menu-separator"></div>
|
|
2447
|
+
<div class="ft-context-menu-item"
|
|
2448
|
+
@click=${() => {
|
|
2449
|
+
this._setColumnHidden(o.key, !0), l();
|
|
2450
|
+
}}>
|
|
2451
|
+
Hide column
|
|
2452
|
+
</div>
|
|
2453
|
+
<div class="ft-context-menu-separator"></div>
|
|
2454
|
+
<div class="ft-context-menu-item"
|
|
2455
|
+
@click=${() => {
|
|
2456
|
+
this._applySortFromMenu(o.key, "asc"), l();
|
|
2457
|
+
}}>
|
|
2458
|
+
Sort ascending ↑
|
|
2459
|
+
</div>
|
|
2460
|
+
<div class="ft-context-menu-item"
|
|
2461
|
+
@click=${() => {
|
|
2462
|
+
this._applySortFromMenu(o.key, "desc"), l();
|
|
2463
|
+
}}>
|
|
2464
|
+
Sort descending ↓
|
|
2465
|
+
</div>
|
|
2466
|
+
<div class="ft-context-menu-separator"></div>
|
|
2467
|
+
<div class="ft-context-menu-item"
|
|
2468
|
+
@click=${() => {
|
|
2469
|
+
this.setFilter(o.key, (e) => e === s), l();
|
|
2470
|
+
}}>
|
|
2471
|
+
Filter by this value
|
|
2472
|
+
</div>
|
|
2473
|
+
${c ? n`
|
|
2474
|
+
<div class="ft-context-menu-item"
|
|
2475
|
+
@click=${() => {
|
|
2476
|
+
this.removeFilter(o.key), l();
|
|
2477
|
+
}}>
|
|
2478
|
+
Clear filter
|
|
2479
|
+
</div>
|
|
2480
|
+
` : ""}
|
|
2481
|
+
</div>
|
|
2482
|
+
`;
|
|
2483
|
+
}
|
|
2484
|
+
_applySortFromMenu(e, t) {
|
|
2485
|
+
this.columns.find((t) => t.key === e) && (this._sortCriteria = [{
|
|
2486
|
+
key: e,
|
|
2487
|
+
direction: t
|
|
2488
|
+
}], this._sortedIndices = S(this.data, this._sortCriteria, this.columns), this.dispatchEvent(new CustomEvent("sort-change", {
|
|
2489
|
+
detail: { sortCriteria: [...this._sortCriteria] },
|
|
2490
|
+
bubbles: !0,
|
|
2491
|
+
composed: !0
|
|
2492
|
+
})), this.requestUpdate());
|
|
2493
|
+
}
|
|
2197
2494
|
_adjustFilterDropdown() {
|
|
2198
2495
|
if (!this._openFilterKey) return;
|
|
2199
2496
|
let e = this.shadowRoot?.querySelector(".ft-filter-dropdown");
|
|
@@ -2220,36 +2517,215 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2220
2517
|
</div>
|
|
2221
2518
|
`;
|
|
2222
2519
|
}
|
|
2520
|
+
_buildTextPredicate(e, t) {
|
|
2521
|
+
let n = e.toLowerCase();
|
|
2522
|
+
switch (t) {
|
|
2523
|
+
case "starts": return (e) => String(e ?? "").toLowerCase().startsWith(n);
|
|
2524
|
+
case "ends": return (e) => String(e ?? "").toLowerCase().endsWith(n);
|
|
2525
|
+
case "wildcard": {
|
|
2526
|
+
let e = n.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, "."), t = RegExp("^" + e + "$", "i");
|
|
2527
|
+
return (e) => t.test(String(e ?? ""));
|
|
2528
|
+
}
|
|
2529
|
+
default: return (e) => String(e ?? "").toLowerCase().includes(n);
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
_applyTextFilter(e) {
|
|
2533
|
+
let t = this._emptyFilterState.get(e);
|
|
2534
|
+
if (t) {
|
|
2535
|
+
this.setFilter(e, this._buildEmptyPredicate(t));
|
|
2536
|
+
return;
|
|
2537
|
+
}
|
|
2538
|
+
let n = this._textFilterState.get(e);
|
|
2539
|
+
n?.value ? this.setFilter(e, this._buildTextPredicate(n.value, n.mode)) : this.removeFilter(e);
|
|
2540
|
+
}
|
|
2541
|
+
_buildEmptyPredicate(e) {
|
|
2542
|
+
return e === "empty" ? (e) => e == null || e === "" : (e) => e != null && e !== "";
|
|
2543
|
+
}
|
|
2544
|
+
_renderEmptyFilterRow(e, t) {
|
|
2545
|
+
return n`
|
|
2546
|
+
<div class="ft-filter-empty-row">
|
|
2547
|
+
<label>Blank cells</label>
|
|
2548
|
+
<select class="ft-filter-mode-select"
|
|
2549
|
+
.value=${this._emptyFilterState.get(e) ?? ""}
|
|
2550
|
+
@change=${(n) => {
|
|
2551
|
+
let r = n.target.value;
|
|
2552
|
+
(r === "" || r === "empty" || r === "non-empty") && (r ? this._emptyFilterState.set(e, r) : this._emptyFilterState.delete(e), t?.(), this._applyFilterForKey(e));
|
|
2553
|
+
}}
|
|
2554
|
+
@keydown=${(e) => {
|
|
2555
|
+
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
2556
|
+
}}>
|
|
2557
|
+
<option value="">— All —</option>
|
|
2558
|
+
<option value="empty">Empty only</option>
|
|
2559
|
+
<option value="non-empty">Non-empty only</option>
|
|
2560
|
+
</select>
|
|
2561
|
+
</div>
|
|
2562
|
+
`;
|
|
2563
|
+
}
|
|
2564
|
+
_evalNumCond(e, t) {
|
|
2565
|
+
let n = t.value;
|
|
2566
|
+
switch (t.op) {
|
|
2567
|
+
case "eq": return e === n;
|
|
2568
|
+
case "neq": return e !== n;
|
|
2569
|
+
case "gt": return e > n;
|
|
2570
|
+
case "lt": return e < n;
|
|
2571
|
+
case "gte": return e >= n;
|
|
2572
|
+
case "lte": return e <= n;
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
_buildNumberPredicate(e) {
|
|
2576
|
+
let t = e.cond1.value != null, n = e.cond2.value != null;
|
|
2577
|
+
return !t && !n ? null : (r) => {
|
|
2578
|
+
let i = Number(r);
|
|
2579
|
+
if (isNaN(i)) return !1;
|
|
2580
|
+
if (t && !n) return this._evalNumCond(i, e.cond1);
|
|
2581
|
+
if (!t && n) return this._evalNumCond(i, e.cond2);
|
|
2582
|
+
let a = this._evalNumCond(i, e.cond1), o = this._evalNumCond(i, e.cond2);
|
|
2583
|
+
return e.join === "or" ? a || o : a && o;
|
|
2584
|
+
};
|
|
2585
|
+
}
|
|
2586
|
+
_buildDatePredicate(e) {
|
|
2587
|
+
return e.from == null && e.to == null ? null : (t) => {
|
|
2588
|
+
if (t == null || t === "") return !1;
|
|
2589
|
+
let n = t instanceof Date ? t : new Date(String(t));
|
|
2590
|
+
if (isNaN(n.getTime()) || e.from && n < new Date(e.from)) return !1;
|
|
2591
|
+
if (e.to) {
|
|
2592
|
+
let t = new Date(e.to);
|
|
2593
|
+
if (e.to.length === 10 && t.setHours(23, 59, 59, 999), n > t) return !1;
|
|
2594
|
+
}
|
|
2595
|
+
return !0;
|
|
2596
|
+
};
|
|
2597
|
+
}
|
|
2598
|
+
_applyFilterForKey(e) {
|
|
2599
|
+
let t = this._emptyFilterState.get(e);
|
|
2600
|
+
if (t) {
|
|
2601
|
+
this.setFilter(e, this._buildEmptyPredicate(t));
|
|
2602
|
+
return;
|
|
2603
|
+
}
|
|
2604
|
+
if (this._textFilterState.has(e)) this._applyTextFilter(e);
|
|
2605
|
+
else if (this._numberFilterState.has(e)) {
|
|
2606
|
+
let t = this._buildNumberPredicate(this._numberFilterState.get(e));
|
|
2607
|
+
t ? this.setFilter(e, t) : this.removeFilter(e);
|
|
2608
|
+
} else if (this._dateFilterState.has(e)) {
|
|
2609
|
+
let t = this._buildDatePredicate(this._dateFilterState.get(e));
|
|
2610
|
+
t ? this.setFilter(e, t) : this.removeFilter(e);
|
|
2611
|
+
} else this.removeFilter(e);
|
|
2612
|
+
}
|
|
2223
2613
|
_renderTextFilter(e) {
|
|
2614
|
+
let t = this._textFilterState.get(e.key) ?? {
|
|
2615
|
+
value: "",
|
|
2616
|
+
mode: "contains"
|
|
2617
|
+
};
|
|
2224
2618
|
return n`
|
|
2619
|
+
<div class="ft-filter-mode-row">
|
|
2620
|
+
<select class="ft-filter-mode-select"
|
|
2621
|
+
.value=${t.mode}
|
|
2622
|
+
@change=${(t) => {
|
|
2623
|
+
let n = t.target.value, r = this._textFilterState.get(e.key) ?? {
|
|
2624
|
+
value: "",
|
|
2625
|
+
mode: "contains"
|
|
2626
|
+
};
|
|
2627
|
+
this._textFilterState.set(e.key, {
|
|
2628
|
+
...r,
|
|
2629
|
+
mode: n
|
|
2630
|
+
}), this._applyTextFilter(e.key);
|
|
2631
|
+
}}
|
|
2632
|
+
@keydown=${(e) => {
|
|
2633
|
+
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
2634
|
+
}}>
|
|
2635
|
+
<option value="contains">Contains</option>
|
|
2636
|
+
<option value="starts">Starts with</option>
|
|
2637
|
+
<option value="ends">Ends with</option>
|
|
2638
|
+
<option value="wildcard">Wildcard</option>
|
|
2639
|
+
</select>
|
|
2640
|
+
</div>
|
|
2225
2641
|
<input class="ft-filter-input" type="text" placeholder="Search..."
|
|
2226
|
-
.value=${
|
|
2642
|
+
.value=${t.value}
|
|
2227
2643
|
@input=${(t) => {
|
|
2228
|
-
let n = t.target.value
|
|
2229
|
-
|
|
2644
|
+
let n = t.target.value, r = this._textFilterState.get(e.key) ?? {
|
|
2645
|
+
value: "",
|
|
2646
|
+
mode: "contains"
|
|
2647
|
+
};
|
|
2648
|
+
this._textFilterState.set(e.key, {
|
|
2649
|
+
...r,
|
|
2650
|
+
value: n
|
|
2651
|
+
}), this._emptyFilterState.delete(e.key), this._applyTextFilter(e.key);
|
|
2230
2652
|
}}
|
|
2231
2653
|
@keydown=${(e) => {
|
|
2232
2654
|
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
2233
2655
|
}}>
|
|
2656
|
+
${this._renderEmptyFilterRow(e.key, () => {
|
|
2657
|
+
this._textFilterState.delete(e.key);
|
|
2658
|
+
})}
|
|
2234
2659
|
`;
|
|
2235
2660
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2661
|
+
_defaultNumState() {
|
|
2662
|
+
return {
|
|
2663
|
+
cond1: {
|
|
2664
|
+
op: "gte",
|
|
2665
|
+
value: null
|
|
2666
|
+
},
|
|
2667
|
+
join: "and",
|
|
2668
|
+
cond2: {
|
|
2669
|
+
op: "lte",
|
|
2670
|
+
value: null
|
|
2671
|
+
}
|
|
2672
|
+
};
|
|
2673
|
+
}
|
|
2674
|
+
_renderNumCondRow(e, t) {
|
|
2675
|
+
let r = (this._numberFilterState.get(e) ?? this._defaultNumState())[t];
|
|
2238
2676
|
return n`
|
|
2239
|
-
<div class="ft-
|
|
2240
|
-
<
|
|
2241
|
-
.value=${
|
|
2242
|
-
@
|
|
2677
|
+
<div class="ft-num-cond-row">
|
|
2678
|
+
<select class="ft-filter-mode-select ft-num-op-select"
|
|
2679
|
+
.value=${r.op}
|
|
2680
|
+
@change=${(n) => {
|
|
2681
|
+
let r = n.target.value, i = this._numberFilterState.get(e) ?? this._defaultNumState();
|
|
2682
|
+
i[t] = {
|
|
2683
|
+
...i[t],
|
|
2684
|
+
op: r
|
|
2685
|
+
}, this._numberFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
|
|
2686
|
+
}}
|
|
2243
2687
|
@keydown=${(e) => {
|
|
2244
2688
|
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
2245
2689
|
}}>
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2690
|
+
${Object.keys(Y).map((e) => n`<option value=${e}>${Y[e]}</option>`)}
|
|
2691
|
+
</select>
|
|
2692
|
+
<input class="ft-filter-input ft-num-cond-input" type="number" placeholder="Value"
|
|
2693
|
+
.value=${r.value == null ? "" : String(r.value)}
|
|
2694
|
+
@input=${(n) => {
|
|
2695
|
+
let r = n.target.value, i = this._numberFilterState.get(e) ?? this._defaultNumState();
|
|
2696
|
+
i[t] = {
|
|
2697
|
+
...i[t],
|
|
2698
|
+
value: r === "" ? null : Number(r)
|
|
2699
|
+
}, this._numberFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
|
|
2700
|
+
}}
|
|
2701
|
+
@keydown=${(e) => {
|
|
2702
|
+
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
2703
|
+
}}>
|
|
2704
|
+
</div>
|
|
2705
|
+
`;
|
|
2706
|
+
}
|
|
2707
|
+
_renderNumberFilter(e) {
|
|
2708
|
+
let t = this._numberFilterState.get(e.key) ?? this._defaultNumState();
|
|
2709
|
+
return n`
|
|
2710
|
+
${this._renderNumCondRow(e.key, "cond1")}
|
|
2711
|
+
<div class="ft-filter-mode-row">
|
|
2712
|
+
<select class="ft-filter-mode-select"
|
|
2713
|
+
.value=${t.join}
|
|
2714
|
+
@change=${(t) => {
|
|
2715
|
+
let n = t.target.value, r = this._numberFilterState.get(e.key) ?? this._defaultNumState();
|
|
2716
|
+
r.join = n, this._numberFilterState.set(e.key, r), this._emptyFilterState.delete(e.key), this._applyFilterForKey(e.key);
|
|
2717
|
+
}}
|
|
2249
2718
|
@keydown=${(e) => {
|
|
2250
2719
|
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
2251
2720
|
}}>
|
|
2721
|
+
<option value="and">AND</option>
|
|
2722
|
+
<option value="or">OR</option>
|
|
2723
|
+
</select>
|
|
2252
2724
|
</div>
|
|
2725
|
+
${this._renderNumCondRow(e.key, "cond2")}
|
|
2726
|
+
${this._renderEmptyFilterRow(e.key, () => {
|
|
2727
|
+
this._numberFilterState.delete(e.key);
|
|
2728
|
+
})}
|
|
2253
2729
|
`;
|
|
2254
2730
|
}
|
|
2255
2731
|
_cellKey(e, t) {
|
|
@@ -2270,13 +2746,6 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2270
2746
|
let n = this._invalidCells.get(this._cellKey(e, t));
|
|
2271
2747
|
return n ? n.error : null;
|
|
2272
2748
|
}
|
|
2273
|
-
_applyNumberFilter(e, t, n) {
|
|
2274
|
-
let r = t.target.value, i = this._numberFilterState.get(e) ?? {};
|
|
2275
|
-
r === "" ? delete i[n] : i[n] = Number(r), this._numberFilterState.set(e, i), i.min == null && i.max == null ? this.removeFilter(e) : this.setFilter(e, (e) => {
|
|
2276
|
-
let t = Number(e);
|
|
2277
|
-
return !(isNaN(t) || i.min != null && t < i.min || i.max != null && t > i.max);
|
|
2278
|
-
});
|
|
2279
|
-
}
|
|
2280
2749
|
_renderDateFilter(e) {
|
|
2281
2750
|
let t = e.type === "datetime" ? "datetime-local" : "date", r = this._dateFilterState.get(e.key) ?? {};
|
|
2282
2751
|
return n`
|
|
@@ -2294,20 +2763,14 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2294
2763
|
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
2295
2764
|
}}>
|
|
2296
2765
|
</div>
|
|
2766
|
+
${this._renderEmptyFilterRow(e.key, () => {
|
|
2767
|
+
this._dateFilterState.delete(e.key);
|
|
2768
|
+
})}
|
|
2297
2769
|
`;
|
|
2298
2770
|
}
|
|
2299
2771
|
_applyDateFilter(e, t, n) {
|
|
2300
2772
|
let r = t.target.value, i = this._dateFilterState.get(e) ?? {};
|
|
2301
|
-
r === "" ? delete i[n] : i[n] = r, this._dateFilterState.set(e, i),
|
|
2302
|
-
if (e == null || e === "") return !1;
|
|
2303
|
-
let t = e instanceof Date ? e : new Date(String(e));
|
|
2304
|
-
if (isNaN(t.getTime()) || i.from && t < new Date(i.from)) return !1;
|
|
2305
|
-
if (i.to) {
|
|
2306
|
-
let e = new Date(i.to);
|
|
2307
|
-
if (i.to.length === 10 && e.setHours(23, 59, 59, 999), t > e) return !1;
|
|
2308
|
-
}
|
|
2309
|
-
return !0;
|
|
2310
|
-
});
|
|
2773
|
+
r === "" ? delete i[n] : i[n] = r, this._dateFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
|
|
2311
2774
|
}
|
|
2312
2775
|
_renderBooleanFilter(e) {
|
|
2313
2776
|
return n`
|
|
@@ -2323,10 +2786,11 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2323
2786
|
<option value="true">\u2714 True</option>
|
|
2324
2787
|
<option value="false">\u2718 False</option>
|
|
2325
2788
|
</select>
|
|
2789
|
+
${this._renderEmptyFilterRow(e.key)}
|
|
2326
2790
|
`;
|
|
2327
2791
|
}
|
|
2328
2792
|
_clearColumnFilter(e) {
|
|
2329
|
-
this.removeFilter(e), this._textFilterState.delete(e), this._numberFilterState.delete(e), this._dateFilterState.delete(e), this._openFilterKey = null;
|
|
2793
|
+
this.removeFilter(e), this._textFilterState.delete(e), this._numberFilterState.delete(e), this._dateFilterState.delete(e), this._emptyFilterState.delete(e), this._openFilterKey = null;
|
|
2330
2794
|
}
|
|
2331
2795
|
_onResizeAutoFit(e, t) {
|
|
2332
2796
|
e.preventDefault(), e.stopPropagation();
|
|
@@ -2334,7 +2798,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2334
2798
|
if (!n) return;
|
|
2335
2799
|
let r = this.shadowRoot?.querySelectorAll(`.ft-cell[data-col-index="${t}"]`), i = 0, a = this.shadowRoot?.querySelector(`.ft-header-cell[data-col-index="${t}"]`);
|
|
2336
2800
|
if (a && (i = Math.max(i, a.scrollWidth)), r) for (let e of r) i = Math.max(i, e.scrollWidth);
|
|
2337
|
-
let o = n.minWidth ??
|
|
2801
|
+
let o = n.minWidth ?? Z, s = Math.max(o, i + 8);
|
|
2338
2802
|
this._columnWidths.set(n.key, s), this.requestUpdate(), this.dispatchEvent(new CustomEvent("column-resize", {
|
|
2339
2803
|
detail: {
|
|
2340
2804
|
key: n.key,
|
|
@@ -2347,7 +2811,7 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2347
2811
|
}
|
|
2348
2812
|
_onResizeStart(e, t) {
|
|
2349
2813
|
e.preventDefault(), e.stopPropagation();
|
|
2350
|
-
let n = this.visibleColumns[t], r = this._columnWidths.get(n.key) ?? n.width ??
|
|
2814
|
+
let n = this.visibleColumns[t], r = this._columnWidths.get(n.key) ?? n.width ?? X;
|
|
2351
2815
|
this._resizing = {
|
|
2352
2816
|
colIndex: t,
|
|
2353
2817
|
startX: e.clientX,
|
|
@@ -2355,13 +2819,13 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2355
2819
|
};
|
|
2356
2820
|
let i = (e) => {
|
|
2357
2821
|
if (!this._resizing) return;
|
|
2358
|
-
let t = e.clientX - this._resizing.startX, r = n.minWidth ??
|
|
2822
|
+
let t = e.clientX - this._resizing.startX, r = n.minWidth ?? Z, i = Math.max(r, this._resizing.startWidth + t);
|
|
2359
2823
|
this._columnWidths.set(n.key, i), this.requestUpdate();
|
|
2360
2824
|
}, a = () => {
|
|
2361
2825
|
document.removeEventListener("mousemove", i), document.removeEventListener("mouseup", o), this._resizeCleanup = null;
|
|
2362
2826
|
}, o = () => {
|
|
2363
2827
|
if (a(), this._resizing) {
|
|
2364
|
-
let e = this._columnWidths.get(n.key) ??
|
|
2828
|
+
let e = this._columnWidths.get(n.key) ?? X;
|
|
2365
2829
|
this.dispatchEvent(new CustomEvent("column-resize", {
|
|
2366
2830
|
detail: {
|
|
2367
2831
|
key: n.key,
|
|
@@ -2795,9 +3259,9 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2795
3259
|
</div>
|
|
2796
3260
|
<div class="ft-empty">${this.data.length === 0 ? "No data" : "No matching data"}</div>
|
|
2797
3261
|
`;
|
|
2798
|
-
let { start: p, end: m } = this.visibleRange, h = [];
|
|
2799
|
-
for (let e = p; e < m; e++)
|
|
2800
|
-
let
|
|
3262
|
+
let { start: p, end: m } = this.visibleRange, h = this._frozenRowCount, g = [];
|
|
3263
|
+
for (let e = p; e < m; e++) g.push(this._renderRow(e, i, a, o, (e - h) * this.rowHeight));
|
|
3264
|
+
let _ = this._renderFillHandle(), v = this._rowDragIndicatorY == null ? "" : n`<div class="ft-row-drop-indicator" style="top:${this._rowDragIndicatorY}px;width:${r + this._prefixWidth}px;"></div>`;
|
|
2801
3265
|
return n`
|
|
2802
3266
|
${this._renderFindPanel()}
|
|
2803
3267
|
<div class="ft-header" role="row" style="width: ${r}px; height: ${t}px;">
|
|
@@ -2805,13 +3269,15 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2805
3269
|
${d}
|
|
2806
3270
|
${f}
|
|
2807
3271
|
</div>
|
|
3272
|
+
${this._renderFrozenRows(i, a, o)}
|
|
2808
3273
|
<div class="ft-body" style="height: ${this.totalBodyHeight}px; width: ${r}px;">
|
|
2809
|
-
${
|
|
3274
|
+
${g}
|
|
2810
3275
|
</div>
|
|
2811
3276
|
${this.footerData ? this._renderFooter(i, a, o) : ""}
|
|
3277
|
+
${v}
|
|
2812
3278
|
${_}
|
|
2813
|
-
${g}
|
|
2814
3279
|
${this._renderHeaderContextMenu()}
|
|
3280
|
+
${this._renderBodyContextMenu()}
|
|
2815
3281
|
`;
|
|
2816
3282
|
}
|
|
2817
3283
|
_onSelectAllChange(e) {
|
|
@@ -2820,6 +3286,17 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2820
3286
|
_onRowCheckboxChange(e, t) {
|
|
2821
3287
|
e.stopPropagation(), this._rowSelection.toggle(t), this._rowSelectionVersion++, this._dispatchRowSelectionEvent();
|
|
2822
3288
|
}
|
|
3289
|
+
_renderFrozenRows(e, t, i) {
|
|
3290
|
+
let a = this._frozenRowCount;
|
|
3291
|
+
if (a === 0) return r;
|
|
3292
|
+
let o = this._totalRowWidth, s = [];
|
|
3293
|
+
for (let n = 0; n < a; n++) s.push(this._renderRow(n, e, t, i, n * this.rowHeight));
|
|
3294
|
+
return n`
|
|
3295
|
+
<div class="ft-frozen-rows" style="top: ${this.headerHeight}px; height: ${this.frozenRowsHeight}px; width: ${o}px;">
|
|
3296
|
+
${s}
|
|
3297
|
+
</div>
|
|
3298
|
+
`;
|
|
3299
|
+
}
|
|
2823
3300
|
_renderFooter(e, t, r) {
|
|
2824
3301
|
if (!this.footerData) return "";
|
|
2825
3302
|
let i = this.visibleColumns, a = this.rowHeight, o = this._totalRowWidth, s = this._scrollLeft, c = 0, l = this.selectable ? n`<div class="ft-footer-cell ft-checkbox-cell"
|
|
@@ -2848,29 +3325,29 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2848
3325
|
</div>
|
|
2849
3326
|
`;
|
|
2850
3327
|
}
|
|
2851
|
-
_renderRow(e, t, r, i) {
|
|
2852
|
-
let
|
|
3328
|
+
_renderRow(e, t, r, i, a) {
|
|
3329
|
+
let o = this.visibleColumns, s = this._toDataIndex(e), c = this.data[s], l = a ?? e * this.rowHeight, u = this.rowHeight, d = this._totalRowWidth, f = e % 2 == 0 ? "ft-row-even" : "ft-row-odd", p = this.selectable && this._rowSelection.isSelected(e), m = this._scrollLeft, h = 0, g = this.selectable ? n`
|
|
2853
3330
|
<div class="ft-checkbox-cell"
|
|
2854
|
-
style="position: absolute; top: 0; left: ${
|
|
3331
|
+
style="position: absolute; top: 0; left: ${m + h}px; width: 36px; height: ${u}px; z-index: 2;">
|
|
2855
3332
|
<input type="checkbox"
|
|
2856
|
-
.checked=${
|
|
3333
|
+
.checked=${p}
|
|
2857
3334
|
@change=${(t) => this._onRowCheckboxChange(t, e)}>
|
|
2858
3335
|
</div>
|
|
2859
3336
|
` : "";
|
|
2860
|
-
this.selectable && (
|
|
2861
|
-
let
|
|
2862
|
-
<div class="ft-row-num ${
|
|
2863
|
-
style="position: absolute; top: 0; left: ${
|
|
3337
|
+
this.selectable && (h += 36);
|
|
3338
|
+
let _ = this._rowDrag?.active && this._rowDrag.rowIndex === e, v = this.showRowNumbers ? n`
|
|
3339
|
+
<div class="ft-row-num ${_ ? "ft-col-dragging" : ""}"
|
|
3340
|
+
style="position: absolute; top: 0; left: ${m + h}px; width: 48px; height: ${u}px; z-index: 2; cursor: grab;"
|
|
2864
3341
|
@mousedown=${(t) => this._onRowNumMouseDown(t, e)}
|
|
2865
|
-
@click=${() => this._onRowNumberClick(e)}>${
|
|
2866
|
-
` : "",
|
|
2867
|
-
for (let t of i)
|
|
2868
|
-
for (let n = t; n < r; n++)
|
|
3342
|
+
@click=${() => this._onRowNumberClick(e)}>${s + 1}</div>
|
|
3343
|
+
` : "", y = [];
|
|
3344
|
+
for (let t of i) y.push(this._renderCell(c, o[t], e, t));
|
|
3345
|
+
for (let n = t; n < r; n++) y.push(this._renderCell(c, o[n], e, n));
|
|
2869
3346
|
return n`
|
|
2870
|
-
<div class="ft-row ${
|
|
2871
|
-
style="top: ${
|
|
2872
|
-
${
|
|
2873
|
-
${
|
|
3347
|
+
<div class="ft-row ${f} ${p ? "ft-row-selected" : ""}" role="row"
|
|
3348
|
+
style="top: ${l}px; height: ${u}px; width: ${d}px;">
|
|
3349
|
+
${g}${v}
|
|
3350
|
+
${y}
|
|
2874
3351
|
</div>
|
|
2875
3352
|
`;
|
|
2876
3353
|
}
|
|
@@ -2991,36 +3468,42 @@ var H = 120, U = 40, W = 32, G = 5, K = class extends e {
|
|
|
2991
3468
|
return isNaN(t.getTime()) ? "" : `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}-${String(t.getDate()).padStart(2, "0")}T${String(t.getHours()).padStart(2, "0")}:${String(t.getMinutes()).padStart(2, "0")}`;
|
|
2992
3469
|
}
|
|
2993
3470
|
};
|
|
2994
|
-
|
|
3471
|
+
J([a({ type: Array })], $.prototype, "columns", void 0), J([a({
|
|
2995
3472
|
type: Array,
|
|
2996
3473
|
hasChanged: () => !0
|
|
2997
|
-
})],
|
|
3474
|
+
})], $.prototype, "data", void 0), J([a({
|
|
2998
3475
|
type: Number,
|
|
2999
3476
|
attribute: "row-height"
|
|
3000
|
-
})],
|
|
3477
|
+
})], $.prototype, "rowHeight", void 0), J([a({
|
|
3001
3478
|
type: Boolean,
|
|
3002
3479
|
attribute: "show-row-numbers"
|
|
3003
|
-
})],
|
|
3480
|
+
})], $.prototype, "showRowNumbers", void 0), J([a({
|
|
3004
3481
|
type: String,
|
|
3005
3482
|
reflect: !0
|
|
3006
|
-
})],
|
|
3483
|
+
})], $.prototype, "theme", void 0), J([a({
|
|
3007
3484
|
type: Number,
|
|
3008
3485
|
attribute: "max-rows"
|
|
3009
|
-
})],
|
|
3486
|
+
})], $.prototype, "maxRows", void 0), J([a({ type: Boolean })], $.prototype, "editable", void 0), J([a({
|
|
3010
3487
|
type: Boolean,
|
|
3011
3488
|
attribute: "show-filters"
|
|
3012
|
-
})],
|
|
3489
|
+
})], $.prototype, "showFilters", void 0), J([a({
|
|
3490
|
+
type: Boolean,
|
|
3491
|
+
attribute: "show-context-menu"
|
|
3492
|
+
})], $.prototype, "showContextMenu", void 0), J([a({
|
|
3493
|
+
type: Number,
|
|
3494
|
+
attribute: "frozen-rows"
|
|
3495
|
+
})], $.prototype, "frozenRows", void 0), J([a({ type: Boolean })], $.prototype, "selectable", void 0), J([a({
|
|
3013
3496
|
type: String,
|
|
3014
3497
|
attribute: "selection-mode"
|
|
3015
|
-
})],
|
|
3498
|
+
})], $.prototype, "selectionMode", null), J([a({
|
|
3016
3499
|
type: String,
|
|
3017
3500
|
attribute: "data-mode"
|
|
3018
|
-
})],
|
|
3501
|
+
})], $.prototype, "dataMode", void 0), J([a({
|
|
3019
3502
|
type: Object,
|
|
3020
3503
|
attribute: "footer-data"
|
|
3021
|
-
})],
|
|
3504
|
+
})], $.prototype, "footerData", void 0), J([a({
|
|
3022
3505
|
type: Number,
|
|
3023
3506
|
attribute: "max-undo-size"
|
|
3024
|
-
})],
|
|
3507
|
+
})], $.prototype, "maxUndoSize", null), J([o()], $.prototype, "_scrollTop", void 0), J([o()], $.prototype, "_scrollLeft", void 0), J([o()], $.prototype, "_viewportHeight", void 0), J([o()], $.prototype, "_viewportWidth", void 0), J([o()], $.prototype, "_activeCell", void 0), J([o()], $.prototype, "_editingCell", void 0), J([o()], $.prototype, "_sortCriteria", void 0), J([o()], $.prototype, "_openFilterKey", void 0), J([o()], $.prototype, "_rowSelectionVersion", void 0), J([o()], $.prototype, "_autocompleteState", void 0), J([o()], $.prototype, "_headerMenu", void 0), J([o()], $.prototype, "_bodyContextMenu", void 0), $ = J([i("flex-table")], $);
|
|
3025
3508
|
//#endregion
|
|
3026
|
-
export { f as a, x as i,
|
|
3509
|
+
export { f as a, x as i, V as n, w as r, $ as t };
|
package/dist/flex-table.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export declare class FlexTable extends LitElement {
|
|
|
15
15
|
maxRows: number;
|
|
16
16
|
editable: boolean;
|
|
17
17
|
showFilters: boolean;
|
|
18
|
+
/** Enable built-in context menu on cell right-click. */
|
|
19
|
+
showContextMenu: boolean;
|
|
20
|
+
/** Number of rows to freeze at the top (always visible during vertical scroll). */
|
|
21
|
+
frozenRows: number;
|
|
18
22
|
/** Enable row-level checkbox selection. */
|
|
19
23
|
selectable: boolean;
|
|
20
24
|
/** Row selection mode: 'single' or 'multi' (default: 'multi'). */
|
|
@@ -46,6 +50,7 @@ export declare class FlexTable extends LitElement {
|
|
|
46
50
|
private _rowSelectionVersion;
|
|
47
51
|
private _autocompleteState;
|
|
48
52
|
private _headerMenu;
|
|
53
|
+
private _bodyContextMenu;
|
|
49
54
|
private _viewDirty;
|
|
50
55
|
private _isDragging;
|
|
51
56
|
private _wasDrag;
|
|
@@ -152,7 +157,7 @@ export declare class FlexTable extends LitElement {
|
|
|
152
157
|
*/
|
|
153
158
|
exportToString(format: ExportFormat, options?: {
|
|
154
159
|
selectionOnly?: boolean;
|
|
155
|
-
}): string;
|
|
160
|
+
}): string | Uint8Array;
|
|
156
161
|
/**
|
|
157
162
|
* Export table data and trigger file download.
|
|
158
163
|
*/
|
|
@@ -166,6 +171,8 @@ export declare class FlexTable extends LitElement {
|
|
|
166
171
|
private get headerHeight();
|
|
167
172
|
/** Number of rows visible after filter + sort. */
|
|
168
173
|
private get _visibleRowCount();
|
|
174
|
+
private get _frozenRowCount();
|
|
175
|
+
private get frozenRowsHeight();
|
|
169
176
|
private get totalBodyHeight();
|
|
170
177
|
private get visibleRange();
|
|
171
178
|
connectedCallback(): void;
|
|
@@ -228,10 +235,22 @@ export declare class FlexTable extends LitElement {
|
|
|
228
235
|
private _onHeaderContextMenu;
|
|
229
236
|
private _showHiddenBefore;
|
|
230
237
|
private _renderHeaderContextMenu;
|
|
238
|
+
private _renderBodyContextMenu;
|
|
239
|
+
private _applySortFromMenu;
|
|
231
240
|
private _adjustFilterDropdown;
|
|
232
241
|
private _onFilterBtnClick;
|
|
233
242
|
private _renderFilterDropdown;
|
|
243
|
+
private _buildTextPredicate;
|
|
244
|
+
private _applyTextFilter;
|
|
245
|
+
private _buildEmptyPredicate;
|
|
246
|
+
private _renderEmptyFilterRow;
|
|
247
|
+
private _evalNumCond;
|
|
248
|
+
private _buildNumberPredicate;
|
|
249
|
+
private _buildDatePredicate;
|
|
250
|
+
private _applyFilterForKey;
|
|
234
251
|
private _renderTextFilter;
|
|
252
|
+
private _defaultNumState;
|
|
253
|
+
private _renderNumCondRow;
|
|
235
254
|
private _renderNumberFilter;
|
|
236
255
|
private _invalidCells;
|
|
237
256
|
private _cellKey;
|
|
@@ -240,7 +259,7 @@ export declare class FlexTable extends LitElement {
|
|
|
240
259
|
private _textFilterState;
|
|
241
260
|
private _numberFilterState;
|
|
242
261
|
private _dateFilterState;
|
|
243
|
-
private
|
|
262
|
+
private _emptyFilterState;
|
|
244
263
|
private _renderDateFilter;
|
|
245
264
|
private _applyDateFilter;
|
|
246
265
|
private _renderBooleanFilter;
|
|
@@ -274,6 +293,7 @@ export declare class FlexTable extends LitElement {
|
|
|
274
293
|
render(): TemplateResult<1>;
|
|
275
294
|
private _onSelectAllChange;
|
|
276
295
|
private _onRowCheckboxChange;
|
|
296
|
+
private _renderFrozenRows;
|
|
277
297
|
private _renderFooter;
|
|
278
298
|
private _renderRow;
|
|
279
299
|
private _renderCell;
|
package/dist/flex-table.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n, r, t as i } from "./flex-table-
|
|
1
|
+
import { a as e, i as t, n, r, t as i } from "./flex-table-BVzjrFBP.js";
|
|
2
2
|
export { i as FlexTable, t as RowSelectionState, r as UndoStack, n as exportData, e as renderCell };
|
package/dist/react.js
CHANGED