@iyulab/flex-table 0.47.0 → 0.48.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,35 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.48.0] - 2026-10-06
4
+
5
+ ### Fixed
6
+
7
+ - **Ctrl+X no longer clears cells that never reached the clipboard.** The keys called the async
8
+ Clipboard API; when the write was refused — no permission, a page outside a secure context, a
9
+ browser without it — the table still cleared the cut range and fired `clipboard-cut`
10
+ (`clipboard-copy` for Ctrl+C). Ctrl+C, Ctrl+X and Ctrl+V now go through the browser's own
11
+ copy/cut/paste and `clipboardData`: they need no clipboard permission, work on any page, and a cut
12
+ range is cleared only once its text is on the clipboard.
13
+ - The context menu's Copy, which still writes through the Clipboard API, fires `clipboard-copy` only
14
+ when the write succeeds; a refused write fires `clipboard-error` alone.
15
+
16
+ ### Changed
17
+
18
+ - `clipboard-error` is now only the context menu's Copy (`action: 'copy'`). Paste no longer reads
19
+ through the Clipboard API, so it has no permission to be refused and never reports `'paste'`.
20
+ - Copy, cut and paste typed in a text field inside the grid (the cell editor, the find panel) are
21
+ that field's own and leave the cells alone.
22
+
23
+ ### Documentation
24
+
25
+ - README: the keyboard table covers every key the grid handles, and the column example uses
26
+ `appearance="plain"` (the `variant` attribute was removed in `@iyulab/components` 2.0).
27
+
28
+ ### Tests
29
+
30
+ - Real key input for Ctrl+C/X/V, Ctrl+Click on a header, and the column menu's Space / Home / End /
31
+ Escape, alongside the rest of the keyboard table.
32
+
3
33
  ## [0.47.0] - 2026-10-05
4
34
 
5
35
  ### Changed
package/README.md CHANGED
@@ -50,7 +50,7 @@ npm install @iyulab/flex-table
50
50
  - **Range Selection** — Shift+Arrow, Shift+Click for multi-cell selection
51
51
  - **Column Selection** — Ctrl+Click header or `selectColumn()` API
52
52
  - **Row Selection** — Checkbox-based row selection (`selectable`, single/multi mode)
53
- - **Clipboard** — Ctrl+C/X/V with TSV format (Excel/Google Sheets compatible, RFC 4180)
53
+ - **Clipboard** — Ctrl+C/X/V with TSV format (Excel/Google Sheets compatible, RFC 4180), through the browser's own copy/cut/paste — no clipboard permission needed
54
54
  - **Sorting** — Click header to sort (asc/desc/none), Shift+click for multi-sort
55
55
  - **Column Menu** — A 24×24 button in every header opens the column's menu: sort, filter, hide/show, auto-fit, wider/narrower (also opens on header right-click)
56
56
  - **Column Resize** — Drag header border, double-click to auto-fit, Alt+Arrow keyboard resize, or the column menu
@@ -208,7 +208,7 @@ hover) always show them, and they are not printed.
208
208
 
209
209
  ```ts
210
210
  { key: 'actions', label: '', width: 72, editable: false, reveal: 'hover',
211
- render: (_, row) => html`<u-button size="sm" variant="ghost" aria-label="Edit">…</u-button>` }
211
+ render: (_, row) => html`<u-button size="sm" appearance="plain" aria-label="Edit">…</u-button>` }
212
212
  ```
213
213
 
214
214
  ### Merging Repeated Values
@@ -334,7 +334,7 @@ All events use `CustomEvent` with `bubbles: true, composed: true`.
334
334
  | `clipboard-copy` | `{ range, text }` | Range copied as TSV |
335
335
  | `clipboard-cut` | `{ range, text }` | Range cut as TSV |
336
336
  | `clipboard-paste` | `{ changes, addedRows }` | Data pasted from clipboard |
337
- | `clipboard-error` | `{ action, error }` | Clipboard API failed (`action`: `'copy'` or `'paste'`) |
337
+ | `clipboard-error` | `{ action, error }` | The context menu's Copy could not write to the clipboard (`action`: `'copy'`); no `clipboard-copy` follows |
338
338
 
339
339
  ### State Events
340
340
 
@@ -429,13 +429,16 @@ package dependency; CSS custom properties are resolved at render time, not impor
429
429
  |-----|--------|
430
430
  | Arrow keys | Navigate cells |
431
431
  | Tab / Shift+Tab | Move to next/previous cell |
432
- | Enter / F2 | Start editing |
433
- | Escape | Cancel edit / clear selection |
432
+ | Enter / F2 | Start editing (Enter on a non-editable cell fires `row-activate`) |
433
+ | Typing a printable character | Start editing an editable cell with that character |
434
+ | Escape | Cancel edit / clear selection / close the find panel |
434
435
  | Home / End | Row start/end |
435
436
  | Ctrl+Home / Ctrl+End | Table start/end |
436
- | Shift+Arrow | Extend selection range |
437
+ | Shift+Arrow / Shift+Click | Extend selection range |
437
438
  | Ctrl+C / Ctrl+X | Copy/Cut selection as TSV |
438
439
  | Ctrl+V | Paste TSV data |
440
+ | Ctrl+D / Ctrl+R | Fill down / fill right |
441
+ | Ctrl+F / Ctrl+H | Find / find and replace |
439
442
  | Delete / Backspace | Clear selected cells |
440
443
  | Ctrl+Z | Undo |
441
444
  | Ctrl+Shift+Z / Ctrl+Y | Redo |
@@ -1477,19 +1477,19 @@ function N(e, t) {
1477
1477
  default: return e;
1478
1478
  }
1479
1479
  }
1480
- function se(e) {
1480
+ function P(e) {
1481
1481
  let t = String(e);
1482
1482
  if (!Number.isFinite(e) || t.includes("e")) return t;
1483
1483
  let n = new Intl.NumberFormat(l.get()).formatToParts(1.5).find((e) => e.type === "decimal")?.value;
1484
1484
  return n && n !== "." ? t.replace(".", n) : t;
1485
1485
  }
1486
- function ce(e) {
1486
+ function se(e) {
1487
1487
  if (e == null || e === "") return "";
1488
1488
  if (e instanceof Date) return Number.isNaN(e.getTime()) ? "" : `${e.getFullYear()}-${String(e.getMonth() + 1).padStart(2, "0")}-${String(e.getDate()).padStart(2, "0")}`;
1489
1489
  let t = String(e), n = /^(\d{4}-\d{2}-\d{2})(?:$|T)/.exec(t);
1490
1490
  return n ? n[1] : t;
1491
1491
  }
1492
- function le(e) {
1492
+ function ce(e) {
1493
1493
  if (e == null || e === "") return "";
1494
1494
  let t = e instanceof Date ? "" : String(e), n = /^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2})(?::\d{2}(?:\.\d+)?)?$/.exec(t);
1495
1495
  if (n) return `${n[1]} ${n[2]}`;
@@ -1500,7 +1500,7 @@ function le(e) {
1500
1500
  }
1501
1501
  //#endregion
1502
1502
  //#region src/export/xlsx-writer.ts
1503
- var ue = (() => {
1503
+ var le = (() => {
1504
1504
  let e = /* @__PURE__ */ new Uint32Array(256);
1505
1505
  for (let t = 0; t < 256; t++) {
1506
1506
  let n = t;
@@ -1509,23 +1509,23 @@ var ue = (() => {
1509
1509
  }
1510
1510
  return e;
1511
1511
  })();
1512
- function de(e) {
1512
+ function ue(e) {
1513
1513
  let t = 4294967295;
1514
- for (let n = 0; n < e.length; n++) t = ue[(t ^ e[n]) & 255] ^ t >>> 8;
1514
+ for (let n = 0; n < e.length; n++) t = le[(t ^ e[n]) & 255] ^ t >>> 8;
1515
1515
  return (t ^ 4294967295) >>> 0;
1516
1516
  }
1517
- var P = new TextEncoder();
1518
- function fe(e) {
1519
- return F(e.map((e) => ({
1517
+ var F = new TextEncoder();
1518
+ function de(e) {
1519
+ return I(e.map((e) => ({
1520
1520
  ...e,
1521
1521
  body: e.data,
1522
1522
  method: 0
1523
1523
  })));
1524
1524
  }
1525
- async function pe(e) {
1525
+ async function fe(e) {
1526
1526
  let t = [];
1527
1527
  for (let n of e) {
1528
- let e = await me(n.data);
1528
+ let e = await pe(n.data);
1529
1529
  t.push(e.length < n.data.length ? {
1530
1530
  ...n,
1531
1531
  body: e,
@@ -1536,9 +1536,9 @@ async function pe(e) {
1536
1536
  method: 0
1537
1537
  });
1538
1538
  }
1539
- return F(t);
1539
+ return I(t);
1540
1540
  }
1541
- async function me(e) {
1541
+ async function pe(e) {
1542
1542
  let t = new CompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
1543
1543
  n.write(e), n.close();
1544
1544
  let i = [];
@@ -1547,52 +1547,52 @@ async function me(e) {
1547
1547
  if (e) break;
1548
1548
  i.push(t);
1549
1549
  }
1550
- return I(i);
1550
+ return L(i);
1551
1551
  }
1552
- function F(e) {
1552
+ function I(e) {
1553
1553
  let t = [], n = [], r = 0;
1554
1554
  for (let i of e) {
1555
- let e = P.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);
1555
+ 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);
1556
1556
  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);
1557
1557
  let d = new ArrayBuffer(46 + e.length), f = new DataView(d);
1558
1558
  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;
1559
1559
  }
1560
- let i = I(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
1561
- return o.setUint32(0, 101010256, !0), o.setUint16(4, 0, !0), o.setUint16(6, 0, !0), o.setUint16(8, e.length, !0), o.setUint16(10, e.length, !0), o.setUint32(12, i.length, !0), o.setUint32(16, r, !0), o.setUint16(20, 0, !0), I([
1560
+ let i = L(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
1561
+ 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), L([
1562
1562
  ...t,
1563
1563
  i,
1564
1564
  new Uint8Array(a)
1565
1565
  ]);
1566
1566
  }
1567
- function I(e) {
1567
+ function L(e) {
1568
1568
  let t = e.reduce((e, t) => e + t.length, 0), n = new Uint8Array(t), r = 0;
1569
1569
  for (let t of e) n.set(t, r), r += t.length;
1570
1570
  return n;
1571
1571
  }
1572
- function L(e) {
1572
+ function R(e) {
1573
1573
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1574
1574
  }
1575
- function he(e) {
1575
+ function me(e) {
1576
1576
  let t = "";
1577
1577
  for (e++; e > 0;) t = String.fromCharCode(64 + (e % 26 || 26)) + t, e = Math.floor((e - 1) / 26);
1578
1578
  return t;
1579
1579
  }
1580
- function R(e, t) {
1581
- return he(t) + (e + 1);
1580
+ function z(e, t) {
1581
+ return me(t) + (e + 1);
1582
1582
  }
1583
- function ge(e) {
1583
+ function he(e) {
1584
1584
  let t = Date.UTC(1899, 11, 30);
1585
1585
  return (e.getTime() - t) / 864e5;
1586
1586
  }
1587
- 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>";
1588
- function Se(e, t) {
1589
- let n = [], r = t.map((e, t) => `<c r="${R(0, t)}" t="str" s="2"><v>${L(e.label)}</v></c>`);
1587
+ 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>";
1588
+ function xe(e, t) {
1589
+ let n = [], r = t.map((e, t) => `<c r="${z(0, t)}" t="str" s="2"><v>${R(e.label)}</v></c>`);
1590
1590
  return n.push(`<row r="1">${r.join("")}</row>`), e.forEach((e, r) => {
1591
1591
  let i = t.map((t, n) => {
1592
- let i = R(r + 1, n), a = e[t.key];
1592
+ let i = z(r + 1, n), a = e[t.key];
1593
1593
  if (a == null) return `<c r="${i}" t="str"><v></v></c>`;
1594
1594
  let o = t.type ?? "text";
1595
- 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>${L(String(a))}</v></c>`;
1595
+ 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>`;
1596
1596
  });
1597
1597
  n.push(`<row r="${r + 2}">${i.join("")}</row>`);
1598
1598
  }), `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@@ -1600,65 +1600,65 @@ function Se(e, t) {
1600
1600
  <sheetData>${n.join("")}</sheetData>
1601
1601
  </worksheet>`;
1602
1602
  }
1603
- function Ce(e, t) {
1604
- return fe(z(e, t));
1603
+ function Se(e, t) {
1604
+ return de(B(e, t));
1605
1605
  }
1606
- function we(e, t) {
1607
- return pe(z(e, t));
1606
+ function Ce(e, t) {
1607
+ return fe(B(e, t));
1608
1608
  }
1609
- function z(e, t) {
1610
- let n = Se(e, t);
1609
+ function B(e, t) {
1610
+ let n = xe(e, t);
1611
1611
  return [
1612
1612
  {
1613
1613
  name: "[Content_Types].xml",
1614
- data: P.encode(_e)
1614
+ data: F.encode(ge)
1615
1615
  },
1616
1616
  {
1617
1617
  name: "_rels/.rels",
1618
- data: P.encode(ve)
1618
+ data: F.encode(_e)
1619
1619
  },
1620
1620
  {
1621
1621
  name: "xl/workbook.xml",
1622
- data: P.encode(ye)
1622
+ data: F.encode(ve)
1623
1623
  },
1624
1624
  {
1625
1625
  name: "xl/_rels/workbook.xml.rels",
1626
- data: P.encode(be)
1626
+ data: F.encode(ye)
1627
1627
  },
1628
1628
  {
1629
1629
  name: "xl/worksheets/sheet1.xml",
1630
- data: P.encode(n)
1630
+ data: F.encode(n)
1631
1631
  },
1632
1632
  {
1633
1633
  name: "xl/styles.xml",
1634
- data: P.encode(xe)
1634
+ data: F.encode(be)
1635
1635
  }
1636
1636
  ];
1637
1637
  }
1638
1638
  //#endregion
1639
1639
  //#region src/export/export.ts
1640
- function B(e, t, n) {
1640
+ function V(e, t, n) {
1641
1641
  switch (n) {
1642
- case "csv": return V(e, t, ",");
1643
- case "tsv": return V(e, t, " ");
1644
- case "json": return De(e, t);
1645
- case "xlsx": return Ce(e, t);
1642
+ case "csv": return H(e, t, ",");
1643
+ case "tsv": return H(e, t, " ");
1644
+ case "json": return Ee(e, t);
1645
+ case "xlsx": return Se(e, t);
1646
1646
  }
1647
1647
  }
1648
- async function Te(e, t, n) {
1649
- let r = n === "xlsx" ? await we(e, t) : B(e, t, n);
1650
- return new Blob([r], { type: je(n) });
1648
+ async function we(e, t, n) {
1649
+ let r = n === "xlsx" ? await Ce(e, t) : V(e, t, n);
1650
+ return new Blob([r], { type: Ae(n) });
1651
1651
  }
1652
- function Ee(e, t) {
1652
+ function Te(e, t) {
1653
1653
  return e == null ? "" : (t.type === "date" || t.type === "datetime") && e instanceof Date ? e.toISOString() : String(e);
1654
1654
  }
1655
- function V(e, t, n) {
1656
- return [t.map((e) => H(e.label, n)).join(n), ...e.map((e) => t.map((t) => H(Ee(e[t.key], t), n)).join(n))].join("\n");
1655
+ function H(e, t, n) {
1656
+ 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");
1657
1657
  }
1658
- function H(e, t) {
1658
+ function U(e, t) {
1659
1659
  return e.includes(t) || e.includes("\"") || e.includes("\n") || e.includes("\r") ? "\"" + e.replace(/"/g, "\"\"") + "\"" : e;
1660
1660
  }
1661
- function De(e, t) {
1661
+ function Ee(e, t) {
1662
1662
  let n = e.map((e) => {
1663
1663
  let n = {};
1664
1664
  for (let r of t) {
@@ -1669,35 +1669,35 @@ function De(e, t) {
1669
1669
  });
1670
1670
  return JSON.stringify(n, null, 2);
1671
1671
  }
1672
- function Oe(e, t) {
1672
+ function De(e, t) {
1673
1673
  let n = URL.createObjectURL(e), r = document.createElement("a");
1674
1674
  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);
1675
1675
  }
1676
- var ke = {
1676
+ var Oe = {
1677
1677
  csv: "text/csv;charset=utf-8",
1678
1678
  tsv: "text/tab-separated-values;charset=utf-8",
1679
1679
  json: "application/json;charset=utf-8",
1680
1680
  xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1681
- }, Ae = {
1681
+ }, ke = {
1682
1682
  csv: ".csv",
1683
1683
  tsv: ".tsv",
1684
1684
  json: ".json",
1685
1685
  xlsx: ".xlsx"
1686
1686
  };
1687
+ function Ae(e) {
1688
+ return Oe[e];
1689
+ }
1687
1690
  function je(e) {
1688
1691
  return ke[e];
1689
1692
  }
1690
- function Me(e) {
1691
- return Ae[e];
1692
- }
1693
1693
  //#endregion
1694
1694
  //#region src/export/xlsx-reader.ts
1695
- function Ne(e) {
1695
+ function Me(e) {
1696
1696
  for (let t = e.byteLength - 22; t >= 0; t--) if (e.getUint32(t, !0) === 101010256) return t;
1697
1697
  throw Error("XLSX: End of central directory not found — not a valid ZIP file");
1698
1698
  }
1699
- function Pe(e) {
1700
- 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;
1699
+ function Ne(e) {
1700
+ 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;
1701
1701
  for (; o < s && e.getUint32(o, !0) === 33639248;) {
1702
1702
  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));
1703
1703
  a.push({
@@ -1710,7 +1710,7 @@ function Pe(e) {
1710
1710
  }
1711
1711
  return a;
1712
1712
  }
1713
- async function Fe(e) {
1713
+ async function Pe(e) {
1714
1714
  let t = new DecompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
1715
1715
  n.write(e), n.close();
1716
1716
  let i = [];
@@ -1723,28 +1723,28 @@ async function Fe(e) {
1723
1723
  for (let e of i) o.set(e, s), s += e.length;
1724
1724
  return o;
1725
1725
  }
1726
- async function Ie(e, t) {
1726
+ async function Fe(e, t) {
1727
1727
  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);
1728
1728
  if (t.compressionMethod === 0) return o.slice();
1729
- if (t.compressionMethod === 8) return Fe(o);
1729
+ if (t.compressionMethod === 8) return Pe(o);
1730
1730
  throw Error(`XLSX: Unsupported compression method ${t.compressionMethod}`);
1731
1731
  }
1732
- async function Le(e) {
1733
- let t = new DataView(e), n = Pe(t), r = /* @__PURE__ */ new Map();
1734
- for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await Ie(t, e));
1732
+ async function Ie(e) {
1733
+ let t = new DataView(e), n = Ne(t), r = /* @__PURE__ */ new Map();
1734
+ for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await Fe(t, e));
1735
1735
  return r;
1736
1736
  }
1737
- var Re = new TextDecoder("utf-8");
1738
- function U(e) {
1739
- let t = Re.decode(e);
1737
+ var Le = new TextDecoder("utf-8");
1738
+ function W(e) {
1739
+ let t = Le.decode(e);
1740
1740
  return new DOMParser().parseFromString(t, "application/xml");
1741
1741
  }
1742
- function ze(e) {
1742
+ function Re(e) {
1743
1743
  if (!e) return [];
1744
- let t = U(e);
1744
+ let t = W(e);
1745
1745
  return Array.from(t.querySelectorAll("si")).map((e) => Array.from(e.querySelectorAll("t")).map((e) => e.textContent ?? "").join(""));
1746
1746
  }
1747
- var Be = /* @__PURE__ */ new Set([
1747
+ var ze = /* @__PURE__ */ new Set([
1748
1748
  14,
1749
1749
  15,
1750
1750
  16,
@@ -1764,37 +1764,37 @@ var Be = /* @__PURE__ */ new Set([
1764
1764
  57,
1765
1765
  58
1766
1766
  ]);
1767
- function Ve(e) {
1767
+ function Be(e) {
1768
1768
  let t = e.replace(/"[^"]*"/g, "").replace(/\\./g, "").replace(/\[[^\]]*\]/g, "").split(";")[0];
1769
1769
  return /[dy]/i.test(t);
1770
1770
  }
1771
- function He(e) {
1771
+ function Ve(e) {
1772
1772
  let t = /* @__PURE__ */ new Set();
1773
1773
  if (!e) return t;
1774
- let n = U(e), r = /* @__PURE__ */ new Map();
1774
+ let n = W(e), r = /* @__PURE__ */ new Map();
1775
1775
  for (let e of Array.from(n.querySelectorAll("numFmts > numFmt"))) r.set(parseInt(e.getAttribute("numFmtId") ?? "", 10), e.getAttribute("formatCode") ?? "");
1776
1776
  return Array.from(n.querySelectorAll("cellXfs > xf")).forEach((e, n) => {
1777
1777
  let i = parseInt(e.getAttribute("numFmtId") ?? "0", 10), a = r.get(i);
1778
- (a === void 0 ? Be.has(i) : Ve(a)) && t.add(n);
1778
+ (a === void 0 ? ze.has(i) : Be(a)) && t.add(n);
1779
1779
  }), t;
1780
1780
  }
1781
- function Ue(e) {
1781
+ function He(e) {
1782
1782
  if (!e) return !1;
1783
- let t = U(e).querySelector("workbookPr")?.getAttribute("date1904");
1783
+ let t = W(e).querySelector("workbookPr")?.getAttribute("date1904");
1784
1784
  return t === "1" || t === "true";
1785
1785
  }
1786
- function We(e, t) {
1786
+ function Ue(e, t) {
1787
1787
  return new Date((t ? Date.UTC(1904, 0, 1) : Date.UTC(1899, 11, 30)) + Math.floor(e) * 864e5).toISOString().slice(0, 10);
1788
1788
  }
1789
- function Ge(e, t, n, r) {
1790
- let i = U(e).querySelectorAll("row");
1789
+ function We(e, t, n, r) {
1790
+ let i = W(e).querySelectorAll("row");
1791
1791
  if (i.length === 0) return [];
1792
1792
  let a = 0, o = /* @__PURE__ */ new Map();
1793
1793
  for (let e of i) {
1794
1794
  let i = parseInt(e.getAttribute("r") ?? "1", 10) - 1, s = /* @__PURE__ */ new Map();
1795
1795
  o.set(i, s);
1796
1796
  for (let i of e.querySelectorAll("c")) {
1797
- let e = Ke(i.getAttribute("r") ?? "");
1797
+ let e = Ge(i.getAttribute("r") ?? "");
1798
1798
  e > a && (a = e);
1799
1799
  let o = i.getAttribute("t") ?? "", c = i.getAttribute("s") ?? "", l = i.querySelector("v")?.textContent ?? "", u = i.querySelector("is > t")?.textContent ?? null, d;
1800
1800
  if (o === "s") d = t[parseInt(l, 10)] ?? "";
@@ -1803,7 +1803,7 @@ function Ge(e, t, n, r) {
1803
1803
  else if (l === "") d = "";
1804
1804
  else {
1805
1805
  let e = parseFloat(l);
1806
- d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ? We(e, r) : l;
1806
+ d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ? Ue(e, r) : l;
1807
1807
  }
1808
1808
  s.set(e, d);
1809
1809
  }
@@ -1817,13 +1817,13 @@ function Ge(e, t, n, r) {
1817
1817
  }
1818
1818
  return c;
1819
1819
  }
1820
- function Ke(e) {
1820
+ function Ge(e) {
1821
1821
  let t = 0, n = 0;
1822
1822
  for (; n < e.length && e[n] >= "A" && e[n] <= "Z";) t = t * 26 + (e.charCodeAt(n) - 64), n++;
1823
1823
  return t - 1;
1824
1824
  }
1825
- async function qe(e) {
1826
- let t = await Le(e), n = ze(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
1825
+ async function Ke(e) {
1826
+ let t = await Ie(e), n = Re(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
1827
1827
  if (!r) {
1828
1828
  for (let [e, n] of t) if (e.toLowerCase().includes("worksheets/sheet")) {
1829
1829
  r = n;
@@ -1831,7 +1831,7 @@ async function qe(e) {
1831
1831
  }
1832
1832
  }
1833
1833
  if (!r) throw Error("XLSX: No worksheet found");
1834
- let i = He(t.get("xl/styles.xml")), a = Ue(t.get("xl/workbook.xml")), o = Ge(r, n, i, a);
1834
+ let i = Ve(t.get("xl/styles.xml")), a = He(t.get("xl/workbook.xml")), o = We(r, n, i, a);
1835
1835
  return o.length === 0 ? {
1836
1836
  headers: [],
1837
1837
  rows: []
@@ -1842,12 +1842,12 @@ async function qe(e) {
1842
1842
  }
1843
1843
  //#endregion
1844
1844
  //#region src/models/types.ts
1845
- function W(e) {
1845
+ function G(e) {
1846
1846
  return e.align ? e.align : e.type === "number" ? "end" : e.type === "boolean" ? "center" : "start";
1847
1847
  }
1848
1848
  //#endregion
1849
1849
  //#region \0@oxc-project+runtime@0.152.0/helpers/esm/decorate.js
1850
- function G(e, t, n, r) {
1850
+ function K(e, t, n, r) {
1851
1851
  var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
1852
1852
  if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
1853
1853
  else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
@@ -1855,16 +1855,20 @@ function G(e, t, n, r) {
1855
1855
  }
1856
1856
  //#endregion
1857
1857
  //#region src/flex-table.ts
1858
- var K = {
1858
+ var q = [
1859
+ "copy",
1860
+ "cut",
1861
+ "paste"
1862
+ ], J = {
1859
1863
  eq: "=",
1860
1864
  neq: "≠",
1861
1865
  gt: ">",
1862
1866
  lt: "<",
1863
1867
  gte: "≥",
1864
1868
  lte: "≤"
1865
- }, q = 120, J = 40, Y = 20, X = 32, Z = 5, Je = 200, Q = class extends n {
1869
+ }, Y = 120, X = 40, qe = 20, Je = 32, Z = 5, Ye = 200, Q = class extends n {
1866
1870
  constructor(...e) {
1867
- super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = X, 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 = () => {
1871
+ super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = Je, 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 = () => {
1868
1872
  this._commitCommentPopup();
1869
1873
  }, 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();
1870
1874
  }
@@ -1879,7 +1883,7 @@ var K = {
1879
1883
  this._data = e, n && !this._inUndoRedo && (this.clearUndoOnDataChange && this._undo.clear(), this.clearSelectionOnDataChange && this._rowSelection.selectedCount > 0 && (this._rowSelection.deselectAll(), this._rowSelectionVersion++, this._dispatchRowSelectionEvent())), this.requestUpdate("data", t);
1880
1884
  }
1881
1885
  get rowHeight() {
1882
- let e = this._rowHeightExplicit ?? this._rowHeightFromCss ?? X;
1886
+ let e = this._rowHeightExplicit ?? this._rowHeightFromCss ?? Je;
1883
1887
  return Math.max(e, this._targetFloor);
1884
1888
  }
1885
1889
  set rowHeight(e) {
@@ -2229,17 +2233,17 @@ var K = {
2229
2233
  }
2230
2234
  exportToString(e, t) {
2231
2235
  let n = this._exportSlice(t);
2232
- return n ? B(n.rows, n.cols, e) : "";
2236
+ return n ? V(n.rows, n.cols, e) : "";
2233
2237
  }
2234
2238
  async exportToBlob(e, t) {
2235
2239
  let n = this._exportSlice(t) ?? {
2236
2240
  rows: [],
2237
2241
  cols: []
2238
2242
  };
2239
- return Te(n.rows, n.cols, e);
2243
+ return we(n.rows, n.cols, e);
2240
2244
  }
2241
2245
  async exportToFile(e, t) {
2242
- Oe(await this.exportToBlob(e), t ?? `export${Me(e)}`);
2246
+ De(await this.exportToBlob(e), t ?? `export${je(e)}`);
2243
2247
  }
2244
2248
  _exportSlice(e) {
2245
2249
  if (e?.selectionOnly) {
@@ -2312,7 +2316,7 @@ var K = {
2312
2316
  async importFromFile(e) {
2313
2317
  let t = e.name.toLowerCase();
2314
2318
  if (t.endsWith(".xlsx")) {
2315
- let t = await qe(await e.arrayBuffer());
2319
+ let t = await Ke(await e.arrayBuffer());
2316
2320
  this._applyImportedSheet(t);
2317
2321
  } else if (t.endsWith(".csv") || t.endsWith(".tsv")) {
2318
2322
  let t = await e.text(), n = h(t);
@@ -2404,8 +2408,8 @@ var K = {
2404
2408
  return this._columnWidths.get(e);
2405
2409
  }
2406
2410
  _getColWidth(e) {
2407
- let t = this._columnWidths.get(e.key) ?? e.width ?? q;
2408
- return Math.max(t, e.minWidth ?? J);
2411
+ let t = this._columnWidths.get(e.key) ?? e.width ?? Y;
2412
+ return Math.max(t, e.minWidth ?? X);
2409
2413
  }
2410
2414
  get headerHeight() {
2411
2415
  return this.rowHeight + 8;
@@ -2438,10 +2442,14 @@ var K = {
2438
2442
  };
2439
2443
  }
2440
2444
  connectedCallback() {
2441
- super.connectedCallback(), this._onScroll = this._onScroll.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDocumentClick = this._onDocumentClick.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this._onDragover = this._onDragover.bind(this), this._onDragleave = this._onDragleave.bind(this), this._onDrop = this._onDrop.bind(this), this.addEventListener("scroll", this._onScroll, { passive: !0 }), this.addEventListener("keydown", this._onKeyDown), this.addEventListener("contextmenu", this._onContextMenu), this.addEventListener("dragover", this._onDragover), this.addEventListener("dragleave", this._onDragleave), this.addEventListener("drop", this._onDrop), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid"), typeof ResizeObserver < "u" && (this._hostResizeObserver = new ResizeObserver(() => this._measureViewport()), this._hostResizeObserver.observe(this));
2445
+ super.connectedCallback(), this._onScroll = this._onScroll.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDocumentClick = this._onDocumentClick.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this._onDragover = this._onDragover.bind(this), this._onDragleave = this._onDragleave.bind(this), this._onDrop = this._onDrop.bind(this), this._onClipboard = this._onClipboard.bind(this), this.addEventListener("scroll", this._onScroll, { passive: !0 }), this.addEventListener("keydown", this._onKeyDown);
2446
+ for (let e of q) this.addEventListener(e, this._onClipboard);
2447
+ this.addEventListener("contextmenu", this._onContextMenu), this.addEventListener("dragover", this._onDragover), this.addEventListener("dragleave", this._onDragleave), this.addEventListener("drop", this._onDrop), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid"), typeof ResizeObserver < "u" && (this._hostResizeObserver = new ResizeObserver(() => this._measureViewport()), this._hostResizeObserver.observe(this));
2442
2448
  }
2443
2449
  disconnectedCallback() {
2444
- super.disconnectedCallback(), this.removeEventListener("scroll", this._onScroll), this.removeEventListener("keydown", this._onKeyDown), this.removeEventListener("contextmenu", this._onContextMenu), this.removeEventListener("dragover", this._onDragover), this.removeEventListener("dragleave", this._onDragleave), this.removeEventListener("drop", this._onDrop), document.removeEventListener("click", this._onDocumentClick), document.removeEventListener("mousedown", this._onCommentPopupOutsideClick), this._isDragging = !1, this._wasDrag = !1, this._resizeCleanup &&= (this._resizeCleanup(), null), this._hostResizeObserver &&= (this._hostResizeObserver.disconnect(), null);
2450
+ super.disconnectedCallback(), this.removeEventListener("scroll", this._onScroll), this.removeEventListener("keydown", this._onKeyDown);
2451
+ for (let e of q) this.removeEventListener(e, this._onClipboard);
2452
+ this.removeEventListener("contextmenu", this._onContextMenu), this.removeEventListener("dragover", this._onDragover), this.removeEventListener("dragleave", this._onDragleave), this.removeEventListener("drop", this._onDrop), document.removeEventListener("click", this._onDocumentClick), document.removeEventListener("mousedown", this._onCommentPopupOutsideClick), this._isDragging = !1, this._wasDrag = !1, this._resizeCleanup &&= (this._resizeCleanup(), null), this._hostResizeObserver &&= (this._hostResizeObserver.disconnect(), null);
2445
2453
  }
2446
2454
  firstUpdated() {
2447
2455
  this._readDensityTokens(), this._measureViewport(), this.shadowRoot && Array.isArray(this.shadowRoot.adoptedStyleSheets) && (this._baseStyleSheets = [...this.shadowRoot.adoptedStyleSheets]), this._syncStylesheets();
@@ -2543,7 +2551,7 @@ var K = {
2543
2551
  e !== this._viewportHeight && (this._viewportHeight = e), t !== this._viewportWidth && (this._viewportWidth = t), this._warnIfUnconstrained();
2544
2552
  }
2545
2553
  _warnIfUnconstrained() {
2546
- 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.`));
2554
+ this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount < Ye || 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.`));
2547
2555
  }
2548
2556
  _onScroll() {
2549
2557
  this._scrollTop = this.scrollTop, this._scrollLeft = this.scrollLeft;
@@ -2887,9 +2895,9 @@ var K = {
2887
2895
  switch (e.key.toLowerCase()) {
2888
2896
  case "z": return e.preventDefault(), e.shiftKey ? this.redo() : this.undo(), !0;
2889
2897
  case "y": return e.preventDefault(), this.redo(), !0;
2890
- case "c": return e.preventDefault(), this._handleCopy(!1), !0;
2891
- case "x": return e.preventDefault(), this._handleCopy(this.editable), !0;
2892
- case "v": return e.preventDefault(), this.editable && this._handlePaste(), !0;
2898
+ case "c":
2899
+ case "x":
2900
+ case "v": return !0;
2893
2901
  case "d": return e.preventDefault(), this.editable && this._handleFillDown(), !0;
2894
2902
  case "r": return e.preventDefault(), this.editable && this._handleFillRight(), !0;
2895
2903
  case "f": return e.preventDefault(), this._toggleFindPanel("find"), !0;
@@ -2901,12 +2909,12 @@ var K = {
2901
2909
  if (!e.altKey || !this._activeCell || e.key !== "ArrowLeft" && e.key !== "ArrowRight") return !1;
2902
2910
  e.preventDefault();
2903
2911
  let n = t[this._activeCell.col];
2904
- return n && this._resizeColumnBy(n.key, e.key === "ArrowRight" ? Y : -20), !0;
2912
+ return n && this._resizeColumnBy(n.key, e.key === "ArrowRight" ? qe : -20), !0;
2905
2913
  }
2906
2914
  _resizeColumnBy(e, t) {
2907
2915
  let n = this.visibleColumns.findIndex((t) => t.key === e), r = this.visibleColumns[n];
2908
2916
  if (!r) return;
2909
- let i = this._columnWidths.get(r.key) ?? r.width ?? q, a = r.minWidth ?? J, o = Math.max(a, i + t);
2917
+ let i = this._columnWidths.get(r.key) ?? r.width ?? Y, a = r.minWidth ?? X, o = Math.max(a, i + t);
2910
2918
  this._columnWidths.set(r.key, o), this.requestUpdate(), this.dispatchEvent(new CustomEvent("column-resize", {
2911
2919
  detail: {
2912
2920
  key: r.key,
@@ -2932,35 +2940,55 @@ var K = {
2932
2940
  default: return !1;
2933
2941
  }
2934
2942
  }
2935
- async _handleCopy(e) {
2936
- let t = this._selection.getEffectiveRange();
2937
- if (!t) return;
2938
- let n = this.visibleColumns, r = oe(this._sortedIndices.map((e) => this.data[e]), n, t);
2939
- try {
2940
- await navigator.clipboard.writeText(r);
2941
- } catch (e) {
2942
- this.dispatchEvent(new CustomEvent("clipboard-error", {
2943
- detail: {
2944
- action: "copy",
2945
- error: e
2946
- },
2947
- bubbles: !0,
2948
- composed: !0
2949
- }));
2943
+ _selectionTsv() {
2944
+ let e = this._selection.getEffectiveRange();
2945
+ return e ? {
2946
+ range: e,
2947
+ text: oe(this._sortedIndices.map((e) => this.data[e]), this.visibleColumns, e)
2948
+ } : null;
2949
+ }
2950
+ _onClipboard(e) {
2951
+ let t = e.composedPath()[0];
2952
+ if (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLElement && t.isContentEditable || !e.clipboardData) return;
2953
+ if (e.type === "paste") {
2954
+ if (!this.editable || !this._activeCell) return;
2955
+ e.preventDefault(), this._pasteText(e.clipboardData.getData("text/plain"));
2956
+ return;
2957
+ }
2958
+ let n = this._selectionTsv();
2959
+ n && (e.preventDefault(), e.clipboardData.setData("text/plain", n.text), this._afterCopy(n.range, n.text, e.type === "cut" && this.editable));
2960
+ }
2961
+ async _copyFromMenu() {
2962
+ let e = this._selectionTsv();
2963
+ if (e) {
2964
+ try {
2965
+ await navigator.clipboard.writeText(e.text);
2966
+ } catch (e) {
2967
+ this.dispatchEvent(new CustomEvent("clipboard-error", {
2968
+ detail: {
2969
+ action: "copy",
2970
+ error: e
2971
+ },
2972
+ bubbles: !0,
2973
+ composed: !0
2974
+ }));
2975
+ return;
2976
+ }
2977
+ this._afterCopy(e.range, e.text, !1);
2950
2978
  }
2951
- e && this._clearRange(t), this.dispatchEvent(new CustomEvent(e ? "clipboard-cut" : "clipboard-copy", {
2979
+ }
2980
+ _afterCopy(e, t, n) {
2981
+ n && this._clearRange(e), this.dispatchEvent(new CustomEvent(n ? "clipboard-cut" : "clipboard-copy", {
2952
2982
  detail: {
2953
- range: t,
2954
- text: r
2983
+ range: e,
2984
+ text: t
2955
2985
  },
2956
2986
  bubbles: !0,
2957
2987
  composed: !0
2958
2988
  }));
2959
2989
  }
2960
- async _handlePaste() {
2990
+ _pasteText(e) {
2961
2991
  if (!this._activeCell) return;
2962
- let e = await this._readClipboardText();
2963
- if (e == null) return;
2964
2992
  let t = h(e);
2965
2993
  if (t.length === 0) return;
2966
2994
  let n = this._expandRowsForPaste(this._activeCell.row, t.length), r = this._applyPasteData(this._activeCell, t);
@@ -2988,20 +3016,6 @@ var K = {
2988
3016
  composed: !0
2989
3017
  }));
2990
3018
  }
2991
- async _readClipboardText() {
2992
- try {
2993
- return await navigator.clipboard.readText();
2994
- } catch (e) {
2995
- return this.dispatchEvent(new CustomEvent("clipboard-error", {
2996
- detail: {
2997
- action: "paste",
2998
- error: e
2999
- },
3000
- bubbles: !0,
3001
- composed: !0
3002
- })), null;
3003
- }
3004
- }
3005
3019
  _selectPastedRange(e, t) {
3006
3020
  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;
3007
3021
  (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 = {
@@ -3228,7 +3242,7 @@ var K = {
3228
3242
  return Math.min(n, i);
3229
3243
  }
3230
3244
  _renderHeaderCell(e, t) {
3231
- let n = e.sortable !== !1, r = this._sortCriteria.find((t) => t.key === e.key), o = this._sortCriteria.length > 1 ? this._sortCriteria.findIndex((t) => t.key === e.key) : -1, s = this._filters.some((t) => t.key === e.key), c = e.pinned === "left", l = e.pinned === "right", u = c || l, d = e.headerAlign ?? W(e), f = [
3245
+ let n = e.sortable !== !1, r = this._sortCriteria.find((t) => t.key === e.key), o = this._sortCriteria.length > 1 ? this._sortCriteria.findIndex((t) => t.key === e.key) : -1, s = this._filters.some((t) => t.key === e.key), c = e.pinned === "left", l = e.pinned === "right", u = c || l, d = e.headerAlign ?? G(e), f = [
3232
3246
  "ft-header-cell",
3233
3247
  n ? "ft-sortable" : "",
3234
3248
  u ? "ft-pinned" : "",
@@ -3400,7 +3414,7 @@ var K = {
3400
3414
  ${r.map((e) => c("show", A("showColumn", { header: e.label }), () => this._setColumnHidden(e.key, !1)))}
3401
3415
  <div class="ft-header-menu-separator" role="separator"></div>
3402
3416
  ${c("autofit", A("autoFitWidth"), () => this._autoFitColumn(e))}
3403
- ${c("wider", A("wider"), () => this._resizeColumnBy(e, Y), !0)}
3417
+ ${c("wider", A("wider"), () => this._resizeColumnBy(e, qe), !0)}
3404
3418
  ${c("narrower", A("narrower"), () => this._resizeColumnBy(e, -20), !0)}
3405
3419
  </div>
3406
3420
  `;
@@ -3423,7 +3437,7 @@ var K = {
3423
3437
  style="position: fixed; left: ${n}px; top: ${r}px; z-index: var(--u-layer-floating, 1000);"
3424
3438
  @mousedown=${(e) => e.stopPropagation()}
3425
3439
  @keydown=${(e) => this._onMenuKeydown(e, ".ft-body-context-menu", l)}>
3426
- ${d(A("copy"), () => this._handleCopy(!1))}
3440
+ ${d(A("copy"), () => this._copyFromMenu())}
3427
3441
  ${f}
3428
3442
  ${d(A("insertRowAbove"), () => this.addRow(void 0, t))}
3429
3443
  ${d(A("insertRowBelow"), () => this.addRow(void 0, t + 1))}
@@ -3689,10 +3703,10 @@ var K = {
3689
3703
  @keydown=${(e) => {
3690
3704
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
3691
3705
  }}>
3692
- ${Object.keys(K).map((e) => i`<option value=${e}>${K[e]}</option>`)}
3706
+ ${Object.keys(J).map((e) => i`<option value=${e}>${J[e]}</option>`)}
3693
3707
  </select>
3694
3708
  <input class="ft-filter-input ft-num-cond-input" type="text" inputmode="decimal" placeholder=${A("valuePlaceholder")}
3695
- .value=${n.text ?? (n.value == null ? "" : se(n.value))}
3709
+ .value=${n.text ?? (n.value == null ? "" : P(n.value))}
3696
3710
  aria-invalid=${n.text && n.value == null ? "true" : "false"}
3697
3711
  @input=${(n) => {
3698
3712
  let r = n.target.value, i = this._numberFilterState.get(e) ?? this._defaultNumState();
@@ -3801,7 +3815,7 @@ var K = {
3801
3815
  if (!n) return;
3802
3816
  let r = this.shadowRoot?.querySelectorAll(`.ft-cell[data-col-index="${t}"]`), i = 0, a = this.shadowRoot?.querySelector(`.ft-header-cell[data-col-index="${t}"]`);
3803
3817
  if (a && (i = Math.max(i, a.scrollWidth)), r) for (let e of r) i = Math.max(i, e.scrollWidth);
3804
- let o = n.minWidth ?? J, s = Math.max(o, i + 8);
3818
+ let o = n.minWidth ?? X, s = Math.max(o, i + 8);
3805
3819
  this._columnWidths.set(n.key, s), this.requestUpdate(), this.dispatchEvent(new CustomEvent("column-resize", {
3806
3820
  detail: {
3807
3821
  key: n.key,
@@ -3814,7 +3828,7 @@ var K = {
3814
3828
  }
3815
3829
  _onResizeStart(e, t) {
3816
3830
  e.preventDefault(), e.stopPropagation();
3817
- let n = this.visibleColumns[t], r = this._columnWidths.get(n.key) ?? n.width ?? q;
3831
+ let n = this.visibleColumns[t], r = this._columnWidths.get(n.key) ?? n.width ?? Y;
3818
3832
  this._resizing = {
3819
3833
  colIndex: t,
3820
3834
  startX: e.clientX,
@@ -3822,13 +3836,13 @@ var K = {
3822
3836
  };
3823
3837
  let i = (e) => {
3824
3838
  if (!this._resizing) return;
3825
- let t = e.clientX - this._resizing.startX, r = n.minWidth ?? J, i = Math.max(r, this._resizing.startWidth + t);
3839
+ let t = e.clientX - this._resizing.startX, r = n.minWidth ?? X, i = Math.max(r, this._resizing.startWidth + t);
3826
3840
  this._columnWidths.set(n.key, i), this.requestUpdate();
3827
3841
  }, a = () => {
3828
3842
  document.removeEventListener("mousemove", i), document.removeEventListener("mouseup", o), this._resizeCleanup = null;
3829
3843
  }, o = () => {
3830
3844
  if (a(), this._resizing) {
3831
- let e = this._columnWidths.get(n.key) ?? q;
3845
+ let e = this._columnWidths.get(n.key) ?? Y;
3832
3846
  this.dispatchEvent(new CustomEvent("column-resize", {
3833
3847
  detail: {
3834
3848
  key: n.key,
@@ -4420,7 +4434,7 @@ var K = {
4420
4434
  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 = [
4421
4435
  "ft-cell",
4422
4436
  `ft-type-${t.type ?? "text"}`,
4423
- `ft-align-${W(t)}`,
4437
+ `ft-align-${G(t)}`,
4424
4438
  s ? "ft-active" : "",
4425
4439
  l ? "ft-selected" : "",
4426
4440
  f ? "ft-pinned" : "",
@@ -4455,7 +4469,7 @@ var K = {
4455
4469
  let n = e[t.key], r = n == null ? "" : String(n);
4456
4470
  if (t.type === "number") return i`
4457
4471
  <input class="ft-editor ft-editor-number" type="text" inputmode="decimal"
4458
- .value=${typeof n == "number" ? se(n) : r}
4472
+ .value=${typeof n == "number" ? P(n) : r}
4459
4473
  @keydown=${this._onEditorKeyDown}
4460
4474
  @blur=${() => this._commitEdit()}>
4461
4475
  `;
@@ -4464,7 +4478,7 @@ var K = {
4464
4478
  return i`
4465
4479
  <u-date-picker class="ft-editor ft-editor-${t.type}" size="sm"
4466
4480
  mode=${e ? "datetime" : "date"} ?confirm=${e}
4467
- .value=${Ye(n, e)}
4481
+ .value=${Xe(n, e)}
4468
4482
  @keydown=${this._onEditorKeyDown}
4469
4483
  @change=${() => this._commitEdit()}
4470
4484
  @blur=${() => this._commitEdit()}></u-date-picker>
@@ -4511,67 +4525,67 @@ var K = {
4511
4525
  `;
4512
4526
  }
4513
4527
  };
4514
- G([s({ type: Array })], Q.prototype, "columns", void 0), G([s({
4528
+ K([s({ type: Array })], Q.prototype, "columns", void 0), K([s({
4515
4529
  type: Array,
4516
4530
  hasChanged: () => !0
4517
- })], Q.prototype, "data", null), G([s({
4531
+ })], Q.prototype, "data", null), K([s({
4518
4532
  type: Boolean,
4519
4533
  attribute: "clear-undo-on-data-change"
4520
- })], Q.prototype, "clearUndoOnDataChange", void 0), G([s({
4534
+ })], Q.prototype, "clearUndoOnDataChange", void 0), K([s({
4521
4535
  type: Boolean,
4522
4536
  attribute: "clear-selection-on-data-change"
4523
- })], Q.prototype, "clearSelectionOnDataChange", void 0), G([s({
4537
+ })], Q.prototype, "clearSelectionOnDataChange", void 0), K([s({
4524
4538
  type: Number,
4525
4539
  attribute: "row-height"
4526
- })], Q.prototype, "rowHeight", null), G([s({
4540
+ })], Q.prototype, "rowHeight", null), K([s({
4527
4541
  type: Boolean,
4528
4542
  attribute: "show-row-numbers"
4529
- })], Q.prototype, "showRowNumbers", void 0), G([s({
4543
+ })], Q.prototype, "showRowNumbers", void 0), K([s({
4530
4544
  type: String,
4531
4545
  reflect: !0
4532
- })], Q.prototype, "theme", void 0), G([s({
4546
+ })], Q.prototype, "theme", void 0), K([s({
4533
4547
  type: Number,
4534
4548
  attribute: "max-rows"
4535
- })], Q.prototype, "maxRows", void 0), G([s({ type: Boolean })], Q.prototype, "editable", void 0), G([s({
4549
+ })], Q.prototype, "maxRows", void 0), K([s({ type: Boolean })], Q.prototype, "editable", void 0), K([s({
4536
4550
  type: Boolean,
4537
4551
  attribute: "show-filters"
4538
- })], Q.prototype, "showFilters", void 0), G([s({
4552
+ })], Q.prototype, "showFilters", void 0), K([s({
4539
4553
  type: Boolean,
4540
4554
  attribute: "show-context-menu"
4541
- })], Q.prototype, "showContextMenu", void 0), G([s({
4555
+ })], Q.prototype, "showContextMenu", void 0), K([s({
4542
4556
  type: Number,
4543
4557
  attribute: "frozen-rows"
4544
- })], Q.prototype, "frozenRows", void 0), G([s({
4558
+ })], Q.prototype, "frozenRows", void 0), K([s({
4545
4559
  type: String,
4546
4560
  attribute: "empty-message"
4547
- })], Q.prototype, "emptyMessage", void 0), G([s({
4561
+ })], Q.prototype, "emptyMessage", void 0), K([s({
4548
4562
  type: String,
4549
4563
  attribute: "no-matching-message"
4550
- })], Q.prototype, "noMatchingMessage", void 0), G([s({
4564
+ })], Q.prototype, "noMatchingMessage", void 0), K([s({
4551
4565
  type: Boolean,
4552
4566
  reflect: !0
4553
- })], Q.prototype, "loading", void 0), G([s({
4567
+ })], Q.prototype, "loading", void 0), K([s({
4554
4568
  type: Boolean,
4555
4569
  attribute: "import-enabled"
4556
- })], Q.prototype, "importEnabled", void 0), G([s({ type: Boolean })], Q.prototype, "selectable", void 0), G([s({
4570
+ })], Q.prototype, "importEnabled", void 0), K([s({ type: Boolean })], Q.prototype, "selectable", void 0), K([s({
4557
4571
  type: String,
4558
4572
  attribute: "selection-mode"
4559
- })], Q.prototype, "selectionMode", null), G([s({
4573
+ })], Q.prototype, "selectionMode", null), K([s({
4560
4574
  type: String,
4561
4575
  attribute: "data-mode"
4562
- })], Q.prototype, "dataMode", void 0), G([s({
4576
+ })], Q.prototype, "dataMode", void 0), K([s({
4563
4577
  type: Object,
4564
4578
  attribute: "footer-data"
4565
- })], Q.prototype, "footerData", void 0), G([s({ attribute: !1 })], Q.prototype, "stylesheets", void 0), G([s({
4579
+ })], Q.prototype, "footerData", void 0), K([s({ attribute: !1 })], Q.prototype, "stylesheets", void 0), K([s({
4566
4580
  type: Number,
4567
4581
  attribute: "max-undo-size"
4568
- })], Q.prototype, "maxUndoSize", null), G([c()], Q.prototype, "_scrollTop", void 0), G([c()], Q.prototype, "_scrollLeft", void 0), G([c()], Q.prototype, "_viewportHeight", void 0), G([c()], Q.prototype, "_viewportWidth", void 0), G([c()], Q.prototype, "_activeCell", void 0), G([c()], Q.prototype, "_editingCell", void 0), G([c()], Q.prototype, "_sortCriteria", void 0), G([c()], Q.prototype, "_openFilterKey", void 0), G([c()], Q.prototype, "_rowSelectionVersion", void 0), G([c()], Q.prototype, "_autocompleteState", void 0), G([c()], Q.prototype, "_headerMenu", void 0), G([c()], Q.prototype, "_bodyContextMenu", void 0), G([c()], Q.prototype, "_commentPopup", void 0), G([c()], Q.prototype, "_isDragOver", void 0), Q = G([o("flex-table")], Q);
4569
- function Ye(e, t) {
4582
+ })], Q.prototype, "maxUndoSize", null), K([c()], Q.prototype, "_scrollTop", void 0), K([c()], Q.prototype, "_scrollLeft", void 0), K([c()], Q.prototype, "_viewportHeight", void 0), K([c()], Q.prototype, "_viewportWidth", void 0), K([c()], Q.prototype, "_activeCell", void 0), K([c()], Q.prototype, "_editingCell", void 0), K([c()], Q.prototype, "_sortCriteria", void 0), K([c()], Q.prototype, "_openFilterKey", void 0), K([c()], Q.prototype, "_rowSelectionVersion", void 0), K([c()], Q.prototype, "_autocompleteState", void 0), K([c()], Q.prototype, "_headerMenu", void 0), K([c()], Q.prototype, "_bodyContextMenu", void 0), K([c()], Q.prototype, "_commentPopup", void 0), K([c()], Q.prototype, "_isDragOver", void 0), Q = K([o("flex-table")], Q);
4583
+ function Xe(e, t) {
4570
4584
  if (t) {
4571
- let t = le(e);
4585
+ let t = ce(e);
4572
4586
  return /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(t) ? t.replace(" ", "T") : void 0;
4573
4587
  }
4574
- let n = ce(e);
4588
+ let n = se(e);
4575
4589
  return /^\d{4}-\d{2}-\d{2}$/.test(n) ? n : void 0;
4576
4590
  }
4577
4591
  function $(e) {
@@ -4582,4 +4596,4 @@ function $(e) {
4582
4596
  }
4583
4597
  }
4584
4598
  //#endregion
4585
- export { j as a, M as i, W as n, k as o, B as r, C as s, Q as t };
4599
+ export { j as a, M as i, G as n, k as o, V as r, C as s, Q as t };
@@ -393,9 +393,20 @@ export declare class FlexTable extends LitElement {
393
393
  /** Widen (positive) or narrow (negative) a visible column by `delta` px, never below its minimum. */
394
394
  private _resizeColumnBy;
395
395
  private _handleNavigation;
396
- private _handleCopy;
397
- private _handlePaste;
398
- private _readClipboardText;
396
+ /**
397
+ * The selection as TSV in display (sorted) order, or `null` without a selection.
398
+ */
399
+ private _selectionTsv;
400
+ /**
401
+ * The browser's copy / cut / paste on the grid. Events from a text field inside the grid (the cell
402
+ * editor, the find panel, a filter input) are that field's own and pass through untouched.
403
+ */
404
+ private _onClipboard;
405
+ /** The context menu's Copy — no clipboard event to fill, so it goes through the async Clipboard API. */
406
+ private _copyFromMenu;
407
+ /** Runs once the text is on the clipboard — only then is a cut range cleared. */
408
+ private _afterCopy;
409
+ private _pasteText;
399
410
  /**
400
411
  * After a paste, the cells it wrote are the selection — as in spreadsheets — so the reader sees
401
412
  * what changed and can copy, clear or undo it as one block. The active cell stays where the
@@ -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-h2noRChg.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-B8ehfxqn.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-h2noRChg.js";
1
+ import { t as e } from "./flex-table-B8ehfxqn.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.47.0",
3
+ "version": "0.48.0",
4
4
  "description": "A minimalist, input-centric data grid web component",
5
5
  "type": "module",
6
6
  "main": "./dist/flex-table.js",
@@ -159,7 +159,7 @@ All are `CustomEvent`s with `bubbles: true, composed: true`. `row`/`index` are d
159
159
  | `selection-change` | `{ selectedIndices, selectedRows }` |
160
160
  | `clipboard-copy` / `clipboard-cut` | `{ range, text }` (TSV) |
161
161
  | `clipboard-paste` | `{ changes, addedRows }` |
162
- | `clipboard-error` | `{ action: 'copy' \| 'paste', error }` |
162
+ | `clipboard-error` | `{ action: 'copy', error }` — the context menu's Copy could not write; no `clipboard-copy` follows |
163
163
  | `fill-handle-apply` | `{ sourceRange, targetRange, cells }` |
164
164
  | `find-replace` | `{ type: 'replace' \| 'replace-all', cells }` |
165
165
  | `comment-change` | `{ dataIndex, colKey, text }` |