twico-ui 1.15.1 → 1.17.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 +98 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -3
- package/dist/index.d.ts +33 -3
- package/dist/index.mjs +98 -60
- package/dist/index.mjs.map +1 -1
- package/llms.txt +2 -0
- 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.17.0](https://github.com/EncryptionL/twico-ui/compare/v1.16.0...v1.17.0) (2026-07-15)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **datatable:** batch action anchorEl + renderBatchEditCell ([#246](https://github.com/EncryptionL/twico-ui/issues/246), [#247](https://github.com/EncryptionL/twico-ui/issues/247)) ([1c84dca](https://github.com/EncryptionL/twico-ui/commit/1c84dcaa7da1d7e9f3edb7481bd1e9ad2671639f)), closes [#236](https://github.com/EncryptionL/twico-ui/issues/236)
|
|
11
|
+
|
|
12
|
+
# [1.16.0](https://github.com/EncryptionL/twico-ui/compare/v1.15.1...v1.16.0) (2026-07-15)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **datatable:** batch editor picks columns (searchable) + showBatchEdit/batchEditFields ([#244](https://github.com/EncryptionL/twico-ui/issues/244)) ([82b8806](https://github.com/EncryptionL/twico-ui/commit/82b8806f32f08153f15653de68bdb82ea2dc7ff3)), closes [#236](https://github.com/EncryptionL/twico-ui/issues/236)
|
|
18
|
+
|
|
5
19
|
## [1.15.1](https://github.com/EncryptionL/twico-ui/compare/v1.15.0...v1.15.1) (2026-07-14)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.cjs
CHANGED
|
@@ -8328,12 +8328,17 @@ var DT_CSS = `
|
|
|
8328
8328
|
.twc-dt__cfg-btn:hover { background: var(--color-surface-sunken); }
|
|
8329
8329
|
.twc-dt__cfg-btn[data-primary="true"] { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-primary-fg); }
|
|
8330
8330
|
.twc-dt__cfg-btn[data-primary="true"]:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }
|
|
8331
|
-
|
|
8332
|
-
.twc-dt__be-
|
|
8333
|
-
.twc-dt__be-
|
|
8334
|
-
.twc-dt__be-
|
|
8335
|
-
.twc-dt__be-check span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
8331
|
+
/* #244: batch editor = pick columns (searchable), then set a value for each. */
|
|
8332
|
+
.twc-dt__be-add { padding: 6px 6px 8px; border-bottom: var(--border-thin) solid var(--color-divider); }
|
|
8333
|
+
.twc-dt__be-row { display: flex; align-items: center; gap: 8px; padding: 5px 6px; }
|
|
8334
|
+
.twc-dt__be-name { width: 108px; flex: none; font-size: var(--text-sm); color: var(--color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
8336
8335
|
.twc-dt__be-ctl { flex: 1; min-width: 0; }
|
|
8336
|
+
.twc-dt__be-x { flex: none; display: inline-grid; place-items: center; width: 24px; height: 24px; padding: 0; border: none;
|
|
8337
|
+
background: transparent; color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-sm);
|
|
8338
|
+
transition: background-color var(--duration-fast), color var(--duration-fast); }
|
|
8339
|
+
.twc-dt__be-x:hover { background: var(--color-surface-sunken); color: var(--color-text); }
|
|
8340
|
+
.twc-dt__be-x svg { width: 14px; height: 14px; }
|
|
8341
|
+
.twc-dt__be-empty { padding: 14px 8px; font-size: var(--text-xs); color: var(--color-text-muted); text-align: center; }
|
|
8337
8342
|
|
|
8338
8343
|
/* Pinned rows */
|
|
8339
8344
|
.twc-dt__row[data-pinned-row] > .twc-dt__td { background: var(--color-primary-subtle); }
|
|
@@ -9004,6 +9009,8 @@ function Datatable({
|
|
|
9004
9009
|
onRowUpdate,
|
|
9005
9010
|
onRowsChange,
|
|
9006
9011
|
onBatchUpdate,
|
|
9012
|
+
showBatchEdit = true,
|
|
9013
|
+
batchEditFields = null,
|
|
9007
9014
|
showPageJumper = true,
|
|
9008
9015
|
selectionMode = "none",
|
|
9009
9016
|
onRowClick,
|
|
@@ -10043,9 +10050,14 @@ function Datatable({
|
|
|
10043
10050
|
cancelEdit();
|
|
10044
10051
|
}
|
|
10045
10052
|
}
|
|
10053
|
+
const batchEditKey = batchEditFields ? batchEditFields.join("\0") : "";
|
|
10046
10054
|
const batchEditableCols = React51__namespace.default.useMemo(
|
|
10047
|
-
() =>
|
|
10048
|
-
|
|
10055
|
+
() => {
|
|
10056
|
+
const base = cols.filter((c) => c.type !== "actions" && (c.editable ?? (editMode && c.editable !== false)));
|
|
10057
|
+
return batchEditFields ? base.filter((c) => batchEditFields.includes(c.field)) : base;
|
|
10058
|
+
},
|
|
10059
|
+
[cols, editMode, batchEditKey]
|
|
10060
|
+
// eslint-disable-line react-hooks/exhaustive-deps
|
|
10049
10061
|
);
|
|
10050
10062
|
const [batchEdit, setBatchEdit] = React51__namespace.default.useState(null);
|
|
10051
10063
|
const [batchEditPos, openBatchEdit, closeBatchEdit] = useFloating();
|
|
@@ -10480,7 +10492,7 @@ function Datatable({
|
|
|
10480
10492
|
" selected"
|
|
10481
10493
|
] }),
|
|
10482
10494
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__batch-actions", children: [
|
|
10483
|
-
batchEditableCols.length ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "twc-dt__batch-btn", onClick: (e) => openBatchEditor(e.currentTarget), children: [
|
|
10495
|
+
showBatchEdit && batchEditableCols.length ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "twc-dt__batch-btn", onClick: (e) => openBatchEditor(e.currentTarget), children: [
|
|
10484
10496
|
/* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.pencil }),
|
|
10485
10497
|
"Edit"
|
|
10486
10498
|
] }) : null,
|
|
@@ -10491,7 +10503,7 @@ function Datatable({
|
|
|
10491
10503
|
className: "twc-dt__batch-btn",
|
|
10492
10504
|
"data-danger": a.danger || void 0,
|
|
10493
10505
|
disabled: a.disabled,
|
|
10494
|
-
onClick: () => a.onClick?.([...selected], selectedRows, clearSelection),
|
|
10506
|
+
onClick: (e) => a.onClick?.([...selected], selectedRows, clearSelection, { anchorEl: e.currentTarget }),
|
|
10495
10507
|
children: [
|
|
10496
10508
|
a.icon,
|
|
10497
10509
|
a.label
|
|
@@ -10969,58 +10981,84 @@ function Datatable({
|
|
|
10969
10981
|
]
|
|
10970
10982
|
}
|
|
10971
10983
|
) : null,
|
|
10972
|
-
batchEdit && batchEditPos ?
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
const
|
|
10982
|
-
|
|
10983
|
-
return
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
|
|
10989
|
-
|
|
10990
|
-
|
|
10991
|
-
|
|
10992
|
-
|
|
10993
|
-
|
|
10994
|
-
|
|
10995
|
-
|
|
10996
|
-
|
|
10997
|
-
|
|
10998
|
-
|
|
10999
|
-
|
|
11000
|
-
|
|
11001
|
-
|
|
11002
|
-
{
|
|
11003
|
-
|
|
11004
|
-
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
|
|
11009
|
-
}
|
|
11010
|
-
|
|
11011
|
-
|
|
11012
|
-
|
|
11013
|
-
|
|
11014
|
-
|
|
11015
|
-
|
|
11016
|
-
|
|
11017
|
-
|
|
11018
|
-
|
|
11019
|
-
|
|
11020
|
-
|
|
10984
|
+
batchEdit && batchEditPos ? (() => {
|
|
10985
|
+
const pickedCols = Object.keys(batchEdit.fields).filter((f) => batchEdit.fields[f]).map((f) => batchEditableCols.find((c) => c.field === f)).filter(Boolean);
|
|
10986
|
+
const unpicked = batchEditableCols.filter((c) => !batchEdit.fields[c.field]);
|
|
10987
|
+
const addField = (f) => {
|
|
10988
|
+
if (f) setBatchEdit((b) => ({ ...b, fields: { ...b.fields, [f]: true }, values: { ...b.values, [f]: b.values[f] ?? "" } }));
|
|
10989
|
+
};
|
|
10990
|
+
const removeField = (f) => setBatchEdit((b) => {
|
|
10991
|
+
const fields = { ...b.fields };
|
|
10992
|
+
delete fields[f];
|
|
10993
|
+
const values = { ...b.values };
|
|
10994
|
+
delete values[f];
|
|
10995
|
+
return { ...b, fields, values };
|
|
10996
|
+
});
|
|
10997
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: batchEditPos.top, left: batchEditPos.left, width: 320 }, children: [
|
|
10998
|
+
/* @__PURE__ */ jsxRuntime.jsx(Caret, { pos: batchEditPos }),
|
|
10999
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-head", children: [
|
|
11000
|
+
"Edit ",
|
|
11001
|
+
selected.size,
|
|
11002
|
+
" selected ",
|
|
11003
|
+
selected.size === 1 ? "row" : "rows"
|
|
11004
|
+
] }),
|
|
11005
|
+
unpicked.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__be-add", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11006
|
+
Select,
|
|
11007
|
+
{
|
|
11008
|
+
size: "sm",
|
|
11009
|
+
portal: true,
|
|
11010
|
+
searchable: true,
|
|
11011
|
+
placeholder: "Add a column\u2026",
|
|
11012
|
+
value: "",
|
|
11013
|
+
"aria-label": "Add a column to edit",
|
|
11014
|
+
options: unpicked.map((c) => ({ value: c.field, label: String(c.headerName ?? c.field) })),
|
|
11015
|
+
onChange: addField
|
|
11016
|
+
}
|
|
11017
|
+
) }) : null,
|
|
11018
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__cfg-list", children: pickedCols.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__be-empty", children: "Pick a column to set its value on all selected rows." }) : pickedCols.map((c) => {
|
|
11019
|
+
const opts = c.valueOptions ? c.valueOptions.map((o) => typeof o === "string" ? { value: o, label: o } : o) : null;
|
|
11020
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__be-row", children: [
|
|
11021
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__be-name", title: String(c.headerName ?? c.field), children: c.headerName }),
|
|
11022
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__be-ctl", children: c.renderBatchEditCell ? c.renderBatchEditCell({
|
|
11023
|
+
value: batchEdit.values[c.field],
|
|
11024
|
+
field: c.field,
|
|
11025
|
+
commit: (v) => setBatchEdit((b) => ({ ...b, values: { ...b.values, [c.field]: v } }))
|
|
11026
|
+
}) : opts ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11027
|
+
Select,
|
|
11028
|
+
{
|
|
11029
|
+
size: "sm",
|
|
11030
|
+
portal: true,
|
|
11031
|
+
searchable: true,
|
|
11032
|
+
placeholder: "New value\u2026",
|
|
11033
|
+
value: batchEdit.values[c.field] ?? "",
|
|
11034
|
+
options: opts,
|
|
11035
|
+
onChange: (v) => setBatchEdit((b) => ({ ...b, values: { ...b.values, [c.field]: v } }))
|
|
11036
|
+
}
|
|
11037
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
11038
|
+
Input,
|
|
11039
|
+
{
|
|
11040
|
+
size: "sm",
|
|
11041
|
+
type: c.type === "number" || c.type === "currency" ? "number" : "text",
|
|
11042
|
+
placeholder: "New value\u2026",
|
|
11043
|
+
value: batchEdit.values[c.field] ?? "",
|
|
11044
|
+
onChange: (e) => setBatchEdit((b) => ({ ...b, values: { ...b.values, [c.field]: e.target.value } }))
|
|
11045
|
+
}
|
|
11046
|
+
) }),
|
|
11047
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__be-x", "aria-label": `Remove ${String(c.headerName ?? c.field)}`, onClick: () => removeField(c.field), children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.x }) })
|
|
11048
|
+
] }, c.field);
|
|
11049
|
+
}) }),
|
|
11050
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-foot", children: [
|
|
11051
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__cfg-btn", onClick: () => {
|
|
11052
|
+
setBatchEdit(null);
|
|
11053
|
+
closeBatchEdit();
|
|
11054
|
+
}, children: "Cancel" }),
|
|
11055
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "twc-dt__cfg-btn", "data-primary": "true", disabled: pickedCols.length === 0, onClick: applyBatchEdit, children: [
|
|
11056
|
+
"Apply to ",
|
|
11057
|
+
selected.size
|
|
11058
|
+
] })
|
|
11021
11059
|
] })
|
|
11022
|
-
] })
|
|
11023
|
-
|
|
11060
|
+
] });
|
|
11061
|
+
})() : null,
|
|
11024
11062
|
colMenu && menuPos ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11025
11063
|
"div",
|
|
11026
11064
|
{
|