@iyulab/flex-table 0.45.0 → 0.46.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/CHANGELOG.md +23 -0
- package/README.md +1 -1
- package/dist/{flex-table-Bv41ls8b.js → flex-table-DIQhqj12.js} +208 -131
- package/dist/flex-table.d.ts +7 -0
- package/dist/flex-table.js +1 -1
- package/dist/react.js +1 -1
- package/package.json +2 -2
- package/skills/iyulab-flex-table/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.46.0] - 2026-10-05
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **Date and datetime cells edit with `u-date-picker`** from `@iyulab/components` — the same text box
|
|
8
|
+
(`YYYY-MM-DD`, `YYYY-MM-DD HH:mm`, the same short forms and the same rejection of text that is not a
|
|
9
|
+
date) with a calendar beside it. A day picked in a `date` cell's calendar is the new value; in a
|
|
10
|
+
`datetime` cell the day and time are applied together with Apply. While the calendar is open,
|
|
11
|
+
Escape closes it and the next Escape cancels the edit. Stored values are unchanged: `YYYY-MM-DD`,
|
|
12
|
+
and the local `YYYY-MM-DDTHH:mm`. **Requires `@iyulab/components` 2.0.1** (peer `>=2.0.1`, was
|
|
13
|
+
`>=1.56.0`) — the release in which pressing the calendar keeps focus in the picker.
|
|
14
|
+
|
|
15
|
+
- **A paste leaves the cells it wrote selected**, as spreadsheets do: after Ctrl+V the pasted block
|
|
16
|
+
(including rows it appended) is the selection, so it can be seen, copied, cleared or undone as one
|
|
17
|
+
block. The active cell stays where the paste began. A single-value paste keeps the single-cell
|
|
18
|
+
selection.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **Typing into a cell editor keeps every key.** The editor was focused and its text selected again on
|
|
23
|
+
every update of the table, so in an autocomplete column — whose list updates on each key — the next
|
|
24
|
+
key replaced what was typed (`apx` became `x`). It is now focused once, when editing starts.
|
|
25
|
+
|
|
3
26
|
## [0.45.0] - 2026-10-05
|
|
4
27
|
|
|
5
28
|
### Added
|
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ The `validator` callback returns `null` if valid, or an error message string. On
|
|
|
161
161
|
|
|
162
162
|
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.
|
|
163
163
|
|
|
164
|
-
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. A `datetime` column's editor works the same with a time: it shows `YYYY-MM-DD HH:mm` in local time, reads `2026-10-02 14:05` (a date alone is midnight), and stores the local `YYYY-MM-DDTHH:mm` string.
|
|
164
|
+
A `date` column's built-in editor is `u-date-picker` from `@iyulab/components`: 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`), with a calendar beside it — click the box or press ArrowDown, and a picked day is the new value. 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. A `datetime` column's editor works the same with a time: it shows `YYYY-MM-DD HH:mm` in local time, reads `2026-10-02 14:05` (a date alone is midnight), and stores the local `YYYY-MM-DDTHH:mm` string; in its calendar a day and a time are applied together with Apply. While the calendar is open, Escape closes the calendar; the next Escape cancels the edit.
|
|
165
165
|
|
|
166
166
|
### `format` vs `render`
|
|
167
167
|
|
|
@@ -2,11 +2,12 @@ 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
|
|
5
|
+
import { formatDate as u, formatNumber as d, parseDate as f, parseDateTime 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 "@iyulab/components/dist/components/date-picker/UDatePicker.js";
|
|
8
|
+
import { isImeComposing as _ } from "@iyulab/components/dist/utilities/keyboard.js";
|
|
8
9
|
//#region src/styles/flex-table.styles.ts
|
|
9
|
-
var
|
|
10
|
+
var v = r`
|
|
10
11
|
/* --- Theme Variables (Light defaults) --- */
|
|
11
12
|
:host {
|
|
12
13
|
--ft-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
@@ -306,6 +307,35 @@ var y = r`
|
|
|
306
307
|
|
|
307
308
|
.ft-editor-number { text-align: right; }
|
|
308
309
|
|
|
310
|
+
/* 날짜 편집기(u-date-picker) — 텍스트 편집기와 같은 자리·여백·초점선으로 셀을 채운다. 테두리는
|
|
311
|
+
셀의 것이고, 달력은 피커 자신의 팝오버다. */
|
|
312
|
+
u-date-picker.ft-editor {
|
|
313
|
+
display: block;
|
|
314
|
+
padding: 0;
|
|
315
|
+
background: none;
|
|
316
|
+
--u-date-picker-display: block;
|
|
317
|
+
--u-date-picker-width: 100%;
|
|
318
|
+
}
|
|
319
|
+
u-date-picker.ft-editor:focus { outline: none; }
|
|
320
|
+
u-date-picker.ft-editor:focus-within {
|
|
321
|
+
outline: 2px solid var(--ft-active-color);
|
|
322
|
+
outline-offset: -2px;
|
|
323
|
+
}
|
|
324
|
+
u-date-picker.ft-editor::part(field) { height: 100%; }
|
|
325
|
+
u-date-picker.ft-editor::part(container) {
|
|
326
|
+
height: 100%;
|
|
327
|
+
min-height: 0;
|
|
328
|
+
border: none;
|
|
329
|
+
border-radius: 0;
|
|
330
|
+
box-shadow: none;
|
|
331
|
+
background: var(--ft-editor-bg);
|
|
332
|
+
padding: var(--ft-cell-padding-block) var(--ft-cell-padding-inline);
|
|
333
|
+
}
|
|
334
|
+
u-date-picker.ft-editor::part(input) {
|
|
335
|
+
font: inherit;
|
|
336
|
+
color: var(--ft-text-color);
|
|
337
|
+
}
|
|
338
|
+
|
|
309
339
|
select.ft-editor {
|
|
310
340
|
cursor: pointer;
|
|
311
341
|
padding: 4px 6px;
|
|
@@ -974,13 +1004,13 @@ var y = r`
|
|
|
974
1004
|
`;
|
|
975
1005
|
//#endregion
|
|
976
1006
|
//#region src/renderers/format.ts
|
|
977
|
-
function
|
|
978
|
-
return e == null ? "" : typeof t == "function" ? t(e) :
|
|
1007
|
+
function y(e, t) {
|
|
1008
|
+
return e == null ? "" : typeof t == "function" ? t(e) : b(t) ? S(e, t) : x(e, t);
|
|
979
1009
|
}
|
|
980
|
-
function
|
|
1010
|
+
function b(e) {
|
|
981
1011
|
return /[yMdHhms]/.test(e);
|
|
982
1012
|
}
|
|
983
|
-
function
|
|
1013
|
+
function x(e, t) {
|
|
984
1014
|
let n = typeof e == "number" ? e : Number(e);
|
|
985
1015
|
if (isNaN(n)) return String(e);
|
|
986
1016
|
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 = {
|
|
@@ -993,7 +1023,7 @@ function S(e, t) {
|
|
|
993
1023
|
style: "percent"
|
|
994
1024
|
}).format(n) : (d = new Intl.NumberFormat(l.get(), u).format(n), a && (d = a + d)), d + "";
|
|
995
1025
|
}
|
|
996
|
-
function
|
|
1026
|
+
function S(e, t) {
|
|
997
1027
|
let n;
|
|
998
1028
|
if (e instanceof Date) n = e;
|
|
999
1029
|
else if (typeof e == "string" || typeof e == "number") n = new Date(e);
|
|
@@ -1004,26 +1034,26 @@ function C(e, t) {
|
|
|
1004
1034
|
}
|
|
1005
1035
|
//#endregion
|
|
1006
1036
|
//#region src/renderers/cell-renderer.ts
|
|
1007
|
-
function
|
|
1008
|
-
return n.render ? n.render(e, t, n) : n.format ? typeof n.format == "function" ? n.format(e, t, n) :
|
|
1037
|
+
function C(e, t, n) {
|
|
1038
|
+
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);
|
|
1009
1039
|
}
|
|
1010
|
-
function
|
|
1040
|
+
function w(e, t) {
|
|
1011
1041
|
if (e == null) return "";
|
|
1012
1042
|
switch (t.type) {
|
|
1013
|
-
case "number": return
|
|
1043
|
+
case "number": return D(e);
|
|
1014
1044
|
case "boolean": return i`<span class="ft-bool">${e ? "✔" : ""}</span>`;
|
|
1015
|
-
case "date": return
|
|
1016
|
-
case "datetime": return
|
|
1017
|
-
case "select": return
|
|
1045
|
+
case "date": return O(e);
|
|
1046
|
+
case "datetime": return ee(e);
|
|
1047
|
+
case "select": return T(e, t);
|
|
1018
1048
|
default: return String(e);
|
|
1019
1049
|
}
|
|
1020
1050
|
}
|
|
1021
|
-
function
|
|
1051
|
+
function T(e, t) {
|
|
1022
1052
|
if (!t.options || t.options.length === 0 || typeof t.options[0] == "string") return e == null ? "" : String(e);
|
|
1023
1053
|
let n = t.options.find((t) => t.value === e);
|
|
1024
1054
|
return n ? n.label : e == null ? "" : String(e);
|
|
1025
1055
|
}
|
|
1026
|
-
var
|
|
1056
|
+
var E = {
|
|
1027
1057
|
year: "numeric",
|
|
1028
1058
|
month: "numeric",
|
|
1029
1059
|
day: "numeric",
|
|
@@ -1031,14 +1061,14 @@ var D = {
|
|
|
1031
1061
|
minute: "numeric",
|
|
1032
1062
|
second: "numeric"
|
|
1033
1063
|
};
|
|
1064
|
+
function D(e) {
|
|
1065
|
+
return typeof e == "number" ? Number.isInteger(e) ? d(e) : d(e, { minimumFractionDigits: 1 }) : String(e);
|
|
1066
|
+
}
|
|
1034
1067
|
function O(e) {
|
|
1035
|
-
return typeof e == "
|
|
1068
|
+
return e instanceof Date || typeof e == "string" ? u(e) : String(e);
|
|
1036
1069
|
}
|
|
1037
1070
|
function ee(e) {
|
|
1038
|
-
return e instanceof Date || typeof e == "string" ?
|
|
1039
|
-
}
|
|
1040
|
-
function te(e) {
|
|
1041
|
-
return e instanceof Date || typeof e == "string" ? d(e, D) : String(e);
|
|
1071
|
+
return e instanceof Date || typeof e == "string" ? u(e, E) : String(e);
|
|
1042
1072
|
}
|
|
1043
1073
|
//#endregion
|
|
1044
1074
|
//#region src/locale.ts
|
|
@@ -1161,7 +1191,7 @@ k.register("en", {
|
|
|
1161
1191
|
var A = (e, t) => k.text(e, t);
|
|
1162
1192
|
//#endregion
|
|
1163
1193
|
//#region src/core/selection.ts
|
|
1164
|
-
function
|
|
1194
|
+
function te(e) {
|
|
1165
1195
|
return {
|
|
1166
1196
|
startRow: Math.min(e.startRow, e.endRow),
|
|
1167
1197
|
startCol: Math.min(e.startCol, e.endCol),
|
|
@@ -1169,7 +1199,7 @@ function ne(e) {
|
|
|
1169
1199
|
endCol: Math.max(e.startCol, e.endCol)
|
|
1170
1200
|
};
|
|
1171
1201
|
}
|
|
1172
|
-
var
|
|
1202
|
+
var ne = class {
|
|
1173
1203
|
constructor() {
|
|
1174
1204
|
this.activeCell = null, this.rangeAnchor = null, this.range = null, this.extraRanges = [], this._rowCount = 0, this._colCount = 0;
|
|
1175
1205
|
}
|
|
@@ -1196,7 +1226,7 @@ var re = class {
|
|
|
1196
1226
|
return e < 0 || e >= this._rowCount || t < 0 || t >= this._colCount ? this.activeCell : (!this.rangeAnchor && this.activeCell && (this.rangeAnchor = { ...this.activeCell }), this.activeCell = {
|
|
1197
1227
|
row: e,
|
|
1198
1228
|
col: t
|
|
1199
|
-
}, this.rangeAnchor && (this.range =
|
|
1229
|
+
}, this.rangeAnchor && (this.range = te({
|
|
1200
1230
|
startRow: this.rangeAnchor.row,
|
|
1201
1231
|
startCol: this.rangeAnchor.col,
|
|
1202
1232
|
endRow: e,
|
|
@@ -1267,7 +1297,7 @@ var re = class {
|
|
|
1267
1297
|
shiftMoveRight() {
|
|
1268
1298
|
return this.activeCell ? this.setActiveWithRange(this.activeCell.row, this.activeCell.col + 1) : null;
|
|
1269
1299
|
}
|
|
1270
|
-
},
|
|
1300
|
+
}, re = class {
|
|
1271
1301
|
constructor() {
|
|
1272
1302
|
this.current = null;
|
|
1273
1303
|
}
|
|
@@ -1349,7 +1379,7 @@ var re = class {
|
|
|
1349
1379
|
};
|
|
1350
1380
|
//#endregion
|
|
1351
1381
|
//#region src/core/filtering.ts
|
|
1352
|
-
function
|
|
1382
|
+
function ie(e, t, n) {
|
|
1353
1383
|
if (t.length === 0) return Array.from({ length: e.length }, (e, t) => t);
|
|
1354
1384
|
let r = [];
|
|
1355
1385
|
for (let i = 0; i < e.length; i++) {
|
|
@@ -1368,9 +1398,9 @@ function ae(e, t, n) {
|
|
|
1368
1398
|
}
|
|
1369
1399
|
//#endregion
|
|
1370
1400
|
//#region src/core/undo.ts
|
|
1371
|
-
var
|
|
1401
|
+
var ae = 100, M = class {
|
|
1372
1402
|
constructor() {
|
|
1373
|
-
this._undoStack = [], this._redoStack = [], this._maxSize =
|
|
1403
|
+
this._undoStack = [], this._redoStack = [], this._maxSize = ae;
|
|
1374
1404
|
}
|
|
1375
1405
|
get maxSize() {
|
|
1376
1406
|
return this._maxSize;
|
|
@@ -1407,7 +1437,7 @@ var oe = 100, M = class {
|
|
|
1407
1437
|
};
|
|
1408
1438
|
//#endregion
|
|
1409
1439
|
//#region src/clipboard/clipboard.ts
|
|
1410
|
-
function
|
|
1440
|
+
function oe(e, t, n) {
|
|
1411
1441
|
let r = [];
|
|
1412
1442
|
for (let i = n.startRow; i <= n.endRow; i++) {
|
|
1413
1443
|
let a = e[i], o = [];
|
|
@@ -1417,20 +1447,20 @@ function se(e, t, n) {
|
|
|
1417
1447
|
}
|
|
1418
1448
|
r.push(o);
|
|
1419
1449
|
}
|
|
1420
|
-
return
|
|
1450
|
+
return g(r);
|
|
1421
1451
|
}
|
|
1422
1452
|
function N(e, t) {
|
|
1423
1453
|
if (e === "") return null;
|
|
1424
1454
|
switch (t.type) {
|
|
1425
1455
|
case "number": {
|
|
1426
|
-
let t =
|
|
1456
|
+
let t = m(e);
|
|
1427
1457
|
if (t !== null) return t;
|
|
1428
1458
|
let n = Number(e.trim());
|
|
1429
1459
|
return e.trim() !== "" && Number.isFinite(n) ? n : e;
|
|
1430
1460
|
}
|
|
1431
1461
|
case "boolean": return e.toLowerCase() === "true" || e === "1";
|
|
1432
|
-
case "date": return
|
|
1433
|
-
case "datetime": return
|
|
1462
|
+
case "date": return f(e) ?? e;
|
|
1463
|
+
case "datetime": return p(e) ?? e;
|
|
1434
1464
|
default: return e;
|
|
1435
1465
|
}
|
|
1436
1466
|
}
|
|
@@ -1440,13 +1470,13 @@ function P(e) {
|
|
|
1440
1470
|
let n = new Intl.NumberFormat(l.get()).formatToParts(1.5).find((e) => e.type === "decimal")?.value;
|
|
1441
1471
|
return n && n !== "." ? t.replace(".", n) : t;
|
|
1442
1472
|
}
|
|
1443
|
-
function
|
|
1473
|
+
function se(e) {
|
|
1444
1474
|
if (e == null || e === "") return "";
|
|
1445
1475
|
if (e instanceof Date) return Number.isNaN(e.getTime()) ? "" : `${e.getFullYear()}-${String(e.getMonth() + 1).padStart(2, "0")}-${String(e.getDate()).padStart(2, "0")}`;
|
|
1446
1476
|
let t = String(e), n = /^(\d{4}-\d{2}-\d{2})(?:$|T)/.exec(t);
|
|
1447
1477
|
return n ? n[1] : t;
|
|
1448
1478
|
}
|
|
1449
|
-
function
|
|
1479
|
+
function ce(e) {
|
|
1450
1480
|
if (e == null || e === "") return "";
|
|
1451
1481
|
let t = e instanceof Date ? "" : String(e), n = /^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2})(?::\d{2}(?:\.\d+)?)?$/.exec(t);
|
|
1452
1482
|
if (n) return `${n[1]} ${n[2]}`;
|
|
@@ -1457,7 +1487,7 @@ function le(e) {
|
|
|
1457
1487
|
}
|
|
1458
1488
|
//#endregion
|
|
1459
1489
|
//#region src/export/xlsx-writer.ts
|
|
1460
|
-
var
|
|
1490
|
+
var le = (() => {
|
|
1461
1491
|
let e = /* @__PURE__ */ new Uint32Array(256);
|
|
1462
1492
|
for (let t = 0; t < 256; t++) {
|
|
1463
1493
|
let n = t;
|
|
@@ -1466,23 +1496,23 @@ var ue = (() => {
|
|
|
1466
1496
|
}
|
|
1467
1497
|
return e;
|
|
1468
1498
|
})();
|
|
1469
|
-
function
|
|
1499
|
+
function ue(e) {
|
|
1470
1500
|
let t = 4294967295;
|
|
1471
|
-
for (let n = 0; n < e.length; n++) t =
|
|
1501
|
+
for (let n = 0; n < e.length; n++) t = le[(t ^ e[n]) & 255] ^ t >>> 8;
|
|
1472
1502
|
return (t ^ 4294967295) >>> 0;
|
|
1473
1503
|
}
|
|
1474
1504
|
var F = new TextEncoder();
|
|
1475
|
-
function
|
|
1505
|
+
function de(e) {
|
|
1476
1506
|
return I(e.map((e) => ({
|
|
1477
1507
|
...e,
|
|
1478
1508
|
body: e.data,
|
|
1479
1509
|
method: 0
|
|
1480
1510
|
})));
|
|
1481
1511
|
}
|
|
1482
|
-
async function
|
|
1512
|
+
async function fe(e) {
|
|
1483
1513
|
let t = [];
|
|
1484
1514
|
for (let n of e) {
|
|
1485
|
-
let e = await
|
|
1515
|
+
let e = await pe(n.data);
|
|
1486
1516
|
t.push(e.length < n.data.length ? {
|
|
1487
1517
|
...n,
|
|
1488
1518
|
body: e,
|
|
@@ -1495,7 +1525,7 @@ async function pe(e) {
|
|
|
1495
1525
|
}
|
|
1496
1526
|
return I(t);
|
|
1497
1527
|
}
|
|
1498
|
-
async function
|
|
1528
|
+
async function pe(e) {
|
|
1499
1529
|
let t = new CompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
|
|
1500
1530
|
n.write(e), n.close();
|
|
1501
1531
|
let i = [];
|
|
@@ -1509,7 +1539,7 @@ async function me(e) {
|
|
|
1509
1539
|
function I(e) {
|
|
1510
1540
|
let t = [], n = [], r = 0;
|
|
1511
1541
|
for (let i of e) {
|
|
1512
|
-
let e = F.encode(i.name), a =
|
|
1542
|
+
let e = F.encode(i.name), a = ue(i.data), o = i.data.length, s = i.body.length, c = i.method === 8 ? 20 : 10, l = new ArrayBuffer(30 + e.length), u = new DataView(l);
|
|
1513
1543
|
u.setUint32(0, 67324752, !0), u.setUint16(4, c, !0), u.setUint16(6, 0, !0), u.setUint16(8, i.method, !0), u.setUint16(10, 0, !0), u.setUint16(12, 33, !0), u.setUint32(14, a, !0), u.setUint32(18, s, !0), u.setUint32(22, o, !0), u.setUint16(26, e.length, !0), u.setUint16(28, 0, !0), new Uint8Array(l, 30).set(e), t.push(new Uint8Array(l)), t.push(i.body);
|
|
1514
1544
|
let d = new ArrayBuffer(46 + e.length), f = new DataView(d);
|
|
1515
1545
|
f.setUint32(0, 33639248, !0), f.setUint16(4, 20, !0), f.setUint16(6, c, !0), f.setUint16(8, 0, !0), f.setUint16(10, i.method, !0), f.setUint16(12, 0, !0), f.setUint16(14, 33, !0), f.setUint32(16, a, !0), f.setUint32(20, s, !0), f.setUint32(24, o, !0), f.setUint16(28, e.length, !0), f.setUint16(30, 0, !0), f.setUint16(32, 0, !0), f.setUint16(34, 0, !0), f.setUint16(36, 0, !0), f.setUint32(38, 0, !0), f.setUint32(42, r, !0), new Uint8Array(d, 46).set(e), n.push(new Uint8Array(d)), r += 30 + e.length + s;
|
|
@@ -1529,27 +1559,27 @@ function L(e) {
|
|
|
1529
1559
|
function R(e) {
|
|
1530
1560
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1531
1561
|
}
|
|
1532
|
-
function
|
|
1562
|
+
function me(e) {
|
|
1533
1563
|
let t = "";
|
|
1534
1564
|
for (e++; e > 0;) t = String.fromCharCode(64 + (e % 26 || 26)) + t, e = Math.floor((e - 1) / 26);
|
|
1535
1565
|
return t;
|
|
1536
1566
|
}
|
|
1537
1567
|
function z(e, t) {
|
|
1538
|
-
return
|
|
1568
|
+
return me(t) + (e + 1);
|
|
1539
1569
|
}
|
|
1540
|
-
function
|
|
1570
|
+
function he(e) {
|
|
1541
1571
|
let t = Date.UTC(1899, 11, 30);
|
|
1542
1572
|
return (e.getTime() - t) / 864e5;
|
|
1543
1573
|
}
|
|
1544
|
-
var
|
|
1545
|
-
function
|
|
1574
|
+
var ge = "<?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>", _e = "<?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>", ve = "<?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>", ye = "<?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>", be = "<?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>";
|
|
1575
|
+
function xe(e, t) {
|
|
1546
1576
|
let n = [], r = t.map((e, t) => `<c r="${z(0, t)}" t="str" s="2"><v>${R(e.label)}</v></c>`);
|
|
1547
1577
|
return n.push(`<row r="1">${r.join("")}</row>`), e.forEach((e, r) => {
|
|
1548
1578
|
let i = t.map((t, n) => {
|
|
1549
1579
|
let i = z(r + 1, n), a = e[t.key];
|
|
1550
1580
|
if (a == null) return `<c r="${i}" t="str"><v></v></c>`;
|
|
1551
1581
|
let o = t.type ?? "text";
|
|
1552
|
-
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>${
|
|
1582
|
+
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>${he(a).toFixed(6)}</v></c>` : o === "boolean" ? `<c r="${i}" t="b"><v>${+!!a}</v></c>` : `<c r="${i}" t="str"><v>${R(String(a))}</v></c>`;
|
|
1553
1583
|
});
|
|
1554
1584
|
n.push(`<row r="${r + 2}">${i.join("")}</row>`);
|
|
1555
1585
|
}), `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
@@ -1557,30 +1587,30 @@ function Se(e, t) {
|
|
|
1557
1587
|
<sheetData>${n.join("")}</sheetData>
|
|
1558
1588
|
</worksheet>`;
|
|
1559
1589
|
}
|
|
1590
|
+
function Se(e, t) {
|
|
1591
|
+
return de(B(e, t));
|
|
1592
|
+
}
|
|
1560
1593
|
function Ce(e, t) {
|
|
1561
1594
|
return fe(B(e, t));
|
|
1562
1595
|
}
|
|
1563
|
-
function we(e, t) {
|
|
1564
|
-
return pe(B(e, t));
|
|
1565
|
-
}
|
|
1566
1596
|
function B(e, t) {
|
|
1567
|
-
let n =
|
|
1597
|
+
let n = xe(e, t);
|
|
1568
1598
|
return [
|
|
1569
1599
|
{
|
|
1570
1600
|
name: "[Content_Types].xml",
|
|
1571
|
-
data: F.encode(
|
|
1601
|
+
data: F.encode(ge)
|
|
1572
1602
|
},
|
|
1573
1603
|
{
|
|
1574
1604
|
name: "_rels/.rels",
|
|
1575
|
-
data: F.encode(
|
|
1605
|
+
data: F.encode(_e)
|
|
1576
1606
|
},
|
|
1577
1607
|
{
|
|
1578
1608
|
name: "xl/workbook.xml",
|
|
1579
|
-
data: F.encode(
|
|
1609
|
+
data: F.encode(ve)
|
|
1580
1610
|
},
|
|
1581
1611
|
{
|
|
1582
1612
|
name: "xl/_rels/workbook.xml.rels",
|
|
1583
|
-
data: F.encode(
|
|
1613
|
+
data: F.encode(ye)
|
|
1584
1614
|
},
|
|
1585
1615
|
{
|
|
1586
1616
|
name: "xl/worksheets/sheet1.xml",
|
|
@@ -1588,7 +1618,7 @@ function B(e, t) {
|
|
|
1588
1618
|
},
|
|
1589
1619
|
{
|
|
1590
1620
|
name: "xl/styles.xml",
|
|
1591
|
-
data: F.encode(
|
|
1621
|
+
data: F.encode(be)
|
|
1592
1622
|
}
|
|
1593
1623
|
];
|
|
1594
1624
|
}
|
|
@@ -1598,24 +1628,24 @@ function V(e, t, n) {
|
|
|
1598
1628
|
switch (n) {
|
|
1599
1629
|
case "csv": return H(e, t, ",");
|
|
1600
1630
|
case "tsv": return H(e, t, " ");
|
|
1601
|
-
case "json": return
|
|
1602
|
-
case "xlsx": return
|
|
1631
|
+
case "json": return Ee(e, t);
|
|
1632
|
+
case "xlsx": return Se(e, t);
|
|
1603
1633
|
}
|
|
1604
1634
|
}
|
|
1605
|
-
async function
|
|
1606
|
-
let r = n === "xlsx" ? await
|
|
1607
|
-
return new Blob([r], { type:
|
|
1635
|
+
async function we(e, t, n) {
|
|
1636
|
+
let r = n === "xlsx" ? await Ce(e, t) : V(e, t, n);
|
|
1637
|
+
return new Blob([r], { type: Ae(n) });
|
|
1608
1638
|
}
|
|
1609
|
-
function
|
|
1639
|
+
function Te(e, t) {
|
|
1610
1640
|
return e == null ? "" : (t.type === "date" || t.type === "datetime") && e instanceof Date ? e.toISOString() : String(e);
|
|
1611
1641
|
}
|
|
1612
1642
|
function H(e, t, n) {
|
|
1613
|
-
return [t.map((e) => U(e.label, n)).join(n), ...e.map((e) => t.map((t) => U(
|
|
1643
|
+
return [t.map((e) => U(e.label, n)).join(n), ...e.map((e) => t.map((t) => U(Te(e[t.key], t), n)).join(n))].join("\n");
|
|
1614
1644
|
}
|
|
1615
1645
|
function U(e, t) {
|
|
1616
1646
|
return e.includes(t) || e.includes("\"") || e.includes("\n") || e.includes("\r") ? "\"" + e.replace(/"/g, "\"\"") + "\"" : e;
|
|
1617
1647
|
}
|
|
1618
|
-
function
|
|
1648
|
+
function Ee(e, t) {
|
|
1619
1649
|
let n = e.map((e) => {
|
|
1620
1650
|
let n = {};
|
|
1621
1651
|
for (let r of t) {
|
|
@@ -1626,35 +1656,35 @@ function De(e, t) {
|
|
|
1626
1656
|
});
|
|
1627
1657
|
return JSON.stringify(n, null, 2);
|
|
1628
1658
|
}
|
|
1629
|
-
function
|
|
1659
|
+
function De(e, t) {
|
|
1630
1660
|
let n = URL.createObjectURL(e), r = document.createElement("a");
|
|
1631
1661
|
r.href = n, r.download = t, r.style.display = "none", document.body.appendChild(r), r.click(), document.body.removeChild(r), setTimeout(() => URL.revokeObjectURL(n), 100);
|
|
1632
1662
|
}
|
|
1633
|
-
var
|
|
1663
|
+
var Oe = {
|
|
1634
1664
|
csv: "text/csv;charset=utf-8",
|
|
1635
1665
|
tsv: "text/tab-separated-values;charset=utf-8",
|
|
1636
1666
|
json: "application/json;charset=utf-8",
|
|
1637
1667
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
1638
|
-
},
|
|
1668
|
+
}, ke = {
|
|
1639
1669
|
csv: ".csv",
|
|
1640
1670
|
tsv: ".tsv",
|
|
1641
1671
|
json: ".json",
|
|
1642
1672
|
xlsx: ".xlsx"
|
|
1643
1673
|
};
|
|
1674
|
+
function Ae(e) {
|
|
1675
|
+
return Oe[e];
|
|
1676
|
+
}
|
|
1644
1677
|
function je(e) {
|
|
1645
1678
|
return ke[e];
|
|
1646
1679
|
}
|
|
1647
|
-
function Me(e) {
|
|
1648
|
-
return Ae[e];
|
|
1649
|
-
}
|
|
1650
1680
|
//#endregion
|
|
1651
1681
|
//#region src/export/xlsx-reader.ts
|
|
1652
|
-
function
|
|
1682
|
+
function Me(e) {
|
|
1653
1683
|
for (let t = e.byteLength - 22; t >= 0; t--) if (e.getUint32(t, !0) === 101010256) return t;
|
|
1654
1684
|
throw Error("XLSX: End of central directory not found — not a valid ZIP file");
|
|
1655
1685
|
}
|
|
1656
|
-
function
|
|
1657
|
-
let t =
|
|
1686
|
+
function Ne(e) {
|
|
1687
|
+
let t = Me(e), n = e.getUint32(t + 16, !0), r = e.getUint32(t + 12, !0), i = new TextDecoder("utf-8"), a = [], o = n, s = n + r;
|
|
1658
1688
|
for (; o < s && e.getUint32(o, !0) === 33639248;) {
|
|
1659
1689
|
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));
|
|
1660
1690
|
a.push({
|
|
@@ -1667,7 +1697,7 @@ function Pe(e) {
|
|
|
1667
1697
|
}
|
|
1668
1698
|
return a;
|
|
1669
1699
|
}
|
|
1670
|
-
async function
|
|
1700
|
+
async function Pe(e) {
|
|
1671
1701
|
let t = new DecompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
|
|
1672
1702
|
n.write(e), n.close();
|
|
1673
1703
|
let i = [];
|
|
@@ -1680,28 +1710,28 @@ async function Fe(e) {
|
|
|
1680
1710
|
for (let e of i) o.set(e, s), s += e.length;
|
|
1681
1711
|
return o;
|
|
1682
1712
|
}
|
|
1683
|
-
async function
|
|
1713
|
+
async function Fe(e, t) {
|
|
1684
1714
|
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);
|
|
1685
1715
|
if (t.compressionMethod === 0) return o.slice();
|
|
1686
|
-
if (t.compressionMethod === 8) return
|
|
1716
|
+
if (t.compressionMethod === 8) return Pe(o);
|
|
1687
1717
|
throw Error(`XLSX: Unsupported compression method ${t.compressionMethod}`);
|
|
1688
1718
|
}
|
|
1689
|
-
async function
|
|
1690
|
-
let t = new DataView(e), n =
|
|
1691
|
-
for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await
|
|
1719
|
+
async function Ie(e) {
|
|
1720
|
+
let t = new DataView(e), n = Ne(t), r = /* @__PURE__ */ new Map();
|
|
1721
|
+
for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await Fe(t, e));
|
|
1692
1722
|
return r;
|
|
1693
1723
|
}
|
|
1694
|
-
var
|
|
1724
|
+
var Le = new TextDecoder("utf-8");
|
|
1695
1725
|
function W(e) {
|
|
1696
|
-
let t =
|
|
1726
|
+
let t = Le.decode(e);
|
|
1697
1727
|
return new DOMParser().parseFromString(t, "application/xml");
|
|
1698
1728
|
}
|
|
1699
|
-
function
|
|
1729
|
+
function Re(e) {
|
|
1700
1730
|
if (!e) return [];
|
|
1701
1731
|
let t = W(e);
|
|
1702
1732
|
return Array.from(t.querySelectorAll("si")).map((e) => Array.from(e.querySelectorAll("t")).map((e) => e.textContent ?? "").join(""));
|
|
1703
1733
|
}
|
|
1704
|
-
var
|
|
1734
|
+
var ze = /* @__PURE__ */ new Set([
|
|
1705
1735
|
14,
|
|
1706
1736
|
15,
|
|
1707
1737
|
16,
|
|
@@ -1721,29 +1751,29 @@ var Be = /* @__PURE__ */ new Set([
|
|
|
1721
1751
|
57,
|
|
1722
1752
|
58
|
|
1723
1753
|
]);
|
|
1724
|
-
function
|
|
1754
|
+
function Be(e) {
|
|
1725
1755
|
let t = e.replace(/"[^"]*"/g, "").replace(/\\./g, "").replace(/\[[^\]]*\]/g, "").split(";")[0];
|
|
1726
1756
|
return /[dy]/i.test(t);
|
|
1727
1757
|
}
|
|
1728
|
-
function
|
|
1758
|
+
function Ve(e) {
|
|
1729
1759
|
let t = /* @__PURE__ */ new Set();
|
|
1730
1760
|
if (!e) return t;
|
|
1731
1761
|
let n = W(e), r = /* @__PURE__ */ new Map();
|
|
1732
1762
|
for (let e of Array.from(n.querySelectorAll("numFmts > numFmt"))) r.set(parseInt(e.getAttribute("numFmtId") ?? "", 10), e.getAttribute("formatCode") ?? "");
|
|
1733
1763
|
return Array.from(n.querySelectorAll("cellXfs > xf")).forEach((e, n) => {
|
|
1734
1764
|
let i = parseInt(e.getAttribute("numFmtId") ?? "0", 10), a = r.get(i);
|
|
1735
|
-
(a === void 0 ?
|
|
1765
|
+
(a === void 0 ? ze.has(i) : Be(a)) && t.add(n);
|
|
1736
1766
|
}), t;
|
|
1737
1767
|
}
|
|
1738
|
-
function
|
|
1768
|
+
function He(e) {
|
|
1739
1769
|
if (!e) return !1;
|
|
1740
1770
|
let t = W(e).querySelector("workbookPr")?.getAttribute("date1904");
|
|
1741
1771
|
return t === "1" || t === "true";
|
|
1742
1772
|
}
|
|
1743
|
-
function
|
|
1773
|
+
function Ue(e, t) {
|
|
1744
1774
|
return new Date((t ? Date.UTC(1904, 0, 1) : Date.UTC(1899, 11, 30)) + Math.floor(e) * 864e5).toISOString().slice(0, 10);
|
|
1745
1775
|
}
|
|
1746
|
-
function
|
|
1776
|
+
function We(e, t, n, r) {
|
|
1747
1777
|
let i = W(e).querySelectorAll("row");
|
|
1748
1778
|
if (i.length === 0) return [];
|
|
1749
1779
|
let a = 0, o = /* @__PURE__ */ new Map();
|
|
@@ -1751,7 +1781,7 @@ function Ge(e, t, n, r) {
|
|
|
1751
1781
|
let i = parseInt(e.getAttribute("r") ?? "1", 10) - 1, s = /* @__PURE__ */ new Map();
|
|
1752
1782
|
o.set(i, s);
|
|
1753
1783
|
for (let i of e.querySelectorAll("c")) {
|
|
1754
|
-
let e =
|
|
1784
|
+
let e = Ge(i.getAttribute("r") ?? "");
|
|
1755
1785
|
e > a && (a = e);
|
|
1756
1786
|
let o = i.getAttribute("t") ?? "", c = i.getAttribute("s") ?? "", l = i.querySelector("v")?.textContent ?? "", u = i.querySelector("is > t")?.textContent ?? null, d;
|
|
1757
1787
|
if (o === "s") d = t[parseInt(l, 10)] ?? "";
|
|
@@ -1760,7 +1790,7 @@ function Ge(e, t, n, r) {
|
|
|
1760
1790
|
else if (l === "") d = "";
|
|
1761
1791
|
else {
|
|
1762
1792
|
let e = parseFloat(l);
|
|
1763
|
-
d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ?
|
|
1793
|
+
d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ? Ue(e, r) : l;
|
|
1764
1794
|
}
|
|
1765
1795
|
s.set(e, d);
|
|
1766
1796
|
}
|
|
@@ -1774,13 +1804,13 @@ function Ge(e, t, n, r) {
|
|
|
1774
1804
|
}
|
|
1775
1805
|
return c;
|
|
1776
1806
|
}
|
|
1777
|
-
function
|
|
1807
|
+
function Ge(e) {
|
|
1778
1808
|
let t = 0, n = 0;
|
|
1779
1809
|
for (; n < e.length && e[n] >= "A" && e[n] <= "Z";) t = t * 26 + (e.charCodeAt(n) - 64), n++;
|
|
1780
1810
|
return t - 1;
|
|
1781
1811
|
}
|
|
1782
|
-
async function
|
|
1783
|
-
let t = await
|
|
1812
|
+
async function Ke(e) {
|
|
1813
|
+
let t = await Ie(e), n = Re(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
|
|
1784
1814
|
if (!r) {
|
|
1785
1815
|
for (let [e, n] of t) if (e.toLowerCase().includes("worksheets/sheet")) {
|
|
1786
1816
|
r = n;
|
|
@@ -1788,7 +1818,7 @@ async function qe(e) {
|
|
|
1788
1818
|
}
|
|
1789
1819
|
}
|
|
1790
1820
|
if (!r) throw Error("XLSX: No worksheet found");
|
|
1791
|
-
let i =
|
|
1821
|
+
let i = Ve(t.get("xl/styles.xml")), a = He(t.get("xl/workbook.xml")), o = We(r, n, i, a);
|
|
1792
1822
|
return o.length === 0 ? {
|
|
1793
1823
|
headers: [],
|
|
1794
1824
|
rows: []
|
|
@@ -1819,14 +1849,14 @@ var q = {
|
|
|
1819
1849
|
lt: "<",
|
|
1820
1850
|
gte: "≥",
|
|
1821
1851
|
lte: "≤"
|
|
1822
|
-
}, J = 120, Y = 40, X = 20, Z = 32, Q = 5,
|
|
1852
|
+
}, J = 120, Y = 40, X = 20, Z = 32, Q = 5, qe = 200, $ = class extends n {
|
|
1823
1853
|
constructor(...e) {
|
|
1824
|
-
super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = Z, this._targetFloor = 0, 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
|
|
1854
|
+
super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = Z, this._targetFloor = 0, 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 = () => {
|
|
1825
1855
|
this._commitCommentPopup();
|
|
1826
1856
|
}, 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();
|
|
1827
1857
|
}
|
|
1828
1858
|
static {
|
|
1829
|
-
this.styles =
|
|
1859
|
+
this.styles = v;
|
|
1830
1860
|
}
|
|
1831
1861
|
get data() {
|
|
1832
1862
|
return this._data;
|
|
@@ -2193,10 +2223,10 @@ var q = {
|
|
|
2193
2223
|
rows: [],
|
|
2194
2224
|
cols: []
|
|
2195
2225
|
};
|
|
2196
|
-
return
|
|
2226
|
+
return we(n.rows, n.cols, e);
|
|
2197
2227
|
}
|
|
2198
2228
|
async exportToFile(e, t) {
|
|
2199
|
-
|
|
2229
|
+
De(await this.exportToBlob(e), t ?? `export${je(e)}`);
|
|
2200
2230
|
}
|
|
2201
2231
|
_exportSlice(e) {
|
|
2202
2232
|
if (e?.selectionOnly) {
|
|
@@ -2269,10 +2299,10 @@ var q = {
|
|
|
2269
2299
|
async importFromFile(e) {
|
|
2270
2300
|
let t = e.name.toLowerCase();
|
|
2271
2301
|
if (t.endsWith(".xlsx")) {
|
|
2272
|
-
let t = await
|
|
2302
|
+
let t = await Ke(await e.arrayBuffer());
|
|
2273
2303
|
this._applyImportedSheet(t);
|
|
2274
2304
|
} else if (t.endsWith(".csv") || t.endsWith(".tsv")) {
|
|
2275
|
-
let t = await e.text(), n =
|
|
2305
|
+
let t = await e.text(), n = h(t);
|
|
2276
2306
|
this._applyImportedRows(n);
|
|
2277
2307
|
} else console.warn(`flex-table importFromFile: unsupported file type "${e.name}"`);
|
|
2278
2308
|
}
|
|
@@ -2461,7 +2491,7 @@ var q = {
|
|
|
2461
2491
|
this._filteredIndices = Array.from({ length: this.data.length }, (e, t) => t), this._sortedIndices = this._filteredIndices;
|
|
2462
2492
|
return;
|
|
2463
2493
|
}
|
|
2464
|
-
if (this._filteredIndices =
|
|
2494
|
+
if (this._filteredIndices = ie(this.data, this._filters, (e, t, n) => {
|
|
2465
2495
|
this.dispatchEvent(new CustomEvent("filter-error", {
|
|
2466
2496
|
detail: {
|
|
2467
2497
|
error: e,
|
|
@@ -2484,14 +2514,23 @@ var q = {
|
|
|
2484
2514
|
_focusEditor() {
|
|
2485
2515
|
if (!this._editingCell) return;
|
|
2486
2516
|
let e = this.shadowRoot?.querySelector(".ft-editor");
|
|
2487
|
-
e &&
|
|
2517
|
+
if (e && this.shadowRoot.activeElement !== e) {
|
|
2518
|
+
if (e.localName === "u-date-picker") {
|
|
2519
|
+
let t = e;
|
|
2520
|
+
t.updateComplete.then(() => {
|
|
2521
|
+
t.isConnected && this.shadowRoot.activeElement !== t && (t.focus(), t.shadowRoot?.querySelector("[part~=\"input\"]")?.select());
|
|
2522
|
+
});
|
|
2523
|
+
return;
|
|
2524
|
+
}
|
|
2525
|
+
e.focus(), e.type === "text" && e.select();
|
|
2526
|
+
}
|
|
2488
2527
|
}
|
|
2489
2528
|
_measureViewport() {
|
|
2490
2529
|
let e = this.clientHeight, t = this.clientWidth;
|
|
2491
2530
|
e !== this._viewportHeight && (this._viewportHeight = e), t !== this._viewportWidth && (this._viewportWidth = t), this._warnIfUnconstrained();
|
|
2492
2531
|
}
|
|
2493
2532
|
_warnIfUnconstrained() {
|
|
2494
|
-
this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount <
|
|
2533
|
+
this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount < qe || 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.`));
|
|
2495
2534
|
}
|
|
2496
2535
|
_onScroll() {
|
|
2497
2536
|
this._scrollTop = this.scrollTop, this._scrollLeft = this.scrollLeft;
|
|
@@ -2619,6 +2658,21 @@ var q = {
|
|
|
2619
2658
|
} else this._cancelEdit();
|
|
2620
2659
|
return;
|
|
2621
2660
|
}
|
|
2661
|
+
if (e.type === "date" || e.type === "datetime") {
|
|
2662
|
+
let t = this.shadowRoot?.querySelector("u-date-picker.ft-editor");
|
|
2663
|
+
if (!t) {
|
|
2664
|
+
this._cancelEdit();
|
|
2665
|
+
return;
|
|
2666
|
+
}
|
|
2667
|
+
if (t.validity?.badInput) {
|
|
2668
|
+
let e = t.shadowRoot?.querySelector("[part~=\"input\"]")?.value ?? "";
|
|
2669
|
+
this._applyEdit(e);
|
|
2670
|
+
return;
|
|
2671
|
+
}
|
|
2672
|
+
let n = t.value || null;
|
|
2673
|
+
this._applyEdit(n && e.type === "datetime" ? n.slice(0, 16) : n);
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2622
2676
|
let t = this.shadowRoot?.querySelector(".ft-editor");
|
|
2623
2677
|
if (t) {
|
|
2624
2678
|
let n = N(t.value, e);
|
|
@@ -2645,7 +2699,7 @@ var q = {
|
|
|
2645
2699
|
}));
|
|
2646
2700
|
return;
|
|
2647
2701
|
}
|
|
2648
|
-
if (a.type === "number" && typeof e == "string" || a.type === "date" && typeof e == "string" &&
|
|
2702
|
+
if (a.type === "number" && typeof e == "string" || a.type === "date" && typeof e == "string" && f(e) === null || a.type === "datetime" && typeof e == "string" && p(e) === null) {
|
|
2649
2703
|
let t = A(a.type === "number" ? "notANumber" : a.type === "date" ? "notADate" : "notADateTime");
|
|
2650
2704
|
this._markCellInvalid(n, r, t), this.dispatchEvent(new CustomEvent("validation-error", {
|
|
2651
2705
|
detail: {
|
|
@@ -2710,7 +2764,9 @@ var q = {
|
|
|
2710
2764
|
}));
|
|
2711
2765
|
}
|
|
2712
2766
|
_onEditorKeyDown(e) {
|
|
2713
|
-
if (
|
|
2767
|
+
if (_(e)) return;
|
|
2768
|
+
let t = e.currentTarget;
|
|
2769
|
+
if (!(t?.localName === "u-date-picker" && (e.composedPath().some((e) => e instanceof Element && e.part?.contains("popover")) || e.key === "Escape" && Ye(t)))) {
|
|
2714
2770
|
if (this._autocompleteState && this._autocompleteState.candidates.length > 0) {
|
|
2715
2771
|
if (e.key === "ArrowDown") {
|
|
2716
2772
|
e.preventDefault(), e.stopPropagation();
|
|
@@ -2778,7 +2834,7 @@ var q = {
|
|
|
2778
2834
|
].includes(t) && this._handleCtrlKey(e)) return;
|
|
2779
2835
|
}
|
|
2780
2836
|
if (t.length !== 0 && this._visibleRowCount !== 0) {
|
|
2781
|
-
if ((e.key === "Enter" || e.key === "F2") && this._activeCell && !
|
|
2837
|
+
if ((e.key === "Enter" || e.key === "F2") && this._activeCell && !_(e)) {
|
|
2782
2838
|
e.preventDefault();
|
|
2783
2839
|
let n = t[this._activeCell.col];
|
|
2784
2840
|
n && this._isCellEditable(n) ? this._startEdit() : e.key === "Enter" && this._fireRowActivate(n);
|
|
@@ -2866,7 +2922,7 @@ var q = {
|
|
|
2866
2922
|
async _handleCopy(e) {
|
|
2867
2923
|
let t = this._selection.getEffectiveRange();
|
|
2868
2924
|
if (!t) return;
|
|
2869
|
-
let n = this.visibleColumns, r =
|
|
2925
|
+
let n = this.visibleColumns, r = oe(this._sortedIndices.map((e) => this.data[e]), n, t);
|
|
2870
2926
|
try {
|
|
2871
2927
|
await navigator.clipboard.writeText(r);
|
|
2872
2928
|
} catch (e) {
|
|
@@ -2892,10 +2948,10 @@ var q = {
|
|
|
2892
2948
|
if (!this._activeCell) return;
|
|
2893
2949
|
let e = await this._readClipboardText();
|
|
2894
2950
|
if (e == null) return;
|
|
2895
|
-
let t =
|
|
2951
|
+
let t = h(e);
|
|
2896
2952
|
if (t.length === 0) return;
|
|
2897
2953
|
let n = this._expandRowsForPaste(this._activeCell.row, t.length), r = this._applyPasteData(this._activeCell, t);
|
|
2898
|
-
if (r.length > 0 || n.length > 0) {
|
|
2954
|
+
if (this._selectPastedRange(this._activeCell, t), r.length > 0 || n.length > 0) {
|
|
2899
2955
|
let e = n.length;
|
|
2900
2956
|
this._undo.push({
|
|
2901
2957
|
label: "paste",
|
|
@@ -2933,6 +2989,13 @@ var q = {
|
|
|
2933
2989
|
})), null;
|
|
2934
2990
|
}
|
|
2935
2991
|
}
|
|
2992
|
+
_selectPastedRange(e, t) {
|
|
2993
|
+
let n = Math.max(...t.map((e) => e.length)), r = Math.min(e.row + t.length, this._visibleRowCount) - 1, i = Math.min(e.col + n, this.visibleColumns.length) - 1;
|
|
2994
|
+
(r !== e.row || i !== e.col) && (this._selection.setDimensions(this._visibleRowCount, this.visibleColumns.length), this._selection.setActive(e.row, e.col), this._selection.setActiveWithRange(r, i), this._activeCell = {
|
|
2995
|
+
row: e.row,
|
|
2996
|
+
col: e.col
|
|
2997
|
+
});
|
|
2998
|
+
}
|
|
2936
2999
|
_expandRowsForPaste(e, t) {
|
|
2937
3000
|
let n = [], r = e + t, i = this.maxRows > 0 ? this.maxRows : Infinity;
|
|
2938
3001
|
for (; this.data.length < r && this.data.length < i;) {
|
|
@@ -3622,7 +3685,7 @@ var q = {
|
|
|
3622
3685
|
i[t] = {
|
|
3623
3686
|
...i[t],
|
|
3624
3687
|
text: r,
|
|
3625
|
-
value: r.trim() === "" ? null :
|
|
3688
|
+
value: r.trim() === "" ? null : m(r)
|
|
3626
3689
|
}, this._numberFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
|
|
3627
3690
|
}}
|
|
3628
3691
|
@keydown=${(e) => {
|
|
@@ -4128,7 +4191,7 @@ var q = {
|
|
|
4128
4191
|
this._closeFindPanel();
|
|
4129
4192
|
return;
|
|
4130
4193
|
}
|
|
4131
|
-
e.key === "Enter" && !
|
|
4194
|
+
e.key === "Enter" && !_(e) && e.target instanceof HTMLInputElement && e.target.classList.contains("ft-find-input") && (e.shiftKey ? this._findPrev() : this._findNext());
|
|
4132
4195
|
}}>
|
|
4133
4196
|
<div class="ft-find-row">
|
|
4134
4197
|
<input class="ft-find-input" type="text" placeholder=${A("findPlaceholder")}
|
|
@@ -4340,7 +4403,7 @@ var q = {
|
|
|
4340
4403
|
${this._renderEditor(e, t)}
|
|
4341
4404
|
</div>
|
|
4342
4405
|
`;
|
|
4343
|
-
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,
|
|
4406
|
+
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 = [
|
|
4344
4407
|
"ft-cell",
|
|
4345
4408
|
`ft-type-${t.type ?? "text"}`,
|
|
4346
4409
|
`ft-align-${G(t)}`,
|
|
@@ -4355,7 +4418,7 @@ var q = {
|
|
|
4355
4418
|
t.reveal === "hover" ? "ft-reveal-hover" : ""
|
|
4356
4419
|
].filter(Boolean).join(" "), T = this._toDataIndex(n), E = this._comments.get(T)?.get(t.key) ?? null, D = E !== null, O = D ? i`<div class="ft-comment-indicator" title=${E}></div>` : a;
|
|
4357
4420
|
return i`
|
|
4358
|
-
<div class=${D ?
|
|
4421
|
+
<div class=${D ? w + " ft-has-comment" : w}
|
|
4359
4422
|
role="gridcell"
|
|
4360
4423
|
aria-colindex=${r + 1}
|
|
4361
4424
|
data-col-index=${r}
|
|
@@ -4369,7 +4432,7 @@ var q = {
|
|
|
4369
4432
|
@click=${(e) => this._onCellClickEvent(e, n, r)}
|
|
4370
4433
|
@dblclick=${() => this._onCellDblClick(n, r)}>
|
|
4371
4434
|
${O}
|
|
4372
|
-
${
|
|
4435
|
+
${C(e[t.key], e, t)}
|
|
4373
4436
|
</div>
|
|
4374
4437
|
`;
|
|
4375
4438
|
}
|
|
@@ -4382,18 +4445,17 @@ var q = {
|
|
|
4382
4445
|
@keydown=${this._onEditorKeyDown}
|
|
4383
4446
|
@blur=${() => this._commitEdit()}>
|
|
4384
4447
|
`;
|
|
4385
|
-
if (t.type === "date")
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
if (t.type === "datetime") return i`
|
|
4392
|
-
<input class="ft-editor ft-editor-datetime" type="text" placeholder=${`${u()} HH:mm`}
|
|
4393
|
-
.value=${le(n)}
|
|
4448
|
+
if (t.type === "date" || t.type === "datetime") {
|
|
4449
|
+
let e = t.type === "datetime";
|
|
4450
|
+
return i`
|
|
4451
|
+
<u-date-picker class="ft-editor ft-editor-${t.type}" size="sm"
|
|
4452
|
+
mode=${e ? "datetime" : "date"} ?confirm=${e}
|
|
4453
|
+
.value=${Je(n, e)}
|
|
4394
4454
|
@keydown=${this._onEditorKeyDown}
|
|
4395
|
-
@
|
|
4455
|
+
@change=${() => this._commitEdit()}
|
|
4456
|
+
@blur=${() => this._commitEdit()}></u-date-picker>
|
|
4396
4457
|
`;
|
|
4458
|
+
}
|
|
4397
4459
|
if (t.type === "select" && t.options && t.options.length > 0) {
|
|
4398
4460
|
let e = t.options, r = typeof e[0] == "string";
|
|
4399
4461
|
return i`
|
|
@@ -4490,5 +4552,20 @@ K([s({ type: Array })], $.prototype, "columns", void 0), K([s({
|
|
|
4490
4552
|
type: Number,
|
|
4491
4553
|
attribute: "max-undo-size"
|
|
4492
4554
|
})], $.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")], $);
|
|
4555
|
+
function Je(e, t) {
|
|
4556
|
+
if (t) {
|
|
4557
|
+
let t = ce(e);
|
|
4558
|
+
return /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(t) ? t.replace(" ", "T") : void 0;
|
|
4559
|
+
}
|
|
4560
|
+
let n = se(e);
|
|
4561
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(n) ? n : void 0;
|
|
4562
|
+
}
|
|
4563
|
+
function Ye(e) {
|
|
4564
|
+
try {
|
|
4565
|
+
return e.matches(":state(open)");
|
|
4566
|
+
} catch {
|
|
4567
|
+
return !1;
|
|
4568
|
+
}
|
|
4569
|
+
}
|
|
4493
4570
|
//#endregion
|
|
4494
|
-
export { j as a, M as i, G as n, k as o, V as r,
|
|
4571
|
+
export { j as a, M as i, G as n, k as o, V as r, C as s, $ as t };
|
package/dist/flex-table.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LitElement, type PropertyValues } from 'lit';
|
|
2
|
+
import '@iyulab/components/dist/components/date-picker/UDatePicker.js';
|
|
2
3
|
import type { ExportFormat } from './export/export.js';
|
|
3
4
|
import type { CellPosition, CellRange } from './core/selection.js';
|
|
4
5
|
import type { SortCriteria } from './core/sorting.js';
|
|
@@ -395,6 +396,12 @@ export declare class FlexTable extends LitElement {
|
|
|
395
396
|
private _handleCopy;
|
|
396
397
|
private _handlePaste;
|
|
397
398
|
private _readClipboardText;
|
|
399
|
+
/**
|
|
400
|
+
* After a paste, the cells it wrote are the selection — as in spreadsheets — so the reader sees
|
|
401
|
+
* what changed and can copy, clear or undo it as one block. The active cell stays where the
|
|
402
|
+
* paste began (the same shape as selecting a column: range to the far corner, focus at the start).
|
|
403
|
+
*/
|
|
404
|
+
private _selectPastedRange;
|
|
398
405
|
private _expandRowsForPaste;
|
|
399
406
|
private _applyPasteData;
|
|
400
407
|
private _handleFillDown;
|
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-DIQhqj12.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/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./flex-table-
|
|
1
|
+
import { t as e } from "./flex-table-DIQhqj12.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.
|
|
3
|
+
"version": "0.46.0",
|
|
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": ">=
|
|
75
|
+
"@iyulab/components": ">=2.0.1",
|
|
76
76
|
"@lit/react": "^1.0.8",
|
|
77
77
|
"react": "^18.0.0 || ^19.0.0"
|
|
78
78
|
},
|
|
@@ -66,7 +66,7 @@ as `text`). See `references/api.md` for every field.
|
|
|
66
66
|
- `editor` returns a Lit template containing an element with class `ft-editor`; its `.value` is committed.
|
|
67
67
|
- `validator` returns `null` when valid, or an error message (the edit is rejected and `validation-error` fires).
|
|
68
68
|
- `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`.
|
|
69
|
-
- `date` cells edit
|
|
69
|
+
- `date` cells edit with `u-date-picker` (a `YYYY-MM-DD` text box in every browser language plus a calendar) (also `20261002`, `2026/10/2`, `10-02`); pasted dates are normalized to ISO. `datetime` cells edit as `YYYY-MM-DD HH:mm` (local) and store `YYYY-MM-DDTHH:mm`.
|
|
70
70
|
- `conditionalRules` applies `{ when, style }` rules in order; later matches override earlier ones.
|
|
71
71
|
- `pinned: 'left' | 'right'` freezes a column during horizontal scroll.
|
|
72
72
|
|