@iyulab/flex-table 0.41.0 → 0.41.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/CHANGELOG.md +17 -0
- package/README.md +2 -0
- package/dist/clipboard/clipboard.d.ts +6 -0
- package/dist/{flex-table-BF46G1Uw.js → flex-table-C6PFutM_.js} +201 -200
- package/dist/flex-table.d.ts +0 -1
- package/dist/flex-table.js +1 -1
- package/dist/locale.d.ts +1 -1
- package/dist/react.js +1 -1
- package/package.json +2 -2
- package/skills/iyulab-flex-table/SKILL.md +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.41.1] - 2026-10-03
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **The `date` cell editor shows and takes `YYYY-MM-DD` in every browser language.** It was the native
|
|
8
|
+
date input, which shows the browser's UI language (`10/02/2026` in an English browser) whatever the
|
|
9
|
+
page's `Locale`. It is now a text box that also reads `2026/10/2`, `20261002`, `2026. 10. 2.` and
|
|
10
|
+
`10-02` (this year), stores the ISO date string as before, and rejects text that is not a date with
|
|
11
|
+
`validation-error` ("Enter a date as YYYY-MM-DD", new `flexTableLocale` key `notADate`).
|
|
12
|
+
- **The editor no longer shifts a date string by a day.** It read `'2026-10-02'` with `new Date()`
|
|
13
|
+
(UTC midnight), which is the previous day west of UTC.
|
|
14
|
+
- **Pasting `2026/10/2` into a date column stores `2026-10-02`.** Text that is not a date still stays text.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **The `@iyulab/components` peer is `>=1.55.0`** — dates are read with its `parseDate`.
|
|
19
|
+
|
|
3
20
|
## [0.41.0] - 2026-10-03
|
|
4
21
|
|
|
5
22
|
### Added
|
package/README.md
CHANGED
|
@@ -160,6 +160,8 @@ The `validator` callback returns `null` if valid, or an error message string. On
|
|
|
160
160
|
|
|
161
161
|
A `number` column's built-in editor reads numbers the way people type them in the active `Locale` — `1,5` on a comma-decimal page is 1.5, `1.234,5` is 1234.5 — and shows the value with that locale's decimal separator. Text that is not a number is rejected the same way as a validator failure (`error` is the localized "Enter a number"). The number filter's conditions and pasted values are read the same way; pasted text that is not a number stays text.
|
|
162
162
|
|
|
163
|
+
A `date` column's built-in editor is a text box that shows and takes `YYYY-MM-DD` in every browser language (the native date input would show the browser's UI language, e.g. `10/02/2026`). It also reads `2026/10/2`, `20261002` and `10-02` (this year), stores the ISO date string, and rejects text that is not a date (`error` is the localized "Enter a date as YYYY-MM-DD"). Pasted dates are read the same way.
|
|
164
|
+
|
|
163
165
|
### `format` vs `render`
|
|
164
166
|
|
|
165
167
|
Both control how a cell's raw value is displayed, but they differ in what they replace:
|
|
@@ -11,3 +11,9 @@ export declare function parseValueForColumn(raw: string, col: ColumnDefinition):
|
|
|
11
11
|
* kept (`1234.5` → `1234,5` on a German page). The inverse is {@link parseValueForColumn}.
|
|
12
12
|
*/
|
|
13
13
|
export declare function editableNumber(value: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* A `date` cell's value as `YYYY-MM-DD` for editing — the form the editor reads back. A date string
|
|
16
|
+
* keeps its own calendar day (`new Date('2026-10-02')` would be UTC midnight, the day before in
|
|
17
|
+
* negative offsets); a `Date` uses its local day. Anything else is shown as it is.
|
|
18
|
+
*/
|
|
19
|
+
export declare function editableDate(value: unknown): string;
|
|
@@ -2,11 +2,11 @@ import { n as e, t } from "./sorting-CjfjRxwL.js";
|
|
|
2
2
|
import { LitElement as n, css as r, html as i, nothing as a } from "lit";
|
|
3
3
|
import { customElement as o, property as s, state as c } from "lit/decorators.js";
|
|
4
4
|
import { Locale as l } from "@iyulab/components/dist/utilities/Locale.js";
|
|
5
|
-
import {
|
|
6
|
-
import { decodeTsv as
|
|
7
|
-
import { isImeComposing as
|
|
5
|
+
import { dateTextPattern as u, formatDate as d, formatNumber as f, parseDate as p, parseNumber as m } from "@iyulab/components/dist/utilities/format.js";
|
|
6
|
+
import { decodeTsv as h, encodeTsv as g } from "@iyulab/components/dist/utilities/tsv.js";
|
|
7
|
+
import { isImeComposing as _ } from "@iyulab/components/dist/utilities/keyboard.js";
|
|
8
8
|
//#region src/styles/flex-table.styles.ts
|
|
9
|
-
var
|
|
9
|
+
var v = r`
|
|
10
10
|
/* --- Theme Variables (Light defaults) --- */
|
|
11
11
|
:host {
|
|
12
12
|
--ft-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
@@ -921,13 +921,13 @@ var g = r`
|
|
|
921
921
|
`;
|
|
922
922
|
//#endregion
|
|
923
923
|
//#region src/renderers/format.ts
|
|
924
|
-
function
|
|
925
|
-
return e == null ? "" : typeof t == "function" ? t(e) :
|
|
924
|
+
function y(e, t) {
|
|
925
|
+
return e == null ? "" : typeof t == "function" ? t(e) : b(t) ? S(e, t) : x(e, t);
|
|
926
926
|
}
|
|
927
|
-
function
|
|
927
|
+
function b(e) {
|
|
928
928
|
return /[yMdHhms]/.test(e);
|
|
929
929
|
}
|
|
930
|
-
function
|
|
930
|
+
function x(e, t) {
|
|
931
931
|
let n = typeof e == "number" ? e : Number(e);
|
|
932
932
|
if (isNaN(n)) return String(e);
|
|
933
933
|
let r = t.endsWith("%"), i = t.match(/^([^#0.,%]+)/), a = i ? i[1] : "", o = t.replace(/^[^#0.,%]+/, "").replace(/%$/, ""), s = o.match(/\.([0#]+)$/), c = s ? s[1].length : 0, u = {
|
|
@@ -940,7 +940,7 @@ function y(e, t) {
|
|
|
940
940
|
style: "percent"
|
|
941
941
|
}).format(n) : (d = new Intl.NumberFormat(l.get(), u).format(n), a && (d = a + d)), d + "";
|
|
942
942
|
}
|
|
943
|
-
function
|
|
943
|
+
function S(e, t) {
|
|
944
944
|
let n;
|
|
945
945
|
if (e instanceof Date) n = e;
|
|
946
946
|
else if (typeof e == "string" || typeof e == "number") n = new Date(e);
|
|
@@ -951,26 +951,26 @@ function b(e, t) {
|
|
|
951
951
|
}
|
|
952
952
|
//#endregion
|
|
953
953
|
//#region src/renderers/cell-renderer.ts
|
|
954
|
-
function
|
|
955
|
-
return n.render ? n.render(e, t, n) : n.format ? typeof n.format == "function" ? n.format(e, t, n) :
|
|
954
|
+
function C(e, t, n) {
|
|
955
|
+
return n.render ? n.render(e, t, n) : n.format ? typeof n.format == "function" ? n.format(e, t, n) : y(e, n.format) : w(e, n);
|
|
956
956
|
}
|
|
957
|
-
function
|
|
957
|
+
function w(e, t) {
|
|
958
958
|
if (e == null) return "";
|
|
959
959
|
switch (t.type) {
|
|
960
|
-
case "number": return
|
|
960
|
+
case "number": return D(e);
|
|
961
961
|
case "boolean": return i`<span class="ft-bool">${e ? "✔" : ""}</span>`;
|
|
962
|
-
case "date": return
|
|
963
|
-
case "datetime": return
|
|
964
|
-
case "select": return
|
|
962
|
+
case "date": return O(e);
|
|
963
|
+
case "datetime": return ee(e);
|
|
964
|
+
case "select": return T(e, t);
|
|
965
965
|
default: return String(e);
|
|
966
966
|
}
|
|
967
967
|
}
|
|
968
|
-
function
|
|
968
|
+
function T(e, t) {
|
|
969
969
|
if (!t.options || t.options.length === 0 || typeof t.options[0] == "string") return e == null ? "" : String(e);
|
|
970
970
|
let n = t.options.find((t) => t.value === e);
|
|
971
971
|
return n ? n.label : e == null ? "" : String(e);
|
|
972
972
|
}
|
|
973
|
-
var
|
|
973
|
+
var E = {
|
|
974
974
|
year: "numeric",
|
|
975
975
|
month: "numeric",
|
|
976
976
|
day: "numeric",
|
|
@@ -978,19 +978,19 @@ var w = {
|
|
|
978
978
|
minute: "numeric",
|
|
979
979
|
second: "numeric"
|
|
980
980
|
};
|
|
981
|
-
function
|
|
982
|
-
return typeof e == "number" ? Number.isInteger(e) ?
|
|
981
|
+
function D(e) {
|
|
982
|
+
return typeof e == "number" ? Number.isInteger(e) ? f(e) : f(e, { minimumFractionDigits: 1 }) : String(e);
|
|
983
983
|
}
|
|
984
|
-
function
|
|
985
|
-
return e instanceof Date || typeof e == "string" ?
|
|
984
|
+
function O(e) {
|
|
985
|
+
return e instanceof Date || typeof e == "string" ? d(e) : String(e);
|
|
986
986
|
}
|
|
987
|
-
function
|
|
988
|
-
return e instanceof Date || typeof e == "string" ?
|
|
987
|
+
function ee(e) {
|
|
988
|
+
return e instanceof Date || typeof e == "string" ? d(e, E) : String(e);
|
|
989
989
|
}
|
|
990
990
|
//#endregion
|
|
991
991
|
//#region src/locale.ts
|
|
992
|
-
var
|
|
993
|
-
|
|
992
|
+
var k = l.namespace("flex-table");
|
|
993
|
+
k.register("en", {
|
|
994
994
|
showHiddenColumns: "Show hidden column(s)",
|
|
995
995
|
columnMenu: "Column menu",
|
|
996
996
|
cellActions: "Cell actions",
|
|
@@ -1044,8 +1044,9 @@ O.register("en", {
|
|
|
1044
1044
|
booleanFalse: "False",
|
|
1045
1045
|
dropFileToImport: "Drop file to import (.xlsx / .csv)",
|
|
1046
1046
|
notANumber: "Enter a number",
|
|
1047
|
+
notADate: "Enter a date as YYYY-MM-DD",
|
|
1047
1048
|
notInList: "Value must be from the existing list"
|
|
1048
|
-
}),
|
|
1049
|
+
}), k.register("ko", {
|
|
1049
1050
|
showHiddenColumns: "숨긴 열 보기",
|
|
1050
1051
|
columnMenu: "열 메뉴",
|
|
1051
1052
|
cellActions: "셀 작업",
|
|
@@ -1099,12 +1100,13 @@ O.register("en", {
|
|
|
1099
1100
|
booleanFalse: "거짓",
|
|
1100
1101
|
dropFileToImport: "가져올 파일을 놓으세요 (.xlsx / .csv)",
|
|
1101
1102
|
notANumber: "숫자를 입력하세요",
|
|
1103
|
+
notADate: "날짜를 YYYY-MM-DD 로 입력하세요",
|
|
1102
1104
|
notInList: "목록에 있는 값이어야 합니다"
|
|
1103
1105
|
});
|
|
1104
|
-
var
|
|
1106
|
+
var A = (e, t) => k.text(e, t);
|
|
1105
1107
|
//#endregion
|
|
1106
1108
|
//#region src/core/selection.ts
|
|
1107
|
-
function
|
|
1109
|
+
function te(e) {
|
|
1108
1110
|
return {
|
|
1109
1111
|
startRow: Math.min(e.startRow, e.endRow),
|
|
1110
1112
|
startCol: Math.min(e.startCol, e.endCol),
|
|
@@ -1112,7 +1114,7 @@ function ee(e) {
|
|
|
1112
1114
|
endCol: Math.max(e.startCol, e.endCol)
|
|
1113
1115
|
};
|
|
1114
1116
|
}
|
|
1115
|
-
var
|
|
1117
|
+
var ne = class {
|
|
1116
1118
|
constructor() {
|
|
1117
1119
|
this.activeCell = null, this.rangeAnchor = null, this.range = null, this.extraRanges = [], this._rowCount = 0, this._colCount = 0;
|
|
1118
1120
|
}
|
|
@@ -1139,7 +1141,7 @@ var te = class {
|
|
|
1139
1141
|
return e < 0 || e >= this._rowCount || t < 0 || t >= this._colCount ? this.activeCell : (!this.rangeAnchor && this.activeCell && (this.rangeAnchor = { ...this.activeCell }), this.activeCell = {
|
|
1140
1142
|
row: e,
|
|
1141
1143
|
col: t
|
|
1142
|
-
}, this.rangeAnchor && (this.range =
|
|
1144
|
+
}, this.rangeAnchor && (this.range = te({
|
|
1143
1145
|
startRow: this.rangeAnchor.row,
|
|
1144
1146
|
startCol: this.rangeAnchor.col,
|
|
1145
1147
|
endRow: e,
|
|
@@ -1210,7 +1212,7 @@ var te = class {
|
|
|
1210
1212
|
shiftMoveRight() {
|
|
1211
1213
|
return this.activeCell ? this.setActiveWithRange(this.activeCell.row, this.activeCell.col + 1) : null;
|
|
1212
1214
|
}
|
|
1213
|
-
},
|
|
1215
|
+
}, re = class {
|
|
1214
1216
|
constructor() {
|
|
1215
1217
|
this.current = null;
|
|
1216
1218
|
}
|
|
@@ -1231,7 +1233,7 @@ var te = class {
|
|
|
1231
1233
|
let e = this.current;
|
|
1232
1234
|
return this.current = null, e;
|
|
1233
1235
|
}
|
|
1234
|
-
},
|
|
1236
|
+
}, j = class {
|
|
1235
1237
|
constructor() {
|
|
1236
1238
|
this._selected = /* @__PURE__ */ new Set(), this._mode = "multi", this._rowCount = 0;
|
|
1237
1239
|
}
|
|
@@ -1292,7 +1294,7 @@ var te = class {
|
|
|
1292
1294
|
};
|
|
1293
1295
|
//#endregion
|
|
1294
1296
|
//#region src/core/filtering.ts
|
|
1295
|
-
function
|
|
1297
|
+
function ie(e, t, n) {
|
|
1296
1298
|
if (t.length === 0) return Array.from({ length: e.length }, (e, t) => t);
|
|
1297
1299
|
let r = [];
|
|
1298
1300
|
for (let i = 0; i < e.length; i++) {
|
|
@@ -1311,9 +1313,9 @@ function re(e, t, n) {
|
|
|
1311
1313
|
}
|
|
1312
1314
|
//#endregion
|
|
1313
1315
|
//#region src/core/undo.ts
|
|
1314
|
-
var
|
|
1316
|
+
var ae = 100, M = class {
|
|
1315
1317
|
constructor() {
|
|
1316
|
-
this._undoStack = [], this._redoStack = [], this._maxSize =
|
|
1318
|
+
this._undoStack = [], this._redoStack = [], this._maxSize = ae;
|
|
1317
1319
|
}
|
|
1318
1320
|
get maxSize() {
|
|
1319
1321
|
return this._maxSize;
|
|
@@ -1350,7 +1352,7 @@ var ie = 100, j = class {
|
|
|
1350
1352
|
};
|
|
1351
1353
|
//#endregion
|
|
1352
1354
|
//#region src/clipboard/clipboard.ts
|
|
1353
|
-
function
|
|
1355
|
+
function oe(e, t, n) {
|
|
1354
1356
|
let r = [];
|
|
1355
1357
|
for (let i = n.startRow; i <= n.endRow; i++) {
|
|
1356
1358
|
let a = e[i], o = [];
|
|
@@ -1360,30 +1362,37 @@ function ae(e, t, n) {
|
|
|
1360
1362
|
}
|
|
1361
1363
|
r.push(o);
|
|
1362
1364
|
}
|
|
1363
|
-
return
|
|
1365
|
+
return g(r);
|
|
1364
1366
|
}
|
|
1365
|
-
function
|
|
1367
|
+
function N(e, t) {
|
|
1366
1368
|
if (e === "") return null;
|
|
1367
1369
|
switch (t.type) {
|
|
1368
1370
|
case "number": {
|
|
1369
|
-
let t =
|
|
1371
|
+
let t = m(e);
|
|
1370
1372
|
if (t !== null) return t;
|
|
1371
1373
|
let n = Number(e.trim());
|
|
1372
1374
|
return e.trim() !== "" && Number.isFinite(n) ? n : e;
|
|
1373
1375
|
}
|
|
1374
1376
|
case "boolean": return e.toLowerCase() === "true" || e === "1";
|
|
1377
|
+
case "date": return p(e) ?? e;
|
|
1375
1378
|
default: return e;
|
|
1376
1379
|
}
|
|
1377
1380
|
}
|
|
1378
|
-
function
|
|
1381
|
+
function P(e) {
|
|
1379
1382
|
let t = String(e);
|
|
1380
1383
|
if (!Number.isFinite(e) || t.includes("e")) return t;
|
|
1381
1384
|
let n = new Intl.NumberFormat(l.get()).formatToParts(1.5).find((e) => e.type === "decimal")?.value;
|
|
1382
1385
|
return n && n !== "." ? t.replace(".", n) : t;
|
|
1383
1386
|
}
|
|
1387
|
+
function se(e) {
|
|
1388
|
+
if (e == null || e === "") return "";
|
|
1389
|
+
if (e instanceof Date) return Number.isNaN(e.getTime()) ? "" : `${e.getFullYear()}-${String(e.getMonth() + 1).padStart(2, "0")}-${String(e.getDate()).padStart(2, "0")}`;
|
|
1390
|
+
let t = String(e), n = /^(\d{4}-\d{2}-\d{2})(?:$|T)/.exec(t);
|
|
1391
|
+
return n ? n[1] : t;
|
|
1392
|
+
}
|
|
1384
1393
|
//#endregion
|
|
1385
1394
|
//#region src/export/xlsx-writer.ts
|
|
1386
|
-
var
|
|
1395
|
+
var ce = (() => {
|
|
1387
1396
|
let e = /* @__PURE__ */ new Uint32Array(256);
|
|
1388
1397
|
for (let t = 0; t < 256; t++) {
|
|
1389
1398
|
let n = t;
|
|
@@ -1392,56 +1401,56 @@ var oe = (() => {
|
|
|
1392
1401
|
}
|
|
1393
1402
|
return e;
|
|
1394
1403
|
})();
|
|
1395
|
-
function
|
|
1404
|
+
function le(e) {
|
|
1396
1405
|
let t = 4294967295;
|
|
1397
|
-
for (let n = 0; n < e.length; n++) t =
|
|
1406
|
+
for (let n = 0; n < e.length; n++) t = ce[(t ^ e[n]) & 255] ^ t >>> 8;
|
|
1398
1407
|
return (t ^ 4294967295) >>> 0;
|
|
1399
1408
|
}
|
|
1400
|
-
var
|
|
1401
|
-
function
|
|
1409
|
+
var F = new TextEncoder();
|
|
1410
|
+
function ue(e) {
|
|
1402
1411
|
let t = [], n = [], r = 0;
|
|
1403
1412
|
for (let i of e) {
|
|
1404
|
-
let e =
|
|
1413
|
+
let e = F.encode(i.name), a = le(i.data), o = i.data.length, s = new ArrayBuffer(30 + e.length), c = new DataView(s);
|
|
1405
1414
|
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);
|
|
1406
1415
|
let l = new ArrayBuffer(46 + e.length), u = new DataView(l);
|
|
1407
1416
|
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;
|
|
1408
1417
|
}
|
|
1409
|
-
let i =
|
|
1410
|
-
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),
|
|
1418
|
+
let i = I(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
|
|
1419
|
+
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), I([
|
|
1411
1420
|
...t,
|
|
1412
1421
|
i,
|
|
1413
1422
|
new Uint8Array(a)
|
|
1414
1423
|
]);
|
|
1415
1424
|
}
|
|
1416
|
-
function
|
|
1425
|
+
function I(e) {
|
|
1417
1426
|
let t = e.reduce((e, t) => e + t.length, 0), n = new Uint8Array(t), r = 0;
|
|
1418
1427
|
for (let t of e) n.set(t, r), r += t.length;
|
|
1419
1428
|
return n;
|
|
1420
1429
|
}
|
|
1421
|
-
function
|
|
1430
|
+
function L(e) {
|
|
1422
1431
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1423
1432
|
}
|
|
1424
|
-
function
|
|
1433
|
+
function de(e) {
|
|
1425
1434
|
let t = "";
|
|
1426
1435
|
for (e++; e > 0;) t = String.fromCharCode(64 + (e % 26 || 26)) + t, e = Math.floor((e - 1) / 26);
|
|
1427
1436
|
return t;
|
|
1428
1437
|
}
|
|
1429
|
-
function
|
|
1430
|
-
return
|
|
1438
|
+
function R(e, t) {
|
|
1439
|
+
return de(t) + (e + 1);
|
|
1431
1440
|
}
|
|
1432
|
-
function
|
|
1441
|
+
function fe(e) {
|
|
1433
1442
|
let t = Date.UTC(1899, 11, 30);
|
|
1434
1443
|
return (e.getTime() - t) / 864e5;
|
|
1435
1444
|
}
|
|
1436
|
-
var
|
|
1437
|
-
function
|
|
1438
|
-
let n = [], r = t.map((e, t) => `<c r="${
|
|
1445
|
+
var pe = "<?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>", me = "<?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>", z = "<?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>", he = "<?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>", ge = "<?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>";
|
|
1446
|
+
function _e(e, t) {
|
|
1447
|
+
let n = [], r = t.map((e, t) => `<c r="${R(0, t)}" t="str" s="2"><v>${L(e.label)}</v></c>`);
|
|
1439
1448
|
return n.push(`<row r="1">${r.join("")}</row>`), e.forEach((e, r) => {
|
|
1440
1449
|
let i = t.map((t, n) => {
|
|
1441
|
-
let i =
|
|
1450
|
+
let i = R(r + 1, n), a = e[t.key];
|
|
1442
1451
|
if (a == null) return `<c r="${i}" t="str"><v></v></c>`;
|
|
1443
1452
|
let o = t.type ?? "text";
|
|
1444
|
-
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>${
|
|
1453
|
+
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>${fe(a).toFixed(6)}</v></c>` : o === "boolean" ? `<c r="${i}" t="b"><v>${+!!a}</v></c>` : `<c r="${i}" t="str"><v>${L(String(a))}</v></c>`;
|
|
1445
1454
|
});
|
|
1446
1455
|
n.push(`<row r="${r + 2}">${i.join("")}</row>`);
|
|
1447
1456
|
}), `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
@@ -1449,32 +1458,32 @@ function z(e, t) {
|
|
|
1449
1458
|
<sheetData>${n.join("")}</sheetData>
|
|
1450
1459
|
</worksheet>`;
|
|
1451
1460
|
}
|
|
1452
|
-
function
|
|
1453
|
-
let n =
|
|
1454
|
-
return
|
|
1461
|
+
function ve(e, t) {
|
|
1462
|
+
let n = _e(e, t);
|
|
1463
|
+
return ue([
|
|
1455
1464
|
{
|
|
1456
1465
|
name: "[Content_Types].xml",
|
|
1457
|
-
data:
|
|
1466
|
+
data: F.encode(pe)
|
|
1458
1467
|
},
|
|
1459
1468
|
{
|
|
1460
1469
|
name: "_rels/.rels",
|
|
1461
|
-
data:
|
|
1470
|
+
data: F.encode(me)
|
|
1462
1471
|
},
|
|
1463
1472
|
{
|
|
1464
1473
|
name: "xl/workbook.xml",
|
|
1465
|
-
data:
|
|
1474
|
+
data: F.encode(z)
|
|
1466
1475
|
},
|
|
1467
1476
|
{
|
|
1468
1477
|
name: "xl/_rels/workbook.xml.rels",
|
|
1469
|
-
data:
|
|
1478
|
+
data: F.encode(he)
|
|
1470
1479
|
},
|
|
1471
1480
|
{
|
|
1472
1481
|
name: "xl/worksheets/sheet1.xml",
|
|
1473
|
-
data:
|
|
1482
|
+
data: F.encode(n)
|
|
1474
1483
|
},
|
|
1475
1484
|
{
|
|
1476
1485
|
name: "xl/styles.xml",
|
|
1477
|
-
data:
|
|
1486
|
+
data: F.encode(ge)
|
|
1478
1487
|
}
|
|
1479
1488
|
]);
|
|
1480
1489
|
}
|
|
@@ -1484,20 +1493,20 @@ function B(e, t, n) {
|
|
|
1484
1493
|
switch (n) {
|
|
1485
1494
|
case "csv": return V(e, t, ",");
|
|
1486
1495
|
case "tsv": return V(e, t, " ");
|
|
1487
|
-
case "json": return
|
|
1488
|
-
case "xlsx": return
|
|
1496
|
+
case "json": return be(e, t);
|
|
1497
|
+
case "xlsx": return ve(e, t);
|
|
1489
1498
|
}
|
|
1490
1499
|
}
|
|
1491
|
-
function
|
|
1500
|
+
function ye(e, t) {
|
|
1492
1501
|
return e == null ? "" : (t.type === "date" || t.type === "datetime") && e instanceof Date ? e.toISOString() : String(e);
|
|
1493
1502
|
}
|
|
1494
1503
|
function V(e, t, n) {
|
|
1495
|
-
return [t.map((e) => H(e.label, n)).join(n), ...e.map((e) => t.map((t) => H(
|
|
1504
|
+
return [t.map((e) => H(e.label, n)).join(n), ...e.map((e) => t.map((t) => H(ye(e[t.key], t), n)).join(n))].join("\n");
|
|
1496
1505
|
}
|
|
1497
1506
|
function H(e, t) {
|
|
1498
1507
|
return e.includes(t) || e.includes("\"") || e.includes("\n") || e.includes("\r") ? "\"" + e.replace(/"/g, "\"\"") + "\"" : e;
|
|
1499
1508
|
}
|
|
1500
|
-
function
|
|
1509
|
+
function be(e, t) {
|
|
1501
1510
|
let n = e.map((e) => {
|
|
1502
1511
|
let n = {};
|
|
1503
1512
|
for (let r of t) {
|
|
@@ -1508,35 +1517,35 @@ function _e(e, t) {
|
|
|
1508
1517
|
});
|
|
1509
1518
|
return JSON.stringify(n, null, 2);
|
|
1510
1519
|
}
|
|
1511
|
-
function
|
|
1520
|
+
function xe(e, t, n) {
|
|
1512
1521
|
let r = new Blob([e], { type: n }), i = URL.createObjectURL(r), a = document.createElement("a");
|
|
1513
1522
|
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);
|
|
1514
1523
|
}
|
|
1515
|
-
var
|
|
1524
|
+
var Se = {
|
|
1516
1525
|
csv: "text/csv;charset=utf-8",
|
|
1517
1526
|
tsv: "text/tab-separated-values;charset=utf-8",
|
|
1518
1527
|
json: "application/json;charset=utf-8",
|
|
1519
1528
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
1520
|
-
},
|
|
1529
|
+
}, Ce = {
|
|
1521
1530
|
csv: ".csv",
|
|
1522
1531
|
tsv: ".tsv",
|
|
1523
1532
|
json: ".json",
|
|
1524
1533
|
xlsx: ".xlsx"
|
|
1525
1534
|
};
|
|
1526
|
-
function
|
|
1527
|
-
return
|
|
1535
|
+
function we(e) {
|
|
1536
|
+
return Se[e];
|
|
1528
1537
|
}
|
|
1529
|
-
function
|
|
1530
|
-
return
|
|
1538
|
+
function Te(e) {
|
|
1539
|
+
return Ce[e];
|
|
1531
1540
|
}
|
|
1532
1541
|
//#endregion
|
|
1533
1542
|
//#region src/export/xlsx-reader.ts
|
|
1534
|
-
function
|
|
1543
|
+
function Ee(e) {
|
|
1535
1544
|
for (let t = e.byteLength - 22; t >= 0; t--) if (e.getUint32(t, !0) === 101010256) return t;
|
|
1536
1545
|
throw Error("XLSX: End of central directory not found — not a valid ZIP file");
|
|
1537
1546
|
}
|
|
1538
|
-
function
|
|
1539
|
-
let t =
|
|
1547
|
+
function De(e) {
|
|
1548
|
+
let t = Ee(e), n = e.getUint32(t + 16, !0), r = e.getUint32(t + 12, !0), i = new TextDecoder("utf-8"), a = [], o = n, s = n + r;
|
|
1540
1549
|
for (; o < s && e.getUint32(o, !0) === 33639248;) {
|
|
1541
1550
|
let t = e.getUint16(o + 10, !0), n = e.getUint32(o + 20, !0), r = e.getUint32(o + 24, !0), s = e.getUint16(o + 28, !0), c = e.getUint16(o + 30, !0), l = e.getUint16(o + 32, !0), u = e.getUint32(o + 42, !0), d = i.decode(new Uint8Array(e.buffer, o + 46, s));
|
|
1542
1551
|
a.push({
|
|
@@ -1549,7 +1558,7 @@ function we(e) {
|
|
|
1549
1558
|
}
|
|
1550
1559
|
return a;
|
|
1551
1560
|
}
|
|
1552
|
-
async function
|
|
1561
|
+
async function Oe(e) {
|
|
1553
1562
|
let t = new DecompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
|
|
1554
1563
|
n.write(e), n.close();
|
|
1555
1564
|
let i = [];
|
|
@@ -1562,28 +1571,28 @@ async function Te(e) {
|
|
|
1562
1571
|
for (let e of i) o.set(e, s), s += e.length;
|
|
1563
1572
|
return o;
|
|
1564
1573
|
}
|
|
1565
|
-
async function
|
|
1574
|
+
async function ke(e, t) {
|
|
1566
1575
|
let n = t.localHeaderOffset, r = e.getUint16(n + 26, !0), i = e.getUint16(n + 28, !0), a = n + 30 + r + i, o = new Uint8Array(e.buffer, a, t.compressedSize);
|
|
1567
1576
|
if (t.compressionMethod === 0) return o.slice();
|
|
1568
|
-
if (t.compressionMethod === 8) return
|
|
1577
|
+
if (t.compressionMethod === 8) return Oe(o);
|
|
1569
1578
|
throw Error(`XLSX: Unsupported compression method ${t.compressionMethod}`);
|
|
1570
1579
|
}
|
|
1571
|
-
async function
|
|
1572
|
-
let t = new DataView(e), n =
|
|
1573
|
-
for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await
|
|
1580
|
+
async function Ae(e) {
|
|
1581
|
+
let t = new DataView(e), n = De(t), r = /* @__PURE__ */ new Map();
|
|
1582
|
+
for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await ke(t, e));
|
|
1574
1583
|
return r;
|
|
1575
1584
|
}
|
|
1576
|
-
var
|
|
1585
|
+
var je = new TextDecoder("utf-8");
|
|
1577
1586
|
function U(e) {
|
|
1578
|
-
let t =
|
|
1587
|
+
let t = je.decode(e);
|
|
1579
1588
|
return new DOMParser().parseFromString(t, "application/xml");
|
|
1580
1589
|
}
|
|
1581
|
-
function
|
|
1590
|
+
function Me(e) {
|
|
1582
1591
|
if (!e) return [];
|
|
1583
1592
|
let t = U(e);
|
|
1584
1593
|
return Array.from(t.querySelectorAll("si")).map((e) => Array.from(e.querySelectorAll("t")).map((e) => e.textContent ?? "").join(""));
|
|
1585
1594
|
}
|
|
1586
|
-
var
|
|
1595
|
+
var Ne = /* @__PURE__ */ new Set([
|
|
1587
1596
|
14,
|
|
1588
1597
|
15,
|
|
1589
1598
|
16,
|
|
@@ -1603,29 +1612,29 @@ var Ae = /* @__PURE__ */ new Set([
|
|
|
1603
1612
|
57,
|
|
1604
1613
|
58
|
|
1605
1614
|
]);
|
|
1606
|
-
function
|
|
1615
|
+
function Pe(e) {
|
|
1607
1616
|
let t = e.replace(/"[^"]*"/g, "").replace(/\\./g, "").replace(/\[[^\]]*\]/g, "").split(";")[0];
|
|
1608
1617
|
return /[dy]/i.test(t);
|
|
1609
1618
|
}
|
|
1610
|
-
function
|
|
1619
|
+
function Fe(e) {
|
|
1611
1620
|
let t = /* @__PURE__ */ new Set();
|
|
1612
1621
|
if (!e) return t;
|
|
1613
1622
|
let n = U(e), r = /* @__PURE__ */ new Map();
|
|
1614
1623
|
for (let e of Array.from(n.querySelectorAll("numFmts > numFmt"))) r.set(parseInt(e.getAttribute("numFmtId") ?? "", 10), e.getAttribute("formatCode") ?? "");
|
|
1615
1624
|
return Array.from(n.querySelectorAll("cellXfs > xf")).forEach((e, n) => {
|
|
1616
1625
|
let i = parseInt(e.getAttribute("numFmtId") ?? "0", 10), a = r.get(i);
|
|
1617
|
-
(a === void 0 ?
|
|
1626
|
+
(a === void 0 ? Ne.has(i) : Pe(a)) && t.add(n);
|
|
1618
1627
|
}), t;
|
|
1619
1628
|
}
|
|
1620
|
-
function
|
|
1629
|
+
function Ie(e) {
|
|
1621
1630
|
if (!e) return !1;
|
|
1622
1631
|
let t = U(e).querySelector("workbookPr")?.getAttribute("date1904");
|
|
1623
1632
|
return t === "1" || t === "true";
|
|
1624
1633
|
}
|
|
1625
|
-
function
|
|
1634
|
+
function W(e, t) {
|
|
1626
1635
|
return new Date((t ? Date.UTC(1904, 0, 1) : Date.UTC(1899, 11, 30)) + Math.floor(e) * 864e5).toISOString().slice(0, 10);
|
|
1627
1636
|
}
|
|
1628
|
-
function
|
|
1637
|
+
function Le(e, t, n, r) {
|
|
1629
1638
|
let i = U(e).querySelectorAll("row");
|
|
1630
1639
|
if (i.length === 0) return [];
|
|
1631
1640
|
let a = 0, o = /* @__PURE__ */ new Map();
|
|
@@ -1633,7 +1642,7 @@ function Fe(e, t, n, r) {
|
|
|
1633
1642
|
let i = parseInt(e.getAttribute("r") ?? "1", 10) - 1, s = /* @__PURE__ */ new Map();
|
|
1634
1643
|
o.set(i, s);
|
|
1635
1644
|
for (let i of e.querySelectorAll("c")) {
|
|
1636
|
-
let e =
|
|
1645
|
+
let e = Re(i.getAttribute("r") ?? "");
|
|
1637
1646
|
e > a && (a = e);
|
|
1638
1647
|
let o = i.getAttribute("t") ?? "", c = i.getAttribute("s") ?? "", l = i.querySelector("v")?.textContent ?? "", u = i.querySelector("is > t")?.textContent ?? null, d;
|
|
1639
1648
|
if (o === "s") d = t[parseInt(l, 10)] ?? "";
|
|
@@ -1642,7 +1651,7 @@ function Fe(e, t, n, r) {
|
|
|
1642
1651
|
else if (l === "") d = "";
|
|
1643
1652
|
else {
|
|
1644
1653
|
let e = parseFloat(l);
|
|
1645
|
-
d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ?
|
|
1654
|
+
d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ? W(e, r) : l;
|
|
1646
1655
|
}
|
|
1647
1656
|
s.set(e, d);
|
|
1648
1657
|
}
|
|
@@ -1656,13 +1665,13 @@ function Fe(e, t, n, r) {
|
|
|
1656
1665
|
}
|
|
1657
1666
|
return c;
|
|
1658
1667
|
}
|
|
1659
|
-
function
|
|
1668
|
+
function Re(e) {
|
|
1660
1669
|
let t = 0, n = 0;
|
|
1661
1670
|
for (; n < e.length && e[n] >= "A" && e[n] <= "Z";) t = t * 26 + (e.charCodeAt(n) - 64), n++;
|
|
1662
1671
|
return t - 1;
|
|
1663
1672
|
}
|
|
1664
|
-
async function
|
|
1665
|
-
let t = await
|
|
1673
|
+
async function ze(e) {
|
|
1674
|
+
let t = await Ae(e), n = Me(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
|
|
1666
1675
|
if (!r) {
|
|
1667
1676
|
for (let [e, n] of t) if (e.toLowerCase().includes("worksheets/sheet")) {
|
|
1668
1677
|
r = n;
|
|
@@ -1670,7 +1679,7 @@ async function W(e) {
|
|
|
1670
1679
|
}
|
|
1671
1680
|
}
|
|
1672
1681
|
if (!r) throw Error("XLSX: No worksheet found");
|
|
1673
|
-
let i =
|
|
1682
|
+
let i = Fe(t.get("xl/styles.xml")), a = Ie(t.get("xl/workbook.xml")), o = Le(r, n, i, a);
|
|
1674
1683
|
return o.length === 0 ? {
|
|
1675
1684
|
headers: [],
|
|
1676
1685
|
rows: []
|
|
@@ -1701,14 +1710,14 @@ var q = {
|
|
|
1701
1710
|
lt: "<",
|
|
1702
1711
|
gte: "≥",
|
|
1703
1712
|
lte: "≤"
|
|
1704
|
-
}, J = 120, Y = 40, X = 20, Z = 32, Q = 5,
|
|
1713
|
+
}, J = 120, Y = 40, X = 20, Z = 32, Q = 5, Be = 200, $ = class extends n {
|
|
1705
1714
|
constructor(...e) {
|
|
1706
|
-
super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = Z, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "No data", this.noMatchingMessage = "No matching data", this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new
|
|
1715
|
+
super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = Z, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "No data", this.noMatchingMessage = "No matching data", this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new ne(), this._editing = new re(), this._rowSelection = new j(), this._undo = new M(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._lastCheckboxRowIndex = null, this._checkboxShiftPending = !1, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._commentPopup = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._wasHeaderDrag = !1, this._wasRowDrag = !1, 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._comments = /* @__PURE__ */ new Map(), this._isDragOver = !1, this._warnedUnconstrained = !1, this._onCommentPopupOutsideClick = () => {
|
|
1707
1716
|
this._commitCommentPopup();
|
|
1708
1717
|
}, 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();
|
|
1709
1718
|
}
|
|
1710
1719
|
static {
|
|
1711
|
-
this.styles =
|
|
1720
|
+
this.styles = v;
|
|
1712
1721
|
}
|
|
1713
1722
|
get data() {
|
|
1714
1723
|
return this._data;
|
|
@@ -2073,7 +2082,7 @@ var q = {
|
|
|
2073
2082
|
return B(this._sortedIndices.map((e) => this.data[e]), this.visibleColumns, e);
|
|
2074
2083
|
}
|
|
2075
2084
|
exportToFile(e, t) {
|
|
2076
|
-
|
|
2085
|
+
xe(this.exportToString(e), t ?? `export${Te(e)}`, we(e));
|
|
2077
2086
|
}
|
|
2078
2087
|
setComment(e, t, n) {
|
|
2079
2088
|
let r = this.getComment(e, t);
|
|
@@ -2130,10 +2139,10 @@ var q = {
|
|
|
2130
2139
|
async importFromFile(e) {
|
|
2131
2140
|
let t = e.name.toLowerCase();
|
|
2132
2141
|
if (t.endsWith(".xlsx")) {
|
|
2133
|
-
let t = await
|
|
2142
|
+
let t = await ze(await e.arrayBuffer());
|
|
2134
2143
|
this._applyImportedSheet(t);
|
|
2135
2144
|
} else if (t.endsWith(".csv") || t.endsWith(".tsv")) {
|
|
2136
|
-
let t = await e.text(), n =
|
|
2145
|
+
let t = await e.text(), n = h(t);
|
|
2137
2146
|
this._applyImportedRows(n);
|
|
2138
2147
|
} else console.warn(`flex-table importFromFile: unsupported file type "${e.name}"`);
|
|
2139
2148
|
}
|
|
@@ -2144,7 +2153,7 @@ var q = {
|
|
|
2144
2153
|
let a = t.get(e);
|
|
2145
2154
|
if (!a) return;
|
|
2146
2155
|
let o = this.columns.find((e) => e.key === a);
|
|
2147
|
-
r[a] = o ?
|
|
2156
|
+
r[a] = o ? N(n[i] ?? "", o) : n[i] ?? null;
|
|
2148
2157
|
}), r;
|
|
2149
2158
|
}), r = [...this.data];
|
|
2150
2159
|
this.data = n, this._undo.push({
|
|
@@ -2169,7 +2178,7 @@ var q = {
|
|
|
2169
2178
|
let a = n.get(t);
|
|
2170
2179
|
if (!a) return;
|
|
2171
2180
|
let o = this.columns.find((e) => e.key === a);
|
|
2172
|
-
r[a] = o ?
|
|
2181
|
+
r[a] = o ? N(e[i] ?? "", o) : e[i] ?? null;
|
|
2173
2182
|
}), r;
|
|
2174
2183
|
}), i = [...this.data];
|
|
2175
2184
|
this.data = r, this._undo.push({
|
|
@@ -2323,7 +2332,7 @@ var q = {
|
|
|
2323
2332
|
this._filteredIndices = Array.from({ length: this.data.length }, (e, t) => t), this._sortedIndices = this._filteredIndices;
|
|
2324
2333
|
return;
|
|
2325
2334
|
}
|
|
2326
|
-
if (this._filteredIndices =
|
|
2335
|
+
if (this._filteredIndices = ie(this.data, this._filters, (e, t, n) => {
|
|
2327
2336
|
this.dispatchEvent(new CustomEvent("filter-error", {
|
|
2328
2337
|
detail: {
|
|
2329
2338
|
error: e,
|
|
@@ -2353,7 +2362,7 @@ var q = {
|
|
|
2353
2362
|
e !== this._viewportHeight && (this._viewportHeight = e), t !== this._viewportWidth && (this._viewportWidth = t), this._warnIfUnconstrained();
|
|
2354
2363
|
}
|
|
2355
2364
|
_warnIfUnconstrained() {
|
|
2356
|
-
this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount <
|
|
2365
|
+
this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount < Be || this.scrollHeight > this.clientHeight + 1 || (this._warnedUnconstrained = !0, console.warn(`[@iyulab/flex-table] ${this._visibleRowCount} rows but the host has no height constraint — it grew to fit every row, so virtual scrolling is off and all rows are rendered. Give the host a height (e.g. height: 400px, or flex: 1 1 auto with min-height: 0 inside a sized parent) so it becomes the scroll container.`));
|
|
2357
2366
|
}
|
|
2358
2367
|
_onScroll() {
|
|
2359
2368
|
this._scrollTop = this.scrollTop, this._scrollLeft = this.scrollLeft;
|
|
@@ -2483,7 +2492,7 @@ var q = {
|
|
|
2483
2492
|
}
|
|
2484
2493
|
let t = this.shadowRoot?.querySelector(".ft-editor");
|
|
2485
2494
|
if (t) {
|
|
2486
|
-
let n =
|
|
2495
|
+
let n = N(t.value, e);
|
|
2487
2496
|
this._applyEdit(n);
|
|
2488
2497
|
} else this._cancelEdit();
|
|
2489
2498
|
}
|
|
@@ -2493,7 +2502,7 @@ var q = {
|
|
|
2493
2502
|
if (this._editingCell = null, !t) return;
|
|
2494
2503
|
let { row: n, col: r } = t.position, i = this._toDataIndex(n), a = this.visibleColumns[r], o = t.originalValue;
|
|
2495
2504
|
if (a.autocomplete === "strict" && e != null && e !== "" && !this._getAutocompleteCandidates(a, "").includes(String(e))) {
|
|
2496
|
-
let t =
|
|
2505
|
+
let t = A("notInList");
|
|
2497
2506
|
this._markCellInvalid(n, r, t), this.dispatchEvent(new CustomEvent("validation-error", {
|
|
2498
2507
|
detail: {
|
|
2499
2508
|
row: i,
|
|
@@ -2507,8 +2516,8 @@ var q = {
|
|
|
2507
2516
|
}));
|
|
2508
2517
|
return;
|
|
2509
2518
|
}
|
|
2510
|
-
if (a.type === "number" && typeof e == "string") {
|
|
2511
|
-
let t =
|
|
2519
|
+
if (a.type === "number" && typeof e == "string" || a.type === "date" && typeof e == "string" && p(e) === null) {
|
|
2520
|
+
let t = A(a.type === "number" ? "notANumber" : "notADate");
|
|
2512
2521
|
this._markCellInvalid(n, r, t), this.dispatchEvent(new CustomEvent("validation-error", {
|
|
2513
2522
|
detail: {
|
|
2514
2523
|
row: i,
|
|
@@ -2572,7 +2581,7 @@ var q = {
|
|
|
2572
2581
|
}));
|
|
2573
2582
|
}
|
|
2574
2583
|
_onEditorKeyDown(e) {
|
|
2575
|
-
if (!
|
|
2584
|
+
if (!_(e)) {
|
|
2576
2585
|
if (this._autocompleteState && this._autocompleteState.candidates.length > 0) {
|
|
2577
2586
|
if (e.key === "ArrowDown") {
|
|
2578
2587
|
e.preventDefault(), e.stopPropagation();
|
|
@@ -2640,7 +2649,7 @@ var q = {
|
|
|
2640
2649
|
].includes(t) && this._handleCtrlKey(e)) return;
|
|
2641
2650
|
}
|
|
2642
2651
|
if (t.length !== 0 && this._visibleRowCount !== 0) {
|
|
2643
|
-
if ((e.key === "Enter" || e.key === "F2") && this._activeCell && !
|
|
2652
|
+
if ((e.key === "Enter" || e.key === "F2") && this._activeCell && !_(e)) {
|
|
2644
2653
|
e.preventDefault();
|
|
2645
2654
|
let n = t[this._activeCell.col];
|
|
2646
2655
|
n && this._isCellEditable(n) ? this._startEdit() : e.key === "Enter" && this._fireRowActivate(n);
|
|
@@ -2728,7 +2737,7 @@ var q = {
|
|
|
2728
2737
|
async _handleCopy(e) {
|
|
2729
2738
|
let t = this._selection.getEffectiveRange();
|
|
2730
2739
|
if (!t) return;
|
|
2731
|
-
let n = this.visibleColumns, r =
|
|
2740
|
+
let n = this.visibleColumns, r = oe(this._sortedIndices.map((e) => this.data[e]), n, t);
|
|
2732
2741
|
try {
|
|
2733
2742
|
await navigator.clipboard.writeText(r);
|
|
2734
2743
|
} catch (e) {
|
|
@@ -2754,7 +2763,7 @@ var q = {
|
|
|
2754
2763
|
if (!this._activeCell) return;
|
|
2755
2764
|
let e = await this._readClipboardText();
|
|
2756
2765
|
if (e == null) return;
|
|
2757
|
-
let t =
|
|
2766
|
+
let t = h(e);
|
|
2758
2767
|
if (t.length === 0) return;
|
|
2759
2768
|
let n = this._expandRowsForPaste(this._activeCell.row, t.length), r = this._applyPasteData(this._activeCell, t);
|
|
2760
2769
|
if (r.length > 0 || n.length > 0) {
|
|
@@ -2812,7 +2821,7 @@ var q = {
|
|
|
2812
2821
|
for (let a = 0; a < t[i].length; a++) {
|
|
2813
2822
|
let s = e.col + a;
|
|
2814
2823
|
if (s >= n.length) break;
|
|
2815
|
-
let c = n[s], l = this.data[o][c.key], u =
|
|
2824
|
+
let c = n[s], l = this.data[o][c.key], u = N(t[i][a], c);
|
|
2816
2825
|
this.data[o][c.key] = u, r.push({
|
|
2817
2826
|
row: o,
|
|
2818
2827
|
col: s,
|
|
@@ -2877,7 +2886,7 @@ var q = {
|
|
|
2877
2886
|
for (let r = e.startCol + 1; r <= e.endCol; r++) {
|
|
2878
2887
|
let e = t[r];
|
|
2879
2888
|
if (!e || !this._isCellEditable(e)) continue;
|
|
2880
|
-
let a =
|
|
2889
|
+
let a = N(o == null ? "" : String(o), e);
|
|
2881
2890
|
n.push({
|
|
2882
2891
|
row: i,
|
|
2883
2892
|
key: e.key,
|
|
@@ -3037,7 +3046,7 @@ var q = {
|
|
|
3037
3046
|
@click=${n ? (t) => this._onHeaderClick(t, e) : void 0}>
|
|
3038
3047
|
${C ? i`
|
|
3039
3048
|
<button class="ft-hidden-col-indicator"
|
|
3040
|
-
title=${
|
|
3049
|
+
title=${A("showHiddenColumns")}
|
|
3041
3050
|
@click=${(t) => {
|
|
3042
3051
|
t.stopPropagation(), this._showHiddenBefore(e);
|
|
3043
3052
|
}}>❯</button>
|
|
@@ -3047,8 +3056,8 @@ var q = {
|
|
|
3047
3056
|
${o >= 0 ? i`<span class="ft-sort-order">${o + 1}</span>` : ""}
|
|
3048
3057
|
<button class="ft-column-menu-btn ${s ? "ft-filter-active" : ""}"
|
|
3049
3058
|
type="button"
|
|
3050
|
-
title=${
|
|
3051
|
-
aria-label=${
|
|
3059
|
+
title=${A("columnMenu")}
|
|
3060
|
+
aria-label=${A("columnMenuFor", { header: e.label })}
|
|
3052
3061
|
aria-haspopup="menu"
|
|
3053
3062
|
aria-expanded=${this._headerMenu?.key === e.key ? "true" : "false"}
|
|
3054
3063
|
@mousedown=${(e) => e.stopPropagation()}
|
|
@@ -3167,26 +3176,26 @@ var q = {
|
|
|
3167
3176
|
}}>${t}</button>
|
|
3168
3177
|
`;
|
|
3169
3178
|
return i`
|
|
3170
|
-
<div class="ft-header-menu" role="menu" aria-label=${
|
|
3179
|
+
<div class="ft-header-menu" role="menu" aria-label=${A("columnMenuRegion", { header: o.label })}
|
|
3171
3180
|
style="position: fixed; left: ${t}px; top: ${n}px; z-index: var(--u-layer-floating, 1000);"
|
|
3172
3181
|
@mousedown=${(e) => e.stopPropagation()}
|
|
3173
3182
|
@keydown=${(e) => this._onHeaderMenuKeydown(e)}>
|
|
3174
3183
|
${o.sortable === !1 ? a : i`
|
|
3175
|
-
${c("sort-asc",
|
|
3176
|
-
${c("sort-desc",
|
|
3184
|
+
${c("sort-asc", A("sortAscending"), () => this._applySortFromMenu(e, "asc"))}
|
|
3185
|
+
${c("sort-desc", A("sortDescending"), () => this._applySortFromMenu(e, "desc"))}
|
|
3177
3186
|
<div class="ft-header-menu-separator" role="separator"></div>
|
|
3178
3187
|
`}
|
|
3179
3188
|
${this.showFilters ? i`
|
|
3180
|
-
${c("filter",
|
|
3181
|
-
${s ? c("clear-filter",
|
|
3189
|
+
${c("filter", A("filter"), () => this._openFilterFromMenu(e))}
|
|
3190
|
+
${s ? c("clear-filter", A("clearFilter"), () => this._clearColumnFilter(e)) : a}
|
|
3182
3191
|
<div class="ft-header-menu-separator" role="separator"></div>
|
|
3183
3192
|
` : a}
|
|
3184
|
-
${c("hide",
|
|
3185
|
-
${r.map((e) => c("show",
|
|
3193
|
+
${c("hide", A("hideColumn"), () => this._setColumnHidden(e, !0))}
|
|
3194
|
+
${r.map((e) => c("show", A("showColumn", { header: e.label }), () => this._setColumnHidden(e.key, !1)))}
|
|
3186
3195
|
<div class="ft-header-menu-separator" role="separator"></div>
|
|
3187
|
-
${c("autofit",
|
|
3188
|
-
${c("wider",
|
|
3189
|
-
${c("narrower",
|
|
3196
|
+
${c("autofit", A("autoFitWidth"), () => this._autoFitColumn(e))}
|
|
3197
|
+
${c("wider", A("wider"), () => this._resizeColumnBy(e, X), !0)}
|
|
3198
|
+
${c("narrower", A("narrower"), () => this._resizeColumnBy(e, -20), !0)}
|
|
3190
3199
|
</div>
|
|
3191
3200
|
`;
|
|
3192
3201
|
}
|
|
@@ -3204,26 +3213,26 @@ var q = {
|
|
|
3204
3213
|
}}>${e}</button>
|
|
3205
3214
|
`, f = i`<div class="ft-context-menu-separator" role="separator"></div>`;
|
|
3206
3215
|
return i`
|
|
3207
|
-
<div class="ft-body-context-menu" role="menu" aria-label=${
|
|
3216
|
+
<div class="ft-body-context-menu" role="menu" aria-label=${A("cellActions")}
|
|
3208
3217
|
style="position: fixed; left: ${n}px; top: ${r}px; z-index: var(--u-layer-floating, 1000);"
|
|
3209
3218
|
@mousedown=${(e) => e.stopPropagation()}
|
|
3210
3219
|
@keydown=${(e) => this._onMenuKeydown(e, ".ft-body-context-menu", l)}>
|
|
3211
|
-
${d(
|
|
3220
|
+
${d(A("copy"), () => this._handleCopy(!1))}
|
|
3212
3221
|
${f}
|
|
3213
|
-
${d(
|
|
3214
|
-
${d(
|
|
3215
|
-
${d(
|
|
3222
|
+
${d(A("insertRowAbove"), () => this.addRow(void 0, t))}
|
|
3223
|
+
${d(A("insertRowBelow"), () => this.addRow(void 0, t + 1))}
|
|
3224
|
+
${d(A("deleteRow"), () => this.deleteRows([t]), !0)}
|
|
3216
3225
|
${f}
|
|
3217
|
-
${d(
|
|
3226
|
+
${d(A("hideColumn"), () => this._setColumnHidden(o.key, !0))}
|
|
3218
3227
|
${f}
|
|
3219
|
-
${d(`${
|
|
3220
|
-
${d(`${
|
|
3228
|
+
${d(`${A("sortAscending")} ↑`, () => this._applySortFromMenu(o.key, "asc"))}
|
|
3229
|
+
${d(`${A("sortDescending")} ↓`, () => this._applySortFromMenu(o.key, "desc"))}
|
|
3221
3230
|
${f}
|
|
3222
|
-
${d(
|
|
3223
|
-
${c ? d(
|
|
3231
|
+
${d(A("filterByThisValue"), () => this.setFilter(o.key, (e) => e === s))}
|
|
3232
|
+
${c ? d(A("clearFilter"), () => this.removeFilter(o.key)) : a}
|
|
3224
3233
|
${f}
|
|
3225
|
-
${d(
|
|
3226
|
-
${u ? d(
|
|
3234
|
+
${d(A(u ? "editComment" : "addComment"), () => this._openCommentPopup(t, o.key, n, r))}
|
|
3235
|
+
${u ? d(A("deleteComment"), () => this.setComment(t, o.key, null), !0) : a}
|
|
3227
3236
|
</div>
|
|
3228
3237
|
`;
|
|
3229
3238
|
}
|
|
@@ -3255,13 +3264,13 @@ var q = {
|
|
|
3255
3264
|
@mousedown=${(e) => e.stopPropagation()}>
|
|
3256
3265
|
<textarea class="ft-comment-popup-textarea"
|
|
3257
3266
|
rows="4"
|
|
3258
|
-
placeholder=${
|
|
3267
|
+
placeholder=${A("addCommentPlaceholder")}
|
|
3259
3268
|
@keydown=${(e) => {
|
|
3260
3269
|
e.key === "Escape" && (e.preventDefault(), this._cancelCommentPopup()), e.key === "Enter" && (e.ctrlKey || e.metaKey) && (e.preventDefault(), this._commitCommentPopup());
|
|
3261
3270
|
}}></textarea>
|
|
3262
3271
|
<div class="ft-comment-popup-buttons">
|
|
3263
|
-
<button class="ft-comment-popup-cancel" @click=${() => this._cancelCommentPopup()}>${
|
|
3264
|
-
<button class="ft-comment-popup-save" @click=${() => this._commitCommentPopup()}>${
|
|
3272
|
+
<button class="ft-comment-popup-cancel" @click=${() => this._cancelCommentPopup()}>${A("cancel")}</button>
|
|
3273
|
+
<button class="ft-comment-popup-save" @click=${() => this._commitCommentPopup()}>${A("save")}</button>
|
|
3265
3274
|
</div>
|
|
3266
3275
|
</div>
|
|
3267
3276
|
`;
|
|
@@ -3297,7 +3306,7 @@ var q = {
|
|
|
3297
3306
|
<div class="ft-filter-dropdown" @click=${(e) => e.stopPropagation()}>
|
|
3298
3307
|
${t === "boolean" ? this._renderBooleanFilter(e) : t === "number" ? this._renderNumberFilter(e) : t === "date" || t === "datetime" ? this._renderDateFilter(e) : this._renderTextFilter(e)}
|
|
3299
3308
|
<div class="ft-filter-actions">
|
|
3300
|
-
<button class="ft-filter-clear" @click=${() => this._clearColumnFilter(e.key)}>${
|
|
3309
|
+
<button class="ft-filter-clear" @click=${() => this._clearColumnFilter(e.key)}>${A("clear")}</button>
|
|
3301
3310
|
</div>
|
|
3302
3311
|
</div>
|
|
3303
3312
|
`;
|
|
@@ -3330,7 +3339,7 @@ var q = {
|
|
|
3330
3339
|
let n = this._emptyFilterState.get(e) ?? "";
|
|
3331
3340
|
return i`
|
|
3332
3341
|
<div class="ft-filter-empty-row">
|
|
3333
|
-
<label>${
|
|
3342
|
+
<label>${A("blankCells")}</label>
|
|
3334
3343
|
<select class="ft-filter-mode-select"
|
|
3335
3344
|
.value=${n}
|
|
3336
3345
|
@change=${(n) => {
|
|
@@ -3340,9 +3349,9 @@ var q = {
|
|
|
3340
3349
|
@keydown=${(e) => {
|
|
3341
3350
|
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
3342
3351
|
}}>
|
|
3343
|
-
<option value="">${
|
|
3344
|
-
<option value="empty">${
|
|
3345
|
-
<option value="non-empty">${
|
|
3352
|
+
<option value="">${A("blankAll")}</option>
|
|
3353
|
+
<option value="empty">${A("emptyOnly")}</option>
|
|
3354
|
+
<option value="non-empty">${A("nonEmptyOnly")}</option>
|
|
3346
3355
|
</select>
|
|
3347
3356
|
</div>
|
|
3348
3357
|
`;
|
|
@@ -3418,13 +3427,13 @@ var q = {
|
|
|
3418
3427
|
@keydown=${(e) => {
|
|
3419
3428
|
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
3420
3429
|
}}>
|
|
3421
|
-
<option value="contains">${
|
|
3422
|
-
<option value="starts">${
|
|
3423
|
-
<option value="ends">${
|
|
3424
|
-
<option value="wildcard">${
|
|
3430
|
+
<option value="contains">${A("contains")}</option>
|
|
3431
|
+
<option value="starts">${A("startsWith")}</option>
|
|
3432
|
+
<option value="ends">${A("endsWith")}</option>
|
|
3433
|
+
<option value="wildcard">${A("wildcard")}</option>
|
|
3425
3434
|
</select>
|
|
3426
3435
|
</div>
|
|
3427
|
-
<input class="ft-filter-input" type="text" placeholder=${
|
|
3436
|
+
<input class="ft-filter-input" type="text" placeholder=${A("searchPlaceholder")}
|
|
3428
3437
|
.value=${t.value}
|
|
3429
3438
|
@input=${(t) => {
|
|
3430
3439
|
let n = t.target.value, r = this._textFilterState.get(e.key) ?? {
|
|
@@ -3475,15 +3484,15 @@ var q = {
|
|
|
3475
3484
|
}}>
|
|
3476
3485
|
${Object.keys(q).map((e) => i`<option value=${e}>${q[e]}</option>`)}
|
|
3477
3486
|
</select>
|
|
3478
|
-
<input class="ft-filter-input ft-num-cond-input" type="text" inputmode="decimal" placeholder=${
|
|
3479
|
-
.value=${n.text ?? (n.value == null ? "" :
|
|
3487
|
+
<input class="ft-filter-input ft-num-cond-input" type="text" inputmode="decimal" placeholder=${A("valuePlaceholder")}
|
|
3488
|
+
.value=${n.text ?? (n.value == null ? "" : P(n.value))}
|
|
3480
3489
|
aria-invalid=${n.text && n.value == null ? "true" : "false"}
|
|
3481
3490
|
@input=${(n) => {
|
|
3482
3491
|
let r = n.target.value, i = this._numberFilterState.get(e) ?? this._defaultNumState();
|
|
3483
3492
|
i[t] = {
|
|
3484
3493
|
...i[t],
|
|
3485
3494
|
text: r,
|
|
3486
|
-
value: r.trim() === "" ? null :
|
|
3495
|
+
value: r.trim() === "" ? null : m(r)
|
|
3487
3496
|
}, this._numberFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
|
|
3488
3497
|
}}
|
|
3489
3498
|
@keydown=${(e) => {
|
|
@@ -3538,13 +3547,13 @@ var q = {
|
|
|
3538
3547
|
let t = e.type === "datetime" ? "datetime-local" : "date", n = this._dateFilterState.get(e.key) ?? {};
|
|
3539
3548
|
return i`
|
|
3540
3549
|
<div class="ft-filter-range">
|
|
3541
|
-
<input class="ft-filter-input" type=${t} placeholder=${
|
|
3550
|
+
<input class="ft-filter-input" type=${t} placeholder=${A("fromPlaceholder")}
|
|
3542
3551
|
.value=${n.from ?? ""}
|
|
3543
3552
|
@input=${(t) => this._applyDateFilter(e.key, t, "from")}
|
|
3544
3553
|
@keydown=${(e) => {
|
|
3545
3554
|
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
3546
3555
|
}}>
|
|
3547
|
-
<input class="ft-filter-input" type=${t} placeholder=${
|
|
3556
|
+
<input class="ft-filter-input" type=${t} placeholder=${A("toPlaceholder")}
|
|
3548
3557
|
.value=${n.to ?? ""}
|
|
3549
3558
|
@input=${(t) => this._applyDateFilter(e.key, t, "to")}
|
|
3550
3559
|
@keydown=${(e) => {
|
|
@@ -3570,9 +3579,9 @@ var q = {
|
|
|
3570
3579
|
@keydown=${(e) => {
|
|
3571
3580
|
e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
|
|
3572
3581
|
}}>
|
|
3573
|
-
<option value="all">${
|
|
3574
|
-
<option value="true">\u2714 ${
|
|
3575
|
-
<option value="false">\u2718 ${
|
|
3582
|
+
<option value="all">${A("all")}</option>
|
|
3583
|
+
<option value="true">\u2714 ${A("booleanTrue")}</option>
|
|
3584
|
+
<option value="false">\u2718 ${A("booleanFalse")}</option>
|
|
3576
3585
|
</select>
|
|
3577
3586
|
${this._renderEmptyFilterRow(e.key)}
|
|
3578
3587
|
`;
|
|
@@ -3989,42 +3998,42 @@ var q = {
|
|
|
3989
3998
|
this._closeFindPanel();
|
|
3990
3999
|
return;
|
|
3991
4000
|
}
|
|
3992
|
-
e.key === "Enter" && !
|
|
4001
|
+
e.key === "Enter" && !_(e) && e.target instanceof HTMLInputElement && e.target.classList.contains("ft-find-input") && (e.shiftKey ? this._findPrev() : this._findNext());
|
|
3993
4002
|
}}>
|
|
3994
4003
|
<div class="ft-find-row">
|
|
3995
|
-
<input class="ft-find-input" type="text" placeholder=${
|
|
4004
|
+
<input class="ft-find-input" type="text" placeholder=${A("findPlaceholder")}
|
|
3996
4005
|
.value=${t}
|
|
3997
4006
|
@input=${(e) => {
|
|
3998
4007
|
this._findState.query = e.target.value, this._findSearch();
|
|
3999
4008
|
}}>
|
|
4000
4009
|
<span class="ft-find-count">${c > 0 ? `${l}/${c}` : t ? "0 results" : ""}</span>
|
|
4001
|
-
<button @click=${() => this._findPrev()} title=${
|
|
4002
|
-
<button @click=${() => this._findNext()} title=${
|
|
4003
|
-
<label title=${
|
|
4010
|
+
<button @click=${() => this._findPrev()} title=${A("findPrevious")}>◀</button>
|
|
4011
|
+
<button @click=${() => this._findNext()} title=${A("findNext")}>▶</button>
|
|
4012
|
+
<label title=${A("matchCase")}><input type="checkbox" ?checked=${r} @change=${(e) => {
|
|
4004
4013
|
this._findState.matchCase = e.target.checked, this._findSearch();
|
|
4005
4014
|
}}> Aa</label>
|
|
4006
|
-
<label title=${
|
|
4015
|
+
<label title=${A("wholeCell")}><input type="checkbox" ?checked=${a} @change=${(e) => {
|
|
4007
4016
|
this._findState.wholeCell = e.target.checked, this._findSearch();
|
|
4008
4017
|
}}> [ ]</label>
|
|
4009
|
-
<button @click=${() => this._closeFindPanel()} title=${
|
|
4018
|
+
<button @click=${() => this._closeFindPanel()} title=${A("closeFind")}>✕</button>
|
|
4010
4019
|
</div>
|
|
4011
4020
|
${e === "replace" ? i`
|
|
4012
4021
|
<div class="ft-find-row">
|
|
4013
|
-
<input class="ft-find-replace-input" type="text" placeholder=${
|
|
4022
|
+
<input class="ft-find-replace-input" type="text" placeholder=${A("replaceWithPlaceholder")}
|
|
4014
4023
|
.value=${n}
|
|
4015
4024
|
@input=${(e) => {
|
|
4016
4025
|
this._findState.replaceWith = e.target.value;
|
|
4017
4026
|
}}>
|
|
4018
|
-
<button @click=${() => this._replaceOne()} ?disabled=${c === 0}>${
|
|
4019
|
-
<button @click=${() => this._replaceAll()} ?disabled=${c === 0}>${
|
|
4027
|
+
<button @click=${() => this._replaceOne()} ?disabled=${c === 0}>${A("replace")}</button>
|
|
4028
|
+
<button @click=${() => this._replaceAll()} ?disabled=${c === 0}>${A("replaceAll")}</button>
|
|
4020
4029
|
</div>
|
|
4021
4030
|
` : ""}
|
|
4022
4031
|
</div>
|
|
4023
4032
|
`;
|
|
4024
4033
|
}
|
|
4025
4034
|
render() {
|
|
4026
|
-
let e = this.visibleColumns, t = this.importEnabled && this._isDragOver ? i`<div class="ft-import-overlay">${
|
|
4027
|
-
if (e.length === 0) return i`${t}${n}<div class="ft-empty">${
|
|
4035
|
+
let e = this.visibleColumns, t = this.importEnabled && this._isDragOver ? i`<div class="ft-import-overlay">${A("dropFileToImport")}</div>` : a, n = this.loading ? i`<div class="ft-loading-overlay"></div>` : a;
|
|
4036
|
+
if (e.length === 0) return i`${t}${n}<div class="ft-empty">${A("noColumnsDefined")}</div>`;
|
|
4028
4037
|
let r = this.headerHeight, o = this._totalRowWidth, { start: s, end: c } = this.visibleColRange, l = [];
|
|
4029
4038
|
for (let t = 0; t < e.length; t++) (e[t].pinned === "left" || e[t].pinned === "right") && (t < s || t >= c) && l.push(t);
|
|
4030
4039
|
let u = 0, d = this._scrollLeft, f = this.selectable ? i`<div class="ft-checkbox-header"
|
|
@@ -4200,7 +4209,7 @@ var q = {
|
|
|
4200
4209
|
${this._renderEditor(e, t)}
|
|
4201
4210
|
</div>
|
|
4202
4211
|
`;
|
|
4203
|
-
let v = s || l, y = this._isCellInvalid(n, r), b = (this._findState?.results ?? []).findIndex((e) => e.row === n && e.col === r),
|
|
4212
|
+
let v = s || l, y = this._isCellInvalid(n, r), b = (this._findState?.results ?? []).findIndex((e) => e.row === n && e.col === r), x = b >= 0, S = x && b === this._findState.currentIndex, w = [
|
|
4204
4213
|
"ft-cell",
|
|
4205
4214
|
`ft-type-${t.type ?? "text"}`,
|
|
4206
4215
|
`ft-align-${G(t)}`,
|
|
@@ -4208,7 +4217,7 @@ var q = {
|
|
|
4208
4217
|
l ? "ft-selected" : "",
|
|
4209
4218
|
f ? "ft-pinned" : "",
|
|
4210
4219
|
y ? "ft-invalid" : "",
|
|
4211
|
-
|
|
4220
|
+
S ? "ft-find-current" : x ? "ft-find-match" : "",
|
|
4212
4221
|
o ? `ft-merge-${o.headParity}` : "",
|
|
4213
4222
|
o?.continues ? "ft-merge-continued" : "",
|
|
4214
4223
|
o?.opensDown ? "ft-merge-open" : ""
|
|
@@ -4228,7 +4237,7 @@ var q = {
|
|
|
4228
4237
|
@click=${(e) => this._onCellClickEvent(e, n, r)}
|
|
4229
4238
|
@dblclick=${() => this._onCellDblClick(n, r)}>
|
|
4230
4239
|
${O}
|
|
4231
|
-
${
|
|
4240
|
+
${C(e[t.key], e, t)}
|
|
4232
4241
|
</div>
|
|
4233
4242
|
`;
|
|
4234
4243
|
}
|
|
@@ -4237,19 +4246,16 @@ var q = {
|
|
|
4237
4246
|
let n = e[t.key], r = n == null ? "" : String(n);
|
|
4238
4247
|
if (t.type === "number") return i`
|
|
4239
4248
|
<input class="ft-editor ft-editor-number" type="text" inputmode="decimal"
|
|
4240
|
-
.value=${typeof n == "number" ?
|
|
4249
|
+
.value=${typeof n == "number" ? P(n) : r}
|
|
4241
4250
|
@keydown=${this._onEditorKeyDown}
|
|
4242
4251
|
@blur=${() => this._commitEdit()}>
|
|
4243
4252
|
`;
|
|
4244
|
-
if (t.type === "date")
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
<input class="ft-editor" type="date"
|
|
4248
|
-
.value=${e}
|
|
4253
|
+
if (t.type === "date") return i`
|
|
4254
|
+
<input class="ft-editor ft-editor-date" type="text" inputmode="numeric" placeholder=${u()}
|
|
4255
|
+
.value=${se(n)}
|
|
4249
4256
|
@keydown=${this._onEditorKeyDown}
|
|
4250
4257
|
@blur=${() => this._commitEdit()}>
|
|
4251
4258
|
`;
|
|
4252
|
-
}
|
|
4253
4259
|
if (t.type === "datetime") {
|
|
4254
4260
|
let e = this._toDateTimeInputValue(n);
|
|
4255
4261
|
return i`
|
|
@@ -4299,11 +4305,6 @@ var q = {
|
|
|
4299
4305
|
@blur=${() => this._commitEdit()}>
|
|
4300
4306
|
`;
|
|
4301
4307
|
}
|
|
4302
|
-
_toDateInputValue(e) {
|
|
4303
|
-
if (!e) return "";
|
|
4304
|
-
let t = e instanceof Date ? e : new Date(String(e));
|
|
4305
|
-
return isNaN(t.getTime()) ? "" : `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}-${String(t.getDate()).padStart(2, "0")}`;
|
|
4306
|
-
}
|
|
4307
4308
|
_toDateTimeInputValue(e) {
|
|
4308
4309
|
if (!e) return "";
|
|
4309
4310
|
let t = e instanceof Date ? e : new Date(String(e));
|
|
@@ -4366,4 +4367,4 @@ K([s({ type: Array })], $.prototype, "columns", void 0), K([s({
|
|
|
4366
4367
|
attribute: "max-undo-size"
|
|
4367
4368
|
})], $.prototype, "maxUndoSize", null), K([c()], $.prototype, "_scrollTop", void 0), K([c()], $.prototype, "_scrollLeft", void 0), K([c()], $.prototype, "_viewportHeight", void 0), K([c()], $.prototype, "_viewportWidth", void 0), K([c()], $.prototype, "_activeCell", void 0), K([c()], $.prototype, "_editingCell", void 0), K([c()], $.prototype, "_sortCriteria", void 0), K([c()], $.prototype, "_openFilterKey", void 0), K([c()], $.prototype, "_rowSelectionVersion", void 0), K([c()], $.prototype, "_autocompleteState", void 0), K([c()], $.prototype, "_headerMenu", void 0), K([c()], $.prototype, "_bodyContextMenu", void 0), K([c()], $.prototype, "_commentPopup", void 0), K([c()], $.prototype, "_isDragOver", void 0), $ = K([o("flex-table")], $);
|
|
4368
4369
|
//#endregion
|
|
4369
|
-
export {
|
|
4370
|
+
export { j as a, M as i, G as n, k as o, B as r, C as s, $ as t };
|
package/dist/flex-table.d.ts
CHANGED
|
@@ -526,7 +526,6 @@ export declare class FlexTable extends LitElement {
|
|
|
526
526
|
private _renderCell;
|
|
527
527
|
private _renderEditor;
|
|
528
528
|
/** Convert value to YYYY-MM-DD for date input (local timezone) */
|
|
529
|
-
private _toDateInputValue;
|
|
530
529
|
/** Convert value to YYYY-MM-DDTHH:mm for datetime-local input (local timezone) */
|
|
531
530
|
private _toDateTimeInputValue;
|
|
532
531
|
}
|
package/dist/flex-table.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./flex-table-
|
|
1
|
+
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./flex-table-C6PFutM_.js";
|
|
2
2
|
export { o as FlexTable, e as RowSelectionState, t as UndoStack, n as effectiveAlign, i as exportData, r as flexTableLocale, a as renderCell };
|
package/dist/locale.d.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* (아이콘 자리의 글리프)는 어느 로케일에서도 같은 것을 뜻하며, 번역하면 오히려 읽히지 않는다.
|
|
26
26
|
* 그 판단은 «번역하지 않기로 한 것»이지 «빠뜨린 것»이 아니다.
|
|
27
27
|
*/
|
|
28
|
-
export type FlexTableMessageKey = 'showHiddenColumns' | 'columnMenu' | 'cellActions' | 'noColumnsDefined' | 'addCommentPlaceholder' | 'cancel' | 'save' | 'clear' | 'blankCells' | 'emptyOnly' | 'nonEmptyOnly' | 'blankAll' | 'all' | 'contains' | 'startsWith' | 'endsWith' | 'wildcard' | 'searchPlaceholder' | 'valuePlaceholder' | 'fromPlaceholder' | 'toPlaceholder' | 'findPlaceholder' | 'findPrevious' | 'findNext' | 'matchCase' | 'wholeCell' | 'closeFind' | 'replaceWithPlaceholder' | 'replace' | 'replaceAll' | 'sortAscending' | 'sortDescending' | 'filter' | 'clearFilter' | 'hideColumn' | 'showColumn' | 'autoFitWidth' | 'wider' | 'narrower' | 'columnMenuFor' | 'columnMenuRegion' | 'copy' | 'insertRowAbove' | 'insertRowBelow' | 'deleteRow' | 'filterByThisValue' | 'addComment' | 'editComment' | 'deleteComment' | 'booleanTrue' | 'booleanFalse' | 'dropFileToImport' | 'notANumber' | 'notInList';
|
|
28
|
+
export type FlexTableMessageKey = 'showHiddenColumns' | 'columnMenu' | 'cellActions' | 'noColumnsDefined' | 'addCommentPlaceholder' | 'cancel' | 'save' | 'clear' | 'blankCells' | 'emptyOnly' | 'nonEmptyOnly' | 'blankAll' | 'all' | 'contains' | 'startsWith' | 'endsWith' | 'wildcard' | 'searchPlaceholder' | 'valuePlaceholder' | 'fromPlaceholder' | 'toPlaceholder' | 'findPlaceholder' | 'findPrevious' | 'findNext' | 'matchCase' | 'wholeCell' | 'closeFind' | 'replaceWithPlaceholder' | 'replace' | 'replaceAll' | 'sortAscending' | 'sortDescending' | 'filter' | 'clearFilter' | 'hideColumn' | 'showColumn' | 'autoFitWidth' | 'wider' | 'narrower' | 'columnMenuFor' | 'columnMenuRegion' | 'copy' | 'insertRowAbove' | 'insertRowBelow' | 'deleteRow' | 'filterByThisValue' | 'addComment' | 'editComment' | 'deleteComment' | 'booleanTrue' | 'booleanFalse' | 'dropFileToImport' | 'notANumber' | 'notADate' | 'notInList';
|
|
29
29
|
/** 이 패키지의 chrome 문자열 묶음. 소비자가 `register()` 로 언어를 더하거나 문구를 덮을 수 있다. */
|
|
30
30
|
export declare const flexTableLocale: import("@iyulab/components/dist/utilities/Locale.js").LocaleNamespace<FlexTableMessageKey>;
|
|
31
31
|
/** 짧은 조회 별칭 — 렌더 코드가 읽히게 유지한다. */
|
package/dist/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./flex-table-
|
|
1
|
+
import { t as e } from "./flex-table-C6PFutM_.js";
|
|
2
2
|
import { i as t, t as n } from "./query-Dw4iO0ir.js";
|
|
3
3
|
import { t as r } from "./view-DiLr-TdY.js";
|
|
4
4
|
import i, { useCallback as a, useEffect as o, useMemo as s, useRef as c, useState as l } from "react";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/flex-table",
|
|
3
|
-
"version": "0.41.
|
|
3
|
+
"version": "0.41.1",
|
|
4
4
|
"description": "A minimalist, input-centric data grid web component",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/flex-table.js",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"odata-query": "^8.1.0"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
|
-
"@iyulab/components": ">=1.
|
|
75
|
+
"@iyulab/components": ">=1.55.0",
|
|
76
76
|
"@lit/react": "^1.0.8",
|
|
77
77
|
"react": "^18.0.0 || ^19.0.0"
|
|
78
78
|
},
|
|
@@ -67,6 +67,7 @@ as `text`). See `references/api.md` for every field.
|
|
|
67
67
|
- `editor` returns a Lit template containing an element with class `ft-editor`; its `.value` is committed.
|
|
68
68
|
- `validator` returns `null` when valid, or an error message (the edit is rejected and `validation-error` fires).
|
|
69
69
|
- `number` cells, the number filter and paste read numbers in the active `Locale` (`1,5` is 1.5 on a comma-decimal page); an edit that is not a number is rejected with `validation-error`.
|
|
70
|
+
- `date` cells edit as a `YYYY-MM-DD` text box in every browser language (also `20261002`, `2026/10/2`, `10-02`); pasted dates are normalized to ISO.
|
|
70
71
|
- `conditionalRules` applies `{ when, style }` rules in order; later matches override earlier ones.
|
|
71
72
|
- `pinned: 'left' | 'right'` freezes a column during horizontal scroll.
|
|
72
73
|
|