twico-ui 1.23.0 → 1.25.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/dist/index.cjs CHANGED
@@ -8560,6 +8560,13 @@ th.twc-dt__rownum .twc-dt__th-inner { padding-inline: 8px; gap: 2px; justify-con
8560
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; }
8561
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); }
8562
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); }
8563
8570
 
8564
8571
  /* Filter panel \u2014 user-resizable (#292): panel size + per-field widths resolve through a two-tier CSS var
8565
8572
  cascade \u2014 user drag (-usr) > #289 measured auto-fit (-fit) > 118px fallback \u2014 entirely in clamp(), so
@@ -8590,7 +8597,9 @@ th.twc-dt__rownum .twc-dt__th-inner { padding-inline: 8px; gap: 2px; justify-con
8590
8597
  /* value: the flex shock-absorber by default; the first drag flips it to a fixed width (data-val-fixed). */
8591
8598
  .twc-dt__f-val { position: relative; flex: 1 1 140px; min-width: 140px; }
8592
8599
  .twc-dt__filters[data-val-fixed] .twc-dt__f-val { flex: 0 0 clamp(140px, var(--twc-dt-fval-usr, 240px), 640px); }
8593
- .twc-dt__filters[data-val-fixed] .twc-dt__frm-x { margin-inline-start: auto; }
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; }
8594
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; }
8595
8604
  .twc-dt__frm-x:hover { background: var(--color-danger-subtle); color: var(--color-danger-subtle-fg); }
8596
8605
  .twc-dt__frm-x svg { width: 15px; height: 15px; }
@@ -8610,6 +8619,13 @@ th.twc-dt__rownum .twc-dt__th-inner { padding-inline: 8px; gap: 2px; justify-con
8610
8619
  .twc-dt__f-rz { width: 16px; inset-inline-end: -6px; opacity: 0.4; }
8611
8620
  .twc-dt__pop-grip { width: 20px; height: 20px; opacity: 0.6; }
8612
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; }
8613
8629
  .twc-dt__empty { padding: 30px 12px; text-align: center; color: var(--color-text-subtle); font-size: var(--text-sm); }
8614
8630
 
8615
8631
  /* Action cell */
@@ -8839,9 +8855,10 @@ function runDatatableQuery(rows, query, options = {}) {
8839
8855
  let out = Array.isArray(rows) ? rows : [];
8840
8856
  const quick = String(q.quickFilter || "").trim().toLowerCase();
8841
8857
  if (quick) out = out.filter((r2) => searchFields.some((f) => String(gv(f, r2) ?? "").toLowerCase().includes(quick)));
8842
- for (const f of q.filters || []) {
8843
- const fc = cols.find((c) => c.field === f.field);
8844
- 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)));
8845
8862
  }
8846
8863
  if (q.sort && q.sort.field) {
8847
8864
  const { field, dir } = q.sort, numeric = typeOf(field) === "number";
@@ -9163,6 +9180,8 @@ function Datatable({
9163
9180
  onQuickFilterChange,
9164
9181
  toolbarActions,
9165
9182
  resizableFilters = true,
9183
+ resizablePopovers = true,
9184
+ // #314: default-on (matches resizableFilters) — set false to opt a grid out
9166
9185
  filterFieldMaxWidth,
9167
9186
  rowPinning = false,
9168
9187
  rowReorder = false,
@@ -9252,6 +9271,7 @@ function Datatable({
9252
9271
  });
9253
9272
  const [sort, setSort] = React51__namespace.default.useState(null);
9254
9273
  const [filters, setFilters] = React51__namespace.default.useState([]);
9274
+ const [filterLogic, setFilterLogic] = React51__namespace.default.useState("and");
9255
9275
  const [hidden, setHidden] = React51__namespace.default.useState(() => /* @__PURE__ */ new Set());
9256
9276
  const [showRowNum, setShowRowNum] = React51__namespace.default.useState(rowNumbers);
9257
9277
  const [wrapped, setWrapped] = React51__namespace.default.useState(() => new Set((columns || []).filter((c) => c.wrapText).map((c) => c.field)));
@@ -9317,9 +9337,12 @@ function Datatable({
9317
9337
  const rowFocusRef = React51__namespace.default.useRef(null);
9318
9338
  const [fWidths, setFWidths] = React51__namespace.default.useState({});
9319
9339
  const [fPanelSize, setFPanelSize] = React51__namespace.default.useState(null);
9340
+ const [popSizes, setPopSizes] = React51__namespace.default.useState({});
9320
9341
  const serializeState = () => ({
9321
9342
  filters: filters.map(({ id, ...f }) => f),
9322
9343
  // strip the internal row id
9344
+ filterLogic,
9345
+ // #303: "and" (default) | "or"
9323
9346
  sort,
9324
9347
  quickFilter: quick,
9325
9348
  page: pageVal,
@@ -9332,12 +9355,15 @@ function Datatable({
9332
9355
  density,
9333
9356
  // #292: additive, optional — user-resized filter panel + field widths (panel-global, not per column).
9334
9357
  filterPanelSize: fPanelSize || void 0,
9335
- filterFieldWidths: fWidths.col != null || fWidths.op != null || fWidths.val != null ? fWidths : void 0
9358
+ filterFieldWidths: fWidths.col != null || fWidths.op != null || fWidths.val != null ? fWidths : void 0,
9359
+ // #304: additive, optional — user-resized sizes of the other toolbar popovers, keyed by popover id.
9360
+ popoverSizes: Object.keys(popSizes).length ? popSizes : void 0
9336
9361
  });
9337
9362
  const applyState = (s) => {
9338
9363
  if (!s || typeof s !== "object") return;
9339
9364
  const known = new Set(cols.map((c) => c.field).filter(Boolean));
9340
9365
  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 })));
9366
+ if (s.filterLogic === "or" || s.filterLogic === "and") setFilterLogic(s.filterLogic);
9341
9367
  if ("sort" in s) setSort(s.sort && known.has(s.sort.field) ? { field: s.sort.field, dir: s.sort.dir === "desc" ? "desc" : "asc" } : null);
9342
9368
  if (typeof s.quickFilter === "string" && quickFilter === void 0) setInternalQuick(s.quickFilter);
9343
9369
  if (typeof s.page === "number" && !pageControlled) setInternalPage(Math.max(0, Math.floor(s.page)));
@@ -9367,6 +9393,14 @@ function Datatable({
9367
9393
  const h = typeof s.filterPanelSize.h === "number" ? clampNum(s.filterPanelSize.h, 120, fMaxH()) : void 0;
9368
9394
  if (w != null || h != null) setFPanelSize({ ...w != null ? { w } : {}, ...h != null ? { h } : {} });
9369
9395
  }
9396
+ if (s.popoverSizes && typeof s.popoverSizes === "object") {
9397
+ const next = {};
9398
+ for (const [id, sz] of Object.entries(s.popoverSizes)) {
9399
+ if (!sz || typeof sz !== "object" || typeof sz.w !== "number" || typeof sz.h !== "number") continue;
9400
+ next[id] = { w: clampNum(sz.w, popMinW(id), fMaxW()), h: clampNum(sz.h, 120, fMaxH()) };
9401
+ }
9402
+ if (Object.keys(next).length) setPopSizes(next);
9403
+ }
9370
9404
  };
9371
9405
  const stateReadyRef = React51__namespace.default.useRef(false);
9372
9406
  const stateRestoredRef = React51__namespace.default.useRef(false);
@@ -9384,7 +9418,7 @@ function Datatable({
9384
9418
  }
9385
9419
  }
9386
9420
  return void 0;
9387
- }, [filters, sort, quick, pageVal, sizeVal, order, widths, hidden, pins, density, fWidths, fPanelSize, stateKey]);
9421
+ }, [filters, filterLogic, sort, quick, pageVal, sizeVal, order, widths, hidden, pins, density, fWidths, fPanelSize, popSizes, stateKey]);
9388
9422
  const restoreState = () => {
9389
9423
  let saved = null;
9390
9424
  if (stateKey) {
@@ -9651,24 +9685,26 @@ function Datatable({
9651
9685
  const CHK_W = checkboxSelection ? rowReorder ? 68 : 44 : 0;
9652
9686
  const numLeft = CHK_W;
9653
9687
  const leadW = numLeft + (showRowNum ? NUM_W : 0);
9688
+ const visLeft = React51__namespace.default.useMemo(() => pins.left.filter((f) => colByField[f] && !hidden.has(f)), [pins.left, colByField, hidden]);
9689
+ const visRight = React51__namespace.default.useMemo(() => pins.right.filter((f) => colByField[f] && !hidden.has(f)), [pins.right, colByField, hidden]);
9654
9690
  const stickyOf = (field) => {
9655
- if (pins.left.includes(field)) {
9691
+ if (visLeft.includes(field)) {
9656
9692
  let off = leadW;
9657
- for (const f of pins.left) {
9693
+ for (const f of visLeft) {
9658
9694
  if (f === field) break;
9659
9695
  off += widthOf(colByField[f] || {});
9660
9696
  }
9661
- const isEdge = pins.left[pins.left.length - 1] === field;
9697
+ const isEdge = visLeft[visLeft.length - 1] === field;
9662
9698
  return { style: { insetInlineStart: off }, pin: "left", edge: isEdge ? "left" : void 0 };
9663
9699
  }
9664
- if (pins.right.includes(field)) {
9700
+ if (visRight.includes(field)) {
9665
9701
  let off = 0;
9666
- const rev = [...pins.right].reverse();
9702
+ const rev = [...visRight].reverse();
9667
9703
  for (const f of rev) {
9668
9704
  if (f === field) break;
9669
9705
  off += widthOf(colByField[f] || {});
9670
9706
  }
9671
- const isEdge = pins.right[0] === field;
9707
+ const isEdge = visRight[0] === field;
9672
9708
  return { style: { insetInlineEnd: off }, pin: "right", edge: isEdge ? "right" : void 0 };
9673
9709
  }
9674
9710
  return {};
@@ -9687,10 +9723,13 @@ function Datatable({
9687
9723
  const searchCols = searchFields && searchFields.length ? searchFields.map((f) => colByField[f] || { field: f }) : visibleCols;
9688
9724
  out = out.filter((r2) => searchCols.some((c) => String(getColVal(c, r2) ?? "").toLowerCase().includes(q)));
9689
9725
  }
9690
- for (const f of filters) {
9691
- const col = colByField[f.field];
9692
- if (!col) continue;
9693
- out = out.filter((r2) => testFilter(getColVal(col, r2), f.op, f.value, filterTypeOf(col)));
9726
+ const activeF = filters.map((f) => [colByField[f.field], f]).filter(([col]) => col);
9727
+ if (activeF.length) {
9728
+ if (filterLogic === "or") {
9729
+ out = out.filter((r2) => activeF.some(([col, f]) => testFilter(getColVal(col, r2), f.op, f.value, filterTypeOf(col))));
9730
+ } else {
9731
+ for (const [col, f] of activeF) out = out.filter((r2) => testFilter(getColVal(col, r2), f.op, f.value, filterTypeOf(col)));
9732
+ }
9694
9733
  }
9695
9734
  if (sort) {
9696
9735
  const col = colByField[sort.field];
@@ -9707,7 +9746,7 @@ function Datatable({
9707
9746
  out = [...out].sort((a, b) => (idx.get(keyOf(a)) ?? 1e9) - (idx.get(keyOf(b)) ?? 1e9));
9708
9747
  }
9709
9748
  return out;
9710
- }, [rows, quick, filters, sort, visibleCols, colByField, serverMode, rowOrder, searchFields]);
9749
+ }, [rows, quick, filters, filterLogic, sort, visibleCols, colByField, serverMode, rowOrder, searchFields]);
9711
9750
  const paginated = pageSize > 0;
9712
9751
  const serverTotal = rowCount == null ? processed.length : rowCount;
9713
9752
  const totalRows = serverMode ? serverTotal : processed.length;
@@ -9982,6 +10021,8 @@ function Datatable({
9982
10021
  pageSize: sizeVal,
9983
10022
  sort,
9984
10023
  filters: filters.map(({ id, ...f }) => f),
10024
+ filterLogic,
10025
+ // #303: "and" (default) | "or" — the server groups its WHERE accordingly
9985
10026
  quickFilter: quick.trim(),
9986
10027
  visibleColumns,
9987
10028
  hiddenColumns
@@ -9989,7 +10030,7 @@ function Datatable({
9989
10030
  });
9990
10031
  }, 250);
9991
10032
  return () => clearTimeout(t);
9992
- }, [serverMode, pageVal, sizeVal, sort, filters, quick, visibleColumns, hiddenColumns]);
10033
+ }, [serverMode, pageVal, sizeVal, sort, filters, filterLogic, quick, visibleColumns, hiddenColumns]);
9993
10034
  const onColVisRef = React51__namespace.default.useRef(onColumnVisibilityChange);
9994
10035
  onColVisRef.current = onColumnVisibilityChange;
9995
10036
  const lastVisibleKey = React51__namespace.default.useRef(null);
@@ -10403,7 +10444,9 @@ function Datatable({
10403
10444
  if (!editing) return;
10404
10445
  const onDown = (e) => {
10405
10446
  if (e.target.closest(".twc-dt__editor-wrap") || e.target.closest(".twc-pop")) return;
10406
- setEditing(null);
10447
+ const col = colByField[editing.field];
10448
+ if (col && col.renderEditCell) setEditing(null);
10449
+ else commitEdit();
10407
10450
  };
10408
10451
  document.addEventListener("mousedown", onDown, true);
10409
10452
  return () => document.removeEventListener("mousedown", onDown, true);
@@ -10647,6 +10690,96 @@ function Datatable({
10647
10690
  }
10648
10691
  };
10649
10692
  const hasFilterSizeOverride = fWidths.col != null || fWidths.op != null || fWidths.val != null || fPanelSize != null;
10693
+ const POP_MIN_W = { columns: 240, agg: 240, pivot: 260, batchedit: 260 };
10694
+ const popMinW = (id) => POP_MIN_W[id] || 200;
10695
+ const clearPop = (id, node) => {
10696
+ if (node) {
10697
+ node.style.removeProperty("--twc-dt-pop-w");
10698
+ node.style.removeProperty("--twc-dt-pop-h");
10699
+ node.removeAttribute("data-pop-sized");
10700
+ }
10701
+ setPopSizes((s) => {
10702
+ if (!(id in s)) return s;
10703
+ const n = { ...s };
10704
+ delete n[id];
10705
+ return n;
10706
+ });
10707
+ };
10708
+ const startPopResize = (id) => (e) => {
10709
+ if (e.button != null && e.button !== 0) return;
10710
+ e.preventDefault();
10711
+ e.stopPropagation();
10712
+ const pop = e.currentTarget.closest(".twc-dt__pop");
10713
+ if (!pop) return;
10714
+ const grip = e.currentTarget;
10715
+ const startX = e.clientX, startY = e.clientY;
10716
+ const r2 = pop.getBoundingClientRect();
10717
+ const startW = r2.width, startH = r2.height;
10718
+ const dir = typeof getComputedStyle !== "undefined" && getComputedStyle(pop).direction === "rtl" ? -1 : 1;
10719
+ pop.style.setProperty("--twc-dt-pop-w", `${startW}px`);
10720
+ pop.style.setProperty("--twc-dt-pop-h", `${startH}px`);
10721
+ grip.setAttribute("data-active", "true");
10722
+ pop.setAttribute("data-pop-sized", "");
10723
+ let lw = startW, lh = startH;
10724
+ const onMove = (ev) => {
10725
+ lw = clampNum(startW + (ev.clientX - startX) * dir, popMinW(id), fMaxW());
10726
+ lh = clampNum(startH + (ev.clientY - startY), 120, fMaxH());
10727
+ pop.style.setProperty("--twc-dt-pop-w", `${lw}px`);
10728
+ pop.style.setProperty("--twc-dt-pop-h", `${lh}px`);
10729
+ };
10730
+ const onUp = () => {
10731
+ setPopSizes((s) => ({ ...s, [id]: { w: lw, h: lh } }));
10732
+ grip.removeAttribute("data-active");
10733
+ window.removeEventListener("pointermove", onMove);
10734
+ window.removeEventListener("pointerup", onUp);
10735
+ };
10736
+ window.addEventListener("pointermove", onMove);
10737
+ window.addEventListener("pointerup", onUp);
10738
+ };
10739
+ const onPopGripKey = (id) => (e) => {
10740
+ if (e.key === "Enter" || e.key === " " || e.key === "Backspace") {
10741
+ e.preventDefault();
10742
+ clearPop(id, e.currentTarget.closest(".twc-dt__pop"));
10743
+ return;
10744
+ }
10745
+ if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"].includes(e.key)) return;
10746
+ e.preventDefault();
10747
+ const pop = e.currentTarget.closest(".twc-dt__pop");
10748
+ if (!pop) return;
10749
+ const r2 = pop.getBoundingClientRect();
10750
+ const step = e.shiftKey ? 4 : 20;
10751
+ const dir = typeof getComputedStyle !== "undefined" && getComputedStyle(pop).direction === "rtl" ? -1 : 1;
10752
+ let w = r2.width, h = r2.height;
10753
+ if (e.key === "ArrowRight") w += step * dir;
10754
+ else if (e.key === "ArrowLeft") w -= step * dir;
10755
+ else if (e.key === "ArrowDown") h += step;
10756
+ else if (e.key === "ArrowUp") h -= step;
10757
+ else if (e.key === "Home") {
10758
+ w = popMinW(id);
10759
+ h = 120;
10760
+ } else if (e.key === "End") {
10761
+ w = fMaxW();
10762
+ h = fMaxH();
10763
+ }
10764
+ setPopSizes((s) => ({ ...s, [id]: { w: clampNum(w, popMinW(id), fMaxW()), h: clampNum(h, 120, fMaxH()) } }));
10765
+ };
10766
+ const popStyle = (id) => popSizes[id] ? { "--twc-dt-pop-w": `${popSizes[id].w}px`, "--twc-dt-pop-h": `${popSizes[id].h}px` } : null;
10767
+ const popGrip = (id) => resizablePopovers ? /* @__PURE__ */ jsxRuntime.jsx(
10768
+ "span",
10769
+ {
10770
+ className: "twc-dt__pop-grip",
10771
+ role: "slider",
10772
+ tabIndex: 0,
10773
+ "aria-label": "Resize panel (Enter or double-click to reset)",
10774
+ "aria-valuetext": popSizes[id] ? `Width ${Math.round(popSizes[id].w)} pixels, height ${Math.round(popSizes[id].h)} pixels` : "Default size",
10775
+ onPointerDown: startPopResize(id),
10776
+ onKeyDown: onPopGripKey(id),
10777
+ onDoubleClick: (e) => {
10778
+ e.preventDefault();
10779
+ clearPop(id, e.currentTarget.closest(".twc-dt__pop"));
10780
+ }
10781
+ }
10782
+ ) : null;
10650
10783
  const fieldHandle = (field, rowIdx) => resizableFilters && rowIdx === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
10651
10784
  "span",
10652
10785
  {
@@ -10769,7 +10902,7 @@ function Datatable({
10769
10902
  onDragEnd: reorderable ? () => setRowDrag({ from: null, over: null, after: false }) : void 0,
10770
10903
  onClick: (e) => handleRowClick(e, k, row),
10771
10904
  children: [
10772
- checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", "data-pin-edge": pins.left.length || showRowNum ? void 0 : "left", style: { insetInlineStart: 0, width: CHK_W }, children: [
10905
+ 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: [
10773
10906
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 4 }, children: [
10774
10907
  reorderable ? rowHandle(k, midIdx, row) : null,
10775
10908
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -10794,7 +10927,7 @@ function Datatable({
10794
10927
  ] }),
10795
10928
  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
10796
10929
  ] }) : null,
10797
- showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": pins.left.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: typeof ri === "number" ? (paginated || serverMode ? pageVal * sizeVal : 0) + ri + 1 : "" }) : null,
10930
+ 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,
10798
10931
  ordered.map((c, ci) => {
10799
10932
  const st = stickyOf(c.field);
10800
10933
  const val = getColVal(c, row);
@@ -11204,7 +11337,7 @@ function Datatable({
11204
11337
  onKeyDown: onGridKeyDown,
11205
11338
  children: [
11206
11339
  /* @__PURE__ */ jsxRuntime.jsx("thead", { ref: theadRef, children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", "aria-rowindex": 1, children: [
11207
- checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th", role: "columnheader", "aria-label": "Select", "data-pin": "left", "data-pin-edge": pins.left.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(
11340
+ 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(
11208
11341
  "span",
11209
11342
  {
11210
11343
  className: "twc-dt__check",
@@ -11224,7 +11357,7 @@ function Datatable({
11224
11357
  children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: allSel ? I.check : I.minus })
11225
11358
  }
11226
11359
  ) }) }) : null,
11227
- showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th twc-dt__rownum", role: "columnheader", "aria-label": "Row number", "data-pin": "left", "data-pin-edge": pins.left.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W, minWidth: NUM_W }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__th-inner", children: [
11360
+ 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: [
11228
11361
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__th-label", style: { flex: "none", cursor: "default" }, children: "#" }),
11229
11362
  /* @__PURE__ */ jsxRuntime.jsx(
11230
11363
  "button",
@@ -11402,8 +11535,8 @@ function Datatable({
11402
11535
  pinnedBottomRows.map((row) => renderLeaf(row, keyIndex.get(keyOf(row)), "bottom"))
11403
11536
  ] }) }),
11404
11537
  hasAggregation && aggOn && !loading && paged.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("tfoot", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", children: [
11405
- checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge": pins.left.length || showRowNum ? void 0 : "left", style: { insetInlineStart: 0, width: CHK_W } }) : null,
11406
- showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": pins.left.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W } }) : null,
11538
+ 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,
11539
+ 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,
11407
11540
  ordered.map((c) => {
11408
11541
  const st = stickyOf(c.field);
11409
11542
  const v = aggregate(c);
@@ -11502,7 +11635,7 @@ function Datatable({
11502
11635
  delete values[f];
11503
11636
  return { ...b, fields, values };
11504
11637
  });
11505
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pop twc-dt__cfg", style: { top: batchEditPos.top, left: batchEditPos.left, width: 320 }, children: [
11638
+ 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: [
11506
11639
  /* @__PURE__ */ jsxRuntime.jsx(Caret, { pos: batchEditPos }),
11507
11640
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-head", children: [
11508
11641
  "Edit ",
@@ -11564,7 +11697,8 @@ function Datatable({
11564
11697
  "Apply to ",
11565
11698
  selected.size
11566
11699
  ] })
11567
- ] })
11700
+ ] }),
11701
+ popGrip("batchedit")
11568
11702
  ] });
11569
11703
  })() : null,
11570
11704
  colMenu && menuPos ? /* @__PURE__ */ jsxRuntime.jsxs(
@@ -11737,7 +11871,7 @@ function Datatable({
11737
11871
  ]
11738
11872
  }
11739
11873
  ) : null,
11740
- 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: [
11874
+ 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: [
11741
11875
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__panel-head", children: [
11742
11876
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-dt__panel-title", children: [
11743
11877
  "Columns ",
@@ -11862,9 +11996,10 @@ function Datatable({
11862
11996
  c.field
11863
11997
  );
11864
11998
  })
11865
- ] })
11999
+ ] }),
12000
+ popGrip("columns")
11866
12001
  ] }) : null,
11867
- 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: [
12002
+ 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: [
11868
12003
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__panel-head", children: [
11869
12004
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__panel-title", children: "Aggregation" }),
11870
12005
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__link", onClick: () => setAggConfig({}), children: "Clear" })
@@ -11913,13 +12048,14 @@ function Datatable({
11913
12048
  }
11914
12049
  ) })
11915
12050
  ] }, c.field);
11916
- }) })
12051
+ }) }),
12052
+ popGrip("agg")
11917
12053
  ] }) : null,
11918
12054
  panel === "pivot" && panelPos ? (() => {
11919
12055
  const fieldOpts = ordered.filter((c) => c.type !== "actions").map((c) => ({ value: c.field, label: c.headerName }));
11920
12056
  const aggOpts = [{ value: "sum", label: "Sum" }, { value: "avg", label: "Avg" }, { value: "min", label: "Min" }, { value: "max", label: "Max" }, { value: "count", label: "Count" }];
11921
12057
  const valueFieldOpts = ordered.filter((c) => c.type !== "actions" && !pivotConfig.values.some((v) => v.field === c.field)).map((c) => ({ value: c.field, label: c.headerName }));
11922
- 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: [
12058
+ 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: [
11923
12059
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__panel-head", children: [
11924
12060
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__panel-title", children: "Pivot" }),
11925
12061
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__link", onClick: () => {
@@ -11927,106 +12063,109 @@ function Datatable({
11927
12063
  setPivotOn(false);
11928
12064
  }, children: "Reset" })
11929
12065
  ] }),
11930
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-toggle", children: [
11931
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Pivot mode" }),
11932
- /* @__PURE__ */ jsxRuntime.jsx(
11933
- "span",
11934
- {
11935
- className: "twc-dt__sw",
11936
- "data-on": pivotOn || void 0,
11937
- role: "switch",
11938
- "aria-checked": pivotOn,
11939
- tabIndex: 0,
11940
- onClick: () => setPivotOn((v) => !v),
11941
- onKeyDown: (e) => {
11942
- if (e.key === "Enter" || e.key === " ") {
11943
- e.preventDefault();
11944
- setPivotOn((v) => !v);
12066
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__pivot-body", children: [
12067
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-toggle", children: [
12068
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Pivot mode" }),
12069
+ /* @__PURE__ */ jsxRuntime.jsx(
12070
+ "span",
12071
+ {
12072
+ className: "twc-dt__sw",
12073
+ "data-on": pivotOn || void 0,
12074
+ role: "switch",
12075
+ "aria-checked": pivotOn,
12076
+ tabIndex: 0,
12077
+ onClick: () => setPivotOn((v) => !v),
12078
+ onKeyDown: (e) => {
12079
+ if (e.key === "Enter" || e.key === " ") {
12080
+ e.preventDefault();
12081
+ setPivotOn((v) => !v);
12082
+ }
11945
12083
  }
11946
12084
  }
11947
- }
11948
- )
11949
- ] }),
11950
- !pivotActive && pivotOn ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-hint", children: [
11951
- "Add at least one ",
11952
- /* @__PURE__ */ jsxRuntime.jsx("b", { children: "Row" }),
11953
- " field and one ",
11954
- /* @__PURE__ */ jsxRuntime.jsx("b", { children: "Value" }),
11955
- " to see the pivot."
11956
- ] }) : null,
11957
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
11958
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Rows" }),
11959
- /* @__PURE__ */ jsxRuntime.jsx(
11960
- MultiSelect,
11961
- {
11962
- portal: true,
11963
- placeholder: "Add row fields\u2026",
11964
- value: pivotConfig.rows,
11965
- options: fieldOpts,
11966
- onChange: (vals) => {
11967
- setPivotConfig((p) => ({ ...p, rows: vals }));
11968
- if (vals.length) setPivotOn(true);
11969
- }
11970
- }
11971
- )
11972
- ] }),
11973
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
11974
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Columns" }),
11975
- /* @__PURE__ */ jsxRuntime.jsx(
11976
- MultiSelect,
11977
- {
11978
- portal: true,
11979
- placeholder: "Add column fields\u2026",
11980
- value: pivotConfig.columns,
11981
- options: fieldOpts,
11982
- onChange: (vals) => setPivotConfig((p) => ({ ...p, columns: vals }))
11983
- }
11984
- )
11985
- ] }),
11986
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
11987
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Values" }),
11988
- pivotConfig.values.map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-row", children: [
11989
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-name", children: colByField[v.field]?.headerName || v.field }),
11990
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__cfg-ctl", children: /* @__PURE__ */ jsxRuntime.jsx(
11991
- Select,
12085
+ )
12086
+ ] }),
12087
+ !pivotActive && pivotOn ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-hint", children: [
12088
+ "Add at least one ",
12089
+ /* @__PURE__ */ jsxRuntime.jsx("b", { children: "Row" }),
12090
+ " field and one ",
12091
+ /* @__PURE__ */ jsxRuntime.jsx("b", { children: "Value" }),
12092
+ " to see the pivot."
12093
+ ] }) : null,
12094
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
12095
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Rows" }),
12096
+ /* @__PURE__ */ jsxRuntime.jsx(
12097
+ MultiSelect,
11992
12098
  {
11993
- size: "sm",
11994
- value: v.agg || "sum",
11995
- options: aggOpts,
11996
12099
  portal: true,
11997
- onChange: (a) => setPivotConfig((p) => ({ ...p, values: p.values.map((x, j) => j === i ? { ...x, agg: a } : x) }))
12100
+ placeholder: "Add row fields\u2026",
12101
+ value: pivotConfig.rows,
12102
+ options: fieldOpts,
12103
+ onChange: (vals) => {
12104
+ setPivotConfig((p) => ({ ...p, rows: vals }));
12105
+ if (vals.length) setPivotOn(true);
12106
+ }
11998
12107
  }
11999
- ) }),
12108
+ )
12109
+ ] }),
12110
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
12111
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Columns" }),
12000
12112
  /* @__PURE__ */ jsxRuntime.jsx(
12001
- "button",
12113
+ MultiSelect,
12002
12114
  {
12003
- type: "button",
12004
- className: "twc-dt__cfg-x",
12005
- "aria-label": `Remove ${colByField[v.field]?.headerName || v.field}`,
12006
- onClick: () => setPivotConfig((p) => ({ ...p, values: p.values.filter((_, j) => j !== i) })),
12007
- children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.x })
12115
+ portal: true,
12116
+ placeholder: "Add column fields\u2026",
12117
+ value: pivotConfig.columns,
12118
+ options: fieldOpts,
12119
+ onChange: (vals) => setPivotConfig((p) => ({ ...p, columns: vals }))
12008
12120
  }
12009
12121
  )
12010
- ] }, v.field + i)),
12011
- valueFieldOpts.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__cfg-add", children: /* @__PURE__ */ jsxRuntime.jsx(
12012
- Select,
12013
- {
12014
- size: "sm",
12015
- placeholder: "Add value field\u2026",
12016
- value: "",
12017
- options: valueFieldOpts,
12018
- portal: true,
12019
- searchable: true,
12020
- searchPlaceholder: "Search fields\u2026",
12021
- onChange: (f) => {
12022
- if (f) {
12023
- setPivotConfig((p) => p.values.some((x) => x.field === f) ? p : { ...p, values: [...p.values, { field: f, agg: "sum" }] });
12024
- setPivotOn(true);
12122
+ ] }),
12123
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-section", children: [
12124
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-label", children: "Values" }),
12125
+ pivotConfig.values.map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__cfg-row", children: [
12126
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__cfg-name", children: colByField[v.field]?.headerName || v.field }),
12127
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__cfg-ctl", children: /* @__PURE__ */ jsxRuntime.jsx(
12128
+ Select,
12129
+ {
12130
+ size: "sm",
12131
+ value: v.agg || "sum",
12132
+ options: aggOpts,
12133
+ portal: true,
12134
+ onChange: (a) => setPivotConfig((p) => ({ ...p, values: p.values.map((x, j) => j === i ? { ...x, agg: a } : x) }))
12135
+ }
12136
+ ) }),
12137
+ /* @__PURE__ */ jsxRuntime.jsx(
12138
+ "button",
12139
+ {
12140
+ type: "button",
12141
+ className: "twc-dt__cfg-x",
12142
+ "aria-label": `Remove ${colByField[v.field]?.headerName || v.field}`,
12143
+ onClick: () => setPivotConfig((p) => ({ ...p, values: p.values.filter((_, j) => j !== i) })),
12144
+ children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.x })
12145
+ }
12146
+ )
12147
+ ] }, v.field + i)),
12148
+ valueFieldOpts.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__cfg-add", children: /* @__PURE__ */ jsxRuntime.jsx(
12149
+ Select,
12150
+ {
12151
+ size: "sm",
12152
+ placeholder: "Add value field\u2026",
12153
+ value: "",
12154
+ options: valueFieldOpts,
12155
+ portal: true,
12156
+ searchable: true,
12157
+ searchPlaceholder: "Search fields\u2026",
12158
+ onChange: (f) => {
12159
+ if (f) {
12160
+ setPivotConfig((p) => p.values.some((x) => x.field === f) ? p : { ...p, values: [...p.values, { field: f, agg: "sum" }] });
12161
+ setPivotOn(true);
12162
+ }
12025
12163
  }
12026
12164
  }
12027
- }
12028
- ) }) : null
12029
- ] })
12165
+ ) }) : null
12166
+ ] })
12167
+ ] }),
12168
+ popGrip("pivot")
12030
12169
  ] });
12031
12170
  })() : null,
12032
12171
  panel === "filters" && panelPos ? /* @__PURE__ */ jsxRuntime.jsxs(
@@ -12050,7 +12189,11 @@ function Datatable({
12050
12189
  children: [
12051
12190
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__panel-head", children: [
12052
12191
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__panel-title", children: "Filters" }),
12053
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", gap: 2 }, children: [
12192
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 6 }, children: [
12193
+ filters.length > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-dt__flogic", role: "group", "aria-label": "Combine filters with", children: [
12194
+ /* @__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" }),
12195
+ /* @__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" })
12196
+ ] }) : null,
12054
12197
  resizableFilters && hasFilterSizeOverride ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__link", onClick: resetFilterSizes, children: "Reset sizes" }) : null,
12055
12198
  filters.length ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__link", onClick: () => setFilters([]), children: "Clear all" }) : null
12056
12199
  ] })
@@ -12123,6 +12266,7 @@ function Datatable({
12123
12266
  ),
12124
12267
  fieldHandle("val", i)
12125
12268
  ] }),
12269
+ /* @__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 }) }),
12126
12270
  /* @__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 }) })
12127
12271
  ] }, f.id);
12128
12272
  }) }),