twico-ui 1.19.1 → 1.20.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 +7 -0
- package/dist/index.cjs +19 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.mjs +19 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2046,6 +2046,13 @@ interface DatatableColumn<T = any> {
|
|
|
2046
2046
|
headerName?: string;
|
|
2047
2047
|
/** Data type. "actions" renders per-row action buttons via getActions. @default "string" */
|
|
2048
2048
|
type?: "string" | "number" | "actions";
|
|
2049
|
+
/** Filter operators + value comparison for this column, **decoupled from the edit `type`** (#270).
|
|
2050
|
+
* A `"number"` column edits by coercing its commit with `Number()`, which would wipe a custom value
|
|
2051
|
+
* (e.g. a value+unit measurement edited via `renderEditCell`) — so such a column must edit as
|
|
2052
|
+
* `type: "string"`, yet may still want **numeric** filter operators (`=` `≠` `>` `≥` `<` `≤`).
|
|
2053
|
+
* Set `filterType: "number"` to offer them (provide a `valueGetter` returning the numeric value so
|
|
2054
|
+
* the comparison is numeric). Falls back to `type`. Sorting still uses `type`. @default type */
|
|
2055
|
+
filterType?: "string" | "number";
|
|
2049
2056
|
/** Column width: a px number, or `"auto"` to size to the header's intrinsic width (chrome + label) so a short column fits without truncating or wasting the 160px default. @default 160 (120 for actions) */
|
|
2050
2057
|
width?: number | "auto";
|
|
2051
2058
|
/** Lower bound (px) for the resolved width, incl. `"auto"` and user resizes. */
|
package/dist/index.d.ts
CHANGED
|
@@ -2046,6 +2046,13 @@ interface DatatableColumn<T = any> {
|
|
|
2046
2046
|
headerName?: string;
|
|
2047
2047
|
/** Data type. "actions" renders per-row action buttons via getActions. @default "string" */
|
|
2048
2048
|
type?: "string" | "number" | "actions";
|
|
2049
|
+
/** Filter operators + value comparison for this column, **decoupled from the edit `type`** (#270).
|
|
2050
|
+
* A `"number"` column edits by coercing its commit with `Number()`, which would wipe a custom value
|
|
2051
|
+
* (e.g. a value+unit measurement edited via `renderEditCell`) — so such a column must edit as
|
|
2052
|
+
* `type: "string"`, yet may still want **numeric** filter operators (`=` `≠` `>` `≥` `<` `≤`).
|
|
2053
|
+
* Set `filterType: "number"` to offer them (provide a `valueGetter` returning the numeric value so
|
|
2054
|
+
* the comparison is numeric). Falls back to `type`. Sorting still uses `type`. @default type */
|
|
2055
|
+
filterType?: "string" | "number";
|
|
2049
2056
|
/** Column width: a px number, or `"auto"` to size to the header's intrinsic width (chrome + label) so a short column fits without truncating or wasting the 160px default. @default 160 (120 for actions) */
|
|
2050
2057
|
width?: number | "auto";
|
|
2051
2058
|
/** Lower bound (px) for the resolved width, incl. `"auto"` and user resizes. */
|
package/dist/index.mjs
CHANGED
|
@@ -6748,6 +6748,7 @@ function Select({
|
|
|
6748
6748
|
"data-disabled": o.disabled || void 0,
|
|
6749
6749
|
"data-selected": isSel || void 0,
|
|
6750
6750
|
"data-active": idx === active || void 0,
|
|
6751
|
+
title: typeof o.label === "string" ? o.label : void 0,
|
|
6751
6752
|
onMouseEnter: () => {
|
|
6752
6753
|
if (!o.disabled) setActive(idx);
|
|
6753
6754
|
},
|
|
@@ -8474,13 +8475,15 @@ th.twc-dt__rownum .twc-dt__th-inner { padding-inline: 8px; gap: 2px; justify-con
|
|
|
8474
8475
|
.twc-dt__col-list { max-height: 230px; overflow-y: auto; }
|
|
8475
8476
|
.twc-dt__col-row { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: var(--radius-md); cursor: pointer; }
|
|
8476
8477
|
.twc-dt__col-row:hover { background: var(--color-surface-sunken); }
|
|
8477
|
-
|
|
8478
|
+
/* #271 (columns-panel analog of #263/#267): grab lives on the grip only, not the whole row \u2014 the row
|
|
8479
|
+
keeps its 'cursor: pointer' (toggles visibility) and stays a drag source for the mouse. */
|
|
8478
8480
|
.twc-dt__col-row[data-dragging="true"] { opacity: 0.5; }
|
|
8479
8481
|
.twc-dt__col-row[data-dropbefore="true"] { box-shadow: inset 0 3px 0 var(--color-primary); }
|
|
8480
8482
|
.twc-dt__col-row[data-dropafter="true"] { box-shadow: inset 0 -3px 0 var(--color-primary); }
|
|
8481
|
-
.twc-dt__col-grip { display: inline-flex; color: var(--color-text-subtle); flex: none; opacity: 0.45; }
|
|
8483
|
+
.twc-dt__col-grip { display: inline-flex; color: var(--color-text-subtle); flex: none; opacity: 0.45; cursor: grab; }
|
|
8482
8484
|
.twc-dt__col-row:hover .twc-dt__col-grip { opacity: 0.8; }
|
|
8483
8485
|
.twc-dt__col-grip svg { width: 14px; height: 14px; }
|
|
8486
|
+
.twc-dt__col-grip:active, .twc-dt__col-row[data-dragging="true"] .twc-dt__col-grip { cursor: grabbing; }
|
|
8484
8487
|
.twc-dt__col-name { flex: 1; font-size: var(--text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
8485
8488
|
.twc-dt__col-pins { display: inline-flex; gap: 2px; flex: none; }
|
|
8486
8489
|
.twc-dt__col-pin { display: inline-grid; place-items: center; width: 24px; height: 24px; border: none; padding: 0; background: transparent; color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-sm); transition: background-color var(--duration-fast), color var(--duration-fast); }
|
|
@@ -8618,6 +8621,11 @@ var NUM_OPS = [
|
|
|
8618
8621
|
];
|
|
8619
8622
|
var opsFor = (type) => type === "number" ? NUM_OPS : STR_OPS;
|
|
8620
8623
|
var isMultiOp = (op) => op === "isAnyOf";
|
|
8624
|
+
var filterTypeOf = (col) => {
|
|
8625
|
+
const ft = col && col.filterType;
|
|
8626
|
+
if (ft === "number" || ft === "string") return ft;
|
|
8627
|
+
return col && col.type === "number" ? "number" : "string";
|
|
8628
|
+
};
|
|
8621
8629
|
var getColVal = (col, row) => col && col.valueGetter ? col.valueGetter(row) : row == null ? void 0 : row[col && col.field];
|
|
8622
8630
|
var diffValueNode = (col, v, row) => col.renderCell ? col.renderCell(v, row) : col.valueFormatter ? col.valueFormatter(v, row) : v == null ? "" : v;
|
|
8623
8631
|
function renderDiffCell(col, val, row) {
|
|
@@ -8700,7 +8708,10 @@ function runDatatableQuery(rows, query, options = {}) {
|
|
|
8700
8708
|
let out = Array.isArray(rows) ? rows : [];
|
|
8701
8709
|
const quick = String(q.quickFilter || "").trim().toLowerCase();
|
|
8702
8710
|
if (quick) out = out.filter((r2) => searchFields.some((f) => String(gv(f, r2) ?? "").toLowerCase().includes(quick)));
|
|
8703
|
-
for (const f of q.filters || [])
|
|
8711
|
+
for (const f of q.filters || []) {
|
|
8712
|
+
const fc = cols.find((c) => c.field === f.field);
|
|
8713
|
+
out = out.filter((r2) => testFilter(gv(f.field, r2), f.op, f.value, filterTypeOf(fc)));
|
|
8714
|
+
}
|
|
8704
8715
|
if (q.sort && q.sort.field) {
|
|
8705
8716
|
const { field, dir } = q.sort, numeric = typeOf(field) === "number";
|
|
8706
8717
|
out = [...out].sort((a, b) => {
|
|
@@ -9518,7 +9529,7 @@ function Datatable({
|
|
|
9518
9529
|
for (const f of filters) {
|
|
9519
9530
|
const col = colByField[f.field];
|
|
9520
9531
|
if (!col) continue;
|
|
9521
|
-
out = out.filter((r2) => testFilter(getColVal(col, r2), f.op, f.value, col
|
|
9532
|
+
out = out.filter((r2) => testFilter(getColVal(col, r2), f.op, f.value, filterTypeOf(col)));
|
|
9522
9533
|
}
|
|
9523
9534
|
if (sort) {
|
|
9524
9535
|
const col = colByField[sort.field];
|
|
@@ -9836,7 +9847,7 @@ function Datatable({
|
|
|
9836
9847
|
}
|
|
9837
9848
|
function addFilter(field) {
|
|
9838
9849
|
const col = colByField[field] || cols[0];
|
|
9839
|
-
setFilters((f) => [...f, { id: Date.now() + Math.random(), field: col.field, op: opsFor(col
|
|
9850
|
+
setFilters((f) => [...f, { id: Date.now() + Math.random(), field: col.field, op: opsFor(filterTypeOf(col))[0].value, value: "" }]);
|
|
9840
9851
|
}
|
|
9841
9852
|
function setPin(field, side) {
|
|
9842
9853
|
setPins((p) => {
|
|
@@ -11651,7 +11662,7 @@ function Datatable({
|
|
|
11651
11662
|
] }),
|
|
11652
11663
|
filters.length === 0 ? /* @__PURE__ */ jsx("div", { className: "twc-dt__empty", style: { padding: "16px 12px" }, children: "No filters applied" }) : filters.map((f) => {
|
|
11653
11664
|
const col = colByField[f.field] || cols[0];
|
|
11654
|
-
const ops = opsFor(col
|
|
11665
|
+
const ops = opsFor(filterTypeOf(col));
|
|
11655
11666
|
const op = ops.find((o) => o.value === f.op) || ops[0];
|
|
11656
11667
|
return /* @__PURE__ */ jsxs("div", { className: "twc-dt__frow", children: [
|
|
11657
11668
|
/* @__PURE__ */ jsx("div", { className: "twc-dt__f-col", children: /* @__PURE__ */ jsx(
|
|
@@ -11663,7 +11674,7 @@ function Datatable({
|
|
|
11663
11674
|
options: filterableCols.map((c) => ({ value: c.field, label: c.headerName })),
|
|
11664
11675
|
onChange: (v) => {
|
|
11665
11676
|
const nc = colByField[v];
|
|
11666
|
-
setFilters((arr) => arr.map((x) => x.id === f.id ? { ...x, field: v, op: opsFor(nc
|
|
11677
|
+
setFilters((arr) => arr.map((x) => x.id === f.id ? { ...x, field: v, op: opsFor(filterTypeOf(nc))[0].value, value: "" } : x));
|
|
11667
11678
|
}
|
|
11668
11679
|
}
|
|
11669
11680
|
) }),
|
|
@@ -11702,7 +11713,7 @@ function Datatable({
|
|
|
11702
11713
|
Input,
|
|
11703
11714
|
{
|
|
11704
11715
|
size: "sm",
|
|
11705
|
-
type: col
|
|
11716
|
+
type: filterTypeOf(col) === "number" ? "number" : "text",
|
|
11706
11717
|
placeholder: "Value",
|
|
11707
11718
|
value: f.value,
|
|
11708
11719
|
onChange: (e) => setFilters((arr) => arr.map((x) => x.id === f.id ? { ...x, value: e.target.value } : x))
|