twico-ui 1.34.0 → 1.35.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
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to Twico UI are documented here (newest first). This file is generated automatically on each release by [semantic-release](https://semantic-release.gitbook.io/) from [Conventional Commits](https://www.conventionalcommits.org/) — do not edit it by hand. The same notes appear on each [GitHub Release](https://github.com/EncryptionL/twico-ui/releases).
4
4
 
5
+ # [1.35.0](https://github.com/EncryptionL/twico-ui/compare/v1.34.0...v1.35.0) (2026-08-28)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **datatable:** harden [#359](https://github.com/EncryptionL/twico-ui/issues/359) row-tree (server no-refire, child edit, numbering, cycle) ([7c0c70b](https://github.com/EncryptionL/twico-ui/commit/7c0c70b11b1689a8f60912df3a9cbcc3a2c36a8c)), closes [#350](https://github.com/EncryptionL/twico-ui/issues/350) [#350](https://github.com/EncryptionL/twico-ui/issues/350)
11
+
12
+
13
+ ### Features
14
+
15
+ * **datatable:** server-mode lazy row-tree — getRowCanExpand/getSubRows/getRowDepth ([15c7c76](https://github.com/EncryptionL/twico-ui/commit/15c7c767212940c96d5f031466bd251ee4cc83cb)), closes [#350](https://github.com/EncryptionL/twico-ui/issues/350) [#350](https://github.com/EncryptionL/twico-ui/issues/350) [#350](https://github.com/EncryptionL/twico-ui/issues/350) [#359](https://github.com/EncryptionL/twico-ui/issues/359)
16
+
5
17
  # [1.34.0](https://github.com/EncryptionL/twico-ui/compare/v1.33.1...v1.34.0) (2026-08-14)
6
18
 
7
19
 
package/dist/index.cjs CHANGED
@@ -9347,6 +9347,13 @@ function Datatable({
9347
9347
  renderRowDetail,
9348
9348
  expandedRowIds,
9349
9349
  onExpandedRowsChange,
9350
+ // #359: server-mode lazy row-tree — `getRowCanExpand(row)` draws the same leading chevron on parent DATA
9351
+ // rows (independent of renderRowDetail); expanding reveals CHILD data rows in the SAME columns rather than a
9352
+ // panel. In server mode the host returns children inline (the expanded set is folded into onServerChange);
9353
+ // in client mode `getSubRows(row)` supplies them. `getRowDepth(row)` indents nested rows so they read as a tree.
9354
+ getRowCanExpand,
9355
+ getRowDepth,
9356
+ getSubRows,
9350
9357
  className = "",
9351
9358
  ...rest
9352
9359
  }) {
@@ -9559,6 +9566,7 @@ function Datatable({
9559
9566
  () => new Set(expandControlled ? expandedRowIds : internalExpanded),
9560
9567
  [expandControlled, expandedRowIds, internalExpanded]
9561
9568
  );
9569
+ const expandedKey = React51__namespace.default.useMemo(() => JSON.stringify([...expandedSet].sort()), [expandedSet]);
9562
9570
  const [pinnedRows, setPinnedRows] = React51__namespace.default.useState({ top: [], bottom: [] });
9563
9571
  const [headH, setHeadH] = React51__namespace.default.useState(41);
9564
9572
  const theadRef = React51__namespace.default.useRef(null);
@@ -9961,7 +9969,10 @@ function Datatable({
9961
9969
  const NUM_W = 56;
9962
9970
  const CHK_W = checkboxSelection ? rowReorder ? 68 : 44 : 0;
9963
9971
  const hasRowDetail = typeof renderRowDetail === "function";
9964
- const EXP_W = hasRowDetail ? 44 : 0;
9972
+ const hasRowTree = typeof getRowCanExpand === "function";
9973
+ const hasExpandCol = hasRowDetail || hasRowTree;
9974
+ const treeExpandedKey = hasRowTree ? expandedKey : "";
9975
+ const EXP_W = hasExpandCol ? 44 : 0;
9965
9976
  const numLeft = EXP_W + CHK_W;
9966
9977
  const leadW = numLeft + (showRowNum ? NUM_W : 0);
9967
9978
  const visLeft = React51__namespace.default.useMemo(() => pins.left.filter((f) => colByField[f] && !effectiveHidden.has(f)), [pins.left, colByField, effectiveHidden]);
@@ -10034,6 +10045,40 @@ function Datatable({
10034
10045
  React51__namespace.default.useEffect(() => {
10035
10046
  if (pageVal > totalPages - 1) commitPage(0);
10036
10047
  }, [totalPages]);
10048
+ const treeRows = React51__namespace.default.useMemo(() => {
10049
+ if (serverMode || typeof getSubRows !== "function") return null;
10050
+ const out = [];
10051
+ const seen2 = /* @__PURE__ */ new Set();
10052
+ const walk = (r2, d) => {
10053
+ const key = keyOf(r2);
10054
+ if (seen2.has(key)) return;
10055
+ seen2.add(key);
10056
+ out.push({ row: r2, depth: d });
10057
+ if (expandedSet.has(key)) for (const c of getSubRows(r2) || []) walk(c, d + 1);
10058
+ };
10059
+ for (const r2 of paged) walk(r2, 0);
10060
+ return out;
10061
+ }, [serverMode, getSubRows, paged, expandedSet, keyOf]);
10062
+ const depthByKey = React51__namespace.default.useMemo(() => {
10063
+ const m = /* @__PURE__ */ new Map();
10064
+ if (treeRows) for (const t of treeRows) m.set(keyOf(t.row), t.depth);
10065
+ return m;
10066
+ }, [treeRows, keyOf]);
10067
+ const treeSeqByKey = React51__namespace.default.useMemo(() => {
10068
+ if (!treeRows) return null;
10069
+ const m = /* @__PURE__ */ new Map();
10070
+ const seen2 = /* @__PURE__ */ new Set();
10071
+ let n = 0;
10072
+ const walk = (r2) => {
10073
+ const key = keyOf(r2);
10074
+ if (seen2.has(key)) return;
10075
+ seen2.add(key);
10076
+ m.set(key, n++);
10077
+ if (expandedSet.has(key)) for (const c of getSubRows(r2) || []) walk(c);
10078
+ };
10079
+ for (const r2 of processed) walk(r2);
10080
+ return m;
10081
+ }, [treeRows, processed, expandedSet, getSubRows, keyOf]);
10037
10082
  const activeGroupBy = React51__namespace.default.useMemo(() => groupBy.filter((f) => colByField[f]), [groupBy, colByField]);
10038
10083
  function subtotalText(rowsIn) {
10039
10084
  const parts = [];
@@ -10084,7 +10129,7 @@ function Datatable({
10084
10129
  };
10085
10130
  return build(paged, 0, "");
10086
10131
  }, [activeGroupBy, collapsed, paged, ordered, aggOn]);
10087
- const leafRows = displayItems ? displayItems.filter((i) => i.kind === "leaf").map((i) => i.row) : paged;
10132
+ const leafRows = displayItems ? displayItems.filter((i) => i.kind === "leaf").map((i) => i.row) : treeRows ? treeRows.map((t) => t.row) : paged;
10088
10133
  function toggleGroup(key) {
10089
10134
  setCollapsed((s) => {
10090
10135
  const n = new Set(s);
@@ -10336,12 +10381,14 @@ function Datatable({
10336
10381
  // #303: "and" (default) | "or" — the server groups its WHERE accordingly
10337
10382
  quickFilter: quick.trim(),
10338
10383
  visibleColumns,
10339
- hiddenColumns
10384
+ hiddenColumns,
10340
10385
  // #191: server can project only the visible columns
10386
+ ...hasRowTree ? { expanded: [...expandedSet] } : null
10387
+ // #359: only a row-tree folds expanded parents in
10341
10388
  });
10342
10389
  }, 250);
10343
10390
  return () => clearTimeout(t);
10344
- }, [serverMode, pageVal, sizeVal, sort, filters, filterLogic, quick, visibleColumns, hiddenColumns]);
10391
+ }, [serverMode, pageVal, sizeVal, sort, filters, filterLogic, quick, visibleColumns, hiddenColumns, treeExpandedKey]);
10345
10392
  const onColVisRef = React51__namespace.default.useRef(onColumnVisibilityChange);
10346
10393
  onColVisRef.current = onColumnVisibilityChange;
10347
10394
  const lastVisibleKey = React51__namespace.default.useRef(null);
@@ -10715,12 +10762,12 @@ function Datatable({
10715
10762
  next = next === "" ? null : Number(next);
10716
10763
  if (Number.isNaN(next)) next = null;
10717
10764
  }
10718
- const row = paged.find((r2, i) => keyOf(r2, i) === editing.key);
10765
+ const row = leafRows.find((r2, i) => keyOf(r2, i) === editing.key);
10719
10766
  setEditing(null);
10720
10767
  if (!row || row[editing.field] === next) return;
10721
10768
  const updated = { ...row, [editing.field]: next };
10722
10769
  onRowUpdate?.(updated, row, editing.field);
10723
- if (onRowsChange) {
10770
+ if (onRowsChange && rows.some((r2, i) => keyOf(r2, i) === editing.key)) {
10724
10771
  onRowsChange(rows.map((r2, i) => keyOf(r2, i) === editing.key ? updated : r2));
10725
10772
  }
10726
10773
  }
@@ -10849,20 +10896,25 @@ function Datatable({
10849
10896
  };
10850
10897
  const writeCellPatches = (patchByKey) => {
10851
10898
  if (!patchByKey.size) return 0;
10852
- const changed = [];
10853
- const nextAll = rows.map((r2, i) => {
10854
- const k = keyOf(r2, i);
10855
- const patch = patchByKey.get(k);
10856
- if (!patch) return r2;
10899
+ let count = 0;
10900
+ leafRows.forEach((r2, i) => {
10901
+ const patch = patchByKey.get(keyOf(r2, i));
10902
+ if (!patch) return;
10857
10903
  const updated = { ...r2, ...patch };
10858
- changed.push([updated, r2, patch]);
10859
- return updated;
10904
+ for (const f of Object.keys(patch)) onRowUpdate?.(updated, r2, f);
10905
+ count++;
10860
10906
  });
10861
- changed.forEach(([updated, orig, patch]) => {
10862
- for (const f of Object.keys(patch)) onRowUpdate?.(updated, orig, f);
10863
- });
10864
- if (onRowsChange && changed.length) onRowsChange(nextAll);
10865
- return changed.length;
10907
+ if (onRowsChange) {
10908
+ let anyTop = false;
10909
+ const nextAll = rows.map((r2, i) => {
10910
+ const patch = patchByKey.get(keyOf(r2, i));
10911
+ if (!patch) return r2;
10912
+ anyTop = true;
10913
+ return { ...r2, ...patch };
10914
+ });
10915
+ if (anyTop) onRowsChange(nextAll);
10916
+ }
10917
+ return count;
10866
10918
  };
10867
10919
  const rectCells = () => {
10868
10920
  if (!cellRect) return null;
@@ -11409,7 +11461,7 @@ function Datatable({
11409
11461
  const manageableCols = cols.filter((c) => c.field !== "__pinactions__");
11410
11462
  const visibleColCount = manageableCols.filter((c) => !effectiveHidden.has(c.field)).length;
11411
11463
  const rppOptions = Array.from(new Set([...pageSizeOptions || [], pageSize].filter((n) => n > 0))).sort((a, b) => a - b).map((n) => ({ value: String(n), label: String(n) }));
11412
- const totalCols = ordered.length + (checkboxSelection ? 1 : 0) + (showRowNum ? 1 : 0) + (hasRowDetail ? 1 : 0);
11464
+ const totalCols = ordered.length + (checkboxSelection ? 1 : 0) + (showRowNum ? 1 : 0) + (hasExpandCol ? 1 : 0);
11413
11465
  function renderGroupRow(item) {
11414
11466
  const subs = aggOn ? subtotalText(item.rows) : [];
11415
11467
  return /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "twc-dt__group-row", role: "row", children: /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "twc-dt__group-cell", role: "gridcell", colSpan: totalCols, style: { maxWidth: "none" }, children: [
@@ -11464,8 +11516,10 @@ function Datatable({
11464
11516
  const k = keyOf(row, ri);
11465
11517
  const sel = selected.has(k);
11466
11518
  const detail = hasRowDetail && !pinSide ? renderRowDetail(row) : null;
11467
- const expandable = detail != null;
11519
+ const canTreeExpand = hasRowTree && !pinSide && !!getRowCanExpand(row);
11520
+ const expandable = detail != null || canTreeExpand;
11468
11521
  const open = expandable && expandedSet.has(k);
11522
+ const depth = getRowDepth ? getRowDepth(row) || 0 : depthByKey.get(k) || 0;
11469
11523
  const rowActive = selectionMode === "row" && activeRowVal === k;
11470
11524
  const stickyStyle = pinSide === "top" ? { position: "sticky", top: headH, zIndex: 5 } : pinSide === "bottom" ? { position: "sticky", bottom: 0, zIndex: 5 } : void 0;
11471
11525
  const h = rowHeights[k];
@@ -11479,7 +11533,7 @@ function Datatable({
11479
11533
  {
11480
11534
  className: "twc-dt__row",
11481
11535
  role: "row",
11482
- "aria-rowindex": (paginated && !serverMode ? pageVal * sizeVal : 0) + ri + 2,
11536
+ "aria-rowindex": treeSeqByKey ? treeSeqByKey.get(k) + 2 : (paginated && !serverMode ? pageVal * sizeVal : 0) + ri + 2,
11483
11537
  "aria-selected": (checkboxSelection ? sel : rowActive) || void 0,
11484
11538
  "data-op": row.__diffop || void 0,
11485
11539
  "data-selected": sel || void 0,
@@ -11513,7 +11567,7 @@ function Datatable({
11513
11567
  onDragEnd: reorderable ? () => setRowDrag({ from: null, over: null, after: false }) : void 0,
11514
11568
  onClick: (e) => handleRowClick(e, k, row),
11515
11569
  children: [
11516
- hasRowDetail ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__expand-cell", role: "gridcell", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W }, children: expandable ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__expand-btn", "aria-expanded": open, "aria-controls": open ? `${gridId}-detail-${ri}` : void 0, "aria-label": open ? "Collapse row" : "Expand row", onClick: (e) => {
11570
+ hasExpandCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__expand-cell", role: "gridcell", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W }, children: expandable ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__expand-btn", "aria-expanded": open, "aria-controls": open && detail != null ? `${gridId}-detail-${ri}` : void 0, "aria-label": open ? "Collapse row" : "Expand row", onClick: (e) => {
11517
11571
  e.stopPropagation();
11518
11572
  toggleRowDetail(k);
11519
11573
  }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__expand-chev", "data-open": open || void 0, children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.chevDown }) }) }) : null }) : null,
@@ -11542,7 +11596,7 @@ function Datatable({
11542
11596
  ] }),
11543
11597
  rowResize && !pinSide ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__row-resizer", title: "Drag to resize row", onPointerDown: (e) => startRowResize(e, k, e.currentTarget.closest("tr")), onClick: (e) => e.stopPropagation() }) : null
11544
11598
  ] }) : null,
11545
- showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": visLeft.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: typeof ri === "number" ? (paginated || serverMode ? pageVal * sizeVal : 0) + ri + 1 : "" }) : null,
11599
+ showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": visLeft.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: treeSeqByKey ? treeSeqByKey.get(k) + 1 : typeof ri === "number" ? (paginated || serverMode ? pageVal * sizeVal : 0) + ri + 1 : "" }) : null,
11546
11600
  ordered.map((c, ci) => {
11547
11601
  const st = stickyOf(c.field);
11548
11602
  const val = getColVal(c, row);
@@ -11565,7 +11619,7 @@ function Datatable({
11565
11619
  role: "gridcell",
11566
11620
  "data-r": ri,
11567
11621
  "data-c": ci,
11568
- "aria-colindex": ci + 1 + (checkboxSelection ? 1 : 0) + (hasRowDetail ? 1 : 0),
11622
+ "aria-colindex": ci + 1 + (checkboxSelection ? 1 : 0) + (hasExpandCol ? 1 : 0),
11569
11623
  tabIndex: focus.r === ri && focus.c === ci ? 0 : -1,
11570
11624
  "aria-selected": cellSelected || void 0,
11571
11625
  "data-num": c.type === "number" || void 0,
@@ -11578,7 +11632,7 @@ function Datatable({
11578
11632
  "data-wrap": effectiveWrapped.has(c.field) || void 0,
11579
11633
  "data-pin": st.pin,
11580
11634
  "data-pin-edge": st.edge,
11581
- style: { width: widthOf(c), ...cellSty, ...st.style, ...st.pin ? { position: "sticky", zIndex: 2 } : null },
11635
+ style: { width: widthOf(c), ...cellSty, ...st.style, ...st.pin ? { position: "sticky", zIndex: 2 } : null, ...ci === 0 && depth ? { paddingInlineStart: `calc(12px + ${depth * 20}px)` } : null },
11582
11636
  "data-ovtext": cellTitle,
11583
11637
  onClick: selectionMode === "cell" ? (e) => handleCellClick(e, k, row, c) : void 0,
11584
11638
  onFocus: () => setFocus((f) => f.r === ri && f.c === ci ? f : { r: ri, c: ci }),
@@ -11630,7 +11684,7 @@ function Datatable({
11630
11684
  ]
11631
11685
  }
11632
11686
  ),
11633
- open ? /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "twc-dt__detail-row", role: "row", children: /* @__PURE__ */ jsxRuntime.jsx("td", { id: `${gridId}-detail-${ri}`, className: "twc-dt__detail-cell", role: "gridcell", colSpan: totalCols, style: { maxWidth: "none" }, children: detail }) }) : null
11687
+ open && detail != null ? /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "twc-dt__detail-row", role: "row", children: /* @__PURE__ */ jsxRuntime.jsx("td", { id: `${gridId}-detail-${ri}`, className: "twc-dt__detail-cell", role: "gridcell", colSpan: totalCols, style: { maxWidth: "none" }, children: detail }) }) : null
11634
11688
  ] }, (pinSide ? "p-" : "") + k);
11635
11689
  }
11636
11690
  function renderPivot() {
@@ -11967,15 +12021,15 @@ function Datatable({
11967
12021
  ref: gridRef,
11968
12022
  role: "grid",
11969
12023
  "aria-label": ariaLabelAttr || ariaLabel,
11970
- "aria-rowcount": totalRows + 1,
11971
- "aria-colcount": ordered.length + (checkboxSelection ? 1 : 0) + (hasRowDetail ? 1 : 0),
12024
+ "aria-rowcount": (treeSeqByKey ? treeSeqByKey.size : totalRows) + 1,
12025
+ "aria-colcount": ordered.length + (checkboxSelection ? 1 : 0) + (hasExpandCol ? 1 : 0),
11972
12026
  "aria-multiselectable": selectionMode === "cell" || void 0,
11973
12027
  "aria-activedescendant": activeCellId,
11974
12028
  "aria-busy": loading || void 0,
11975
12029
  onKeyDown: onGridKeyDown,
11976
12030
  children: [
11977
12031
  /* @__PURE__ */ jsxRuntime.jsx("thead", { ref: theadRef, children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", "aria-rowindex": 1, children: [
11978
- hasRowDetail ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th twc-dt__expand-cell", role: "columnheader", "aria-label": "Expand", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W, minWidth: EXP_W } }) : null,
12032
+ hasExpandCol ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th twc-dt__expand-cell", role: "columnheader", "aria-label": "Expand", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W, minWidth: EXP_W } }) : null,
11979
12033
  checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th", role: "columnheader", "aria-label": "Select", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: EXP_W, width: CHK_W, minWidth: CHK_W }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__th-inner", style: { justifyContent: "center", padding: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
11980
12034
  "span",
11981
12035
  {
@@ -12152,7 +12206,7 @@ function Datatable({
12152
12206
  })
12153
12207
  ] }) }),
12154
12208
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: loading ? Array.from({ length: paginated ? Math.min(sizeVal, 8) : 8 }).map((_, ri) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "twc-dt__row", role: "row", children: [
12155
- hasRowDetail ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__expand-cell", role: "gridcell", "data-pin": "left", style: { insetInlineStart: 0, width: EXP_W } }) : null,
12209
+ hasExpandCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__expand-cell", role: "gridcell", "data-pin": "left", style: { insetInlineStart: 0, width: EXP_W } }) : null,
12156
12210
  checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", style: { insetInlineStart: EXP_W, width: CHK_W }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__sk", "aria-hidden": "true", style: { "--_w": "18px", height: 18, borderRadius: 4 } }) }) : null,
12157
12211
  showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__sk", "aria-hidden": "true", style: { "--_w": "16px", height: 14, borderRadius: 4 } }) }) : null,
12158
12212
  ordered.map((c, ci) => {
@@ -12175,7 +12229,7 @@ function Datatable({
12175
12229
  pinnedBottomRows.map((row) => renderLeaf(row, keyIndex.get(keyOf(row)), "bottom"))
12176
12230
  ] }) }),
12177
12231
  hasAggregation && aggOn && !loading && paged.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("tfoot", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", children: [
12178
- hasRowDetail ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W } }) : null,
12232
+ hasExpandCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W } }) : null,
12179
12233
  checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: EXP_W, width: CHK_W } }) : null,
12180
12234
  showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": visLeft.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W } }) : null,
12181
12235
  ordered.map((c) => {