twico-ui 1.15.0 → 1.16.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 +99 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.mjs +99 -59
- package/dist/index.mjs.map +1 -1
- package/llms.txt +2 -0
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1893,6 +1893,14 @@ interface DatatableProps<T = any> extends Omit<React.HTMLAttributes<HTMLDivEleme
|
|
|
1893
1893
|
* resolves only rows on the currently loaded page; for cross-page selections use the
|
|
1894
1894
|
* complete `selectedKeys` array and apply the `patch` server-side. */
|
|
1895
1895
|
onBatchUpdate?: (changedRows: T[], patch: Record<string, any>, selectedKeys: Array<string | number>) => void;
|
|
1896
|
+
/** Render the built-in "Edit" button in the selection toolbar (the batch editor). Set `false` to
|
|
1897
|
+
* suppress it and ship your own batch-edit action via `batchActions` — otherwise you'd get two
|
|
1898
|
+
* "Edit" buttons. @default true */
|
|
1899
|
+
showBatchEdit?: boolean;
|
|
1900
|
+
/** Allow-list the column `field`s the built-in batch editor offers. Defaults to every editable
|
|
1901
|
+
* column. Use it to trim a wide grid's editor **without** touching `editable` (which would also
|
|
1902
|
+
* disable inline cell editing). */
|
|
1903
|
+
batchEditFields?: string[];
|
|
1896
1904
|
/** Show a "Go to" page jumper in the footer when there are more than 5 pages. @default true */
|
|
1897
1905
|
showPageJumper?: boolean;
|
|
1898
1906
|
/** Click-to-select mode: "row" highlights the clicked row, "cell" highlights a single cell. @default "none" */
|
package/dist/index.d.ts
CHANGED
|
@@ -1893,6 +1893,14 @@ interface DatatableProps<T = any> extends Omit<React.HTMLAttributes<HTMLDivEleme
|
|
|
1893
1893
|
* resolves only rows on the currently loaded page; for cross-page selections use the
|
|
1894
1894
|
* complete `selectedKeys` array and apply the `patch` server-side. */
|
|
1895
1895
|
onBatchUpdate?: (changedRows: T[], patch: Record<string, any>, selectedKeys: Array<string | number>) => void;
|
|
1896
|
+
/** Render the built-in "Edit" button in the selection toolbar (the batch editor). Set `false` to
|
|
1897
|
+
* suppress it and ship your own batch-edit action via `batchActions` — otherwise you'd get two
|
|
1898
|
+
* "Edit" buttons. @default true */
|
|
1899
|
+
showBatchEdit?: boolean;
|
|
1900
|
+
/** Allow-list the column `field`s the built-in batch editor offers. Defaults to every editable
|
|
1901
|
+
* column. Use it to trim a wide grid's editor **without** touching `editable` (which would also
|
|
1902
|
+
* disable inline cell editing). */
|
|
1903
|
+
batchEditFields?: string[];
|
|
1896
1904
|
/** Show a "Go to" page jumper in the footer when there are more than 5 pages. @default true */
|
|
1897
1905
|
showPageJumper?: boolean;
|
|
1898
1906
|
/** Click-to-select mode: "row" highlights the clicked row, "cell" highlights a single cell. @default "none" */
|
package/dist/index.mjs
CHANGED
|
@@ -8307,12 +8307,17 @@ var DT_CSS = `
|
|
|
8307
8307
|
.twc-dt__cfg-btn:hover { background: var(--color-surface-sunken); }
|
|
8308
8308
|
.twc-dt__cfg-btn[data-primary="true"] { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-primary-fg); }
|
|
8309
8309
|
.twc-dt__cfg-btn[data-primary="true"]:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }
|
|
8310
|
-
|
|
8311
|
-
.twc-dt__be-
|
|
8312
|
-
.twc-dt__be-
|
|
8313
|
-
.twc-dt__be-
|
|
8314
|
-
.twc-dt__be-check span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
8310
|
+
/* #244: batch editor = pick columns (searchable), then set a value for each. */
|
|
8311
|
+
.twc-dt__be-add { padding: 6px 6px 8px; border-bottom: var(--border-thin) solid var(--color-divider); }
|
|
8312
|
+
.twc-dt__be-row { display: flex; align-items: center; gap: 8px; padding: 5px 6px; }
|
|
8313
|
+
.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; }
|
|
8315
8314
|
.twc-dt__be-ctl { flex: 1; min-width: 0; }
|
|
8315
|
+
.twc-dt__be-x { flex: none; display: inline-grid; place-items: center; width: 24px; height: 24px; padding: 0; border: none;
|
|
8316
|
+
background: transparent; color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-sm);
|
|
8317
|
+
transition: background-color var(--duration-fast), color var(--duration-fast); }
|
|
8318
|
+
.twc-dt__be-x:hover { background: var(--color-surface-sunken); color: var(--color-text); }
|
|
8319
|
+
.twc-dt__be-x svg { width: 14px; height: 14px; }
|
|
8320
|
+
.twc-dt__be-empty { padding: 14px 8px; font-size: var(--text-xs); color: var(--color-text-muted); text-align: center; }
|
|
8316
8321
|
|
|
8317
8322
|
/* Pinned rows */
|
|
8318
8323
|
.twc-dt__row[data-pinned-row] > .twc-dt__td { background: var(--color-primary-subtle); }
|
|
@@ -8327,6 +8332,12 @@ var DT_CSS = `
|
|
|
8327
8332
|
.twc-dt__row[data-op="added"] > .twc-dt__td { background: color-mix(in srgb, var(--color-success) 7%, transparent); }
|
|
8328
8333
|
.twc-dt__row[data-op="removed"] > .twc-dt__td { background: color-mix(in srgb, var(--color-danger) 7%, transparent); }
|
|
8329
8334
|
.twc-dt__row[data-op="modified"] > .twc-dt__td { background: color-mix(in srgb, var(--color-warning) 6%, transparent); }
|
|
8335
|
+
/* #242: pinned cells in a diff row must stay OPAQUE (composite the tint over the surface, not over
|
|
8336
|
+
transparent) or the cells scrolling under a sticky column bleed through. Specificity (0,4,0) wins
|
|
8337
|
+
over the (0,3,0) tint above and matches the non-pinned cells' effective color (tint over surface). */
|
|
8338
|
+
.twc-dt__row[data-op="added"] > .twc-dt__td[data-pin] { background: color-mix(in srgb, var(--color-success) 7%, var(--color-surface)); }
|
|
8339
|
+
.twc-dt__row[data-op="removed"] > .twc-dt__td[data-pin] { background: color-mix(in srgb, var(--color-danger) 7%, var(--color-surface)); }
|
|
8340
|
+
.twc-dt__row[data-op="modified"] > .twc-dt__td[data-pin] { background: color-mix(in srgb, var(--color-warning) 6%, var(--color-surface)); }
|
|
8330
8341
|
.twc-dt__diff-change { display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; }
|
|
8331
8342
|
.twc-dt__diff-old { text-decoration: line-through; color: var(--color-text-subtle); }
|
|
8332
8343
|
.twc-dt__diff-new { color: var(--color-success-subtle-fg); font-weight: var(--font-medium); }
|
|
@@ -8977,6 +8988,8 @@ function Datatable({
|
|
|
8977
8988
|
onRowUpdate,
|
|
8978
8989
|
onRowsChange,
|
|
8979
8990
|
onBatchUpdate,
|
|
8991
|
+
showBatchEdit = true,
|
|
8992
|
+
batchEditFields = null,
|
|
8980
8993
|
showPageJumper = true,
|
|
8981
8994
|
selectionMode = "none",
|
|
8982
8995
|
onRowClick,
|
|
@@ -10016,9 +10029,14 @@ function Datatable({
|
|
|
10016
10029
|
cancelEdit();
|
|
10017
10030
|
}
|
|
10018
10031
|
}
|
|
10032
|
+
const batchEditKey = batchEditFields ? batchEditFields.join("\0") : "";
|
|
10019
10033
|
const batchEditableCols = React51__default.useMemo(
|
|
10020
|
-
() =>
|
|
10021
|
-
|
|
10034
|
+
() => {
|
|
10035
|
+
const base = cols.filter((c) => c.type !== "actions" && (c.editable ?? (editMode && c.editable !== false)));
|
|
10036
|
+
return batchEditFields ? base.filter((c) => batchEditFields.includes(c.field)) : base;
|
|
10037
|
+
},
|
|
10038
|
+
[cols, editMode, batchEditKey]
|
|
10039
|
+
// eslint-disable-line react-hooks/exhaustive-deps
|
|
10022
10040
|
);
|
|
10023
10041
|
const [batchEdit, setBatchEdit] = React51__default.useState(null);
|
|
10024
10042
|
const [batchEditPos, openBatchEdit, closeBatchEdit] = useFloating();
|
|
@@ -10453,7 +10471,7 @@ function Datatable({
|
|
|
10453
10471
|
" selected"
|
|
10454
10472
|
] }),
|
|
10455
10473
|
/* @__PURE__ */ jsxs("div", { className: "twc-dt__batch-actions", children: [
|
|
10456
|
-
batchEditableCols.length ? /* @__PURE__ */ jsxs("button", { type: "button", className: "twc-dt__batch-btn", onClick: (e) => openBatchEditor(e.currentTarget), children: [
|
|
10474
|
+
showBatchEdit && batchEditableCols.length ? /* @__PURE__ */ jsxs("button", { type: "button", className: "twc-dt__batch-btn", onClick: (e) => openBatchEditor(e.currentTarget), children: [
|
|
10457
10475
|
/* @__PURE__ */ jsx(Svg, { d: I.pencil }),
|
|
10458
10476
|
"Edit"
|
|
10459
10477
|
] }) : null,
|
|
@@ -10942,58 +10960,80 @@ function Datatable({
|
|
|
10942
10960
|
]
|
|
10943
10961
|
}
|
|
10944
10962
|
) : null,
|
|
10945
|
-
batchEdit && batchEditPos ?
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
const
|
|
10955
|
-
|
|
10956
|
-
return
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
{
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
}
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
|
|
10989
|
-
|
|
10990
|
-
|
|
10991
|
-
|
|
10992
|
-
|
|
10993
|
-
|
|
10963
|
+
batchEdit && batchEditPos ? (() => {
|
|
10964
|
+
const pickedCols = Object.keys(batchEdit.fields).filter((f) => batchEdit.fields[f]).map((f) => batchEditableCols.find((c) => c.field === f)).filter(Boolean);
|
|
10965
|
+
const unpicked = batchEditableCols.filter((c) => !batchEdit.fields[c.field]);
|
|
10966
|
+
const addField = (f) => {
|
|
10967
|
+
if (f) setBatchEdit((b) => ({ ...b, fields: { ...b.fields, [f]: true }, values: { ...b.values, [f]: b.values[f] ?? "" } }));
|
|
10968
|
+
};
|
|
10969
|
+
const removeField = (f) => setBatchEdit((b) => {
|
|
10970
|
+
const fields = { ...b.fields };
|
|
10971
|
+
delete fields[f];
|
|
10972
|
+
const values = { ...b.values };
|
|
10973
|
+
delete values[f];
|
|
10974
|
+
return { ...b, fields, values };
|
|
10975
|
+
});
|
|
10976
|
+
return /* @__PURE__ */ jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: batchEditPos.top, left: batchEditPos.left, width: 320 }, children: [
|
|
10977
|
+
/* @__PURE__ */ jsx(Caret, { pos: batchEditPos }),
|
|
10978
|
+
/* @__PURE__ */ jsxs("div", { className: "twc-dt__cfg-head", children: [
|
|
10979
|
+
"Edit ",
|
|
10980
|
+
selected.size,
|
|
10981
|
+
" selected ",
|
|
10982
|
+
selected.size === 1 ? "row" : "rows"
|
|
10983
|
+
] }),
|
|
10984
|
+
unpicked.length ? /* @__PURE__ */ jsx("div", { className: "twc-dt__be-add", children: /* @__PURE__ */ jsx(
|
|
10985
|
+
Select,
|
|
10986
|
+
{
|
|
10987
|
+
size: "sm",
|
|
10988
|
+
portal: true,
|
|
10989
|
+
searchable: true,
|
|
10990
|
+
placeholder: "Add a column\u2026",
|
|
10991
|
+
value: "",
|
|
10992
|
+
"aria-label": "Add a column to edit",
|
|
10993
|
+
options: unpicked.map((c) => ({ value: c.field, label: String(c.headerName ?? c.field) })),
|
|
10994
|
+
onChange: addField
|
|
10995
|
+
}
|
|
10996
|
+
) }) : null,
|
|
10997
|
+
/* @__PURE__ */ jsx("div", { className: "twc-dt__cfg-list", children: pickedCols.length === 0 ? /* @__PURE__ */ jsx("div", { className: "twc-dt__be-empty", children: "Pick a column to set its value on all selected rows." }) : pickedCols.map((c) => {
|
|
10998
|
+
const opts = c.valueOptions ? c.valueOptions.map((o) => typeof o === "string" ? { value: o, label: o } : o) : null;
|
|
10999
|
+
return /* @__PURE__ */ jsxs("div", { className: "twc-dt__be-row", children: [
|
|
11000
|
+
/* @__PURE__ */ jsx("span", { className: "twc-dt__be-name", title: String(c.headerName ?? c.field), children: c.headerName }),
|
|
11001
|
+
/* @__PURE__ */ jsx("div", { className: "twc-dt__be-ctl", children: opts ? /* @__PURE__ */ jsx(
|
|
11002
|
+
Select,
|
|
11003
|
+
{
|
|
11004
|
+
size: "sm",
|
|
11005
|
+
portal: true,
|
|
11006
|
+
searchable: true,
|
|
11007
|
+
placeholder: "New value\u2026",
|
|
11008
|
+
value: batchEdit.values[c.field] ?? "",
|
|
11009
|
+
options: opts,
|
|
11010
|
+
onChange: (v) => setBatchEdit((b) => ({ ...b, values: { ...b.values, [c.field]: v } }))
|
|
11011
|
+
}
|
|
11012
|
+
) : /* @__PURE__ */ jsx(
|
|
11013
|
+
Input,
|
|
11014
|
+
{
|
|
11015
|
+
size: "sm",
|
|
11016
|
+
type: c.type === "number" || c.type === "currency" ? "number" : "text",
|
|
11017
|
+
placeholder: "New value\u2026",
|
|
11018
|
+
value: batchEdit.values[c.field] ?? "",
|
|
11019
|
+
onChange: (e) => setBatchEdit((b) => ({ ...b, values: { ...b.values, [c.field]: e.target.value } }))
|
|
11020
|
+
}
|
|
11021
|
+
) }),
|
|
11022
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "twc-dt__be-x", "aria-label": `Remove ${String(c.headerName ?? c.field)}`, onClick: () => removeField(c.field), children: /* @__PURE__ */ jsx(Svg, { d: I.x }) })
|
|
11023
|
+
] }, c.field);
|
|
11024
|
+
}) }),
|
|
11025
|
+
/* @__PURE__ */ jsxs("div", { className: "twc-dt__cfg-foot", children: [
|
|
11026
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "twc-dt__cfg-btn", onClick: () => {
|
|
11027
|
+
setBatchEdit(null);
|
|
11028
|
+
closeBatchEdit();
|
|
11029
|
+
}, children: "Cancel" }),
|
|
11030
|
+
/* @__PURE__ */ jsxs("button", { type: "button", className: "twc-dt__cfg-btn", "data-primary": "true", disabled: pickedCols.length === 0, onClick: applyBatchEdit, children: [
|
|
11031
|
+
"Apply to ",
|
|
11032
|
+
selected.size
|
|
11033
|
+
] })
|
|
10994
11034
|
] })
|
|
10995
|
-
] })
|
|
10996
|
-
|
|
11035
|
+
] });
|
|
11036
|
+
})() : null,
|
|
10997
11037
|
colMenu && menuPos ? /* @__PURE__ */ jsxs(
|
|
10998
11038
|
"div",
|
|
10999
11039
|
{
|