twico-ui 1.27.0 → 1.29.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 +14 -0
- package/dist/index.cjs +49 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.mjs +49 -21
- package/dist/index.mjs.map +1 -1
- package/llms.txt +4 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
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.29.0](https://github.com/EncryptionL/twico-ui/compare/v1.28.0...v1.29.0) (2026-08-03)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **datatable:** controlled active row for selectionMode="row" (activeRowId) ([#324](https://github.com/EncryptionL/twico-ui/issues/324)) ([c118a06](https://github.com/EncryptionL/twico-ui/commit/c118a069d3f91ce9640b39751cab24717569be2b))
|
|
11
|
+
|
|
12
|
+
# [1.28.0](https://github.com/EncryptionL/twico-ui/compare/v1.27.0...v1.28.0) (2026-08-03)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **datatable:** selection-aware batch actions (predicate disabled/hidden) + onRowSelectionChange ([#322](https://github.com/EncryptionL/twico-ui/issues/322)) ([33a1c36](https://github.com/EncryptionL/twico-ui/commit/33a1c36340e36cf0c9cc763cda7ed5d26fd46baa))
|
|
18
|
+
|
|
5
19
|
# [1.27.0](https://github.com/EncryptionL/twico-ui/compare/v1.26.0...v1.27.0) (2026-08-03)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.cjs
CHANGED
|
@@ -9158,6 +9158,7 @@ function Datatable({
|
|
|
9158
9158
|
onServerChange,
|
|
9159
9159
|
onColumnVisibilityChange,
|
|
9160
9160
|
batchActions = [],
|
|
9161
|
+
onRowSelectionChange,
|
|
9161
9162
|
showExport = false,
|
|
9162
9163
|
showDensity = false,
|
|
9163
9164
|
showPivot = false,
|
|
@@ -9182,6 +9183,8 @@ function Datatable({
|
|
|
9182
9183
|
onCellClick,
|
|
9183
9184
|
onActiveCellChange,
|
|
9184
9185
|
onCellSelectionChange,
|
|
9186
|
+
activeRowId,
|
|
9187
|
+
scrollActiveRowIntoView = true,
|
|
9185
9188
|
enableClipboard = false,
|
|
9186
9189
|
onCellsCopy,
|
|
9187
9190
|
onCellsPaste,
|
|
@@ -9314,6 +9317,8 @@ function Datatable({
|
|
|
9314
9317
|
};
|
|
9315
9318
|
const [selected, setSelected] = React51__namespace.default.useState(() => /* @__PURE__ */ new Set());
|
|
9316
9319
|
const [activeRow, setActiveRow] = React51__namespace.default.useState(null);
|
|
9320
|
+
const activeRowControlled = activeRowId !== void 0;
|
|
9321
|
+
const activeRowVal = activeRowControlled ? activeRowId : activeRow;
|
|
9317
9322
|
const [activeCell, setActiveCell] = React51__namespace.default.useState(null);
|
|
9318
9323
|
const [anchorCell, setAnchorCell] = React51__namespace.default.useState(null);
|
|
9319
9324
|
const gridId = React51__namespace.default.useId();
|
|
@@ -10301,7 +10306,7 @@ function Datatable({
|
|
|
10301
10306
|
if (selectionMode === "none") return;
|
|
10302
10307
|
if (e.target.closest("button, a, input, select, .twc-dt__check, .twc-dt__editor-wrap")) return;
|
|
10303
10308
|
if (selectionMode === "row") {
|
|
10304
|
-
setActiveRow(k);
|
|
10309
|
+
if (!activeRowControlled) setActiveRow(k);
|
|
10305
10310
|
onRowClick?.(row, k);
|
|
10306
10311
|
onActiveCellChange?.(null);
|
|
10307
10312
|
}
|
|
@@ -10380,8 +10385,9 @@ function Datatable({
|
|
|
10380
10385
|
}
|
|
10381
10386
|
if (selectionMode === "row") {
|
|
10382
10387
|
e.preventDefault();
|
|
10383
|
-
|
|
10384
|
-
|
|
10388
|
+
const rk = keyOf(leafRows[r2], r2);
|
|
10389
|
+
if (!activeRowControlled) setActiveRow(rk);
|
|
10390
|
+
onRowClick?.(leafRows[r2], rk);
|
|
10385
10391
|
return;
|
|
10386
10392
|
}
|
|
10387
10393
|
handled = false;
|
|
@@ -10410,6 +10416,23 @@ function Datatable({
|
|
|
10410
10416
|
setFocus((f) => ({ r: Math.min(f.r, Math.max(0, leafRows.length - 1)), c: Math.min(f.c, Math.max(0, ordered.length - 1)) }));
|
|
10411
10417
|
}, [leafRows.length, ordered.length, pageVal]);
|
|
10412
10418
|
const selectedRows = React51__namespace.default.useMemo(() => rows.filter((r2, i) => selected.has(keyOf(r2, i))), [rows, selected]);
|
|
10419
|
+
const selKeys = React51__namespace.default.useMemo(() => [...selected], [selected]);
|
|
10420
|
+
const onRowSelRef = React51__namespace.default.useRef(onRowSelectionChange);
|
|
10421
|
+
onRowSelRef.current = onRowSelectionChange;
|
|
10422
|
+
const prevRowSelSigRef = React51__namespace.default.useRef("");
|
|
10423
|
+
React51__namespace.default.useEffect(() => {
|
|
10424
|
+
const cb = onRowSelRef.current;
|
|
10425
|
+
if (!cb) return;
|
|
10426
|
+
const sig = selKeys.join(",");
|
|
10427
|
+
if (sig === prevRowSelSigRef.current) return;
|
|
10428
|
+
prevRowSelSigRef.current = sig;
|
|
10429
|
+
cb(selKeys, selectedRows);
|
|
10430
|
+
}, [selKeys, selectedRows]);
|
|
10431
|
+
React51__namespace.default.useEffect(() => {
|
|
10432
|
+
if (!activeRowControlled || !scrollActiveRowIntoView || activeRowId == null) return;
|
|
10433
|
+
const el = gridRef.current && gridRef.current.querySelector('.twc-dt__row[data-active="true"]');
|
|
10434
|
+
if (el && el.scrollIntoView) el.scrollIntoView({ block: "nearest" });
|
|
10435
|
+
}, [activeRowId, activeRowControlled, scrollActiveRowIntoView]);
|
|
10413
10436
|
function clearSelection() {
|
|
10414
10437
|
setSelected(/* @__PURE__ */ new Set());
|
|
10415
10438
|
}
|
|
@@ -10506,11 +10529,11 @@ function Datatable({
|
|
|
10506
10529
|
}
|
|
10507
10530
|
patch[c.field] = v;
|
|
10508
10531
|
});
|
|
10509
|
-
const
|
|
10532
|
+
const selKeys2 = new Set(selected);
|
|
10510
10533
|
const changedRows = [];
|
|
10511
10534
|
const nextAll = rows.map((r2, i) => {
|
|
10512
10535
|
const k = keyOf(r2, i);
|
|
10513
|
-
if (!
|
|
10536
|
+
if (!selKeys2.has(k)) return r2;
|
|
10514
10537
|
const updated = { ...r2, ...patch };
|
|
10515
10538
|
changedRows.push(updated);
|
|
10516
10539
|
return updated;
|
|
@@ -11127,7 +11150,7 @@ function Datatable({
|
|
|
11127
11150
|
function renderLeaf(row, ri, pinSide, midIdx) {
|
|
11128
11151
|
const k = keyOf(row, ri);
|
|
11129
11152
|
const sel = selected.has(k);
|
|
11130
|
-
const rowActive = selectionMode === "row" &&
|
|
11153
|
+
const rowActive = selectionMode === "row" && activeRowVal === k;
|
|
11131
11154
|
const stickyStyle = pinSide === "top" ? { position: "sticky", top: headH, zIndex: 5 } : pinSide === "bottom" ? { position: "sticky", bottom: 0, zIndex: 5 } : void 0;
|
|
11132
11155
|
const h = rowHeights[k];
|
|
11133
11156
|
const rowStyle = { ...stickyStyle || {}, ...h ? { height: h } : {} };
|
|
@@ -11400,21 +11423,26 @@ function Datatable({
|
|
|
11400
11423
|
/* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.pencil }),
|
|
11401
11424
|
"Edit"
|
|
11402
11425
|
] }) : null,
|
|
11403
|
-
batchActions.map((a, i) =>
|
|
11404
|
-
"
|
|
11405
|
-
|
|
11406
|
-
|
|
11407
|
-
|
|
11408
|
-
"
|
|
11409
|
-
|
|
11410
|
-
|
|
11411
|
-
|
|
11412
|
-
a.
|
|
11413
|
-
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11426
|
+
batchActions.map((a, i) => {
|
|
11427
|
+
const isHidden = typeof a.hidden === "function" ? a.hidden(selKeys, selectedRows) : !!a.hidden;
|
|
11428
|
+
if (isHidden) return null;
|
|
11429
|
+
const isDisabled = typeof a.disabled === "function" ? a.disabled(selKeys, selectedRows) : !!a.disabled;
|
|
11430
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11431
|
+
"button",
|
|
11432
|
+
{
|
|
11433
|
+
type: "button",
|
|
11434
|
+
className: "twc-dt__batch-btn",
|
|
11435
|
+
"data-danger": a.danger || void 0,
|
|
11436
|
+
disabled: isDisabled,
|
|
11437
|
+
onClick: (e) => a.onClick?.(selKeys, selectedRows, clearSelection, { anchorEl: e.currentTarget }),
|
|
11438
|
+
children: [
|
|
11439
|
+
a.icon,
|
|
11440
|
+
a.label
|
|
11441
|
+
]
|
|
11442
|
+
},
|
|
11443
|
+
i
|
|
11444
|
+
);
|
|
11445
|
+
})
|
|
11418
11446
|
] })
|
|
11419
11447
|
] }) : null,
|
|
11420
11448
|
isDiff && diff.showSummary !== false ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-dt__diff-summary", "aria-label": "Diff summary", children: [
|