twico-ui 1.22.3 → 1.24.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 +274 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.mjs +274 -125
- package/dist/index.mjs.map +1 -1
- package/llms.txt +3 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5671,6 +5671,10 @@ var COMBO_CSS = `
|
|
|
5671
5671
|
.twc-opt__main { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
|
|
5672
5672
|
.twc-opt__label { line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
5673
5673
|
.twc-opt__desc { font-size: var(--text-xs); color: var(--color-text-muted); line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
5674
|
+
/* #300: wrapOptions \u2014 let long labels/descriptions wrap onto multiple lines instead of truncating.
|
|
5675
|
+
overflow-wrap: anywhere also breaks a single very long token so it can't overflow the popover edge. */
|
|
5676
|
+
.twc-opt[data-wrap="true"] { align-items: flex-start; }
|
|
5677
|
+
.twc-opt[data-wrap="true"] .twc-opt__label, .twc-opt[data-wrap="true"] .twc-opt__desc { overflow: visible; text-overflow: clip; white-space: normal; overflow-wrap: anywhere; }
|
|
5674
5678
|
.twc-opt__check { flex: none; color: var(--color-primary); display: inline-flex; }
|
|
5675
5679
|
.twc-opt__check svg { width: 16px; height: 16px; }
|
|
5676
5680
|
.twc-pop__empty { padding: 14px 12px; text-align: center; font-size: var(--text-sm); color: var(--color-text-subtle); }
|
|
@@ -5731,8 +5735,9 @@ function Combobox({
|
|
|
5731
5735
|
loading = false,
|
|
5732
5736
|
emptyText = "No results found",
|
|
5733
5737
|
name,
|
|
5734
|
-
virtualized = false,
|
|
5738
|
+
virtualized: virtualizedProp = false,
|
|
5735
5739
|
overscan = 8,
|
|
5740
|
+
wrapOptions = false,
|
|
5736
5741
|
id,
|
|
5737
5742
|
className = "",
|
|
5738
5743
|
onFocus,
|
|
@@ -5740,6 +5745,8 @@ function Combobox({
|
|
|
5740
5745
|
...rest
|
|
5741
5746
|
}) {
|
|
5742
5747
|
const __twcStyles = useScopedStyles("twc-combo-styles", COMBO_CSS);
|
|
5748
|
+
if (virtualizedProp && wrapOptions) warnOnce("combobox-wrap-virtualized", "twico-ui Combobox: `wrapOptions` disables `virtualized` \u2014 wrapped option rows aren't a fixed height.");
|
|
5749
|
+
const virtualized = virtualizedProp && !wrapOptions;
|
|
5743
5750
|
const groups = React51__namespace.default.useMemo(() => normalizeGroups(options), [options]);
|
|
5744
5751
|
const flat = React51__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
|
|
5745
5752
|
const autoId = React51__namespace.default.useId();
|
|
@@ -5926,6 +5933,7 @@ function Combobox({
|
|
|
5926
5933
|
"data-disabled": o.disabled || void 0,
|
|
5927
5934
|
"data-selected": isSel || void 0,
|
|
5928
5935
|
"data-active": idx === active || void 0,
|
|
5936
|
+
"data-wrap": wrapOptions || void 0,
|
|
5929
5937
|
onMouseEnter: () => {
|
|
5930
5938
|
if (!o.disabled) setActive(idx);
|
|
5931
5939
|
},
|
|
@@ -8552,6 +8560,13 @@ th.twc-dt__rownum .twc-dt__th-inner { padding-inline: 8px; gap: 2px; justify-con
|
|
|
8552
8560
|
.twc-dt__panel-count { font-weight: 600; color: var(--color-text-muted); text-transform: none; letter-spacing: 0; margin-inline-start: 6px; font-variant-numeric: tabular-nums; }
|
|
8553
8561
|
.twc-dt__link { border: none; background: transparent; color: var(--color-primary); font-family: inherit; font-size: var(--text-xs); font-weight: 600; cursor: pointer; padding: 2px 4px; border-radius: var(--radius-sm); }
|
|
8554
8562
|
.twc-dt__link:hover { background: var(--color-primary-subtle); }
|
|
8563
|
+
/* #303: AND/OR connective toggle (segmented pill) in the Filters panel head. */
|
|
8564
|
+
.twc-dt__flogic { display: inline-flex; border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; }
|
|
8565
|
+
.twc-dt__flogic-btn { border: none; background: transparent; color: var(--color-text-muted); font-family: inherit; font-size: 10px; font-weight: 700; letter-spacing: var(--tracking-wide); cursor: pointer; padding: 2px 8px; }
|
|
8566
|
+
.twc-dt__flogic-btn + .twc-dt__flogic-btn { border-inline-start: var(--border-thin) solid var(--color-border); }
|
|
8567
|
+
.twc-dt__flogic-btn:hover { background: var(--color-surface-sunken); }
|
|
8568
|
+
.twc-dt__flogic-btn[data-active] { background: var(--color-primary); color: var(--color-primary-fg); }
|
|
8569
|
+
.twc-dt__flogic-btn[data-active]:hover { background: var(--color-primary); }
|
|
8555
8570
|
|
|
8556
8571
|
/* Filter panel \u2014 user-resizable (#292): panel size + per-field widths resolve through a two-tier CSS var
|
|
8557
8572
|
cascade \u2014 user drag (-usr) > #289 measured auto-fit (-fit) > 118px fallback \u2014 entirely in clamp(), so
|
|
@@ -8582,7 +8597,9 @@ th.twc-dt__rownum .twc-dt__th-inner { padding-inline: 8px; gap: 2px; justify-con
|
|
|
8582
8597
|
/* value: the flex shock-absorber by default; the first drag flips it to a fixed width (data-val-fixed). */
|
|
8583
8598
|
.twc-dt__f-val { position: relative; flex: 1 1 140px; min-width: 140px; }
|
|
8584
8599
|
.twc-dt__filters[data-val-fixed] .twc-dt__f-val { flex: 0 0 clamp(140px, var(--twc-dt-fval-usr, 240px), 640px); }
|
|
8585
|
-
|
|
8600
|
+
/* #303: each row now has two .twc-dt__frm-x (the add-condition "+" then remove "x"); put the auto margin
|
|
8601
|
+
only on the first so the pair hugs the row end together (two auto margins would split the free space). */
|
|
8602
|
+
.twc-dt__filters[data-val-fixed] .twc-dt__frm-x:first-of-type { margin-inline-start: auto; }
|
|
8586
8603
|
.twc-dt__frm-x { display: inline-grid; place-items: center; width: 30px; height: 38px; border: none; background: transparent; color: var(--color-text-subtle); border-radius: var(--radius-md); cursor: pointer; flex: none; align-self: flex-start; }
|
|
8587
8604
|
.twc-dt__frm-x:hover { background: var(--color-danger-subtle); color: var(--color-danger-subtle-fg); }
|
|
8588
8605
|
.twc-dt__frm-x svg { width: 15px; height: 15px; }
|
|
@@ -8602,6 +8619,13 @@ th.twc-dt__rownum .twc-dt__th-inner { padding-inline: 8px; gap: 2px; justify-con
|
|
|
8602
8619
|
.twc-dt__f-rz { width: 16px; inset-inline-end: -6px; opacity: 0.4; }
|
|
8603
8620
|
.twc-dt__pop-grip { width: 20px; height: 20px; opacity: 0.6; }
|
|
8604
8621
|
}
|
|
8622
|
+
/* #304: generic resizable popovers. When the grip commits a size, the panel carries data-pop-sized +
|
|
8623
|
+
--twc-dt-pop-w/-h; the width override beats each panel default (incl. inline widths) and the inner
|
|
8624
|
+
scroll list drops its max-height and flexes to fill the taller panel. The panel keeps its base
|
|
8625
|
+
position: fixed (the absolute grip anchors to it) \u2014 do NOT set position here (see #294). Filters keep
|
|
8626
|
+
their own data-panel-sized system (untouched). */
|
|
8627
|
+
.twc-dt__pop[data-pop-sized] { display: flex; flex-direction: column; width: var(--twc-dt-pop-w) !important; height: var(--twc-dt-pop-h); max-width: calc(100vw - 32px); max-height: calc(100vh - 32px); }
|
|
8628
|
+
.twc-dt__pop[data-pop-sized] .twc-dt__col-list, .twc-dt__pop[data-pop-sized] .twc-dt__cfg-list, .twc-dt__pop[data-pop-sized] .twc-dt__pivot-body { max-height: none; flex: 1 1 auto; overflow-y: auto; }
|
|
8605
8629
|
.twc-dt__empty { padding: 30px 12px; text-align: center; color: var(--color-text-subtle); font-size: var(--text-sm); }
|
|
8606
8630
|
|
|
8607
8631
|
/* Action cell */
|
|
@@ -8831,9 +8855,10 @@ function runDatatableQuery(rows, query, options = {}) {
|
|
|
8831
8855
|
let out = Array.isArray(rows) ? rows : [];
|
|
8832
8856
|
const quick = String(q.quickFilter || "").trim().toLowerCase();
|
|
8833
8857
|
if (quick) out = out.filter((r2) => searchFields.some((f) => String(gv(f, r2) ?? "").toLowerCase().includes(quick)));
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
out = out.filter((r2) => testFilter(gv(f.field, r2), f.op, f.value, filterTypeOf(fc)));
|
|
8858
|
+
const qF = (q.filters || []).map((f) => [cols.find((c) => c.field === f.field), f]).filter(([fc]) => fc);
|
|
8859
|
+
if (qF.length) {
|
|
8860
|
+
if (q.filterLogic === "or") out = out.filter((r2) => qF.some(([fc, f]) => testFilter(gv(f.field, r2), f.op, f.value, filterTypeOf(fc))));
|
|
8861
|
+
else for (const [fc, f] of qF) out = out.filter((r2) => testFilter(gv(f.field, r2), f.op, f.value, filterTypeOf(fc)));
|
|
8837
8862
|
}
|
|
8838
8863
|
if (q.sort && q.sort.field) {
|
|
8839
8864
|
const { field, dir } = q.sort, numeric = typeOf(field) === "number";
|
|
@@ -9155,6 +9180,7 @@ function Datatable({
|
|
|
9155
9180
|
onQuickFilterChange,
|
|
9156
9181
|
toolbarActions,
|
|
9157
9182
|
resizableFilters = true,
|
|
9183
|
+
resizablePopovers = false,
|
|
9158
9184
|
filterFieldMaxWidth,
|
|
9159
9185
|
rowPinning = false,
|
|
9160
9186
|
rowReorder = false,
|
|
@@ -9244,6 +9270,7 @@ function Datatable({
|
|
|
9244
9270
|
});
|
|
9245
9271
|
const [sort, setSort] = React51__namespace.default.useState(null);
|
|
9246
9272
|
const [filters, setFilters] = React51__namespace.default.useState([]);
|
|
9273
|
+
const [filterLogic, setFilterLogic] = React51__namespace.default.useState("and");
|
|
9247
9274
|
const [hidden, setHidden] = React51__namespace.default.useState(() => /* @__PURE__ */ new Set());
|
|
9248
9275
|
const [showRowNum, setShowRowNum] = React51__namespace.default.useState(rowNumbers);
|
|
9249
9276
|
const [wrapped, setWrapped] = React51__namespace.default.useState(() => new Set((columns || []).filter((c) => c.wrapText).map((c) => c.field)));
|
|
@@ -9309,9 +9336,12 @@ function Datatable({
|
|
|
9309
9336
|
const rowFocusRef = React51__namespace.default.useRef(null);
|
|
9310
9337
|
const [fWidths, setFWidths] = React51__namespace.default.useState({});
|
|
9311
9338
|
const [fPanelSize, setFPanelSize] = React51__namespace.default.useState(null);
|
|
9339
|
+
const [popSizes, setPopSizes] = React51__namespace.default.useState({});
|
|
9312
9340
|
const serializeState = () => ({
|
|
9313
9341
|
filters: filters.map(({ id, ...f }) => f),
|
|
9314
9342
|
// strip the internal row id
|
|
9343
|
+
filterLogic,
|
|
9344
|
+
// #303: "and" (default) | "or"
|
|
9315
9345
|
sort,
|
|
9316
9346
|
quickFilter: quick,
|
|
9317
9347
|
page: pageVal,
|
|
@@ -9324,12 +9354,15 @@ function Datatable({
|
|
|
9324
9354
|
density,
|
|
9325
9355
|
// #292: additive, optional — user-resized filter panel + field widths (panel-global, not per column).
|
|
9326
9356
|
filterPanelSize: fPanelSize || void 0,
|
|
9327
|
-
filterFieldWidths: fWidths.col != null || fWidths.op != null || fWidths.val != null ? fWidths : void 0
|
|
9357
|
+
filterFieldWidths: fWidths.col != null || fWidths.op != null || fWidths.val != null ? fWidths : void 0,
|
|
9358
|
+
// #304: additive, optional — user-resized sizes of the other toolbar popovers, keyed by popover id.
|
|
9359
|
+
popoverSizes: Object.keys(popSizes).length ? popSizes : void 0
|
|
9328
9360
|
});
|
|
9329
9361
|
const applyState = (s) => {
|
|
9330
9362
|
if (!s || typeof s !== "object") return;
|
|
9331
9363
|
const known = new Set(cols.map((c) => c.field).filter(Boolean));
|
|
9332
9364
|
if (Array.isArray(s.filters)) setFilters(s.filters.filter((f) => f && known.has(f.field)).map((f, i) => ({ id: Date.now() + Math.random() + i, field: f.field, op: f.op, value: f.value })));
|
|
9365
|
+
if (s.filterLogic === "or" || s.filterLogic === "and") setFilterLogic(s.filterLogic);
|
|
9333
9366
|
if ("sort" in s) setSort(s.sort && known.has(s.sort.field) ? { field: s.sort.field, dir: s.sort.dir === "desc" ? "desc" : "asc" } : null);
|
|
9334
9367
|
if (typeof s.quickFilter === "string" && quickFilter === void 0) setInternalQuick(s.quickFilter);
|
|
9335
9368
|
if (typeof s.page === "number" && !pageControlled) setInternalPage(Math.max(0, Math.floor(s.page)));
|
|
@@ -9359,6 +9392,14 @@ function Datatable({
|
|
|
9359
9392
|
const h = typeof s.filterPanelSize.h === "number" ? clampNum(s.filterPanelSize.h, 120, fMaxH()) : void 0;
|
|
9360
9393
|
if (w != null || h != null) setFPanelSize({ ...w != null ? { w } : {}, ...h != null ? { h } : {} });
|
|
9361
9394
|
}
|
|
9395
|
+
if (s.popoverSizes && typeof s.popoverSizes === "object") {
|
|
9396
|
+
const next = {};
|
|
9397
|
+
for (const [id, sz] of Object.entries(s.popoverSizes)) {
|
|
9398
|
+
if (!sz || typeof sz !== "object" || typeof sz.w !== "number" || typeof sz.h !== "number") continue;
|
|
9399
|
+
next[id] = { w: clampNum(sz.w, popMinW(id), fMaxW()), h: clampNum(sz.h, 120, fMaxH()) };
|
|
9400
|
+
}
|
|
9401
|
+
if (Object.keys(next).length) setPopSizes(next);
|
|
9402
|
+
}
|
|
9362
9403
|
};
|
|
9363
9404
|
const stateReadyRef = React51__namespace.default.useRef(false);
|
|
9364
9405
|
const stateRestoredRef = React51__namespace.default.useRef(false);
|
|
@@ -9376,7 +9417,7 @@ function Datatable({
|
|
|
9376
9417
|
}
|
|
9377
9418
|
}
|
|
9378
9419
|
return void 0;
|
|
9379
|
-
}, [filters, sort, quick, pageVal, sizeVal, order, widths, hidden, pins, density, fWidths, fPanelSize, stateKey]);
|
|
9420
|
+
}, [filters, filterLogic, sort, quick, pageVal, sizeVal, order, widths, hidden, pins, density, fWidths, fPanelSize, popSizes, stateKey]);
|
|
9380
9421
|
const restoreState = () => {
|
|
9381
9422
|
let saved = null;
|
|
9382
9423
|
if (stateKey) {
|
|
@@ -9643,24 +9684,26 @@ function Datatable({
|
|
|
9643
9684
|
const CHK_W = checkboxSelection ? rowReorder ? 68 : 44 : 0;
|
|
9644
9685
|
const numLeft = CHK_W;
|
|
9645
9686
|
const leadW = numLeft + (showRowNum ? NUM_W : 0);
|
|
9687
|
+
const visLeft = React51__namespace.default.useMemo(() => pins.left.filter((f) => colByField[f] && !hidden.has(f)), [pins.left, colByField, hidden]);
|
|
9688
|
+
const visRight = React51__namespace.default.useMemo(() => pins.right.filter((f) => colByField[f] && !hidden.has(f)), [pins.right, colByField, hidden]);
|
|
9646
9689
|
const stickyOf = (field) => {
|
|
9647
|
-
if (
|
|
9690
|
+
if (visLeft.includes(field)) {
|
|
9648
9691
|
let off = leadW;
|
|
9649
|
-
for (const f of
|
|
9692
|
+
for (const f of visLeft) {
|
|
9650
9693
|
if (f === field) break;
|
|
9651
9694
|
off += widthOf(colByField[f] || {});
|
|
9652
9695
|
}
|
|
9653
|
-
const isEdge =
|
|
9696
|
+
const isEdge = visLeft[visLeft.length - 1] === field;
|
|
9654
9697
|
return { style: { insetInlineStart: off }, pin: "left", edge: isEdge ? "left" : void 0 };
|
|
9655
9698
|
}
|
|
9656
|
-
if (
|
|
9699
|
+
if (visRight.includes(field)) {
|
|
9657
9700
|
let off = 0;
|
|
9658
|
-
const rev = [...
|
|
9701
|
+
const rev = [...visRight].reverse();
|
|
9659
9702
|
for (const f of rev) {
|
|
9660
9703
|
if (f === field) break;
|
|
9661
9704
|
off += widthOf(colByField[f] || {});
|
|
9662
9705
|
}
|
|
9663
|
-
const isEdge =
|
|
9706
|
+
const isEdge = visRight[0] === field;
|
|
9664
9707
|
return { style: { insetInlineEnd: off }, pin: "right", edge: isEdge ? "right" : void 0 };
|
|
9665
9708
|
}
|
|
9666
9709
|
return {};
|
|
@@ -9679,10 +9722,13 @@ function Datatable({
|
|
|
9679
9722
|
const searchCols = searchFields && searchFields.length ? searchFields.map((f) => colByField[f] || { field: f }) : visibleCols;
|
|
9680
9723
|
out = out.filter((r2) => searchCols.some((c) => String(getColVal(c, r2) ?? "").toLowerCase().includes(q)));
|
|
9681
9724
|
}
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
if (
|
|
9685
|
-
|
|
9725
|
+
const activeF = filters.map((f) => [colByField[f.field], f]).filter(([col]) => col);
|
|
9726
|
+
if (activeF.length) {
|
|
9727
|
+
if (filterLogic === "or") {
|
|
9728
|
+
out = out.filter((r2) => activeF.some(([col, f]) => testFilter(getColVal(col, r2), f.op, f.value, filterTypeOf(col))));
|
|
9729
|
+
} else {
|
|
9730
|
+
for (const [col, f] of activeF) out = out.filter((r2) => testFilter(getColVal(col, r2), f.op, f.value, filterTypeOf(col)));
|
|
9731
|
+
}
|
|
9686
9732
|
}
|
|
9687
9733
|
if (sort) {
|
|
9688
9734
|
const col = colByField[sort.field];
|
|
@@ -9699,7 +9745,7 @@ function Datatable({
|
|
|
9699
9745
|
out = [...out].sort((a, b) => (idx.get(keyOf(a)) ?? 1e9) - (idx.get(keyOf(b)) ?? 1e9));
|
|
9700
9746
|
}
|
|
9701
9747
|
return out;
|
|
9702
|
-
}, [rows, quick, filters, sort, visibleCols, colByField, serverMode, rowOrder, searchFields]);
|
|
9748
|
+
}, [rows, quick, filters, filterLogic, sort, visibleCols, colByField, serverMode, rowOrder, searchFields]);
|
|
9703
9749
|
const paginated = pageSize > 0;
|
|
9704
9750
|
const serverTotal = rowCount == null ? processed.length : rowCount;
|
|
9705
9751
|
const totalRows = serverMode ? serverTotal : processed.length;
|
|
@@ -9974,6 +10020,8 @@ function Datatable({
|
|
|
9974
10020
|
pageSize: sizeVal,
|
|
9975
10021
|
sort,
|
|
9976
10022
|
filters: filters.map(({ id, ...f }) => f),
|
|
10023
|
+
filterLogic,
|
|
10024
|
+
// #303: "and" (default) | "or" — the server groups its WHERE accordingly
|
|
9977
10025
|
quickFilter: quick.trim(),
|
|
9978
10026
|
visibleColumns,
|
|
9979
10027
|
hiddenColumns
|
|
@@ -9981,7 +10029,7 @@ function Datatable({
|
|
|
9981
10029
|
});
|
|
9982
10030
|
}, 250);
|
|
9983
10031
|
return () => clearTimeout(t);
|
|
9984
|
-
}, [serverMode, pageVal, sizeVal, sort, filters, quick, visibleColumns, hiddenColumns]);
|
|
10032
|
+
}, [serverMode, pageVal, sizeVal, sort, filters, filterLogic, quick, visibleColumns, hiddenColumns]);
|
|
9985
10033
|
const onColVisRef = React51__namespace.default.useRef(onColumnVisibilityChange);
|
|
9986
10034
|
onColVisRef.current = onColumnVisibilityChange;
|
|
9987
10035
|
const lastVisibleKey = React51__namespace.default.useRef(null);
|
|
@@ -10639,7 +10687,97 @@ function Datatable({
|
|
|
10639
10687
|
}
|
|
10640
10688
|
};
|
|
10641
10689
|
const hasFilterSizeOverride = fWidths.col != null || fWidths.op != null || fWidths.val != null || fPanelSize != null;
|
|
10642
|
-
const
|
|
10690
|
+
const POP_MIN_W = { columns: 240, agg: 240, pivot: 260, batchedit: 260 };
|
|
10691
|
+
const popMinW = (id) => POP_MIN_W[id] || 200;
|
|
10692
|
+
const clearPop = (id, node) => {
|
|
10693
|
+
if (node) {
|
|
10694
|
+
node.style.removeProperty("--twc-dt-pop-w");
|
|
10695
|
+
node.style.removeProperty("--twc-dt-pop-h");
|
|
10696
|
+
node.removeAttribute("data-pop-sized");
|
|
10697
|
+
}
|
|
10698
|
+
setPopSizes((s) => {
|
|
10699
|
+
if (!(id in s)) return s;
|
|
10700
|
+
const n = { ...s };
|
|
10701
|
+
delete n[id];
|
|
10702
|
+
return n;
|
|
10703
|
+
});
|
|
10704
|
+
};
|
|
10705
|
+
const startPopResize = (id) => (e) => {
|
|
10706
|
+
if (e.button != null && e.button !== 0) return;
|
|
10707
|
+
e.preventDefault();
|
|
10708
|
+
e.stopPropagation();
|
|
10709
|
+
const pop = e.currentTarget.closest(".twc-dt__pop");
|
|
10710
|
+
if (!pop) return;
|
|
10711
|
+
const grip = e.currentTarget;
|
|
10712
|
+
const startX = e.clientX, startY = e.clientY;
|
|
10713
|
+
const r2 = pop.getBoundingClientRect();
|
|
10714
|
+
const startW = r2.width, startH = r2.height;
|
|
10715
|
+
const dir = typeof getComputedStyle !== "undefined" && getComputedStyle(pop).direction === "rtl" ? -1 : 1;
|
|
10716
|
+
pop.style.setProperty("--twc-dt-pop-w", `${startW}px`);
|
|
10717
|
+
pop.style.setProperty("--twc-dt-pop-h", `${startH}px`);
|
|
10718
|
+
grip.setAttribute("data-active", "true");
|
|
10719
|
+
pop.setAttribute("data-pop-sized", "");
|
|
10720
|
+
let lw = startW, lh = startH;
|
|
10721
|
+
const onMove = (ev) => {
|
|
10722
|
+
lw = clampNum(startW + (ev.clientX - startX) * dir, popMinW(id), fMaxW());
|
|
10723
|
+
lh = clampNum(startH + (ev.clientY - startY), 120, fMaxH());
|
|
10724
|
+
pop.style.setProperty("--twc-dt-pop-w", `${lw}px`);
|
|
10725
|
+
pop.style.setProperty("--twc-dt-pop-h", `${lh}px`);
|
|
10726
|
+
};
|
|
10727
|
+
const onUp = () => {
|
|
10728
|
+
setPopSizes((s) => ({ ...s, [id]: { w: lw, h: lh } }));
|
|
10729
|
+
grip.removeAttribute("data-active");
|
|
10730
|
+
window.removeEventListener("pointermove", onMove);
|
|
10731
|
+
window.removeEventListener("pointerup", onUp);
|
|
10732
|
+
};
|
|
10733
|
+
window.addEventListener("pointermove", onMove);
|
|
10734
|
+
window.addEventListener("pointerup", onUp);
|
|
10735
|
+
};
|
|
10736
|
+
const onPopGripKey = (id) => (e) => {
|
|
10737
|
+
if (e.key === "Enter" || e.key === " " || e.key === "Backspace") {
|
|
10738
|
+
e.preventDefault();
|
|
10739
|
+
clearPop(id, e.currentTarget.closest(".twc-dt__pop"));
|
|
10740
|
+
return;
|
|
10741
|
+
}
|
|
10742
|
+
if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"].includes(e.key)) return;
|
|
10743
|
+
e.preventDefault();
|
|
10744
|
+
const pop = e.currentTarget.closest(".twc-dt__pop");
|
|
10745
|
+
if (!pop) return;
|
|
10746
|
+
const r2 = pop.getBoundingClientRect();
|
|
10747
|
+
const step = e.shiftKey ? 4 : 20;
|
|
10748
|
+
const dir = typeof getComputedStyle !== "undefined" && getComputedStyle(pop).direction === "rtl" ? -1 : 1;
|
|
10749
|
+
let w = r2.width, h = r2.height;
|
|
10750
|
+
if (e.key === "ArrowRight") w += step * dir;
|
|
10751
|
+
else if (e.key === "ArrowLeft") w -= step * dir;
|
|
10752
|
+
else if (e.key === "ArrowDown") h += step;
|
|
10753
|
+
else if (e.key === "ArrowUp") h -= step;
|
|
10754
|
+
else if (e.key === "Home") {
|
|
10755
|
+
w = popMinW(id);
|
|
10756
|
+
h = 120;
|
|
10757
|
+
} else if (e.key === "End") {
|
|
10758
|
+
w = fMaxW();
|
|
10759
|
+
h = fMaxH();
|
|
10760
|
+
}
|
|
10761
|
+
setPopSizes((s) => ({ ...s, [id]: { w: clampNum(w, popMinW(id), fMaxW()), h: clampNum(h, 120, fMaxH()) } }));
|
|
10762
|
+
};
|
|
10763
|
+
const popStyle = (id) => popSizes[id] ? { "--twc-dt-pop-w": `${popSizes[id].w}px`, "--twc-dt-pop-h": `${popSizes[id].h}px` } : null;
|
|
10764
|
+
const popGrip = (id) => resizablePopovers ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
10765
|
+
"span",
|
|
10766
|
+
{
|
|
10767
|
+
className: "twc-dt__pop-grip",
|
|
10768
|
+
role: "slider",
|
|
10769
|
+
tabIndex: 0,
|
|
10770
|
+
"aria-label": "Resize panel (Enter or double-click to reset)",
|
|
10771
|
+
"aria-valuetext": popSizes[id] ? `Width ${Math.round(popSizes[id].w)} pixels, height ${Math.round(popSizes[id].h)} pixels` : "Default size",
|
|
10772
|
+
onPointerDown: startPopResize(id),
|
|
10773
|
+
onKeyDown: onPopGripKey(id),
|
|
10774
|
+
onDoubleClick: (e) => {
|
|
10775
|
+
e.preventDefault();
|
|
10776
|
+
clearPop(id, e.currentTarget.closest(".twc-dt__pop"));
|
|
10777
|
+
}
|
|
10778
|
+
}
|
|
10779
|
+
) : null;
|
|
10780
|
+
const fieldHandle = (field, rowIdx) => (resizableFilters || resizablePopovers) && rowIdx === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
10643
10781
|
"span",
|
|
10644
10782
|
{
|
|
10645
10783
|
className: "twc-dt__f-rz",
|
|
@@ -10761,7 +10899,7 @@ function Datatable({
|
|
|
10761
10899
|
onDragEnd: reorderable ? () => setRowDrag({ from: null, over: null, after: false }) : void 0,
|
|
10762
10900
|
onClick: (e) => handleRowClick(e, k, row),
|
|
10763
10901
|
children: [
|
|
10764
|
-
checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", "data-pin-edge":
|
|
10902
|
+
checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: 0, width: CHK_W }, children: [
|
|
10765
10903
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 4 }, children: [
|
|
10766
10904
|
reorderable ? rowHandle(k, midIdx, row) : null,
|
|
10767
10905
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10786,7 +10924,7 @@ function Datatable({
|
|
|
10786
10924
|
] }),
|
|
10787
10925
|
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
|
|
10788
10926
|
] }) : null,
|
|
10789
|
-
showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge":
|
|
10927
|
+
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,
|
|
10790
10928
|
ordered.map((c, ci) => {
|
|
10791
10929
|
const st = stickyOf(c.field);
|
|
10792
10930
|
const val = getColVal(c, row);
|
|
@@ -11196,7 +11334,7 @@ function Datatable({
|
|
|
11196
11334
|
onKeyDown: onGridKeyDown,
|
|
11197
11335
|
children: [
|
|
11198
11336
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { ref: theadRef, children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", "aria-rowindex": 1, children: [
|
|
11199
|
-
checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th", role: "columnheader", "aria-label": "Select", "data-pin": "left", "data-pin-edge":
|
|
11337
|
+
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: 0, 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(
|
|
11200
11338
|
"span",
|
|
11201
11339
|
{
|
|
11202
11340
|
className: "twc-dt__check",
|
|
@@ -11216,7 +11354,7 @@ function Datatable({
|
|
|
11216
11354
|
children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: allSel ? I.check : I.minus })
|
|
11217
11355
|
}
|
|
11218
11356
|
) }) }) : null,
|
|
11219
|
-
showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th twc-dt__rownum", role: "columnheader", "aria-label": "Row number", "data-pin": "left", "data-pin-edge":
|
|
11357
|
+
showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th twc-dt__rownum", role: "columnheader", "aria-label": "Row number", "data-pin": "left", "data-pin-edge": visLeft.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W, minWidth: NUM_W }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__th-inner", children: [
|
|
11220
11358
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__th-label", style: { flex: "none", cursor: "default" }, children: "#" }),
|
|
11221
11359
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11222
11360
|
"button",
|
|
@@ -11394,8 +11532,8 @@ function Datatable({
|
|
|
11394
11532
|
pinnedBottomRows.map((row) => renderLeaf(row, keyIndex.get(keyOf(row)), "bottom"))
|
|
11395
11533
|
] }) }),
|
|
11396
11534
|
hasAggregation && aggOn && !loading && paged.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("tfoot", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", children: [
|
|
11397
|
-
checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge":
|
|
11398
|
-
showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge":
|
|
11535
|
+
checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: 0, width: CHK_W } }) : null,
|
|
11536
|
+
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,
|
|
11399
11537
|
ordered.map((c) => {
|
|
11400
11538
|
const st = stickyOf(c.field);
|
|
11401
11539
|
const v = aggregate(c);
|
|
@@ -11494,7 +11632,7 @@ function Datatable({
|
|
|
11494
11632
|
delete values[f];
|
|
11495
11633
|
return { ...b, fields, values };
|
|
11496
11634
|
});
|
|
11497
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: batchEditPos.top, left: batchEditPos.left, width: 320 }, children: [
|
|
11635
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: batchEditPos.top, left: batchEditPos.left, width: 320, ...popStyle("batchedit") }, "data-pop-sized": popSizes.batchedit ? "" : void 0, children: [
|
|
11498
11636
|
/* @__PURE__ */ jsxRuntime.jsx(Caret, { pos: batchEditPos }),
|
|
11499
11637
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-head", children: [
|
|
11500
11638
|
"Edit ",
|
|
@@ -11556,7 +11694,8 @@ function Datatable({
|
|
|
11556
11694
|
"Apply to ",
|
|
11557
11695
|
selected.size
|
|
11558
11696
|
] })
|
|
11559
|
-
] })
|
|
11697
|
+
] }),
|
|
11698
|
+
popGrip("batchedit")
|
|
11560
11699
|
] });
|
|
11561
11700
|
})() : null,
|
|
11562
11701
|
colMenu && menuPos ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -11729,7 +11868,7 @@ function Datatable({
|
|
|
11729
11868
|
]
|
|
11730
11869
|
}
|
|
11731
11870
|
) : null,
|
|
11732
|
-
panel === "columns" && panelPos ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cols", style: { top: panelPos.top, left: panelPos.left }, role: "dialog", "aria-label": "Column settings", children: [
|
|
11871
|
+
panel === "columns" && panelPos ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cols", style: { top: panelPos.top, left: panelPos.left, ...popStyle("columns") }, "data-pop-sized": popSizes.columns ? "" : void 0, role: "dialog", "aria-label": "Column settings", children: [
|
|
11733
11872
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__panel-head", children: [
|
|
11734
11873
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-dt__panel-title", children: [
|
|
11735
11874
|
"Columns ",
|
|
@@ -11854,9 +11993,10 @@ function Datatable({
|
|
|
11854
11993
|
c.field
|
|
11855
11994
|
);
|
|
11856
11995
|
})
|
|
11857
|
-
] })
|
|
11996
|
+
] }),
|
|
11997
|
+
popGrip("columns")
|
|
11858
11998
|
] }) : null,
|
|
11859
|
-
panel === "agg" && panelPos ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: panelPos.top, left: panelPos.left, width: 300 }, role: "dialog", "aria-label": "Aggregation settings", children: [
|
|
11999
|
+
panel === "agg" && panelPos ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: panelPos.top, left: panelPos.left, width: 300, ...popStyle("agg") }, "data-pop-sized": popSizes.agg ? "" : void 0, role: "dialog", "aria-label": "Aggregation settings", children: [
|
|
11860
12000
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__panel-head", children: [
|
|
11861
12001
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__panel-title", children: "Aggregation" }),
|
|
11862
12002
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__link", onClick: () => setAggConfig({}), children: "Clear" })
|
|
@@ -11905,13 +12045,14 @@ function Datatable({
|
|
|
11905
12045
|
}
|
|
11906
12046
|
) })
|
|
11907
12047
|
] }, c.field);
|
|
11908
|
-
}) })
|
|
12048
|
+
}) }),
|
|
12049
|
+
popGrip("agg")
|
|
11909
12050
|
] }) : null,
|
|
11910
12051
|
panel === "pivot" && panelPos ? (() => {
|
|
11911
12052
|
const fieldOpts = ordered.filter((c) => c.type !== "actions").map((c) => ({ value: c.field, label: c.headerName }));
|
|
11912
12053
|
const aggOpts = [{ value: "sum", label: "Sum" }, { value: "avg", label: "Avg" }, { value: "min", label: "Min" }, { value: "max", label: "Max" }, { value: "count", label: "Count" }];
|
|
11913
12054
|
const valueFieldOpts = ordered.filter((c) => c.type !== "actions" && !pivotConfig.values.some((v) => v.field === c.field)).map((c) => ({ value: c.field, label: c.headerName }));
|
|
11914
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: panelPos.top, left: panelPos.left, width: 320 }, role: "dialog", "aria-label": "Pivot settings", children: [
|
|
12055
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: panelPos.top, left: panelPos.left, width: 320, ...popStyle("pivot") }, "data-pop-sized": popSizes.pivot ? "" : void 0, role: "dialog", "aria-label": "Pivot settings", children: [
|
|
11915
12056
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__panel-head", children: [
|
|
11916
12057
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__panel-title", children: "Pivot" }),
|
|
11917
12058
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__link", onClick: () => {
|
|
@@ -11919,106 +12060,109 @@ function Datatable({
|
|
|
11919
12060
|
setPivotOn(false);
|
|
11920
12061
|
}, children: "Reset" })
|
|
11921
12062
|
] }),
|
|
11922
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-
|
|
11923
|
-
/* @__PURE__ */ jsxRuntime.
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
e.
|
|
11936
|
-
|
|
12063
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pivot-body", children: [
|
|
12064
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-toggle", children: [
|
|
12065
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Pivot mode" }),
|
|
12066
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12067
|
+
"span",
|
|
12068
|
+
{
|
|
12069
|
+
className: "twc-dt__sw",
|
|
12070
|
+
"data-on": pivotOn || void 0,
|
|
12071
|
+
role: "switch",
|
|
12072
|
+
"aria-checked": pivotOn,
|
|
12073
|
+
tabIndex: 0,
|
|
12074
|
+
onClick: () => setPivotOn((v) => !v),
|
|
12075
|
+
onKeyDown: (e) => {
|
|
12076
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
12077
|
+
e.preventDefault();
|
|
12078
|
+
setPivotOn((v) => !v);
|
|
12079
|
+
}
|
|
11937
12080
|
}
|
|
11938
12081
|
}
|
|
11939
|
-
|
|
11940
|
-
)
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
MultiSelect,
|
|
11953
|
-
{
|
|
11954
|
-
portal: true,
|
|
11955
|
-
placeholder: "Add row fields\u2026",
|
|
11956
|
-
value: pivotConfig.rows,
|
|
11957
|
-
options: fieldOpts,
|
|
11958
|
-
onChange: (vals) => {
|
|
11959
|
-
setPivotConfig((p) => ({ ...p, rows: vals }));
|
|
11960
|
-
if (vals.length) setPivotOn(true);
|
|
11961
|
-
}
|
|
11962
|
-
}
|
|
11963
|
-
)
|
|
11964
|
-
] }),
|
|
11965
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
|
|
11966
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Columns" }),
|
|
11967
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11968
|
-
MultiSelect,
|
|
11969
|
-
{
|
|
11970
|
-
portal: true,
|
|
11971
|
-
placeholder: "Add column fields\u2026",
|
|
11972
|
-
value: pivotConfig.columns,
|
|
11973
|
-
options: fieldOpts,
|
|
11974
|
-
onChange: (vals) => setPivotConfig((p) => ({ ...p, columns: vals }))
|
|
11975
|
-
}
|
|
11976
|
-
)
|
|
11977
|
-
] }),
|
|
11978
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
|
|
11979
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Values" }),
|
|
11980
|
-
pivotConfig.values.map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-row", children: [
|
|
11981
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-name", children: colByField[v.field]?.headerName || v.field }),
|
|
11982
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__cfg-ctl", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11983
|
-
Select,
|
|
12082
|
+
)
|
|
12083
|
+
] }),
|
|
12084
|
+
!pivotActive && pivotOn ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-hint", children: [
|
|
12085
|
+
"Add at least one ",
|
|
12086
|
+
/* @__PURE__ */ jsxRuntime.jsx("b", { children: "Row" }),
|
|
12087
|
+
" field and one ",
|
|
12088
|
+
/* @__PURE__ */ jsxRuntime.jsx("b", { children: "Value" }),
|
|
12089
|
+
" to see the pivot."
|
|
12090
|
+
] }) : null,
|
|
12091
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
|
|
12092
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Rows" }),
|
|
12093
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12094
|
+
MultiSelect,
|
|
11984
12095
|
{
|
|
11985
|
-
size: "sm",
|
|
11986
|
-
value: v.agg || "sum",
|
|
11987
|
-
options: aggOpts,
|
|
11988
12096
|
portal: true,
|
|
11989
|
-
|
|
12097
|
+
placeholder: "Add row fields\u2026",
|
|
12098
|
+
value: pivotConfig.rows,
|
|
12099
|
+
options: fieldOpts,
|
|
12100
|
+
onChange: (vals) => {
|
|
12101
|
+
setPivotConfig((p) => ({ ...p, rows: vals }));
|
|
12102
|
+
if (vals.length) setPivotOn(true);
|
|
12103
|
+
}
|
|
11990
12104
|
}
|
|
11991
|
-
)
|
|
12105
|
+
)
|
|
12106
|
+
] }),
|
|
12107
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
|
|
12108
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Columns" }),
|
|
11992
12109
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11993
|
-
|
|
12110
|
+
MultiSelect,
|
|
11994
12111
|
{
|
|
11995
|
-
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
|
|
11999
|
-
|
|
12112
|
+
portal: true,
|
|
12113
|
+
placeholder: "Add column fields\u2026",
|
|
12114
|
+
value: pivotConfig.columns,
|
|
12115
|
+
options: fieldOpts,
|
|
12116
|
+
onChange: (vals) => setPivotConfig((p) => ({ ...p, columns: vals }))
|
|
12000
12117
|
}
|
|
12001
12118
|
)
|
|
12002
|
-
] }
|
|
12003
|
-
|
|
12004
|
-
|
|
12005
|
-
{
|
|
12006
|
-
|
|
12007
|
-
|
|
12008
|
-
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
|
|
12014
|
-
|
|
12015
|
-
|
|
12016
|
-
|
|
12119
|
+
] }),
|
|
12120
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
|
|
12121
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Values" }),
|
|
12122
|
+
pivotConfig.values.map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-row", children: [
|
|
12123
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-name", children: colByField[v.field]?.headerName || v.field }),
|
|
12124
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__cfg-ctl", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
12125
|
+
Select,
|
|
12126
|
+
{
|
|
12127
|
+
size: "sm",
|
|
12128
|
+
value: v.agg || "sum",
|
|
12129
|
+
options: aggOpts,
|
|
12130
|
+
portal: true,
|
|
12131
|
+
onChange: (a) => setPivotConfig((p) => ({ ...p, values: p.values.map((x, j) => j === i ? { ...x, agg: a } : x) }))
|
|
12132
|
+
}
|
|
12133
|
+
) }),
|
|
12134
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12135
|
+
"button",
|
|
12136
|
+
{
|
|
12137
|
+
type: "button",
|
|
12138
|
+
className: "twc-dt__cfg-x",
|
|
12139
|
+
"aria-label": `Remove ${colByField[v.field]?.headerName || v.field}`,
|
|
12140
|
+
onClick: () => setPivotConfig((p) => ({ ...p, values: p.values.filter((_, j) => j !== i) })),
|
|
12141
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.x })
|
|
12142
|
+
}
|
|
12143
|
+
)
|
|
12144
|
+
] }, v.field + i)),
|
|
12145
|
+
valueFieldOpts.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__cfg-add", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
12146
|
+
Select,
|
|
12147
|
+
{
|
|
12148
|
+
size: "sm",
|
|
12149
|
+
placeholder: "Add value field\u2026",
|
|
12150
|
+
value: "",
|
|
12151
|
+
options: valueFieldOpts,
|
|
12152
|
+
portal: true,
|
|
12153
|
+
searchable: true,
|
|
12154
|
+
searchPlaceholder: "Search fields\u2026",
|
|
12155
|
+
onChange: (f) => {
|
|
12156
|
+
if (f) {
|
|
12157
|
+
setPivotConfig((p) => p.values.some((x) => x.field === f) ? p : { ...p, values: [...p.values, { field: f, agg: "sum" }] });
|
|
12158
|
+
setPivotOn(true);
|
|
12159
|
+
}
|
|
12017
12160
|
}
|
|
12018
12161
|
}
|
|
12019
|
-
}
|
|
12020
|
-
|
|
12021
|
-
] })
|
|
12162
|
+
) }) : null
|
|
12163
|
+
] })
|
|
12164
|
+
] }),
|
|
12165
|
+
popGrip("pivot")
|
|
12022
12166
|
] });
|
|
12023
12167
|
})() : null,
|
|
12024
12168
|
panel === "filters" && panelPos ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -12042,8 +12186,12 @@ function Datatable({
|
|
|
12042
12186
|
children: [
|
|
12043
12187
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__panel-head", children: [
|
|
12044
12188
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__panel-title", children: "Filters" }),
|
|
12045
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", gap:
|
|
12046
|
-
|
|
12189
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 6 }, children: [
|
|
12190
|
+
filters.length > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-dt__flogic", role: "group", "aria-label": "Combine filters with", children: [
|
|
12191
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__flogic-btn", "data-active": filterLogic === "and" || void 0, "aria-pressed": filterLogic === "and", onClick: () => setFilterLogic("and"), children: "AND" }),
|
|
12192
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__flogic-btn", "data-active": filterLogic === "or" || void 0, "aria-pressed": filterLogic === "or", onClick: () => setFilterLogic("or"), children: "OR" })
|
|
12193
|
+
] }) : null,
|
|
12194
|
+
(resizableFilters || resizablePopovers) && hasFilterSizeOverride ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__link", onClick: resetFilterSizes, children: "Reset sizes" }) : null,
|
|
12047
12195
|
filters.length ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__link", onClick: () => setFilters([]), children: "Clear all" }) : null
|
|
12048
12196
|
] })
|
|
12049
12197
|
] }),
|
|
@@ -12115,6 +12263,7 @@ function Datatable({
|
|
|
12115
12263
|
),
|
|
12116
12264
|
fieldHandle("val", i)
|
|
12117
12265
|
] }),
|
|
12266
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__frm-x", "aria-label": `Add another condition on ${col.headerName}`, title: "Add another condition on this column", onClick: () => addFilter(f.field), children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.plus }) }),
|
|
12118
12267
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__frm-x", "aria-label": "Remove filter", onClick: () => setFilters((arr) => arr.filter((x) => x.id !== f.id)), children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.x }) })
|
|
12119
12268
|
] }, f.id);
|
|
12120
12269
|
}) }),
|
|
@@ -12122,7 +12271,7 @@ function Datatable({
|
|
|
12122
12271
|
/* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.plus, style: { color: "var(--color-primary)" } }),
|
|
12123
12272
|
" Add filter"
|
|
12124
12273
|
] }) }),
|
|
12125
|
-
resizableFilters ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
12274
|
+
resizableFilters || resizablePopovers ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
12126
12275
|
"span",
|
|
12127
12276
|
{
|
|
12128
12277
|
className: "twc-dt__pop-grip",
|