@iyulab/flex-table 0.40.3 → 0.41.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.
@@ -2,11 +2,11 @@ import { n as e, t } from "./sorting-CjfjRxwL.js";
2
2
  import { LitElement as n, css as r, html as i, nothing as a } from "lit";
3
3
  import { customElement as o, property as s, state as c } from "lit/decorators.js";
4
4
  import { Locale as l } from "@iyulab/components/dist/utilities/Locale.js";
5
- import { formatDate as u, formatNumber as d } from "@iyulab/components/dist/utilities/format.js";
6
- import { decodeTsv as f, encodeTsv as p } from "@iyulab/components/dist/utilities/tsv.js";
7
- import { isImeComposing as m } from "@iyulab/components/dist/utilities/keyboard.js";
5
+ import { formatDate as u, formatNumber as d, parseNumber as f } from "@iyulab/components/dist/utilities/format.js";
6
+ import { decodeTsv as p, encodeTsv as m } from "@iyulab/components/dist/utilities/tsv.js";
7
+ import { isImeComposing as h } from "@iyulab/components/dist/utilities/keyboard.js";
8
8
  //#region src/styles/flex-table.styles.ts
9
- var h = r`
9
+ var g = r`
10
10
  /* --- Theme Variables (Light defaults) --- */
11
11
  :host {
12
12
  --ft-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
@@ -262,6 +262,15 @@ var h = r`
262
262
  .ft-row-even:hover .ft-cell { background: var(--ft-row-hover-bg); }
263
263
  .ft-row-odd:hover .ft-cell { background: var(--ft-row-odd-hover-bg); }
264
264
 
265
+ /* mergeRepeated — one surface per run: the row it starts on sets the background, the lines
266
+ inside the run go, and the repeated values stay in the DOM (copy, find and screen readers
267
+ read them) but are not painted. A selected or active cell paints its value again. */
268
+ .ft-row-even .ft-cell.ft-merge-even:not(.ft-invalid), .ft-row-odd .ft-cell.ft-merge-even:not(.ft-invalid) { background: var(--ft-row-even-bg); }
269
+ .ft-row-even .ft-cell.ft-merge-odd:not(.ft-invalid), .ft-row-odd .ft-cell.ft-merge-odd:not(.ft-invalid) { background: var(--ft-row-odd-bg); }
270
+ .ft-cell.ft-merge-open { border-bottom-color: transparent; }
271
+ .ft-cell.ft-merge-continued:not(.ft-active):not(.ft-selected) { color: transparent; }
272
+ .ft-cell.ft-merge-continued:not(.ft-active):not(.ft-selected) > :not(.ft-comment-indicator) { opacity: 0; }
273
+
265
274
  .ft-cell.ft-active {
266
275
  outline: 2px solid var(--ft-active-color);
267
276
  outline-offset: -2px;
@@ -912,13 +921,13 @@ var h = r`
912
921
  `;
913
922
  //#endregion
914
923
  //#region src/renderers/format.ts
915
- function g(e, t) {
916
- return e == null ? "" : typeof t == "function" ? t(e) : _(t) ? y(e, t) : v(e, t);
924
+ function _(e, t) {
925
+ return e == null ? "" : typeof t == "function" ? t(e) : v(t) ? b(e, t) : y(e, t);
917
926
  }
918
- function _(e) {
927
+ function v(e) {
919
928
  return /[yMdHhms]/.test(e);
920
929
  }
921
- function v(e, t) {
930
+ function y(e, t) {
922
931
  let n = typeof e == "number" ? e : Number(e);
923
932
  if (isNaN(n)) return String(e);
924
933
  let r = t.endsWith("%"), i = t.match(/^([^#0.,%]+)/), a = i ? i[1] : "", o = t.replace(/^[^#0.,%]+/, "").replace(/%$/, ""), s = o.match(/\.([0#]+)$/), c = s ? s[1].length : 0, u = {
@@ -931,7 +940,7 @@ function v(e, t) {
931
940
  style: "percent"
932
941
  }).format(n) : (d = new Intl.NumberFormat(l.get(), u).format(n), a && (d = a + d)), d + "";
933
942
  }
934
- function y(e, t) {
943
+ function b(e, t) {
935
944
  let n;
936
945
  if (e instanceof Date) n = e;
937
946
  else if (typeof e == "string" || typeof e == "number") n = new Date(e);
@@ -942,26 +951,26 @@ function y(e, t) {
942
951
  }
943
952
  //#endregion
944
953
  //#region src/renderers/cell-renderer.ts
945
- function b(e, t, n) {
946
- return n.render ? n.render(e, t, n) : n.format ? typeof n.format == "function" ? n.format(e, t, n) : g(e, n.format) : x(e, n);
954
+ function x(e, t, n) {
955
+ return n.render ? n.render(e, t, n) : n.format ? typeof n.format == "function" ? n.format(e, t, n) : _(e, n.format) : S(e, n);
947
956
  }
948
- function x(e, t) {
957
+ function S(e, t) {
949
958
  if (e == null) return "";
950
959
  switch (t.type) {
951
- case "number": return w(e);
960
+ case "number": return T(e);
952
961
  case "boolean": return i`<span class="ft-bool">${e ? "✔" : ""}</span>`;
953
- case "date": return T(e);
954
- case "datetime": return E(e);
955
- case "select": return S(e, t);
962
+ case "date": return E(e);
963
+ case "datetime": return D(e);
964
+ case "select": return C(e, t);
956
965
  default: return String(e);
957
966
  }
958
967
  }
959
- function S(e, t) {
968
+ function C(e, t) {
960
969
  if (!t.options || t.options.length === 0 || typeof t.options[0] == "string") return e == null ? "" : String(e);
961
970
  let n = t.options.find((t) => t.value === e);
962
971
  return n ? n.label : e == null ? "" : String(e);
963
972
  }
964
- var C = {
973
+ var w = {
965
974
  year: "numeric",
966
975
  month: "numeric",
967
976
  day: "numeric",
@@ -969,19 +978,19 @@ var C = {
969
978
  minute: "numeric",
970
979
  second: "numeric"
971
980
  };
972
- function w(e) {
981
+ function T(e) {
973
982
  return typeof e == "number" ? Number.isInteger(e) ? d(e) : d(e, { minimumFractionDigits: 1 }) : String(e);
974
983
  }
975
- function T(e) {
984
+ function E(e) {
976
985
  return e instanceof Date || typeof e == "string" ? u(e) : String(e);
977
986
  }
978
- function E(e) {
979
- return e instanceof Date || typeof e == "string" ? u(e, C) : String(e);
987
+ function D(e) {
988
+ return e instanceof Date || typeof e == "string" ? u(e, w) : String(e);
980
989
  }
981
990
  //#endregion
982
991
  //#region src/locale.ts
983
- var D = l.namespace("flex-table");
984
- D.register("en", {
992
+ var O = l.namespace("flex-table");
993
+ O.register("en", {
985
994
  showHiddenColumns: "Show hidden column(s)",
986
995
  columnMenu: "Column menu",
987
996
  cellActions: "Cell actions",
@@ -1033,8 +1042,10 @@ D.register("en", {
1033
1042
  deleteComment: "Delete Comment",
1034
1043
  booleanTrue: "True",
1035
1044
  booleanFalse: "False",
1036
- dropFileToImport: "Drop file to import (.xlsx / .csv)"
1037
- }), D.register("ko", {
1045
+ dropFileToImport: "Drop file to import (.xlsx / .csv)",
1046
+ notANumber: "Enter a number",
1047
+ notInList: "Value must be from the existing list"
1048
+ }), O.register("ko", {
1038
1049
  showHiddenColumns: "숨긴 열 보기",
1039
1050
  columnMenu: "열 메뉴",
1040
1051
  cellActions: "셀 작업",
@@ -1086,9 +1097,11 @@ D.register("en", {
1086
1097
  deleteComment: "메모 삭제",
1087
1098
  booleanTrue: "참",
1088
1099
  booleanFalse: "거짓",
1089
- dropFileToImport: "가져올 파일을 놓으세요 (.xlsx / .csv)"
1100
+ dropFileToImport: "가져올 파일을 놓으세요 (.xlsx / .csv)",
1101
+ notANumber: "숫자를 입력하세요",
1102
+ notInList: "목록에 있는 값이어야 합니다"
1090
1103
  });
1091
- var O = (e, t) => D.text(e, t);
1104
+ var k = (e, t) => O.text(e, t);
1092
1105
  //#endregion
1093
1106
  //#region src/core/selection.ts
1094
1107
  function ee(e) {
@@ -1218,7 +1231,7 @@ var te = class {
1218
1231
  let e = this.current;
1219
1232
  return this.current = null, e;
1220
1233
  }
1221
- }, k = class {
1234
+ }, A = class {
1222
1235
  constructor() {
1223
1236
  this._selected = /* @__PURE__ */ new Set(), this._mode = "multi", this._rowCount = 0;
1224
1237
  }
@@ -1298,7 +1311,7 @@ function re(e, t, n) {
1298
1311
  }
1299
1312
  //#endregion
1300
1313
  //#region src/core/undo.ts
1301
- var ie = 100, A = class {
1314
+ var ie = 100, j = class {
1302
1315
  constructor() {
1303
1316
  this._undoStack = [], this._redoStack = [], this._maxSize = ie;
1304
1317
  }
@@ -1347,22 +1360,30 @@ function ae(e, t, n) {
1347
1360
  }
1348
1361
  r.push(o);
1349
1362
  }
1350
- return p(r);
1363
+ return m(r);
1351
1364
  }
1352
- function j(e, t) {
1365
+ function M(e, t) {
1353
1366
  if (e === "") return null;
1354
1367
  switch (t.type) {
1355
1368
  case "number": {
1356
- let t = Number(e);
1357
- return isNaN(t) ? e : t;
1369
+ let t = f(e);
1370
+ if (t !== null) return t;
1371
+ let n = Number(e.trim());
1372
+ return e.trim() !== "" && Number.isFinite(n) ? n : e;
1358
1373
  }
1359
1374
  case "boolean": return e.toLowerCase() === "true" || e === "1";
1360
1375
  default: return e;
1361
1376
  }
1362
1377
  }
1378
+ function N(e) {
1379
+ let t = String(e);
1380
+ if (!Number.isFinite(e) || t.includes("e")) return t;
1381
+ let n = new Intl.NumberFormat(l.get()).formatToParts(1.5).find((e) => e.type === "decimal")?.value;
1382
+ return n && n !== "." ? t.replace(".", n) : t;
1383
+ }
1363
1384
  //#endregion
1364
1385
  //#region src/export/xlsx-writer.ts
1365
- var M = (() => {
1386
+ var oe = (() => {
1366
1387
  let e = /* @__PURE__ */ new Uint32Array(256);
1367
1388
  for (let t = 0; t < 256; t++) {
1368
1389
  let n = t;
@@ -1371,56 +1392,56 @@ var M = (() => {
1371
1392
  }
1372
1393
  return e;
1373
1394
  })();
1374
- function oe(e) {
1395
+ function se(e) {
1375
1396
  let t = 4294967295;
1376
- for (let n = 0; n < e.length; n++) t = M[(t ^ e[n]) & 255] ^ t >>> 8;
1397
+ for (let n = 0; n < e.length; n++) t = oe[(t ^ e[n]) & 255] ^ t >>> 8;
1377
1398
  return (t ^ 4294967295) >>> 0;
1378
1399
  }
1379
- var N = new TextEncoder();
1380
- function se(e) {
1400
+ var P = new TextEncoder();
1401
+ function ce(e) {
1381
1402
  let t = [], n = [], r = 0;
1382
1403
  for (let i of e) {
1383
- let e = N.encode(i.name), a = oe(i.data), o = i.data.length, s = new ArrayBuffer(30 + e.length), c = new DataView(s);
1404
+ let e = P.encode(i.name), a = se(i.data), o = i.data.length, s = new ArrayBuffer(30 + e.length), c = new DataView(s);
1384
1405
  c.setUint32(0, 67324752, !0), c.setUint16(4, 20, !0), c.setUint16(6, 0, !0), c.setUint16(8, 0, !0), c.setUint16(10, 0, !0), c.setUint16(12, 33, !0), c.setUint32(14, a, !0), c.setUint32(18, o, !0), c.setUint32(22, o, !0), c.setUint16(26, e.length, !0), c.setUint16(28, 0, !0), new Uint8Array(s, 30).set(e), t.push(new Uint8Array(s)), t.push(i.data);
1385
1406
  let l = new ArrayBuffer(46 + e.length), u = new DataView(l);
1386
1407
  u.setUint32(0, 33639248, !0), u.setUint16(4, 20, !0), u.setUint16(6, 20, !0), u.setUint16(8, 0, !0), u.setUint16(10, 0, !0), u.setUint16(12, 0, !0), u.setUint16(14, 33, !0), u.setUint32(16, a, !0), u.setUint32(20, o, !0), u.setUint32(24, o, !0), u.setUint16(28, e.length, !0), u.setUint16(30, 0, !0), u.setUint16(32, 0, !0), u.setUint16(34, 0, !0), u.setUint16(36, 0, !0), u.setUint32(38, 0, !0), u.setUint32(42, r, !0), new Uint8Array(l, 46).set(e), n.push(new Uint8Array(l)), r += 30 + e.length + o;
1387
1408
  }
1388
- let i = P(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
1389
- return o.setUint32(0, 101010256, !0), o.setUint16(4, 0, !0), o.setUint16(6, 0, !0), o.setUint16(8, e.length, !0), o.setUint16(10, e.length, !0), o.setUint32(12, i.length, !0), o.setUint32(16, r, !0), o.setUint16(20, 0, !0), P([
1409
+ let i = F(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
1410
+ return o.setUint32(0, 101010256, !0), o.setUint16(4, 0, !0), o.setUint16(6, 0, !0), o.setUint16(8, e.length, !0), o.setUint16(10, e.length, !0), o.setUint32(12, i.length, !0), o.setUint32(16, r, !0), o.setUint16(20, 0, !0), F([
1390
1411
  ...t,
1391
1412
  i,
1392
1413
  new Uint8Array(a)
1393
1414
  ]);
1394
1415
  }
1395
- function P(e) {
1416
+ function F(e) {
1396
1417
  let t = e.reduce((e, t) => e + t.length, 0), n = new Uint8Array(t), r = 0;
1397
1418
  for (let t of e) n.set(t, r), r += t.length;
1398
1419
  return n;
1399
1420
  }
1400
- function F(e) {
1421
+ function I(e) {
1401
1422
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1402
1423
  }
1403
- function ce(e) {
1424
+ function le(e) {
1404
1425
  let t = "";
1405
1426
  for (e++; e > 0;) t = String.fromCharCode(64 + (e % 26 || 26)) + t, e = Math.floor((e - 1) / 26);
1406
1427
  return t;
1407
1428
  }
1408
- function I(e, t) {
1409
- return ce(t) + (e + 1);
1429
+ function L(e, t) {
1430
+ return le(t) + (e + 1);
1410
1431
  }
1411
- function le(e) {
1432
+ function ue(e) {
1412
1433
  let t = Date.UTC(1899, 11, 30);
1413
1434
  return (e.getTime() - t) / 864e5;
1414
1435
  }
1415
- var ue = "<?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>", de = "<?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>", fe = "<?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>", pe = "<?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>", L = "<?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>";
1416
- function R(e, t) {
1417
- let n = [], r = t.map((e, t) => `<c r="${I(0, t)}" t="str" s="2"><v>${F(e.label)}</v></c>`);
1436
+ var de = "<?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>", fe = "<?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>", pe = "<?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>", me = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>", R = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">\n <numFmts count=\"1\"><numFmt numFmtId=\"164\" formatCode=\"yyyy-mm-dd\"/></numFmts>\n <fonts count=\"2\">\n <font><sz val=\"11\"/><name val=\"Calibri\"/></font>\n <font><sz val=\"11\"/><b/><name val=\"Calibri\"/></font>\n </fonts>\n <fills count=\"2\">\n <fill><patternFill patternType=\"none\"/></fill>\n <fill><patternFill patternType=\"gray125\"/></fill>\n </fills>\n <borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>\n <cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>\n <cellXfs count=\"3\">\n <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>\n <xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>\n <xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>\n </cellXfs>\n</styleSheet>";
1437
+ function z(e, t) {
1438
+ let n = [], r = t.map((e, t) => `<c r="${L(0, t)}" t="str" s="2"><v>${I(e.label)}</v></c>`);
1418
1439
  return n.push(`<row r="1">${r.join("")}</row>`), e.forEach((e, r) => {
1419
1440
  let i = t.map((t, n) => {
1420
- let i = I(r + 1, n), a = e[t.key];
1441
+ let i = L(r + 1, n), a = e[t.key];
1421
1442
  if (a == null) return `<c r="${i}" t="str"><v></v></c>`;
1422
1443
  let o = t.type ?? "text";
1423
- 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>${le(a).toFixed(6)}</v></c>` : o === "boolean" ? `<c r="${i}" t="b"><v>${+!!a}</v></c>` : `<c r="${i}" t="str"><v>${F(String(a))}</v></c>`;
1444
+ return o === "number" && typeof a == "number" ? `<c r="${i}"><v>${a}</v></c>` : (o === "date" || o === "datetime") && a instanceof Date ? `<c r="${i}" s="1"><v>${ue(a).toFixed(6)}</v></c>` : o === "boolean" ? `<c r="${i}" t="b"><v>${+!!a}</v></c>` : `<c r="${i}" t="str"><v>${I(String(a))}</v></c>`;
1424
1445
  });
1425
1446
  n.push(`<row r="${r + 2}">${i.join("")}</row>`);
1426
1447
  }), `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@@ -1428,32 +1449,32 @@ function R(e, t) {
1428
1449
  <sheetData>${n.join("")}</sheetData>
1429
1450
  </worksheet>`;
1430
1451
  }
1431
- function z(e, t) {
1432
- let n = R(e, t);
1433
- return se([
1452
+ function he(e, t) {
1453
+ let n = z(e, t);
1454
+ return ce([
1434
1455
  {
1435
1456
  name: "[Content_Types].xml",
1436
- data: N.encode(ue)
1457
+ data: P.encode(de)
1437
1458
  },
1438
1459
  {
1439
1460
  name: "_rels/.rels",
1440
- data: N.encode(de)
1461
+ data: P.encode(fe)
1441
1462
  },
1442
1463
  {
1443
1464
  name: "xl/workbook.xml",
1444
- data: N.encode(fe)
1465
+ data: P.encode(pe)
1445
1466
  },
1446
1467
  {
1447
1468
  name: "xl/_rels/workbook.xml.rels",
1448
- data: N.encode(pe)
1469
+ data: P.encode(me)
1449
1470
  },
1450
1471
  {
1451
1472
  name: "xl/worksheets/sheet1.xml",
1452
- data: N.encode(n)
1473
+ data: P.encode(n)
1453
1474
  },
1454
1475
  {
1455
1476
  name: "xl/styles.xml",
1456
- data: N.encode(L)
1477
+ data: P.encode(R)
1457
1478
  }
1458
1479
  ]);
1459
1480
  }
@@ -1463,20 +1484,20 @@ function B(e, t, n) {
1463
1484
  switch (n) {
1464
1485
  case "csv": return V(e, t, ",");
1465
1486
  case "tsv": return V(e, t, " ");
1466
- case "json": return he(e, t);
1467
- case "xlsx": return z(e, t);
1487
+ case "json": return _e(e, t);
1488
+ case "xlsx": return he(e, t);
1468
1489
  }
1469
1490
  }
1470
- function me(e, t) {
1491
+ function ge(e, t) {
1471
1492
  return e == null ? "" : (t.type === "date" || t.type === "datetime") && e instanceof Date ? e.toISOString() : String(e);
1472
1493
  }
1473
1494
  function V(e, t, n) {
1474
- return [t.map((e) => H(e.label, n)).join(n), ...e.map((e) => t.map((t) => H(me(e[t.key], t), n)).join(n))].join("\n");
1495
+ return [t.map((e) => H(e.label, n)).join(n), ...e.map((e) => t.map((t) => H(ge(e[t.key], t), n)).join(n))].join("\n");
1475
1496
  }
1476
1497
  function H(e, t) {
1477
1498
  return e.includes(t) || e.includes("\"") || e.includes("\n") || e.includes("\r") ? "\"" + e.replace(/"/g, "\"\"") + "\"" : e;
1478
1499
  }
1479
- function he(e, t) {
1500
+ function _e(e, t) {
1480
1501
  let n = e.map((e) => {
1481
1502
  let n = {};
1482
1503
  for (let r of t) {
@@ -1487,35 +1508,35 @@ function he(e, t) {
1487
1508
  });
1488
1509
  return JSON.stringify(n, null, 2);
1489
1510
  }
1490
- function ge(e, t, n) {
1511
+ function ve(e, t, n) {
1491
1512
  let r = new Blob([e], { type: n }), i = URL.createObjectURL(r), a = document.createElement("a");
1492
1513
  a.href = i, a.download = t, a.style.display = "none", document.body.appendChild(a), a.click(), document.body.removeChild(a), setTimeout(() => URL.revokeObjectURL(i), 100);
1493
1514
  }
1494
- var _e = {
1515
+ var ye = {
1495
1516
  csv: "text/csv;charset=utf-8",
1496
1517
  tsv: "text/tab-separated-values;charset=utf-8",
1497
1518
  json: "application/json;charset=utf-8",
1498
1519
  xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1499
- }, ve = {
1520
+ }, be = {
1500
1521
  csv: ".csv",
1501
1522
  tsv: ".tsv",
1502
1523
  json: ".json",
1503
1524
  xlsx: ".xlsx"
1504
1525
  };
1505
- function ye(e) {
1506
- return _e[e];
1526
+ function xe(e) {
1527
+ return ye[e];
1507
1528
  }
1508
- function be(e) {
1509
- return ve[e];
1529
+ function Se(e) {
1530
+ return be[e];
1510
1531
  }
1511
1532
  //#endregion
1512
1533
  //#region src/export/xlsx-reader.ts
1513
- function xe(e) {
1534
+ function Ce(e) {
1514
1535
  for (let t = e.byteLength - 22; t >= 0; t--) if (e.getUint32(t, !0) === 101010256) return t;
1515
1536
  throw Error("XLSX: End of central directory not found — not a valid ZIP file");
1516
1537
  }
1517
- function Se(e) {
1518
- let t = xe(e), n = e.getUint32(t + 16, !0), r = e.getUint32(t + 12, !0), i = new TextDecoder("utf-8"), a = [], o = n, s = n + r;
1538
+ function we(e) {
1539
+ let t = Ce(e), n = e.getUint32(t + 16, !0), r = e.getUint32(t + 12, !0), i = new TextDecoder("utf-8"), a = [], o = n, s = n + r;
1519
1540
  for (; o < s && e.getUint32(o, !0) === 33639248;) {
1520
1541
  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));
1521
1542
  a.push({
@@ -1528,7 +1549,7 @@ function Se(e) {
1528
1549
  }
1529
1550
  return a;
1530
1551
  }
1531
- async function Ce(e) {
1552
+ async function Te(e) {
1532
1553
  let t = new DecompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
1533
1554
  n.write(e), n.close();
1534
1555
  let i = [];
@@ -1541,28 +1562,28 @@ async function Ce(e) {
1541
1562
  for (let e of i) o.set(e, s), s += e.length;
1542
1563
  return o;
1543
1564
  }
1544
- async function we(e, t) {
1565
+ async function Ee(e, t) {
1545
1566
  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);
1546
1567
  if (t.compressionMethod === 0) return o.slice();
1547
- if (t.compressionMethod === 8) return Ce(o);
1568
+ if (t.compressionMethod === 8) return Te(o);
1548
1569
  throw Error(`XLSX: Unsupported compression method ${t.compressionMethod}`);
1549
1570
  }
1550
- async function Te(e) {
1551
- let t = new DataView(e), n = Se(t), r = /* @__PURE__ */ new Map();
1552
- for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await we(t, e));
1571
+ async function De(e) {
1572
+ let t = new DataView(e), n = we(t), r = /* @__PURE__ */ new Map();
1573
+ for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await Ee(t, e));
1553
1574
  return r;
1554
1575
  }
1555
- var Ee = new TextDecoder("utf-8");
1576
+ var Oe = new TextDecoder("utf-8");
1556
1577
  function U(e) {
1557
- let t = Ee.decode(e);
1578
+ let t = Oe.decode(e);
1558
1579
  return new DOMParser().parseFromString(t, "application/xml");
1559
1580
  }
1560
- function De(e) {
1581
+ function ke(e) {
1561
1582
  if (!e) return [];
1562
1583
  let t = U(e);
1563
1584
  return Array.from(t.querySelectorAll("si")).map((e) => Array.from(e.querySelectorAll("t")).map((e) => e.textContent ?? "").join(""));
1564
1585
  }
1565
- var Oe = /* @__PURE__ */ new Set([
1586
+ var Ae = /* @__PURE__ */ new Set([
1566
1587
  14,
1567
1588
  15,
1568
1589
  16,
@@ -1582,29 +1603,29 @@ var Oe = /* @__PURE__ */ new Set([
1582
1603
  57,
1583
1604
  58
1584
1605
  ]);
1585
- function ke(e) {
1606
+ function je(e) {
1586
1607
  let t = e.replace(/"[^"]*"/g, "").replace(/\\./g, "").replace(/\[[^\]]*\]/g, "").split(";")[0];
1587
1608
  return /[dy]/i.test(t);
1588
1609
  }
1589
- function Ae(e) {
1610
+ function Me(e) {
1590
1611
  let t = /* @__PURE__ */ new Set();
1591
1612
  if (!e) return t;
1592
1613
  let n = U(e), r = /* @__PURE__ */ new Map();
1593
1614
  for (let e of Array.from(n.querySelectorAll("numFmts > numFmt"))) r.set(parseInt(e.getAttribute("numFmtId") ?? "", 10), e.getAttribute("formatCode") ?? "");
1594
1615
  return Array.from(n.querySelectorAll("cellXfs > xf")).forEach((e, n) => {
1595
1616
  let i = parseInt(e.getAttribute("numFmtId") ?? "0", 10), a = r.get(i);
1596
- (a === void 0 ? Oe.has(i) : ke(a)) && t.add(n);
1617
+ (a === void 0 ? Ae.has(i) : je(a)) && t.add(n);
1597
1618
  }), t;
1598
1619
  }
1599
- function je(e) {
1620
+ function Ne(e) {
1600
1621
  if (!e) return !1;
1601
1622
  let t = U(e).querySelector("workbookPr")?.getAttribute("date1904");
1602
1623
  return t === "1" || t === "true";
1603
1624
  }
1604
- function Me(e, t) {
1625
+ function Pe(e, t) {
1605
1626
  return new Date((t ? Date.UTC(1904, 0, 1) : Date.UTC(1899, 11, 30)) + Math.floor(e) * 864e5).toISOString().slice(0, 10);
1606
1627
  }
1607
- function Ne(e, t, n, r) {
1628
+ function Fe(e, t, n, r) {
1608
1629
  let i = U(e).querySelectorAll("row");
1609
1630
  if (i.length === 0) return [];
1610
1631
  let a = 0, o = /* @__PURE__ */ new Map();
@@ -1612,7 +1633,7 @@ function Ne(e, t, n, r) {
1612
1633
  let i = parseInt(e.getAttribute("r") ?? "1", 10) - 1, s = /* @__PURE__ */ new Map();
1613
1634
  o.set(i, s);
1614
1635
  for (let i of e.querySelectorAll("c")) {
1615
- let e = W(i.getAttribute("r") ?? "");
1636
+ let e = Ie(i.getAttribute("r") ?? "");
1616
1637
  e > a && (a = e);
1617
1638
  let o = i.getAttribute("t") ?? "", c = i.getAttribute("s") ?? "", l = i.querySelector("v")?.textContent ?? "", u = i.querySelector("is > t")?.textContent ?? null, d;
1618
1639
  if (o === "s") d = t[parseInt(l, 10)] ?? "";
@@ -1621,7 +1642,7 @@ function Ne(e, t, n, r) {
1621
1642
  else if (l === "") d = "";
1622
1643
  else {
1623
1644
  let e = parseFloat(l);
1624
- d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ? Me(e, r) : l;
1645
+ d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ? Pe(e, r) : l;
1625
1646
  }
1626
1647
  s.set(e, d);
1627
1648
  }
@@ -1635,13 +1656,13 @@ function Ne(e, t, n, r) {
1635
1656
  }
1636
1657
  return c;
1637
1658
  }
1638
- function W(e) {
1659
+ function Ie(e) {
1639
1660
  let t = 0, n = 0;
1640
1661
  for (; n < e.length && e[n] >= "A" && e[n] <= "Z";) t = t * 26 + (e.charCodeAt(n) - 64), n++;
1641
1662
  return t - 1;
1642
1663
  }
1643
- async function Pe(e) {
1644
- let t = await Te(e), n = De(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
1664
+ async function W(e) {
1665
+ let t = await De(e), n = ke(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
1645
1666
  if (!r) {
1646
1667
  for (let [e, n] of t) if (e.toLowerCase().includes("worksheets/sheet")) {
1647
1668
  r = n;
@@ -1649,7 +1670,7 @@ async function Pe(e) {
1649
1670
  }
1650
1671
  }
1651
1672
  if (!r) throw Error("XLSX: No worksheet found");
1652
- let i = Ae(t.get("xl/styles.xml")), a = je(t.get("xl/workbook.xml")), o = Ne(r, n, i, a);
1673
+ let i = Me(t.get("xl/styles.xml")), a = Ne(t.get("xl/workbook.xml")), o = Fe(r, n, i, a);
1653
1674
  return o.length === 0 ? {
1654
1675
  headers: [],
1655
1676
  rows: []
@@ -1664,7 +1685,7 @@ function G(e) {
1664
1685
  return e.align ? e.align : e.type === "number" ? "end" : e.type === "boolean" ? "center" : "start";
1665
1686
  }
1666
1687
  //#endregion
1667
- //#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorate.js
1688
+ //#region \0@oxc-project+runtime@0.152.0/helpers/esm/decorate.js
1668
1689
  function K(e, t, n, r) {
1669
1690
  var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
1670
1691
  if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
@@ -1680,14 +1701,14 @@ var q = {
1680
1701
  lt: "<",
1681
1702
  gte: "≥",
1682
1703
  lte: "≤"
1683
- }, J = 120, Y = 40, X = 20, Z = 32, Q = 5, Fe = 200, $ = class extends n {
1704
+ }, J = 120, Y = 40, X = 20, Z = 32, Q = 5, Le = 200, $ = class extends n {
1684
1705
  constructor(...e) {
1685
- super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = Z, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "No data", this.noMatchingMessage = "No matching data", this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new te(), this._editing = new ne(), this._rowSelection = new k(), this._undo = new A(), 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 = () => {
1706
+ super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = Z, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "No data", this.noMatchingMessage = "No matching data", this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new te(), this._editing = new ne(), this._rowSelection = new A(), this._undo = new j(), 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 = () => {
1686
1707
  this._commitCommentPopup();
1687
1708
  }, 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();
1688
1709
  }
1689
1710
  static {
1690
- this.styles = h;
1711
+ this.styles = g;
1691
1712
  }
1692
1713
  get data() {
1693
1714
  return this._data;
@@ -2052,7 +2073,7 @@ var q = {
2052
2073
  return B(this._sortedIndices.map((e) => this.data[e]), this.visibleColumns, e);
2053
2074
  }
2054
2075
  exportToFile(e, t) {
2055
- ge(this.exportToString(e), t ?? `export${be(e)}`, ye(e));
2076
+ ve(this.exportToString(e), t ?? `export${Se(e)}`, xe(e));
2056
2077
  }
2057
2078
  setComment(e, t, n) {
2058
2079
  let r = this.getComment(e, t);
@@ -2109,10 +2130,10 @@ var q = {
2109
2130
  async importFromFile(e) {
2110
2131
  let t = e.name.toLowerCase();
2111
2132
  if (t.endsWith(".xlsx")) {
2112
- let t = await Pe(await e.arrayBuffer());
2133
+ let t = await W(await e.arrayBuffer());
2113
2134
  this._applyImportedSheet(t);
2114
2135
  } else if (t.endsWith(".csv") || t.endsWith(".tsv")) {
2115
- let t = await e.text(), n = f(t);
2136
+ let t = await e.text(), n = p(t);
2116
2137
  this._applyImportedRows(n);
2117
2138
  } else console.warn(`flex-table importFromFile: unsupported file type "${e.name}"`);
2118
2139
  }
@@ -2123,7 +2144,7 @@ var q = {
2123
2144
  let a = t.get(e);
2124
2145
  if (!a) return;
2125
2146
  let o = this.columns.find((e) => e.key === a);
2126
- r[a] = o ? j(n[i] ?? "", o) : n[i] ?? null;
2147
+ r[a] = o ? M(n[i] ?? "", o) : n[i] ?? null;
2127
2148
  }), r;
2128
2149
  }), r = [...this.data];
2129
2150
  this.data = n, this._undo.push({
@@ -2148,7 +2169,7 @@ var q = {
2148
2169
  let a = n.get(t);
2149
2170
  if (!a) return;
2150
2171
  let o = this.columns.find((e) => e.key === a);
2151
- r[a] = o ? j(e[i] ?? "", o) : e[i] ?? null;
2172
+ r[a] = o ? M(e[i] ?? "", o) : e[i] ?? null;
2152
2173
  }), r;
2153
2174
  }), i = [...this.data];
2154
2175
  this.data = r, this._undo.push({
@@ -2325,14 +2346,14 @@ var q = {
2325
2346
  _focusEditor() {
2326
2347
  if (!this._editingCell) return;
2327
2348
  let e = this.shadowRoot?.querySelector(".ft-editor");
2328
- e && document.activeElement !== e && (e.focus(), (e.type === "text" || e.type === "number") && e.select());
2349
+ e && document.activeElement !== e && (e.focus(), e.type === "text" && e.select());
2329
2350
  }
2330
2351
  _measureViewport() {
2331
2352
  let e = this.clientHeight, t = this.clientWidth;
2332
2353
  e !== this._viewportHeight && (this._viewportHeight = e), t !== this._viewportWidth && (this._viewportWidth = t), this._warnIfUnconstrained();
2333
2354
  }
2334
2355
  _warnIfUnconstrained() {
2335
- this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount < Fe || 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.`));
2356
+ this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount < Le || 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.`));
2336
2357
  }
2337
2358
  _onScroll() {
2338
2359
  this._scrollTop = this.scrollTop, this._scrollLeft = this.scrollLeft;
@@ -2462,7 +2483,7 @@ var q = {
2462
2483
  }
2463
2484
  let t = this.shadowRoot?.querySelector(".ft-editor");
2464
2485
  if (t) {
2465
- let n = j(t.value, e);
2486
+ let n = M(t.value, e);
2466
2487
  this._applyEdit(n);
2467
2488
  } else this._cancelEdit();
2468
2489
  }
@@ -2472,7 +2493,22 @@ var q = {
2472
2493
  if (this._editingCell = null, !t) return;
2473
2494
  let { row: n, col: r } = t.position, i = this._toDataIndex(n), a = this.visibleColumns[r], o = t.originalValue;
2474
2495
  if (a.autocomplete === "strict" && e != null && e !== "" && !this._getAutocompleteCandidates(a, "").includes(String(e))) {
2475
- let t = "Value must be from the existing list";
2496
+ let t = k("notInList");
2497
+ this._markCellInvalid(n, r, t), this.dispatchEvent(new CustomEvent("validation-error", {
2498
+ detail: {
2499
+ row: i,
2500
+ col: r,
2501
+ key: a.key,
2502
+ value: e,
2503
+ error: t
2504
+ },
2505
+ bubbles: !0,
2506
+ composed: !0
2507
+ }));
2508
+ return;
2509
+ }
2510
+ if (a.type === "number" && typeof e == "string") {
2511
+ let t = k("notANumber");
2476
2512
  this._markCellInvalid(n, r, t), this.dispatchEvent(new CustomEvent("validation-error", {
2477
2513
  detail: {
2478
2514
  row: i,
@@ -2536,7 +2572,7 @@ var q = {
2536
2572
  }));
2537
2573
  }
2538
2574
  _onEditorKeyDown(e) {
2539
- if (!m(e)) {
2575
+ if (!h(e)) {
2540
2576
  if (this._autocompleteState && this._autocompleteState.candidates.length > 0) {
2541
2577
  if (e.key === "ArrowDown") {
2542
2578
  e.preventDefault(), e.stopPropagation();
@@ -2604,7 +2640,7 @@ var q = {
2604
2640
  ].includes(t) && this._handleCtrlKey(e)) return;
2605
2641
  }
2606
2642
  if (t.length !== 0 && this._visibleRowCount !== 0) {
2607
- if ((e.key === "Enter" || e.key === "F2") && this._activeCell && !m(e)) {
2643
+ if ((e.key === "Enter" || e.key === "F2") && this._activeCell && !h(e)) {
2608
2644
  e.preventDefault();
2609
2645
  let n = t[this._activeCell.col];
2610
2646
  n && this._isCellEditable(n) ? this._startEdit() : e.key === "Enter" && this._fireRowActivate(n);
@@ -2718,7 +2754,7 @@ var q = {
2718
2754
  if (!this._activeCell) return;
2719
2755
  let e = await this._readClipboardText();
2720
2756
  if (e == null) return;
2721
- let t = f(e);
2757
+ let t = p(e);
2722
2758
  if (t.length === 0) return;
2723
2759
  let n = this._expandRowsForPaste(this._activeCell.row, t.length), r = this._applyPasteData(this._activeCell, t);
2724
2760
  if (r.length > 0 || n.length > 0) {
@@ -2776,7 +2812,7 @@ var q = {
2776
2812
  for (let a = 0; a < t[i].length; a++) {
2777
2813
  let s = e.col + a;
2778
2814
  if (s >= n.length) break;
2779
- let c = n[s], l = this.data[o][c.key], u = j(t[i][a], c);
2815
+ let c = n[s], l = this.data[o][c.key], u = M(t[i][a], c);
2780
2816
  this.data[o][c.key] = u, r.push({
2781
2817
  row: o,
2782
2818
  col: s,
@@ -2841,7 +2877,7 @@ var q = {
2841
2877
  for (let r = e.startCol + 1; r <= e.endCol; r++) {
2842
2878
  let e = t[r];
2843
2879
  if (!e || !this._isCellEditable(e)) continue;
2844
- let a = j(o == null ? "" : String(o), e);
2880
+ let a = M(o == null ? "" : String(o), e);
2845
2881
  n.push({
2846
2882
  row: i,
2847
2883
  key: e.key,
@@ -3001,7 +3037,7 @@ var q = {
3001
3037
  @click=${n ? (t) => this._onHeaderClick(t, e) : void 0}>
3002
3038
  ${C ? i`
3003
3039
  <button class="ft-hidden-col-indicator"
3004
- title=${O("showHiddenColumns")}
3040
+ title=${k("showHiddenColumns")}
3005
3041
  @click=${(t) => {
3006
3042
  t.stopPropagation(), this._showHiddenBefore(e);
3007
3043
  }}>&#x276F;</button>
@@ -3011,8 +3047,8 @@ var q = {
3011
3047
  ${o >= 0 ? i`<span class="ft-sort-order">${o + 1}</span>` : ""}
3012
3048
  <button class="ft-column-menu-btn ${s ? "ft-filter-active" : ""}"
3013
3049
  type="button"
3014
- title=${O("columnMenu")}
3015
- aria-label=${O("columnMenuFor", { header: e.label })}
3050
+ title=${k("columnMenu")}
3051
+ aria-label=${k("columnMenuFor", { header: e.label })}
3016
3052
  aria-haspopup="menu"
3017
3053
  aria-expanded=${this._headerMenu?.key === e.key ? "true" : "false"}
3018
3054
  @mousedown=${(e) => e.stopPropagation()}
@@ -3131,26 +3167,26 @@ var q = {
3131
3167
  }}>${t}</button>
3132
3168
  `;
3133
3169
  return i`
3134
- <div class="ft-header-menu" role="menu" aria-label=${O("columnMenuRegion", { header: o.label })}
3170
+ <div class="ft-header-menu" role="menu" aria-label=${k("columnMenuRegion", { header: o.label })}
3135
3171
  style="position: fixed; left: ${t}px; top: ${n}px; z-index: var(--u-layer-floating, 1000);"
3136
3172
  @mousedown=${(e) => e.stopPropagation()}
3137
3173
  @keydown=${(e) => this._onHeaderMenuKeydown(e)}>
3138
3174
  ${o.sortable === !1 ? a : i`
3139
- ${c("sort-asc", O("sortAscending"), () => this._applySortFromMenu(e, "asc"))}
3140
- ${c("sort-desc", O("sortDescending"), () => this._applySortFromMenu(e, "desc"))}
3175
+ ${c("sort-asc", k("sortAscending"), () => this._applySortFromMenu(e, "asc"))}
3176
+ ${c("sort-desc", k("sortDescending"), () => this._applySortFromMenu(e, "desc"))}
3141
3177
  <div class="ft-header-menu-separator" role="separator"></div>
3142
3178
  `}
3143
3179
  ${this.showFilters ? i`
3144
- ${c("filter", O("filter"), () => this._openFilterFromMenu(e))}
3145
- ${s ? c("clear-filter", O("clearFilter"), () => this._clearColumnFilter(e)) : a}
3180
+ ${c("filter", k("filter"), () => this._openFilterFromMenu(e))}
3181
+ ${s ? c("clear-filter", k("clearFilter"), () => this._clearColumnFilter(e)) : a}
3146
3182
  <div class="ft-header-menu-separator" role="separator"></div>
3147
3183
  ` : a}
3148
- ${c("hide", O("hideColumn"), () => this._setColumnHidden(e, !0))}
3149
- ${r.map((e) => c("show", O("showColumn", { header: e.label }), () => this._setColumnHidden(e.key, !1)))}
3184
+ ${c("hide", k("hideColumn"), () => this._setColumnHidden(e, !0))}
3185
+ ${r.map((e) => c("show", k("showColumn", { header: e.label }), () => this._setColumnHidden(e.key, !1)))}
3150
3186
  <div class="ft-header-menu-separator" role="separator"></div>
3151
- ${c("autofit", O("autoFitWidth"), () => this._autoFitColumn(e))}
3152
- ${c("wider", O("wider"), () => this._resizeColumnBy(e, X), !0)}
3153
- ${c("narrower", O("narrower"), () => this._resizeColumnBy(e, -20), !0)}
3187
+ ${c("autofit", k("autoFitWidth"), () => this._autoFitColumn(e))}
3188
+ ${c("wider", k("wider"), () => this._resizeColumnBy(e, X), !0)}
3189
+ ${c("narrower", k("narrower"), () => this._resizeColumnBy(e, -20), !0)}
3154
3190
  </div>
3155
3191
  `;
3156
3192
  }
@@ -3168,26 +3204,26 @@ var q = {
3168
3204
  }}>${e}</button>
3169
3205
  `, f = i`<div class="ft-context-menu-separator" role="separator"></div>`;
3170
3206
  return i`
3171
- <div class="ft-body-context-menu" role="menu" aria-label=${O("cellActions")}
3207
+ <div class="ft-body-context-menu" role="menu" aria-label=${k("cellActions")}
3172
3208
  style="position: fixed; left: ${n}px; top: ${r}px; z-index: var(--u-layer-floating, 1000);"
3173
3209
  @mousedown=${(e) => e.stopPropagation()}
3174
3210
  @keydown=${(e) => this._onMenuKeydown(e, ".ft-body-context-menu", l)}>
3175
- ${d(O("copy"), () => this._handleCopy(!1))}
3211
+ ${d(k("copy"), () => this._handleCopy(!1))}
3176
3212
  ${f}
3177
- ${d(O("insertRowAbove"), () => this.addRow(void 0, t))}
3178
- ${d(O("insertRowBelow"), () => this.addRow(void 0, t + 1))}
3179
- ${d(O("deleteRow"), () => this.deleteRows([t]), !0)}
3213
+ ${d(k("insertRowAbove"), () => this.addRow(void 0, t))}
3214
+ ${d(k("insertRowBelow"), () => this.addRow(void 0, t + 1))}
3215
+ ${d(k("deleteRow"), () => this.deleteRows([t]), !0)}
3180
3216
  ${f}
3181
- ${d(O("hideColumn"), () => this._setColumnHidden(o.key, !0))}
3217
+ ${d(k("hideColumn"), () => this._setColumnHidden(o.key, !0))}
3182
3218
  ${f}
3183
- ${d(`${O("sortAscending")} ↑`, () => this._applySortFromMenu(o.key, "asc"))}
3184
- ${d(`${O("sortDescending")} ↓`, () => this._applySortFromMenu(o.key, "desc"))}
3219
+ ${d(`${k("sortAscending")} ↑`, () => this._applySortFromMenu(o.key, "asc"))}
3220
+ ${d(`${k("sortDescending")} ↓`, () => this._applySortFromMenu(o.key, "desc"))}
3185
3221
  ${f}
3186
- ${d(O("filterByThisValue"), () => this.setFilter(o.key, (e) => e === s))}
3187
- ${c ? d(O("clearFilter"), () => this.removeFilter(o.key)) : a}
3222
+ ${d(k("filterByThisValue"), () => this.setFilter(o.key, (e) => e === s))}
3223
+ ${c ? d(k("clearFilter"), () => this.removeFilter(o.key)) : a}
3188
3224
  ${f}
3189
- ${d(O(u ? "editComment" : "addComment"), () => this._openCommentPopup(t, o.key, n, r))}
3190
- ${u ? d(O("deleteComment"), () => this.setComment(t, o.key, null), !0) : a}
3225
+ ${d(k(u ? "editComment" : "addComment"), () => this._openCommentPopup(t, o.key, n, r))}
3226
+ ${u ? d(k("deleteComment"), () => this.setComment(t, o.key, null), !0) : a}
3191
3227
  </div>
3192
3228
  `;
3193
3229
  }
@@ -3219,13 +3255,13 @@ var q = {
3219
3255
  @mousedown=${(e) => e.stopPropagation()}>
3220
3256
  <textarea class="ft-comment-popup-textarea"
3221
3257
  rows="4"
3222
- placeholder=${O("addCommentPlaceholder")}
3258
+ placeholder=${k("addCommentPlaceholder")}
3223
3259
  @keydown=${(e) => {
3224
3260
  e.key === "Escape" && (e.preventDefault(), this._cancelCommentPopup()), e.key === "Enter" && (e.ctrlKey || e.metaKey) && (e.preventDefault(), this._commitCommentPopup());
3225
3261
  }}></textarea>
3226
3262
  <div class="ft-comment-popup-buttons">
3227
- <button class="ft-comment-popup-cancel" @click=${() => this._cancelCommentPopup()}>${O("cancel")}</button>
3228
- <button class="ft-comment-popup-save" @click=${() => this._commitCommentPopup()}>${O("save")}</button>
3263
+ <button class="ft-comment-popup-cancel" @click=${() => this._cancelCommentPopup()}>${k("cancel")}</button>
3264
+ <button class="ft-comment-popup-save" @click=${() => this._commitCommentPopup()}>${k("save")}</button>
3229
3265
  </div>
3230
3266
  </div>
3231
3267
  `;
@@ -3261,7 +3297,7 @@ var q = {
3261
3297
  <div class="ft-filter-dropdown" @click=${(e) => e.stopPropagation()}>
3262
3298
  ${t === "boolean" ? this._renderBooleanFilter(e) : t === "number" ? this._renderNumberFilter(e) : t === "date" || t === "datetime" ? this._renderDateFilter(e) : this._renderTextFilter(e)}
3263
3299
  <div class="ft-filter-actions">
3264
- <button class="ft-filter-clear" @click=${() => this._clearColumnFilter(e.key)}>${O("clear")}</button>
3300
+ <button class="ft-filter-clear" @click=${() => this._clearColumnFilter(e.key)}>${k("clear")}</button>
3265
3301
  </div>
3266
3302
  </div>
3267
3303
  `;
@@ -3294,7 +3330,7 @@ var q = {
3294
3330
  let n = this._emptyFilterState.get(e) ?? "";
3295
3331
  return i`
3296
3332
  <div class="ft-filter-empty-row">
3297
- <label>${O("blankCells")}</label>
3333
+ <label>${k("blankCells")}</label>
3298
3334
  <select class="ft-filter-mode-select"
3299
3335
  .value=${n}
3300
3336
  @change=${(n) => {
@@ -3304,9 +3340,9 @@ var q = {
3304
3340
  @keydown=${(e) => {
3305
3341
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
3306
3342
  }}>
3307
- <option value="">${O("blankAll")}</option>
3308
- <option value="empty">${O("emptyOnly")}</option>
3309
- <option value="non-empty">${O("nonEmptyOnly")}</option>
3343
+ <option value="">${k("blankAll")}</option>
3344
+ <option value="empty">${k("emptyOnly")}</option>
3345
+ <option value="non-empty">${k("nonEmptyOnly")}</option>
3310
3346
  </select>
3311
3347
  </div>
3312
3348
  `;
@@ -3382,13 +3418,13 @@ var q = {
3382
3418
  @keydown=${(e) => {
3383
3419
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
3384
3420
  }}>
3385
- <option value="contains">${O("contains")}</option>
3386
- <option value="starts">${O("startsWith")}</option>
3387
- <option value="ends">${O("endsWith")}</option>
3388
- <option value="wildcard">${O("wildcard")}</option>
3421
+ <option value="contains">${k("contains")}</option>
3422
+ <option value="starts">${k("startsWith")}</option>
3423
+ <option value="ends">${k("endsWith")}</option>
3424
+ <option value="wildcard">${k("wildcard")}</option>
3389
3425
  </select>
3390
3426
  </div>
3391
- <input class="ft-filter-input" type="text" placeholder=${O("searchPlaceholder")}
3427
+ <input class="ft-filter-input" type="text" placeholder=${k("searchPlaceholder")}
3392
3428
  .value=${t.value}
3393
3429
  @input=${(t) => {
3394
3430
  let n = t.target.value, r = this._textFilterState.get(e.key) ?? {
@@ -3439,13 +3475,15 @@ var q = {
3439
3475
  }}>
3440
3476
  ${Object.keys(q).map((e) => i`<option value=${e}>${q[e]}</option>`)}
3441
3477
  </select>
3442
- <input class="ft-filter-input ft-num-cond-input" type="number" placeholder=${O("valuePlaceholder")}
3443
- .value=${n.value == null ? "" : String(n.value)}
3478
+ <input class="ft-filter-input ft-num-cond-input" type="text" inputmode="decimal" placeholder=${k("valuePlaceholder")}
3479
+ .value=${n.text ?? (n.value == null ? "" : N(n.value))}
3480
+ aria-invalid=${n.text && n.value == null ? "true" : "false"}
3444
3481
  @input=${(n) => {
3445
3482
  let r = n.target.value, i = this._numberFilterState.get(e) ?? this._defaultNumState();
3446
3483
  i[t] = {
3447
3484
  ...i[t],
3448
- value: r === "" ? null : Number(r)
3485
+ text: r,
3486
+ value: r.trim() === "" ? null : f(r)
3449
3487
  }, this._numberFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
3450
3488
  }}
3451
3489
  @keydown=${(e) => {
@@ -3500,13 +3538,13 @@ var q = {
3500
3538
  let t = e.type === "datetime" ? "datetime-local" : "date", n = this._dateFilterState.get(e.key) ?? {};
3501
3539
  return i`
3502
3540
  <div class="ft-filter-range">
3503
- <input class="ft-filter-input" type=${t} placeholder=${O("fromPlaceholder")}
3541
+ <input class="ft-filter-input" type=${t} placeholder=${k("fromPlaceholder")}
3504
3542
  .value=${n.from ?? ""}
3505
3543
  @input=${(t) => this._applyDateFilter(e.key, t, "from")}
3506
3544
  @keydown=${(e) => {
3507
3545
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
3508
3546
  }}>
3509
- <input class="ft-filter-input" type=${t} placeholder=${O("toPlaceholder")}
3547
+ <input class="ft-filter-input" type=${t} placeholder=${k("toPlaceholder")}
3510
3548
  .value=${n.to ?? ""}
3511
3549
  @input=${(t) => this._applyDateFilter(e.key, t, "to")}
3512
3550
  @keydown=${(e) => {
@@ -3532,9 +3570,9 @@ var q = {
3532
3570
  @keydown=${(e) => {
3533
3571
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
3534
3572
  }}>
3535
- <option value="all">${O("all")}</option>
3536
- <option value="true">\u2714 ${O("booleanTrue")}</option>
3537
- <option value="false">\u2718 ${O("booleanFalse")}</option>
3573
+ <option value="all">${k("all")}</option>
3574
+ <option value="true">\u2714 ${k("booleanTrue")}</option>
3575
+ <option value="false">\u2718 ${k("booleanFalse")}</option>
3538
3576
  </select>
3539
3577
  ${this._renderEmptyFilterRow(e.key)}
3540
3578
  `;
@@ -3951,42 +3989,42 @@ var q = {
3951
3989
  this._closeFindPanel();
3952
3990
  return;
3953
3991
  }
3954
- e.key === "Enter" && !m(e) && e.target instanceof HTMLInputElement && e.target.classList.contains("ft-find-input") && (e.shiftKey ? this._findPrev() : this._findNext());
3992
+ e.key === "Enter" && !h(e) && e.target instanceof HTMLInputElement && e.target.classList.contains("ft-find-input") && (e.shiftKey ? this._findPrev() : this._findNext());
3955
3993
  }}>
3956
3994
  <div class="ft-find-row">
3957
- <input class="ft-find-input" type="text" placeholder=${O("findPlaceholder")}
3995
+ <input class="ft-find-input" type="text" placeholder=${k("findPlaceholder")}
3958
3996
  .value=${t}
3959
3997
  @input=${(e) => {
3960
3998
  this._findState.query = e.target.value, this._findSearch();
3961
3999
  }}>
3962
4000
  <span class="ft-find-count">${c > 0 ? `${l}/${c}` : t ? "0 results" : ""}</span>
3963
- <button @click=${() => this._findPrev()} title=${O("findPrevious")}>◀</button>
3964
- <button @click=${() => this._findNext()} title=${O("findNext")}>▶</button>
3965
- <label title=${O("matchCase")}><input type="checkbox" ?checked=${r} @change=${(e) => {
4001
+ <button @click=${() => this._findPrev()} title=${k("findPrevious")}>◀</button>
4002
+ <button @click=${() => this._findNext()} title=${k("findNext")}>▶</button>
4003
+ <label title=${k("matchCase")}><input type="checkbox" ?checked=${r} @change=${(e) => {
3966
4004
  this._findState.matchCase = e.target.checked, this._findSearch();
3967
4005
  }}> Aa</label>
3968
- <label title=${O("wholeCell")}><input type="checkbox" ?checked=${a} @change=${(e) => {
4006
+ <label title=${k("wholeCell")}><input type="checkbox" ?checked=${a} @change=${(e) => {
3969
4007
  this._findState.wholeCell = e.target.checked, this._findSearch();
3970
4008
  }}> [ ]</label>
3971
- <button @click=${() => this._closeFindPanel()} title=${O("closeFind")}>✕</button>
4009
+ <button @click=${() => this._closeFindPanel()} title=${k("closeFind")}>✕</button>
3972
4010
  </div>
3973
4011
  ${e === "replace" ? i`
3974
4012
  <div class="ft-find-row">
3975
- <input class="ft-find-replace-input" type="text" placeholder=${O("replaceWithPlaceholder")}
4013
+ <input class="ft-find-replace-input" type="text" placeholder=${k("replaceWithPlaceholder")}
3976
4014
  .value=${n}
3977
4015
  @input=${(e) => {
3978
4016
  this._findState.replaceWith = e.target.value;
3979
4017
  }}>
3980
- <button @click=${() => this._replaceOne()} ?disabled=${c === 0}>${O("replace")}</button>
3981
- <button @click=${() => this._replaceAll()} ?disabled=${c === 0}>${O("replaceAll")}</button>
4018
+ <button @click=${() => this._replaceOne()} ?disabled=${c === 0}>${k("replace")}</button>
4019
+ <button @click=${() => this._replaceAll()} ?disabled=${c === 0}>${k("replaceAll")}</button>
3982
4020
  </div>
3983
4021
  ` : ""}
3984
4022
  </div>
3985
4023
  `;
3986
4024
  }
3987
4025
  render() {
3988
- let e = this.visibleColumns, t = this.importEnabled && this._isDragOver ? i`<div class="ft-import-overlay">${O("dropFileToImport")}</div>` : a, n = this.loading ? i`<div class="ft-loading-overlay"></div>` : a;
3989
- if (e.length === 0) return i`${t}${n}<div class="ft-empty">${O("noColumnsDefined")}</div>`;
4026
+ let e = this.visibleColumns, t = this.importEnabled && this._isDragOver ? i`<div class="ft-import-overlay">${k("dropFileToImport")}</div>` : a, n = this.loading ? i`<div class="ft-loading-overlay"></div>` : a;
4027
+ if (e.length === 0) return i`${t}${n}<div class="ft-empty">${k("noColumnsDefined")}</div>`;
3990
4028
  let r = this.headerHeight, o = this._totalRowWidth, { start: s, end: c } = this.visibleColRange, l = [];
3991
4029
  for (let t = 0; t < e.length; t++) (e[t].pinned === "left" || e[t].pinned === "right") && (t < s || t >= c) && l.push(t);
3992
4030
  let u = 0, d = this._scrollLeft, f = this.selectable ? i`<div class="ft-checkbox-header"
@@ -4105,8 +4143,8 @@ var q = {
4105
4143
  @mousedown=${(t) => this._onRowNumMouseDown(t, e)}
4106
4144
  @click=${() => this._onRowNumberClick(e)}>${s + 1}</div>
4107
4145
  ` : "", y = [];
4108
- for (let t of r) y.push(this._renderCell(c, o[t], e, t));
4109
- for (let r = t; r < n; r++) y.push(this._renderCell(c, o[r], e, r));
4146
+ for (let t of r) y.push(this._renderCell(c, o[t], e, t, this._mergeState(o[t], e)));
4147
+ for (let r = t; r < n; r++) y.push(this._renderCell(c, o[r], e, r, this._mergeState(o[r], e)));
4110
4148
  return i`
4111
4149
  <div class="ft-row ${f} ${p ? "ft-row-selected" : ""}" role="row" aria-rowindex=${e + 2}
4112
4150
  style="top: ${l}px; height: ${u}px; width: ${d}px;">
@@ -4115,52 +4153,82 @@ var q = {
4115
4153
  </div>
4116
4154
  `;
4117
4155
  }
4118
- _renderCell(e, t, n, r) {
4119
- let o = this._activeCell?.row === n && this._activeCell?.col === r, s = this._editingCell?.row === n && this._editingCell?.col === r, c = this._selection.isInRange(n, r), l = t.pinned === "left", u = t.pinned === "right", d = l || u, f = this._getColWidth(t), p = this.rowHeight, m = this._colLeftOffsets[r] ?? 0, h;
4120
- h = l ? `position: absolute; top: 0; left: ${this._scrollLeft + this._getPinnedLeft(r)}px; width: ${f}px; height: ${p}px; z-index: 2;` : u ? `position: absolute; top: 0; left: ${this._getPinnedRightLeft(r)}px; width: ${f}px; height: ${p}px; z-index: 2;` : `left: ${m}px; width: ${f}px; height: ${p}px;`;
4121
- let g = !this._isCellEditable(t);
4156
+ _continuesRun(e, t) {
4157
+ let n = e.mergeRepeated;
4158
+ if (!n || t <= 0 || t >= this._visibleRowCount) return !1;
4159
+ let r = this.data[this._toDataIndex(t)], i = this.data[this._toDataIndex(t - 1)];
4160
+ if (!r || !i) return !1;
4161
+ if (typeof n == "function") return n(r, i, e);
4162
+ let a = r[e.key];
4163
+ if (a == null || a === "") return !1;
4164
+ let o = i[e.key];
4165
+ return a instanceof Date && o instanceof Date ? a.getTime() === o.getTime() : Object.is(a, o);
4166
+ }
4167
+ _isForcedRunHead(e) {
4168
+ let t = this._frozenRowCount;
4169
+ return e === t ? !0 : e < t ? !1 : e === t + Math.floor((this._scrollTop + this.rowHeight / 2) / this.rowHeight);
4170
+ }
4171
+ _mergeState(e, t) {
4172
+ if (!e.mergeRepeated) return null;
4173
+ let n = !this._isForcedRunHead(t) && this._continuesRun(e, t), r = !this._isForcedRunHead(t + 1) && this._continuesRun(e, t + 1);
4174
+ if (!n && !r) return null;
4175
+ let i = t;
4176
+ for (; i > 0 && !this._isForcedRunHead(i) && this._continuesRun(e, i);) i--;
4177
+ return {
4178
+ continues: n,
4179
+ opensDown: r,
4180
+ headParity: i % 2 == 0 ? "even" : "odd"
4181
+ };
4182
+ }
4183
+ _renderCell(e, t, n, r, o = null) {
4184
+ let s = this._activeCell?.row === n && this._activeCell?.col === r, c = this._editingCell?.row === n && this._editingCell?.col === r, l = this._selection.isInRange(n, r), u = t.pinned === "left", d = t.pinned === "right", f = u || d, p = this._getColWidth(t), m = this.rowHeight, h = this._colLeftOffsets[r] ?? 0, g;
4185
+ g = u ? `position: absolute; top: 0; left: ${this._scrollLeft + this._getPinnedLeft(r)}px; width: ${p}px; height: ${m}px; z-index: 2;` : d ? `position: absolute; top: 0; left: ${this._getPinnedRightLeft(r)}px; width: ${p}px; height: ${m}px; z-index: 2;` : `left: ${h}px; width: ${p}px; height: ${m}px;`;
4186
+ let _ = !this._isCellEditable(t);
4122
4187
  if (t.conditionalRules && t.conditionalRules.length > 0) {
4123
4188
  let n = e[t.key], r = {};
4124
4189
  for (let i of t.conditionalRules) i.when(n, e, t) && (i.style.background && (r.background = i.style.background), i.style.color && (r.color = i.style.color), i.style.fontWeight && (r["font-weight"] = i.style.fontWeight), i.style.fontStyle && (r["font-style"] = i.style.fontStyle));
4125
4190
  let i = Object.entries(r).map(([e, t]) => `${e}: ${t}`).join("; ");
4126
- i && (h += " " + i + ";");
4191
+ i && (g += " " + i + ";");
4127
4192
  }
4128
- if (s) return i`
4129
- <div class="ft-cell ft-editing ft-active ${d ? "ft-pinned" : ""}" role="gridcell"
4193
+ if (c) return i`
4194
+ <div class="ft-cell ft-editing ft-active ${f ? "ft-pinned" : ""}" role="gridcell"
4130
4195
  aria-colindex=${r + 1}
4131
4196
  data-col-index=${r}
4132
4197
  aria-selected="true"
4133
- aria-readonly=${g ? "true" : a}
4134
- style=${h}>
4198
+ aria-readonly=${_ ? "true" : a}
4199
+ style=${g}>
4135
4200
  ${this._renderEditor(e, t)}
4136
4201
  </div>
4137
4202
  `;
4138
- let _ = o || c, v = this._isCellInvalid(n, r), y = (this._findState?.results ?? []).findIndex((e) => e.row === n && e.col === r), x = y >= 0, S = x && y === this._findState.currentIndex, C = [
4203
+ let v = s || l, y = this._isCellInvalid(n, r), b = (this._findState?.results ?? []).findIndex((e) => e.row === n && e.col === r), S = b >= 0, C = S && b === this._findState.currentIndex, w = [
4139
4204
  "ft-cell",
4140
4205
  `ft-type-${t.type ?? "text"}`,
4141
4206
  `ft-align-${G(t)}`,
4142
- o ? "ft-active" : "",
4143
- c ? "ft-selected" : "",
4144
- d ? "ft-pinned" : "",
4145
- v ? "ft-invalid" : "",
4146
- S ? "ft-find-current" : x ? "ft-find-match" : ""
4147
- ].filter(Boolean).join(" "), w = this._toDataIndex(n), T = this._comments.get(w)?.get(t.key) ?? null, E = T !== null, D = E ? i`<div class="ft-comment-indicator" title=${T}></div>` : a;
4207
+ s ? "ft-active" : "",
4208
+ l ? "ft-selected" : "",
4209
+ f ? "ft-pinned" : "",
4210
+ y ? "ft-invalid" : "",
4211
+ C ? "ft-find-current" : S ? "ft-find-match" : "",
4212
+ o ? `ft-merge-${o.headParity}` : "",
4213
+ o?.continues ? "ft-merge-continued" : "",
4214
+ o?.opensDown ? "ft-merge-open" : ""
4215
+ ].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;
4148
4216
  return i`
4149
- <div class=${E ? C + " ft-has-comment" : C}
4217
+ <div class=${D ? w + " ft-has-comment" : w}
4150
4218
  role="gridcell"
4151
4219
  aria-colindex=${r + 1}
4152
4220
  data-col-index=${r}
4153
- aria-selected=${_ ? "true" : "false"}
4154
- aria-readonly=${g ? "true" : a}
4155
- aria-invalid=${v ? "true" : a}
4156
- title=${v ?? a}
4157
- style=${h}
4221
+ aria-selected=${v ? "true" : "false"}
4222
+ aria-readonly=${_ ? "true" : a}
4223
+ aria-invalid=${y ? "true" : a}
4224
+ title=${y ?? a}
4225
+ style=${g}
4158
4226
  @mousedown=${(e) => this._onCellMouseDown(e, n, r)}
4159
4227
  @mouseenter=${() => this._onCellMouseEnter(n, r)}
4160
4228
  @click=${(e) => this._onCellClickEvent(e, n, r)}
4161
4229
  @dblclick=${() => this._onCellDblClick(n, r)}>
4162
- ${D}
4163
- ${b(e[t.key], e, t)}
4230
+ ${O}
4231
+ ${x(e[t.key], e, t)}
4164
4232
  </div>
4165
4233
  `;
4166
4234
  }
@@ -4168,8 +4236,8 @@ var q = {
4168
4236
  if (t.editor) return t.editor(e[t.key], e, t);
4169
4237
  let n = e[t.key], r = n == null ? "" : String(n);
4170
4238
  if (t.type === "number") return i`
4171
- <input class="ft-editor ft-editor-number" type="number"
4172
- .value=${r}
4239
+ <input class="ft-editor ft-editor-number" type="text" inputmode="decimal"
4240
+ .value=${typeof n == "number" ? N(n) : r}
4173
4241
  @keydown=${this._onEditorKeyDown}
4174
4242
  @blur=${() => this._commitEdit()}>
4175
4243
  `;
@@ -4298,4 +4366,4 @@ K([s({ type: Array })], $.prototype, "columns", void 0), K([s({
4298
4366
  attribute: "max-undo-size"
4299
4367
  })], $.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")], $);
4300
4368
  //#endregion
4301
- export { k as a, A as i, G as n, D as o, B as r, b as s, $ as t };
4369
+ export { A as a, j as i, G as n, O as o, B as r, x as s, $ as t };