@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 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 { dateTextPattern as u, formatDate as d, formatNumber as f, parseDate as p, parseDateTime as m, parseNumber as h } from "@iyulab/components/dist/utilities/format.js";
6
- import { decodeTsv as g, encodeTsv as _ } from "@iyulab/components/dist/utilities/tsv.js";
7
- import { isImeComposing as v } from "@iyulab/components/dist/utilities/keyboard.js";
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 y = r`
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 b(e, t) {
978
- return e == null ? "" : typeof t == "function" ? t(e) : x(t) ? C(e, t) : S(e, t);
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 x(e) {
1010
+ function b(e) {
981
1011
  return /[yMdHhms]/.test(e);
982
1012
  }
983
- function S(e, t) {
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 C(e, t) {
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 w(e, t, n) {
1008
- return n.render ? n.render(e, t, n) : n.format ? typeof n.format == "function" ? n.format(e, t, n) : b(e, n.format) : T(e, 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 T(e, t) {
1040
+ function w(e, t) {
1011
1041
  if (e == null) return "";
1012
1042
  switch (t.type) {
1013
- case "number": return O(e);
1043
+ case "number": return D(e);
1014
1044
  case "boolean": return i`<span class="ft-bool">${e ? "✔" : ""}</span>`;
1015
- case "date": return ee(e);
1016
- case "datetime": return te(e);
1017
- case "select": return E(e, t);
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 E(e, t) {
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 D = {
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 == "number" ? Number.isInteger(e) ? f(e) : f(e, { minimumFractionDigits: 1 }) : String(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" ? d(e) : String(e);
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 ne(e) {
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 re = class {
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 = ne({
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
- }, ie = class {
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 ae(e, t, n) {
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 oe = 100, M = class {
1401
+ var ae = 100, M = class {
1372
1402
  constructor() {
1373
- this._undoStack = [], this._redoStack = [], this._maxSize = oe;
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 se(e, t, n) {
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 _(r);
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 = h(e);
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 p(e) ?? e;
1433
- case "datetime": return m(e) ?? e;
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 ce(e) {
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 le(e) {
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 ue = (() => {
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 de(e) {
1499
+ function ue(e) {
1470
1500
  let t = 4294967295;
1471
- for (let n = 0; n < e.length; n++) t = ue[(t ^ e[n]) & 255] ^ t >>> 8;
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 fe(e) {
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 pe(e) {
1512
+ async function fe(e) {
1483
1513
  let t = [];
1484
1514
  for (let n of e) {
1485
- let e = await me(n.data);
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 me(e) {
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 = de(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);
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1531
1561
  }
1532
- function he(e) {
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 he(t) + (e + 1);
1568
+ return me(t) + (e + 1);
1539
1569
  }
1540
- function ge(e) {
1570
+ function he(e) {
1541
1571
  let t = Date.UTC(1899, 11, 30);
1542
1572
  return (e.getTime() - t) / 864e5;
1543
1573
  }
1544
- var _e = "<?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>", ve = "<?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>", ye = "<?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>", be = "<?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>", xe = "<?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>";
1545
- function Se(e, t) {
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>${ge(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>`;
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 = Se(e, t);
1597
+ let n = xe(e, t);
1568
1598
  return [
1569
1599
  {
1570
1600
  name: "[Content_Types].xml",
1571
- data: F.encode(_e)
1601
+ data: F.encode(ge)
1572
1602
  },
1573
1603
  {
1574
1604
  name: "_rels/.rels",
1575
- data: F.encode(ve)
1605
+ data: F.encode(_e)
1576
1606
  },
1577
1607
  {
1578
1608
  name: "xl/workbook.xml",
1579
- data: F.encode(ye)
1609
+ data: F.encode(ve)
1580
1610
  },
1581
1611
  {
1582
1612
  name: "xl/_rels/workbook.xml.rels",
1583
- data: F.encode(be)
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(xe)
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 De(e, t);
1602
- case "xlsx": return Ce(e, t);
1631
+ case "json": return Ee(e, t);
1632
+ case "xlsx": return Se(e, t);
1603
1633
  }
1604
1634
  }
1605
- async function Te(e, t, n) {
1606
- let r = n === "xlsx" ? await we(e, t) : V(e, t, n);
1607
- return new Blob([r], { type: je(n) });
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 Ee(e, t) {
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(Ee(e[t.key], t), n)).join(n))].join("\n");
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 De(e, t) {
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 Oe(e, t) {
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 ke = {
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
- }, Ae = {
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 Ne(e) {
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 Pe(e) {
1657
- let t = Ne(e), n = e.getUint32(t + 16, !0), r = e.getUint32(t + 12, !0), i = new TextDecoder("utf-8"), a = [], o = n, s = n + r;
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 Fe(e) {
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 Ie(e, t) {
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 Fe(o);
1716
+ if (t.compressionMethod === 8) return Pe(o);
1687
1717
  throw Error(`XLSX: Unsupported compression method ${t.compressionMethod}`);
1688
1718
  }
1689
- async function Le(e) {
1690
- let t = new DataView(e), n = Pe(t), r = /* @__PURE__ */ new Map();
1691
- for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await Ie(t, e));
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 Re = new TextDecoder("utf-8");
1724
+ var Le = new TextDecoder("utf-8");
1695
1725
  function W(e) {
1696
- let t = Re.decode(e);
1726
+ let t = Le.decode(e);
1697
1727
  return new DOMParser().parseFromString(t, "application/xml");
1698
1728
  }
1699
- function ze(e) {
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 Be = /* @__PURE__ */ new Set([
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 Ve(e) {
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 He(e) {
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 ? Be.has(i) : Ve(a)) && t.add(n);
1765
+ (a === void 0 ? ze.has(i) : Be(a)) && t.add(n);
1736
1766
  }), t;
1737
1767
  }
1738
- function Ue(e) {
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 We(e, t) {
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 Ge(e, t, n, r) {
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 = Ke(i.getAttribute("r") ?? "");
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 ? We(e, r) : l;
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 Ke(e) {
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 qe(e) {
1783
- let t = await Le(e), n = ze(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
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 = He(t.get("xl/styles.xml")), a = Ue(t.get("xl/workbook.xml")), o = Ge(r, n, i, a);
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, Je = 200, $ = class extends n {
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 re(), this._editing = new ie(), 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 = () => {
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 = y;
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 Te(n.rows, n.cols, e);
2226
+ return we(n.rows, n.cols, e);
2197
2227
  }
2198
2228
  async exportToFile(e, t) {
2199
- Oe(await this.exportToBlob(e), t ?? `export${Me(e)}`);
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 qe(await e.arrayBuffer());
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 = g(t);
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 = ae(this.data, this._filters, (e, t, n) => {
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 && document.activeElement !== e && (e.focus(), e.type === "text" && e.select());
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 < Je || 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.`));
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" && p(e) === null || a.type === "datetime" && typeof e == "string" && m(e) === null) {
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 (!v(e)) {
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 && !v(e)) {
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 = se(this._sortedIndices.map((e) => this.data[e]), n, t);
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 = g(e);
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 : h(r)
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" && !v(e) && e.target instanceof HTMLInputElement && e.target.classList.contains("ft-find-input") && (e.shiftKey ? this._findPrev() : this._findNext());
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, C = [
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 ? C + " ft-has-comment" : C}
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
- ${w(e[t.key], e, t)}
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") return i`
4386
- <input class="ft-editor ft-editor-date" type="text" inputmode="numeric" placeholder=${u()}
4387
- .value=${ce(n)}
4388
- @keydown=${this._onEditorKeyDown}
4389
- @blur=${() => this._commitEdit()}>
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
- @blur=${() => this._commitEdit()}>
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, w as s, $ as t };
4571
+ export { j as a, M as i, G as n, k as o, V as r, C as s, $ as t };
@@ -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;
@@ -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-Bv41ls8b.js";
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-Bv41ls8b.js";
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.45.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": ">=1.56.0",
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 as a `YYYY-MM-DD` text box in every browser language (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`.
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