@ai-matrx/design-system 0.49.12 → 0.49.18

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/data-table/copy-helpers.d.cts +1 -1
  3. package/dist/data-table/copy-helpers.d.ts +1 -1
  4. package/dist/data-table/facets.cjs +2 -0
  5. package/dist/data-table/facets.cjs.map +1 -1
  6. package/dist/data-table/facets.d.cts +3 -1
  7. package/dist/data-table/facets.d.ts +3 -1
  8. package/dist/data-table/facets.js +2 -0
  9. package/dist/data-table/facets.js.map +1 -1
  10. package/dist/data-table/filter-engine.d.cts +1 -1
  11. package/dist/data-table/filter-engine.d.ts +1 -1
  12. package/dist/data-table/host.d.cts +1 -1
  13. package/dist/data-table/host.d.ts +1 -1
  14. package/dist/data-table/index.cjs +501 -325
  15. package/dist/data-table/index.cjs.map +1 -1
  16. package/dist/data-table/index.d.cts +7 -3
  17. package/dist/data-table/index.d.ts +7 -3
  18. package/dist/data-table/index.js +432 -256
  19. package/dist/data-table/index.js.map +1 -1
  20. package/dist/data-table/infer-filter.d.cts +1 -1
  21. package/dist/data-table/infer-filter.d.ts +1 -1
  22. package/dist/data-table/layered-filters.d.cts +1 -1
  23. package/dist/data-table/layered-filters.d.ts +1 -1
  24. package/dist/data-table/menu-targets.cjs.map +1 -1
  25. package/dist/data-table/menu-targets.d.cts +5 -0
  26. package/dist/data-table/menu-targets.d.ts +5 -0
  27. package/dist/data-table/menu-targets.js.map +1 -1
  28. package/dist/data-table/query-control.d.cts +1 -1
  29. package/dist/data-table/query-control.d.ts +1 -1
  30. package/dist/data-table/types.cjs.map +1 -1
  31. package/dist/data-table/types.d.cts +1 -1
  32. package/dist/data-table/types.d.ts +1 -1
  33. package/dist/data-table/url-state.d.cts +1 -1
  34. package/dist/data-table/url-state.d.ts +1 -1
  35. package/dist/data-table/xlsx.d.cts +1 -1
  36. package/dist/data-table/xlsx.d.ts +1 -1
  37. package/dist/{layered-filters-B-znwvFV.d.cts → layered-filters-BltsILT3.d.cts} +7 -1
  38. package/dist/{layered-filters-Dhfam7uI.d.ts → layered-filters-DrGJ_nuG.d.ts} +7 -1
  39. package/package.json +1 -1
@@ -34006,12 +34006,12 @@ import {
34006
34006
  isValidElement as isValidElement2,
34007
34007
  memo,
34008
34008
  useCallback as useCallback10,
34009
- useEffect as useEffect21,
34009
+ useEffect as useEffect22,
34010
34010
  useId as useId3,
34011
34011
  useLayoutEffect as useLayoutEffect5,
34012
34012
  useMemo as useMemo11,
34013
- useRef as useRef20,
34014
- useState as useState25
34013
+ useRef as useRef21,
34014
+ useState as useState26
34015
34015
  } from "react";
34016
34016
  import { createPortal as createPortal3 } from "react-dom";
34017
34017
  import {
@@ -35104,7 +35104,11 @@ function TableTitleRow({
35104
35104
  "data-matrx-table-toolbar": true,
35105
35105
  className: cn(
35106
35106
  "relative flex min-w-0 shrink-0 items-center gap-2",
35107
- singleRow ? "flex-nowrap overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden" : "flex-wrap",
35107
+ // `max-w-full`: drawn into a page's row slot (`portalInto`), the row is held to the slot's
35108
+ // width, so IT is the scroller its pinned controls stick to — never a row as wide as its
35109
+ // content inside a narrower slot, where "sticky" had nothing to stick to and "New record"
35110
+ // sat past the slot's edge, cut to "N" (merged-grid leftovers, 2026-09-28).
35111
+ singleRow ? "max-w-full flex-nowrap overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden" : "flex-wrap",
35108
35112
  // ONE CONTROL HEIGHT ON A TOOLBAR ROW (lane C, review 2026-09-26: 28/32/44 mixed): a host's
35109
35113
  // tap-target toolbar actions draw at 32px like every other control; a finger (coarse
35110
35114
  // pointer) keeps the 44px floor.
@@ -36597,7 +36601,7 @@ function GenericTablePagination({
36597
36601
  // src/data-table/TableViewTabs.tsx
36598
36602
  import { useEffect as useEffect5, useRef as useRef6, useState as useState8 } from "react";
36599
36603
  import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
36600
- function TableViewTabs({ tabs, activeId, onSelect, onAdd, onClose, onRename, related, editingId, onEditCancel, onEditDone }) {
36604
+ function TableViewTabs({ tabs, activeId, onSelect, onAdd, onClose, onRename, related, editingId, onEditCancel, onEditDone, closable = true, addHint = "New view from the current one \xB7 double-click a tab to rename", renameable = true }) {
36601
36605
  const [renaming, setRenaming] = useState8(null);
36602
36606
  const [draft, setDraft] = useState8("");
36603
36607
  const opened = useRef6(null);
@@ -36648,8 +36652,10 @@ function TableViewTabs({ tabs, activeId, onSelect, onAdd, onClose, onRename, rel
36648
36652
  tabIndex: tab.id === activeId ? 0 : -1,
36649
36653
  onClick: () => onSelect(tab.id),
36650
36654
  onDoubleClick: () => {
36651
- setDraft(tab.label);
36652
- setRenaming(tab.id);
36655
+ if (renameable && tab.id !== "default") {
36656
+ setDraft(tab.label);
36657
+ setRenaming(tab.id);
36658
+ }
36653
36659
  },
36654
36660
  onKeyDown: (e) => {
36655
36661
  const next = e.key === "ArrowRight" ? (index + 1) % tabs.length : e.key === "ArrowLeft" ? (index + tabs.length - 1) % tabs.length : e.key === "Home" ? 0 : e.key === "End" ? tabs.length - 1 : -1;
@@ -36667,7 +36673,7 @@ function TableViewTabs({ tabs, activeId, onSelect, onAdd, onClose, onRename, rel
36667
36673
  ]
36668
36674
  }
36669
36675
  ),
36670
- tabs.length > 1 && tab.id !== "default" && /* @__PURE__ */ jsxs16(Tooltip, { children: [
36676
+ closable && tabs.length > 1 && tab.id !== "default" && /* @__PURE__ */ jsxs16(Tooltip, { children: [
36671
36677
  /* @__PURE__ */ jsx24(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx24("button", { type: "button", "aria-label": `Close ${tab.label}`, onClick: () => onClose(tab.id), className: "flex size-7 items-center justify-center rounded hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring", children: /* @__PURE__ */ jsx24(X, { className: "size-4" }) }) }),
36672
36678
  /* @__PURE__ */ jsxs16(TooltipContent, { children: [
36673
36679
  "Close ",
@@ -36677,7 +36683,7 @@ function TableViewTabs({ tabs, activeId, onSelect, onAdd, onClose, onRename, rel
36677
36683
  ] }, tab.id)),
36678
36684
  /* @__PURE__ */ jsxs16(Tooltip, { children: [
36679
36685
  /* @__PURE__ */ jsx24(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx24("button", { type: "button", "aria-label": "New table tab", onClick: onAdd, className: "flex size-8 shrink-0 items-center justify-center rounded hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring", children: /* @__PURE__ */ jsx24(Plus, { className: "size-4" }) }) }),
36680
- /* @__PURE__ */ jsx24(TooltipContent, { children: "New view from the current one \xB7 double-click a tab to rename" })
36686
+ /* @__PURE__ */ jsx24(TooltipContent, { children: addHint })
36681
36687
  ] })
36682
36688
  ] }),
36683
36689
  related && /* @__PURE__ */ jsx24("div", { className: "flex shrink-0 items-center gap-1 border-l px-2", children: related })
@@ -42117,6 +42123,7 @@ CommandShortcut.displayName = "CommandShortcut";
42117
42123
  var MAX_LISTABLE_FACET_LENGTH = 300;
42118
42124
  var DEFAULT_FACET_LIMIT = 200;
42119
42125
  var MAX_FACET_LIMIT = 500;
42126
+ var CORE_SUGGESTION_DISTINCT_EXCLUSIVE_LIMIT = 15;
42120
42127
  function facetText(raw) {
42121
42128
  if (raw === null || raw === void 0) return "";
42122
42129
  if (typeof raw === "object") {
@@ -42243,6 +42250,7 @@ function HeaderMenuItems({
42243
42250
  const disabled = Boolean(item.disabledReason);
42244
42251
  const hasSubmenu = Boolean(item.submenu && item.submenu.length > 0);
42245
42252
  return /* @__PURE__ */ jsxs28("div", { className: "flex flex-col", children: [
42253
+ item.separatorBefore ? /* @__PURE__ */ jsx38("div", { role: "separator", className: "-mx-1 my-1 h-px bg-border" }) : null,
42246
42254
  /* @__PURE__ */ jsxs28(
42247
42255
  Button,
42248
42256
  {
@@ -42312,7 +42320,7 @@ function ColumnHeaderCell({
42312
42320
  compact = false,
42313
42321
  marker,
42314
42322
  filterApplyLabel,
42315
- filterShowCancel = false,
42323
+ filterShowCancel,
42316
42324
  filterFooterHint,
42317
42325
  allowNegation = false,
42318
42326
  allowNullModes = false,
@@ -42350,7 +42358,8 @@ function ColumnHeaderCell({
42350
42358
  } : void 0;
42351
42359
  const reorderClass = reorderEnabled ? "touch-none cursor-grab active:cursor-grabbing" : void 0;
42352
42360
  const filterActive = isColumnFilterActive(filterValue);
42353
- const deferredFilter = filterApplyLabel !== void 0 || filterShowCancel || filterFooterHint !== void 0;
42361
+ const deferredFilter = filterKind === "text" || filterApplyLabel !== void 0 || Boolean(filterShowCancel) || filterFooterHint !== void 0;
42362
+ const showFilterCancel = filterShowCancel ?? filterKind === "text";
42354
42363
  const [filterOpen, setFilterOpen] = useState17(false);
42355
42364
  const [pendingNegation, setPendingNegation] = useState17(false);
42356
42365
  const [draftFilter, setDraftFilter] = useState17(filterValue);
@@ -42511,7 +42520,7 @@ function ColumnHeaderCell({
42511
42520
  filterKind && deferredFilter ? /* @__PURE__ */ jsxs28("div", { className: "mt-2 border-t border-border pt-2", children: [
42512
42521
  filterFooterHint ? /* @__PURE__ */ jsx38("div", { className: "mb-2 text-xs text-muted-foreground", children: filterFooterHint }) : null,
42513
42522
  /* @__PURE__ */ jsxs28("div", { className: "flex justify-end gap-2", children: [
42514
- filterShowCancel ? /* @__PURE__ */ jsx38(Button, { type: "button", variant: "ghost", size: "sm", onClick: cancelFilter, children: "Cancel" }) : null,
42523
+ showFilterCancel ? /* @__PURE__ */ jsx38(Button, { type: "button", variant: "ghost", size: "sm", onClick: cancelFilter, children: "Cancel" }) : null,
42515
42524
  /* @__PURE__ */ jsx38(Button, { type: "button", size: "sm", onClick: applyFilter, children: filterApplyLabel ?? "Apply" })
42516
42525
  ] })
42517
42526
  ] }) : null,
@@ -42858,7 +42867,7 @@ function FacetChecklist({
42858
42867
  onChange
42859
42868
  }) {
42860
42869
  const [query, setQuery] = useState17("");
42861
- const selected = value?.kind === "select" ? value.values ?? (value.value && value.value !== "__all__" ? [value.value] : []) : [];
42870
+ const selected = value?.kind === "select" ? (value.values ?? (value.value && value.value !== "__all__" ? [value.value] : [])).map((candidate) => candidate === SELECT_EMPTY_VALUE ? "" : candidate) : [];
42862
42871
  const selectedSet = new Set(selected);
42863
42872
  const rows = useMemo8(() => {
42864
42873
  if (!facets) return [];
@@ -42876,7 +42885,7 @@ function FacetChecklist({
42876
42885
  const next = new Set(selectedSet);
42877
42886
  if (next.has(candidate)) next.delete(candidate);
42878
42887
  else next.add(candidate);
42879
- const values = [...next];
42888
+ const values = [...next].map((value2) => value2 === "" ? SELECT_EMPTY_VALUE : value2);
42880
42889
  onChange(
42881
42890
  values.length === 0 ? void 0 : { kind: "select", value: values[0] ?? "", values }
42882
42891
  );
@@ -45442,6 +45451,62 @@ function ToolbarListedLabel({ label, children }) {
45442
45451
  ] });
45443
45452
  }
45444
45453
 
45454
+ // src/data-table/pinned-fold.ts
45455
+ import { useEffect as useEffect17, useRef as useRef18, useState as useState21 } from "react";
45456
+ function pinnedMustFold(room, full) {
45457
+ if (room <= 0 || full === null) return false;
45458
+ return full > room + 0.5;
45459
+ }
45460
+ function usePinnedFold(el, active) {
45461
+ const [folded, setFolded] = useState21(false);
45462
+ const full = useRef18(null);
45463
+ const current = useRef18(false);
45464
+ useEffect17(() => {
45465
+ if (!active || !el) {
45466
+ if (current.current) {
45467
+ current.current = false;
45468
+ setFolded(false);
45469
+ }
45470
+ return;
45471
+ }
45472
+ const row = el.closest("[data-matrx-table-toolbar]") ?? el.parentElement;
45473
+ if (!row) return;
45474
+ let pending = 0;
45475
+ let stopped = false;
45476
+ const measure = () => {
45477
+ pending = 0;
45478
+ if (stopped) return;
45479
+ if (!current.current) {
45480
+ const width = Math.max(el.getBoundingClientRect().width || 0, el.scrollWidth || 0);
45481
+ if (width > 0) full.current = width;
45482
+ }
45483
+ const next = pinnedMustFold(row.clientWidth, full.current);
45484
+ if (next !== current.current) {
45485
+ current.current = next;
45486
+ setFolded(next);
45487
+ }
45488
+ };
45489
+ const schedule = () => {
45490
+ if (pending) return;
45491
+ pending = typeof requestAnimationFrame === "function" && typeof document !== "undefined" && document.visibilityState !== "hidden" ? requestAnimationFrame(measure) : setTimeout(measure, 0);
45492
+ };
45493
+ const sizes = typeof ResizeObserver === "function" ? new ResizeObserver(schedule) : null;
45494
+ sizes?.observe(row);
45495
+ sizes?.observe(el);
45496
+ const content = typeof MutationObserver === "function" ? new MutationObserver(schedule) : null;
45497
+ content?.observe(el, { childList: true, subtree: true, characterData: true });
45498
+ if (typeof window !== "undefined") window.addEventListener("resize", schedule);
45499
+ measure();
45500
+ return () => {
45501
+ stopped = true;
45502
+ sizes?.disconnect();
45503
+ content?.disconnect();
45504
+ if (typeof window !== "undefined") window.removeEventListener("resize", schedule);
45505
+ };
45506
+ }, [el, active]);
45507
+ return folded;
45508
+ }
45509
+
45445
45510
  // src/data-table/coverage.ts
45446
45511
  var PARTIAL_BADGE = "Partial";
45447
45512
  var UNKNOWN_TOTAL_BADGE = "Unknown total";
@@ -45590,7 +45655,7 @@ function rankTableSearchRows(rows, columns, query, options = {}, extraText) {
45590
45655
  }
45591
45656
 
45592
45657
  // src/data-table/ColumnManager.tsx
45593
- import { useEffect as useEffect17, useMemo as useMemo10, useState as useState21 } from "react";
45658
+ import { useEffect as useEffect18, useMemo as useMemo10, useState as useState22 } from "react";
45594
45659
  import { useDndMonitor, useDraggable as useDraggable2, useDroppable } from "@dnd-kit/core";
45595
45660
  import { jsx as jsx43, jsxs as jsxs32 } from "react/jsx-runtime";
45596
45661
  function ColumnManager({
@@ -45605,11 +45670,11 @@ function ColumnManager({
45605
45670
  () => new Map(columns.map((column) => [columnId(column), column])),
45606
45671
  [columns]
45607
45672
  );
45608
- const [draftOrder, setDraftOrder] = useState21(order);
45609
- const [draftHidden, setDraftHidden] = useState21(() => new Set(hidden));
45610
- const [draggedColumnId, setDraggedColumnId] = useState21(null);
45611
- const [dropTarget, setDropTarget] = useState21(null);
45612
- useEffect17(() => {
45673
+ const [draftOrder, setDraftOrder] = useState22(order);
45674
+ const [draftHidden, setDraftHidden] = useState22(() => new Set(hidden));
45675
+ const [draggedColumnId, setDraggedColumnId] = useState22(null);
45676
+ const [dropTarget, setDropTarget] = useState22(null);
45677
+ useEffect18(() => {
45613
45678
  if (!open) return;
45614
45679
  setDraftOrder(order);
45615
45680
  setDraftHidden(new Set(hidden));
@@ -46096,7 +46161,7 @@ var layeredRuleSchema = z2.object({ id: z2.string().min(1), field: z2.string().m
46096
46161
  var snapshotSchema = z2.object({
46097
46162
  __kind: z2.literal("matrx-table-view"),
46098
46163
  version: z2.literal(1),
46099
- query: z2.object({ pageSize: z2.number().int().positive(), search: z2.string(), searchMatchMode: z2.enum(["contains", "whole_words"]).optional(), searchScope: z2.string().min(1).optional(), anyOf: z2.string(), layeredFilters: z2.array(layeredRuleSchema).optional(), columnFilters: z2.record(z2.string(), filterSchema.optional()), sort: z2.object({ id: z2.string().min(1), direction: z2.enum(["asc", "desc"]) }).nullable() }),
46164
+ query: z2.object({ pageSize: z2.number().int().nonnegative(), search: z2.string(), searchMatchMode: z2.enum(["contains", "whole_words"]).optional(), searchScope: z2.string().min(1).optional(), anyOf: z2.string(), layeredFilters: z2.array(layeredRuleSchema).optional(), columnFilters: z2.record(z2.string(), filterSchema.optional()), sort: z2.object({ id: z2.string().min(1), direction: z2.enum(["asc", "desc"]) }).nullable() }),
46100
46165
  columns: z2.object({
46101
46166
  order: z2.array(z2.string().min(1)).refine((order) => new Set(order).size === order.length, {
46102
46167
  message: "Column order must not contain duplicate IDs"
@@ -46152,9 +46217,9 @@ function parseTableViewSnapshot(raw) {
46152
46217
 
46153
46218
  // src/data-table/MatrxUuidCell.tsx
46154
46219
  import {
46155
- useEffect as useEffect18,
46156
- useRef as useRef18,
46157
- useState as useState22
46220
+ useEffect as useEffect19,
46221
+ useRef as useRef19,
46222
+ useState as useState23
46158
46223
  } from "react";
46159
46224
  import { jsx as jsx44, jsxs as jsxs33 } from "react/jsx-runtime";
46160
46225
  var SHORT_LEN = 8;
@@ -46195,11 +46260,11 @@ function MatrxUuidCell({
46195
46260
  }) {
46196
46261
  const { resolveEntityDoors, ResourcePeek } = useMatrxDataTableHost();
46197
46262
  const { notify, notice } = useTableNotice();
46198
- const [copied, setCopied] = useState22(false);
46199
- const [opening, setOpening] = useState22(false);
46200
- const [peekOpen, setPeekOpen] = useState22(false);
46201
- const timer = useRef18(null);
46202
- useEffect18(
46263
+ const [copied, setCopied] = useState23(false);
46264
+ const [opening, setOpening] = useState23(false);
46265
+ const [peekOpen, setPeekOpen] = useState23(false);
46266
+ const timer = useRef19(null);
46267
+ useEffect19(
46203
46268
  () => () => {
46204
46269
  if (timer.current) clearTimeout(timer.current);
46205
46270
  },
@@ -46494,7 +46559,7 @@ function DataRowInspector({
46494
46559
  }
46495
46560
 
46496
46561
  // src/data-table/DataRowWindow.tsx
46497
- import { useEffect as useEffect19, useState as useState23 } from "react";
46562
+ import { useEffect as useEffect20, useState as useState24 } from "react";
46498
46563
  import { jsx as jsx46, jsxs as jsxs35 } from "react/jsx-runtime";
46499
46564
  function DataRowWindow({
46500
46565
  isOpen,
@@ -46515,8 +46580,8 @@ function DataRowWindow({
46515
46580
  const hasEdit = editContent != null;
46516
46581
  const hasTabs = hasEdit && children == null;
46517
46582
  const initialTab = defaultTab ?? (hasEdit ? "edit" : "view");
46518
- const [tab, setTab] = useState23(initialTab);
46519
- useEffect19(() => {
46583
+ const [tab, setTab] = useState24(initialTab);
46584
+ useEffect20(() => {
46520
46585
  if (!isOpen) return;
46521
46586
  setTab(defaultTab ?? (hasEdit ? "edit" : "view"));
46522
46587
  }, [isOpen, windowId, hasEdit, defaultTab]);
@@ -47761,7 +47826,7 @@ function DirtySavePill({
47761
47826
  }
47762
47827
 
47763
47828
  // src/data-table/EditableTableCell.tsx
47764
- import { useEffect as useEffect20, useRef as useRef19, useState as useState24 } from "react";
47829
+ import { useEffect as useEffect21, useRef as useRef20, useState as useState25 } from "react";
47765
47830
  import { jsx as jsx49, jsxs as jsxs38 } from "react/jsx-runtime";
47766
47831
  function CellRefusal({ reason }) {
47767
47832
  return /* @__PURE__ */ jsx49(
@@ -47823,12 +47888,12 @@ function EditableTableCell({
47823
47888
  editRequest,
47824
47889
  editSeed
47825
47890
  }) {
47826
- const [open, setOpen] = useState24(false);
47827
- const [refusal, setRefusal] = useState24(null);
47828
- useEffect20(() => {
47891
+ const [open, setOpen] = useState25(false);
47892
+ const [refusal, setRefusal] = useState25(null);
47893
+ useEffect21(() => {
47829
47894
  if (editRequest !== void 0) setOpen(true);
47830
47895
  }, [editRequest]);
47831
- useEffect20(() => {
47896
+ useEffect21(() => {
47832
47897
  if (!open) setRefusal(null);
47833
47898
  }, [open]);
47834
47899
  const usePencil = Boolean(href) || editTrigger === "pencil";
@@ -47932,13 +47997,13 @@ function InlineStringEditor({
47932
47997
  editRequest,
47933
47998
  editSeed
47934
47999
  }) {
47935
- const [editing, setEditing] = useState24(false);
47936
- const [draft, setDraft] = useState24(value);
47937
- const [refusal, setRefusal] = useState24(null);
47938
- const handledEditRequest = useRef19(void 0);
47939
- const seedRef = useRef19(editSeed);
48000
+ const [editing, setEditing] = useState25(false);
48001
+ const [draft, setDraft] = useState25(value);
48002
+ const [refusal, setRefusal] = useState25(null);
48003
+ const handledEditRequest = useRef20(void 0);
48004
+ const seedRef = useRef20(editSeed);
47940
48005
  seedRef.current = editSeed;
47941
- useEffect20(() => {
48006
+ useEffect21(() => {
47942
48007
  if (editRequest === void 0 || handledEditRequest.current === editRequest) return;
47943
48008
  handledEditRequest.current = editRequest;
47944
48009
  setDraft(seedRef.current ?? value);
@@ -48098,8 +48163,8 @@ function DateEditor({
48098
48163
  onCommit,
48099
48164
  onCancel
48100
48165
  }) {
48101
- const [draft, setDraft] = useState24(value);
48102
- const done = useRef19(false);
48166
+ const [draft, setDraft] = useState25(value);
48167
+ const done = useRef20(false);
48103
48168
  const finish = () => {
48104
48169
  if (done.current) return;
48105
48170
  done.current = true;
@@ -48134,8 +48199,8 @@ function TagsEditor({
48134
48199
  onCommit,
48135
48200
  onCancel
48136
48201
  }) {
48137
- const [tags, setTags] = useState24(value);
48138
- const [draft, setDraft] = useState24("");
48202
+ const [tags, setTags] = useState25(value);
48203
+ const [draft, setDraft] = useState25("");
48139
48204
  const add = (raw) => {
48140
48205
  const next = raw.trim();
48141
48206
  if (!next || tags.includes(next)) return;
@@ -48232,7 +48297,7 @@ function NumberEditor({
48232
48297
  onCommit,
48233
48298
  onCancel
48234
48299
  }) {
48235
- const [draft, setDraft] = useState24(String(value));
48300
+ const [draft, setDraft] = useState25(String(value));
48236
48301
  return /* @__PURE__ */ jsxs38("div", { className: "flex flex-col gap-2", children: [
48237
48302
  /* @__PURE__ */ jsx49(
48238
48303
  Input,
@@ -48636,6 +48701,7 @@ function safeQueryPage(requestedPage, totalItems, pageSize) {
48636
48701
 
48637
48702
  // src/data-table/MatrxDataTable.tsx
48638
48703
  import { Fragment as Fragment12, jsx as jsx51, jsxs as jsxs40 } from "react/jsx-runtime";
48704
+ var EMPTY_TABLE_ROWS = [];
48639
48705
  function TableToolbarAction({
48640
48706
  HostAction,
48641
48707
  ariaLabel,
@@ -48745,7 +48811,7 @@ function MatrxDataTableWithUrlState({
48745
48811
  ...urlState.history === void 0 ? {} : { history: urlState.history },
48746
48812
  ...urlState.textHistory === void 0 ? {} : { textHistory: urlState.textHistory }
48747
48813
  });
48748
- useEffect21(() => {
48814
+ useEffect22(() => {
48749
48815
  if (activeUrlTableIds.has(urlState.id)) {
48750
48816
  throw new Error(
48751
48817
  `Duplicate MatrxDataTable urlState.id "${urlState.id}" on one page. Give every table a unique stable id.`
@@ -48854,7 +48920,7 @@ var DND_MEASURING = { droppable: { strategy: MeasuringStrategy.Always } };
48854
48920
  var NO_LAYERED_FILTERS = [];
48855
48921
  var NO_GROUPING_VALUE = "__matrx_no_grouping__";
48856
48922
  function useRenderEpoch(values) {
48857
- const held = useRef20(null);
48923
+ const held = useRef21(null);
48858
48924
  const previous = held.current;
48859
48925
  if (previous !== null && previous.values.length === values.length && previous.values.every((value, i) => Object.is(value, values[i]))) {
48860
48926
  return previous.epoch;
@@ -48998,9 +49064,9 @@ function MatrxDataTableCore(coreProps) {
48998
49064
  } = coreProps;
48999
49065
  const appendQuery = query?.mode === "controlled-append" ? query : null;
49000
49066
  const appendQueryKey = appendQuery?.pagination.queryKey ?? null;
49001
- const committedAppendQueryKey = useRef20(appendQueryKey);
49067
+ const committedAppendQueryKey = useRef21(appendQueryKey);
49002
49068
  const appendSourceChanged = appendQuery !== null && committedAppendQueryKey.current !== appendQueryKey;
49003
- const data = (appendQuery ? appendQuery.pagination.rows : suppliedData) ?? [];
49069
+ const data = (appendQuery ? appendQuery.pagination.rows : suppliedData) ?? EMPTY_TABLE_ROWS;
49004
49070
  const readView = tableReadView(read, data.length, appendQuery ? appendQuery.pagination.loading : suppliedLoading);
49005
49071
  const isLoading = readView.loading;
49006
49072
  const isFetching = appendQuery ? appendQuery.pagination.isFetchingNextPage : suppliedFetching;
@@ -49011,19 +49077,21 @@ function MatrxDataTableCore(coreProps) {
49011
49077
  const ContextMenuBoundary = host.ContextMenuBoundary ?? TableContextPassthrough;
49012
49078
  const resolvedDensity = density ?? host.defaultDensity ?? "normal";
49013
49079
  const SavedViews = host.SavedViews;
49080
+ const savedViewsId = tableId ?? urlState?.id;
49081
+ const showViewTabs = viewTabs && Boolean(viewTabsStore || savedViewsId && SavedViews);
49014
49082
  const Link = host.Link ?? DefaultTableLink;
49015
49083
  const SidePanelSurface = host.SidePanelSurface ?? DefaultTableSidePanel;
49016
49084
  const { notify: toast, notice } = useTableNotice();
49017
- const [savedViewError, setSavedViewError] = useState25(null);
49018
- const [toolbarActionError, setToolbarActionError] = useState25(null);
49019
- const [toolbarActionPending, setToolbarActionPending] = useState25({ refresh: false, add: false });
49020
- const toolbarActionPendingRef = useRef20({ refresh: false, add: false });
49085
+ const [savedViewError, setSavedViewError] = useState26(null);
49086
+ const [toolbarActionError, setToolbarActionError] = useState26(null);
49087
+ const [toolbarActionPending, setToolbarActionPending] = useState26({ refresh: false, add: false });
49088
+ const toolbarActionPendingRef = useRef21({ refresh: false, add: false });
49021
49089
  const CHECKBOX_TAP_AREA = "h-4 w-4 touch-manipulation";
49022
49090
  const mobileCardsClass = mobileCardsBreakpoint === "lg" ? "lg:hidden" : "sm:hidden";
49023
49091
  const tableWithCardsClass = mobileCardsBreakpoint === "lg" ? "max-lg:hidden" : "max-sm:hidden";
49024
49092
  const cardsQuery = mobileCardsBreakpoint === "lg" ? "(max-width: 1023px)" : "(max-width: 639px)";
49025
- const [cardsActive, setCardsActive] = useState25(null);
49026
- useEffect21(() => {
49093
+ const [cardsActive, setCardsActive] = useState26(null);
49094
+ useEffect22(() => {
49027
49095
  if (!mobileCards || typeof window === "undefined" || !window.matchMedia) return;
49028
49096
  const mql = window.matchMedia(cardsQuery);
49029
49097
  const read2 = () => setCardsActive(mql.matches);
@@ -49039,10 +49107,10 @@ function MatrxDataTableCore(coreProps) {
49039
49107
  const appendDefaultsToSourceProcessing = appendQuery !== null && sourceProcessing === void 0;
49040
49108
  const sourceColumnFilterOwnership = sourceProcessing?.columnFilters;
49041
49109
  const sourceOwnsColumnFilters = appendDefaultsToSourceProcessing ? true : sourceColumnFilterOwnership === "source" || typeof sourceColumnFilterOwnership === "object" && sourceColumnFilterOwnership.source.length > 0;
49042
- const remoteQueryUsesLocalColumnFilters = remoteQuery !== null && sourceColumnFilterOwnership === "local";
49110
+ const remoteQueryUsesLocalProcessing = remoteQuery !== null && (sourceColumnFilterOwnership === "local" || remoteQuery.mode === "controlled" && (sourceProcessing?.search === "local" || sourceProcessing?.sort === "local"));
49043
49111
  const sourceOwnsSort = appendQuery !== null && sourceProcessing === void 0 ? true : sourceProcessing?.sort === "source";
49044
49112
  const sourceOwnsIntelligentSearch = sourceProcessing?.intelligentSearch === "source";
49045
- const sourceOwnsSearch = remoteQuery?.mode === "controlled" || appendQuery !== null && sourceProcessing === void 0 || sourceProcessing?.search === "source" || sourceOwnsIntelligentSearch;
49113
+ const sourceOwnsSearch = remoteQuery?.mode === "controlled" && sourceProcessing?.search !== "local" || appendQuery !== null && sourceProcessing === void 0 || sourceProcessing?.search === "source" || sourceOwnsIntelligentSearch;
49046
49114
  const intelligentSearchEnabled = toolbar?.intelligentSearch !== void 0 && (sourceOwnsIntelligentSearch || remoteQuery === null && !sourceOwnsSearch);
49047
49115
  const emitControlledQueryChange = useCallback10(
49048
49116
  (patch, options) => {
@@ -49053,8 +49121,8 @@ function MatrxDataTableCore(coreProps) {
49053
49121
  },
49054
49122
  [controlledQuery]
49055
49123
  );
49056
- const [internalSearch, setInternalSearch] = useState25("");
49057
- const [draggedRowId, setDraggedRowId] = useState25(null);
49124
+ const [internalSearch, setInternalSearch] = useState26("");
49125
+ const [draggedRowId, setDraggedRowId] = useState26(null);
49058
49126
  const hierarchySensors = useSensors(useSensor(PointerSensor, POINTER_SENSOR_OPTIONS));
49059
49127
  const toolbarSearchControlled = toolbar?.searchValue !== void 0;
49060
49128
  const searchValue = controlledQuery ? controlledQuery.state.search : toolbarSearchControlled ? toolbar?.searchValue ?? "" : internalSearch;
@@ -49066,7 +49134,7 @@ function MatrxDataTableCore(coreProps) {
49066
49134
  }
49067
49135
  toolbar?.onSearchChange?.(v);
49068
49136
  };
49069
- const [internalSearchMatchMode, setInternalSearchMatchMode] = useState25(
49137
+ const [internalSearchMatchMode, setInternalSearchMatchMode] = useState26(
49070
49138
  toolbar?.searchMatch?.defaultMode ?? "contains"
49071
49139
  );
49072
49140
  const searchMatchMode = controlledQuery ? controlledQuery.state.searchMatchMode ?? toolbar?.searchMatch?.defaultMode ?? "contains" : internalSearchMatchMode;
@@ -49077,7 +49145,7 @@ function MatrxDataTableCore(coreProps) {
49077
49145
  }
49078
49146
  setInternalSearchMatchMode(mode);
49079
49147
  };
49080
- const [internalSearchScope, setInternalSearchScope] = useState25("all");
49148
+ const [internalSearchScope, setInternalSearchScope] = useState26("all");
49081
49149
  const searchScope = controlledQuery ? controlledQuery.state.searchScope ?? "all" : internalSearchScope;
49082
49150
  const setSearchScope = (scope) => {
49083
49151
  if (controlledQuery) {
@@ -49086,7 +49154,7 @@ function MatrxDataTableCore(coreProps) {
49086
49154
  }
49087
49155
  setInternalSearchScope(scope);
49088
49156
  };
49089
- const [internalAnyOf, setInternalAnyOf] = useState25("");
49157
+ const [internalAnyOf, setInternalAnyOf] = useState26("");
49090
49158
  const toolbarAnyOfControlled = toolbar?.anyOf?.value !== void 0;
49091
49159
  const anyOfValue = controlledQuery ? controlledQuery.state.anyOf : toolbarAnyOfControlled ? toolbar?.anyOf?.value ?? "" : internalAnyOf;
49092
49160
  const setAnyOfValue = (v) => {
@@ -49097,7 +49165,7 @@ function MatrxDataTableCore(coreProps) {
49097
49165
  }
49098
49166
  toolbar?.anyOf?.onChange?.(v);
49099
49167
  };
49100
- const [internalLayeredFilters, setInternalLayeredFilters] = useState25([]);
49168
+ const [internalLayeredFilters, setInternalLayeredFilters] = useState26([]);
49101
49169
  const layeredFilters = controlledQuery ? controlledQuery.state.layeredFilters ?? NO_LAYERED_FILTERS : internalLayeredFilters;
49102
49170
  const setLayeredFilters = (next) => {
49103
49171
  if (controlledQuery) {
@@ -49106,7 +49174,7 @@ function MatrxDataTableCore(coreProps) {
49106
49174
  }
49107
49175
  setInternalLayeredFilters(next);
49108
49176
  };
49109
- const [internalColumnFilters, setInternalColumnFilters] = useState25({});
49177
+ const [internalColumnFilters, setInternalColumnFilters] = useState26({});
49110
49178
  const columnFilters = controlledQuery ? controlledQuery.state.columnFilters : internalColumnFilters;
49111
49179
  const localColumnFilters = useMemo11(() => {
49112
49180
  if (appendDefaultsToSourceProcessing) return {};
@@ -49130,7 +49198,7 @@ function MatrxDataTableCore(coreProps) {
49130
49198
  }
49131
49199
  setInternalColumnFilters(nextFilters);
49132
49200
  };
49133
- const [internalSort, setInternalSort] = useState25(defaultSort);
49201
+ const [internalSort, setInternalSort] = useState26(defaultSort);
49134
49202
  const sort = controlledQuery ? controlledQuery.state.sort : internalSort;
49135
49203
  const setSort = (next) => {
49136
49204
  if (controlledQuery) {
@@ -49139,7 +49207,7 @@ function MatrxDataTableCore(coreProps) {
49139
49207
  }
49140
49208
  setInternalSort(next);
49141
49209
  };
49142
- const [internalPage, setInternalPage] = useState25(1);
49210
+ const [internalPage, setInternalPage] = useState26(1);
49143
49211
  const page = controlledQuery ? controlledQuery.state.page : internalPage;
49144
49212
  const setPage = (next) => {
49145
49213
  if (controlledQuery) {
@@ -49148,7 +49216,7 @@ function MatrxDataTableCore(coreProps) {
49148
49216
  }
49149
49217
  setInternalPage(next);
49150
49218
  };
49151
- const [internalPageSize, setInternalPageSize] = useState25(
49219
+ const [internalPageSize, setInternalPageSize] = useState26(
49152
49220
  defaultPageSize
49153
49221
  );
49154
49222
  const pageSize = controlledQuery ? controlledQuery.state.pageSize : internalPageSize;
@@ -49159,28 +49227,28 @@ function MatrxDataTableCore(coreProps) {
49159
49227
  }
49160
49228
  setInternalPageSize(next);
49161
49229
  };
49162
- const [uncontrolledSelectedId, setUncontrolledSelectedId] = useState25(null);
49230
+ const [uncontrolledSelectedId, setUncontrolledSelectedId] = useState26(null);
49163
49231
  const rawSelectedId = controlledSelectedId !== void 0 ? controlledSelectedId : uncontrolledSelectedId;
49164
49232
  const selectedId = appendSourceChanged ? null : rawSelectedId;
49165
49233
  const setSelectedId = (id) => {
49166
49234
  if (controlledSelectedId === void 0) setUncontrolledSelectedId(id);
49167
49235
  onSelectedIdChange?.(id);
49168
49236
  };
49169
- const [uncontrolledWindowRowId, setUncontrolledWindowRowId] = useState25(null);
49237
+ const [uncontrolledWindowRowId, setUncontrolledWindowRowId] = useState26(null);
49170
49238
  const rawWindowRowId = controlledWindowRowId !== void 0 ? controlledWindowRowId : uncontrolledWindowRowId;
49171
49239
  const windowRowId = appendSourceChanged ? null : rawWindowRowId;
49172
49240
  const setWindowRowId = (id) => {
49173
49241
  if (controlledWindowRowId === void 0) setUncontrolledWindowRowId(id);
49174
49242
  onWindowRowIdChange?.(id);
49175
49243
  };
49176
- const [windowRowSnapshot, setWindowRowSnapshot] = useState25(null);
49244
+ const [windowRowSnapshot, setWindowRowSnapshot] = useState26(null);
49177
49245
  const editScopeKey = appendQueryKey === null ? "\0local" : `append:${appendQueryKey}`;
49178
- const [editsByScope, setEditsByScope] = useState25({});
49179
- const editRevisionRef = useRef20({});
49180
- const [savingByScope, setSavingByScope] = useState25({});
49181
- const savingScopesRef = useRef20(/* @__PURE__ */ new Set());
49182
- const [editRequest, setEditRequest] = useState25(null);
49183
- const [confirmForeignDraftDiscard, setConfirmForeignDraftDiscard] = useState25(false);
49246
+ const [editsByScope, setEditsByScope] = useState26({});
49247
+ const editRevisionRef = useRef21({});
49248
+ const [savingByScope, setSavingByScope] = useState26({});
49249
+ const savingScopesRef = useRef21(/* @__PURE__ */ new Set());
49250
+ const [editRequest, setEditRequest] = useState26(null);
49251
+ const [confirmForeignDraftDiscard, setConfirmForeignDraftDiscard] = useState26(false);
49184
49252
  const edits = editsByScope[editScopeKey]?.values ?? {};
49185
49253
  const saving = (savingByScope[editScopeKey] ?? 0) > 0;
49186
49254
  const setEdits = (next) => {
@@ -49247,7 +49315,7 @@ function MatrxDataTableCore(coreProps) {
49247
49315
  rows: Object.entries(draft.values).map(([rowId, columns2]) => ({ rowId, columns: columns2 }))
49248
49316
  }));
49249
49317
  const selection = appendSourceChanged && selectionConfig ? { ...selectionConfig, selectedIds: [] } : selectionConfig;
49250
- useEffect21(() => {
49318
+ useEffect22(() => {
49251
49319
  const previous = committedAppendQueryKey.current;
49252
49320
  committedAppendQueryKey.current = appendQueryKey;
49253
49321
  if (previous === null || appendQueryKey === null || previous === appendQueryKey) {
@@ -49265,13 +49333,13 @@ function MatrxDataTableCore(coreProps) {
49265
49333
  onWindowRowIdChange,
49266
49334
  selectionConfig
49267
49335
  ]);
49268
- const scrollRef = useRef20(null);
49269
- const tableRef = useRef20(null);
49270
- const tableHeaderRef = useRef20(null);
49271
- const cardsScrollRef = useRef20(null);
49272
- const [documentStickyHeader, setDocumentStickyHeader] = useState25(false);
49273
- const documentStickyHeaderRef = useRef20(false);
49274
- const previousAppendKeyForScrollReset = useRef20(appendQueryKey);
49336
+ const scrollRef = useRef21(null);
49337
+ const tableRef = useRef21(null);
49338
+ const tableHeaderRef = useRef21(null);
49339
+ const cardsScrollRef = useRef21(null);
49340
+ const [documentStickyHeader, setDocumentStickyHeader] = useState26(false);
49341
+ const documentStickyHeaderRef = useRef21(false);
49342
+ const previousAppendKeyForScrollReset = useRef21(appendQueryKey);
49275
49343
  useLayoutEffect5(() => {
49276
49344
  const previous = previousAppendKeyForScrollReset.current;
49277
49345
  previousAppendKeyForScrollReset.current = appendQueryKey;
@@ -49297,13 +49365,13 @@ function MatrxDataTableCore(coreProps) {
49297
49365
  ...appendScrollPolicy?.mode === "scroll" && appendScrollPolicy.thresholdPx !== void 0 ? { thresholdPx: appendScrollPolicy.thresholdPx } : {},
49298
49366
  ...appendScrollPolicy?.mode === "scroll" && appendScrollPolicy.intentTimeoutMs !== void 0 ? { intentTimeoutMs: appendScrollPolicy.intentTimeoutMs } : {}
49299
49367
  });
49300
- const rootRef = useRef20(null);
49368
+ const rootRef = useRef21(null);
49301
49369
  useClippedContentGuard(rootRef, {
49302
49370
  label: typeof copy === "object" && copy.listLabel ? `Table: ${copy.listLabel}` : "MatrxDataTable"
49303
49371
  });
49304
- const [scrollHintRight, setScrollHintRight] = useState25(false);
49305
- const [scrollHintLeft, setScrollHintLeft] = useState25(false);
49306
- const [scrollHintRightInset, setScrollHintRightInset] = useState25(6);
49372
+ const [scrollHintRight, setScrollHintRight] = useState26(false);
49373
+ const [scrollHintLeft, setScrollHintLeft] = useState26(false);
49374
+ const [scrollHintRightInset, setScrollHintRightInset] = useState26(6);
49307
49375
  const updateScrollHint = useCallback10(() => {
49308
49376
  const el = scrollRef.current;
49309
49377
  if (!el) return;
@@ -49321,7 +49389,7 @@ function MatrxDataTableCore(coreProps) {
49321
49389
  behavior: "smooth"
49322
49390
  });
49323
49391
  };
49324
- useEffect21(() => {
49392
+ useEffect22(() => {
49325
49393
  updateScrollHint();
49326
49394
  window.addEventListener("resize", updateScrollHint);
49327
49395
  const el = scrollRef.current;
@@ -49395,26 +49463,26 @@ function MatrxDataTableCore(coreProps) {
49395
49463
  window.removeEventListener("resize", requestUpdate);
49396
49464
  };
49397
49465
  }, [stickyHeader, data, columns]);
49398
- const [columnOrder, setColumnOrder] = useState25(() => columnState?.order ?? columns.map(columnId));
49399
- const [hiddenColumnIds, setHiddenColumnIds] = useState25(
49466
+ const [columnOrder, setColumnOrder] = useState26(() => columnState?.order ?? columns.map(columnId));
49467
+ const [hiddenColumnIds, setHiddenColumnIds] = useState26(
49400
49468
  () => new Set(columnState?.hidden ?? columns.filter((column) => column.hidden).map(columnId))
49401
49469
  );
49402
- const [columnWidths, setColumnWidths] = useState25(
49470
+ const [columnWidths, setColumnWidths] = useState26(
49403
49471
  () => normalizeColumnWidthsForColumns(columnState?.widths, columns)
49404
49472
  );
49405
- const [fixedTableGeometry, setFixedTableGeometry] = useState25(null);
49406
- const knownColumnIds = useRef20(new Set(columns.map(columnId)));
49407
- const draggedColumnId = useRef20(null);
49408
- const columnDragActive = useRef20(false);
49409
- const columnDragRaf = useRef20(null);
49410
- const columnDragScrollDirection = useRef20(0);
49411
- const [columnDragPreview, setColumnDragPreview] = useState25(null);
49473
+ const [fixedTableGeometry, setFixedTableGeometry] = useState26(null);
49474
+ const knownColumnIds = useRef21(new Set(columns.map(columnId)));
49475
+ const draggedColumnId = useRef21(null);
49476
+ const columnDragActive = useRef21(false);
49477
+ const columnDragRaf = useRef21(null);
49478
+ const columnDragScrollDirection = useRef21(0);
49479
+ const [columnDragPreview, setColumnDragPreview] = useState26(null);
49412
49480
  const stopColumnDragScroll = useCallback10(() => {
49413
49481
  if (columnDragRaf.current !== null) cancelAnimationFrame(columnDragRaf.current);
49414
49482
  columnDragRaf.current = null;
49415
49483
  columnDragScrollDirection.current = 0;
49416
49484
  }, []);
49417
- useEffect21(() => () => {
49485
+ useEffect22(() => () => {
49418
49486
  columnDragActive.current = false;
49419
49487
  stopColumnDragScroll();
49420
49488
  }, [stopColumnDragScroll]);
@@ -49452,7 +49520,7 @@ function MatrxDataTableCore(coreProps) {
49452
49520
  setHiddenColumnIds(hidden);
49453
49521
  }
49454
49522
  }, [columnState]);
49455
- const [internalColumnManagerOpen, setInternalColumnManagerOpen] = useState25(false);
49523
+ const [internalColumnManagerOpen, setInternalColumnManagerOpen] = useState26(false);
49456
49524
  const columnManagerOpen = controlledColumnManager?.open ?? internalColumnManagerOpen;
49457
49525
  const setColumnManagerOpen = controlledColumnManager?.onOpenChange ?? setInternalColumnManagerOpen;
49458
49526
  const columnIds = useMemo11(() => columns.map(columnId), [columns]);
@@ -49462,7 +49530,7 @@ function MatrxDataTableCore(coreProps) {
49462
49530
  () => normalizeColumnWidthsForColumns(columnState?.widths ?? columnWidths, columns),
49463
49531
  [columns, columnState?.widths, columnWidths]
49464
49532
  );
49465
- const resizeGestureSnapshotRef = useRef20(null);
49533
+ const resizeGestureSnapshotRef = useRef21(null);
49466
49534
  const measureVisibleColumnWidths = useCallback10(() => {
49467
49535
  const measured = {};
49468
49536
  const headers = tableRef.current ? Array.from(tableRef.current.querySelectorAll(
@@ -49540,7 +49608,7 @@ function MatrxDataTableCore(coreProps) {
49540
49608
  }
49541
49609
  setColumnWidths(normalized);
49542
49610
  }, [columnIds, columnState, columns, measureFixedTableGeometry, measureVisibleColumnWidths]);
49543
- useEffect21(() => {
49611
+ useEffect22(() => {
49544
49612
  const ids = columns.map(columnId);
49545
49613
  if (columnState) return;
49546
49614
  const previousIds = knownColumnIds.current;
@@ -49607,7 +49675,7 @@ function MatrxDataTableCore(coreProps) {
49607
49675
  const fixedLayoutActive = usesMeasuredFixedLayout && fixedTableGeometry !== null;
49608
49676
  const freezeWanted = visibleColumns.some((column) => column.frozen);
49609
49677
  const selectionColumnWidth = fixedTableGeometry?.selectionWidth ?? (selection && (freezeWanted || fitToWidth) ? SELECTION_COLUMN_PX : void 0);
49610
- const [fitSpace, setFitSpace] = useState25(null);
49678
+ const [fitSpace, setFitSpace] = useState26(null);
49611
49679
  useLayoutEffect5(() => {
49612
49680
  if (!fitToWidth) {
49613
49681
  setFitSpace(null);
@@ -49623,19 +49691,28 @@ function MatrxDataTableCore(coreProps) {
49623
49691
  ...strips.map((strip) => Math.ceil(strip.scrollWidth) + 16),
49624
49692
  actionsHeader ? Math.ceil(actionsHeader.scrollWidth) : 0
49625
49693
  );
49626
- const next = { width: el.clientWidth, actions };
49627
- setFitSpace((now) => now && now.width === next.width && now.actions === next.actions ? now : next);
49694
+ const table2 = el.querySelector(":scope > table");
49695
+ const spill = table2 && table2.hasAttribute("data-matrx-table-fit") ? Math.max(0, el.scrollWidth - el.clientWidth) : 0;
49696
+ setFitSpace((now) => {
49697
+ const sameWidth = now !== null && now.width === el.clientWidth;
49698
+ const slack = sameWidth ? now.slack + spill : spill;
49699
+ const next = { width: el.clientWidth, actions, slack };
49700
+ return now && now.width === next.width && now.actions === next.actions && now.slack === next.slack ? now : next;
49701
+ });
49628
49702
  };
49629
49703
  read2();
49630
49704
  if (typeof ResizeObserver === "undefined") return;
49631
49705
  const observer = new ResizeObserver(read2);
49632
49706
  observer.observe(el);
49707
+ const table = el.querySelector(":scope > table");
49708
+ if (table) observer.observe(table);
49633
49709
  return () => observer.disconnect();
49634
49710
  }, [fitToWidth, data.length]);
49635
49711
  const fittedWidths = useMemo11(() => {
49636
49712
  if (!fitToWidth || !fitSpace) return null;
49637
- const scaling = visibleColumns.filter((col) => resolveColumnMarker(col) === void 0);
49638
- const fixed = visibleColumns.filter((col) => resolveColumnMarker(col) !== void 0).reduce((sum, col) => sum + (pixelWidth(col.width) ?? 40), 0);
49713
+ const keepsItsWidth = (col) => resolveColumnMarker(col) !== void 0 || col.resizable === false && pixelWidth(col.width) !== void 0;
49714
+ const scaling = visibleColumns.filter((col) => !keepsItsWidth(col));
49715
+ const fixed = visibleColumns.filter(keepsItsWidth).reduce((sum, col) => sum + (pixelWidth(col.width) ?? 40), 0);
49639
49716
  const utilities = (selection ? selectionColumnWidth ?? SELECTION_COLUMN_PX : 0) + fitSpace.actions;
49640
49717
  return fitColumnWidths(
49641
49718
  scaling.map(columnId),
@@ -49643,7 +49720,7 @@ function MatrxDataTableCore(coreProps) {
49643
49720
  const col = scaling.find((c) => columnId(c) === id);
49644
49721
  return effectiveColumnWidths[id] ?? pixelWidth(col?.width) ?? FIT_DEFAULT_COLUMN_PX;
49645
49722
  },
49646
- fitSpace.width - utilities - fixed
49723
+ fitSpace.width - utilities - fixed - fitSpace.slack
49647
49724
  );
49648
49725
  }, [fitToWidth, fitSpace, visibleColumns, selection, selectionColumnWidth, effectiveColumnWidths]);
49649
49726
  const fitActive = fittedWidths !== null;
@@ -49721,7 +49798,7 @@ function MatrxDataTableCore(coreProps) {
49721
49798
  const effectiveCopy = copy === false ? void 0 : copy ?? defaultCopy;
49722
49799
  const effectiveCopyColumns = copy === void 0 ? declaredVisibleCopyColumns : visibleColumns;
49723
49800
  const copySubsetVariant2 = useCopySubsetVariant();
49724
- const chromeLatest = useRef20({
49801
+ const chromeLatest = useRef21({
49725
49802
  processed: [],
49726
49803
  data: [],
49727
49804
  toggleAllOnPage: () => void 0,
@@ -49765,7 +49842,7 @@ function MatrxDataTableCore(coreProps) {
49765
49842
  [columns, data, toolbar?.intelligentSearch?.roles, toolbar?.intelligentSearch?.scopes]
49766
49843
  );
49767
49844
  const processed = useMemo11(() => {
49768
- if (remoteQuery && !appendUsesLocalProcessing && !remoteQueryUsesLocalColumnFilters) return data;
49845
+ if (remoteQuery && !appendUsesLocalProcessing && !remoteQueryUsesLocalProcessing) return data;
49769
49846
  if (processLocalRows) {
49770
49847
  return processLocalRows(data, {
49771
49848
  page,
@@ -49821,15 +49898,15 @@ function MatrxDataTableCore(coreProps) {
49821
49898
  pageSize,
49822
49899
  remoteQuery,
49823
49900
  appendUsesLocalProcessing,
49824
- remoteQueryUsesLocalColumnFilters,
49901
+ remoteQueryUsesLocalProcessing,
49825
49902
  sourceOwnsColumnFilters,
49826
49903
  sourceOwnsSort,
49827
49904
  sourceOwnsSearch,
49828
49905
  intelligentSearchEnabled,
49829
49906
  searchScope
49830
49907
  ]);
49831
- const lastNotifiedViewRows = useRef20(null);
49832
- useEffect21(() => {
49908
+ const lastNotifiedViewRows = useRef21(null);
49909
+ useEffect22(() => {
49833
49910
  if (!onViewChange) {
49834
49911
  lastNotifiedViewRows.current = null;
49835
49912
  return;
@@ -49838,7 +49915,7 @@ function MatrxDataTableCore(coreProps) {
49838
49915
  lastNotifiedViewRows.current = processed;
49839
49916
  if (changed) onViewChange(processed);
49840
49917
  }, [processed, onViewChange]);
49841
- useEffect21(() => {
49918
+ useEffect22(() => {
49842
49919
  if (controlledQuery) return;
49843
49920
  setInternalPage(1);
49844
49921
  }, [
@@ -49891,7 +49968,7 @@ function MatrxDataTableCore(coreProps) {
49891
49968
  return processed.slice(start, start + effectivePageSize);
49892
49969
  }, [processed, safePage, effectivePageSize, pageSize, remoteQuery, hidePagination, localProgressiveEnabled, progressiveRows.rows]);
49893
49970
  const groupingColumnId = grouping?.columnId ?? null;
49894
- const [uncontrolledCollapsed, setUncontrolledCollapsed] = useState25([]);
49971
+ const [uncontrolledCollapsed, setUncontrolledCollapsed] = useState26([]);
49895
49972
  const collapsedGroups = grouping?.collapsed ?? uncontrolledCollapsed;
49896
49973
  const setCollapsedGroups = useCallback10(
49897
49974
  (next) => {
@@ -49948,9 +50025,9 @@ function MatrxDataTableCore(coreProps) {
49948
50025
  return run;
49949
50026
  }, [visibleColumns, frozenColumns]);
49950
50027
  const columnVirtualizeActive = virtualizeConfig !== null && virtualizeConfig.enabled !== false && virtualizeConfig.columns === true && visibleColumns.length - frozenRunLength > 30 && !hierarchy && mobileCards === void 0;
49951
- const [rowWindow, setRowWindow] = useState25(null);
49952
- const [columnWindow, setColumnWindow] = useState25(null);
49953
- const windowInputs = useRef20({
50028
+ const [rowWindow, setRowWindow] = useState26(null);
50029
+ const [columnWindow, setColumnWindow] = useState26(null);
50030
+ const windowInputs = useRef21({
49954
50031
  virtualizeActive: false,
49955
50032
  bodyEntryCount: 0,
49956
50033
  virtualRowHeight: 40,
@@ -50022,7 +50099,7 @@ function MatrxDataTableCore(coreProps) {
50022
50099
  frozenRunLength
50023
50100
  ]);
50024
50101
  const metricsWanted = virtualizeActive || columnVirtualizeActive;
50025
- useEffect21(() => {
50102
+ useEffect22(() => {
50026
50103
  recomputeWindows();
50027
50104
  }, [
50028
50105
  recomputeWindows,
@@ -50034,7 +50111,7 @@ function MatrxDataTableCore(coreProps) {
50034
50111
  columnWindowWidth,
50035
50112
  frozenRunLength
50036
50113
  ]);
50037
- useEffect21(() => {
50114
+ useEffect22(() => {
50038
50115
  if (!metricsWanted) return;
50039
50116
  const el = scrollRef.current;
50040
50117
  if (!el) return;
@@ -50103,7 +50180,7 @@ function MatrxDataTableCore(coreProps) {
50103
50180
  windowed.push({ kind: "spacer", height: effectiveRowWindow.padEnd, place: "end" });
50104
50181
  return windowed;
50105
50182
  }, [groupedRenderRows, collapsedGroups, paginated, effectiveRowWindow]);
50106
- const getRowIdRef = useRef20(getRowId);
50183
+ const getRowIdRef = useRef21(getRowId);
50107
50184
  getRowIdRef.current = getRowId;
50108
50185
  const spreadsheetRowIds = useMemo11(
50109
50186
  () => paginated.map((row) => getRowIdRef.current(row)),
@@ -50124,7 +50201,7 @@ function MatrxDataTableCore(coreProps) {
50124
50201
  return map;
50125
50202
  }, [visibleColumns]);
50126
50203
  const spreadsheetEnabled = Boolean(spreadsheet && spreadsheet.enabled !== false);
50127
- const openRowRef = useRef20(() => void 0);
50204
+ const openRowRef = useRef21(() => void 0);
50128
50205
  const sheet = useSpreadsheetGrid(
50129
50206
  spreadsheetEnabled && spreadsheet ? {
50130
50207
  rowIds: spreadsheetRowIds,
@@ -50166,12 +50243,12 @@ function MatrxDataTableCore(coreProps) {
50166
50243
  } : null
50167
50244
  );
50168
50245
  if (spreadsheet?.controllerRef) spreadsheet.controllerRef.current = spreadsheetEnabled ? sheet.controller : null;
50169
- const sheetRef = useRef20(sheet);
50246
+ const sheetRef = useRef21(sheet);
50170
50247
  sheetRef.current = sheet;
50171
- const onSheetSelectionRef = useRef20(spreadsheet?.onSelectionChange);
50248
+ const onSheetSelectionRef = useRef21(spreadsheet?.onSelectionChange);
50172
50249
  onSheetSelectionRef.current = spreadsheet?.onSelectionChange;
50173
50250
  const sheetSelectionKey = sheet.range ? `${sheet.range.anchor.rowId}\0${sheet.range.anchor.fieldName}\0${sheet.range.focus.rowId}\0${sheet.range.focus.fieldName}\0${sheet.bounds ? `${sheet.bounds.r0}:${sheet.bounds.r1}:${sheet.bounds.c0}:${sheet.bounds.c1}` : ""}` : "";
50174
- useEffect21(() => {
50251
+ useEffect22(() => {
50175
50252
  const tell = onSheetSelectionRef.current;
50176
50253
  if (!tell) return;
50177
50254
  const current = sheetRef.current;
@@ -50188,10 +50265,11 @@ function MatrxDataTableCore(coreProps) {
50188
50265
  tsv: current.selectionTsv()
50189
50266
  });
50190
50267
  }, [sheetSelectionKey]);
50191
- const searchValueRef = useRef20(searchValue);
50268
+ const searchValueRef = useRef21(searchValue);
50192
50269
  searchValueRef.current = searchValue;
50193
50270
  const facetsEnabled = Boolean(facets && facets.enabled !== false);
50194
- const [facetState, setFacetState] = useState25({});
50271
+ const coreSuggestionsEnabled = facets?.enabled !== false;
50272
+ const [facetState, setFacetState] = useState26({});
50195
50273
  const facetReadCell = useCallback10(
50196
50274
  (row, colId) => {
50197
50275
  if (facets?.readCell) return facets.readCell(row, colId);
@@ -50200,12 +50278,37 @@ function MatrxDataTableCore(coreProps) {
50200
50278
  },
50201
50279
  [facets, visibleColumns]
50202
50280
  );
50203
- const facetInputsRef = useRef20({ data, facets, facetReadCell });
50204
- facetInputsRef.current = { data, facets, facetReadCell };
50205
- const facetRequestRef = useRef20(/* @__PURE__ */ new Map());
50281
+ const coreFacetTotal = remoteQuery?.mode === "controlled" ? remoteQuery.totalItems : appendQuery?.pagination.sourceRecords?.total ?? coverage?.matched ?? coverage?.total;
50282
+ const coreFacetLoaded = appendQuery?.pagination.sourceRecords?.loaded;
50283
+ const facetInputsRef = useRef21({ data, facets, facetReadCell, coreFacetTotal, coreFacetLoaded });
50284
+ facetInputsRef.current = { data, facets, facetReadCell, coreFacetTotal, coreFacetLoaded };
50285
+ const facetRequestRef = useRef21(/* @__PURE__ */ new Map());
50206
50286
  const requestFacets = useCallback10((colId) => {
50207
- const { data: rows, facets: config, facetReadCell: readCell } = facetInputsRef.current;
50208
- if (!config || config.enabled === false) return;
50287
+ const { data: rows, facets: config, facetReadCell: readCell, coreFacetTotal: total, coreFacetLoaded: loaded } = facetInputsRef.current;
50288
+ if (!config || config.enabled === false) {
50289
+ const complete2 = localFacetsAreComplete(loaded ?? rows.length, total ?? rows.length);
50290
+ const hasArrayValue = rows.some((row) => {
50291
+ try {
50292
+ return Array.isArray(readCell(row, colId));
50293
+ } catch {
50294
+ return false;
50295
+ }
50296
+ });
50297
+ const suggestions = computeColumnFacets({
50298
+ columnId: colId,
50299
+ rows,
50300
+ readValue: readCell,
50301
+ complete: complete2
50302
+ });
50303
+ setFacetState((current) => ({
50304
+ ...current,
50305
+ [colId]: {
50306
+ loading: false,
50307
+ data: !hasArrayValue && suggestions.distinctCount + (suggestions.blank > 0 ? 1 : 0) < CORE_SUGGESTION_DISTINCT_EXCLUSIVE_LIMIT ? suggestions : null
50308
+ }
50309
+ }));
50310
+ return;
50311
+ }
50209
50312
  const complete = localFacetsAreComplete(rows.length, config.totalRows);
50210
50313
  const limit = config.limit;
50211
50314
  if (complete || !config.source) {
@@ -50262,13 +50365,12 @@ function MatrxDataTableCore(coreProps) {
50262
50365
  }));
50263
50366
  });
50264
50367
  }, []);
50265
- useEffect21(() => {
50266
- if (!facetsEnabled) return;
50368
+ useEffect22(() => {
50267
50369
  setFacetState({});
50268
50370
  facetRequestRef.current = /* @__PURE__ */ new Map();
50269
- }, [facetsEnabled, data, searchValue]);
50371
+ }, [facetsEnabled, data, searchValue, coreFacetTotal, coreFacetLoaded]);
50270
50372
  const totalIsKnown = !isLoading && !readView.failure;
50271
- useEffect21(() => {
50373
+ useEffect22(() => {
50272
50374
  if (!controlledQuery || !totalIsKnown || controlledQuery.state.page === safePage) return;
50273
50375
  emitControlledQueryChange({ page: safePage });
50274
50376
  }, [controlledQuery, emitControlledQueryChange, safePage, totalIsKnown]);
@@ -50295,39 +50397,60 @@ function MatrxDataTableCore(coreProps) {
50295
50397
  const target = toolbar.portalInto;
50296
50398
  return target ? createPortal3(node, target) : null;
50297
50399
  };
50400
+ const [pinnedEl, setPinnedEl] = useState26(null);
50401
+ const pinnedRowActive = Boolean(
50402
+ toolbar?.singleRow && toolbar.overflow && toolbar.overflow.mode !== "sheet" && (toolbar.overflow.pinned || toolbar.overflow.mode === "menu")
50403
+ );
50404
+ const pinnedFolded = usePinnedFold(pinnedEl, pinnedRowActive);
50405
+ const toolbarEnd = { node: null };
50298
50406
  const renderToolbarControls = (controls) => {
50407
+ toolbarEnd.node = null;
50299
50408
  const overflow = toolbar?.overflow;
50300
50409
  const mode = overflow?.mode ?? "inline";
50301
- const stick = (node) => toolbar?.singleRow ? /* @__PURE__ */ jsx51(
50302
- "span",
50303
- {
50304
- "data-matrx-table-toolbar-pinned": "",
50305
- className: "sticky right-0 z-[1] flex shrink-0 items-center gap-1 bg-background pl-1 before:pointer-events-none before:absolute before:inset-y-0 before:-left-6 before:w-6 before:bg-gradient-to-l before:from-background before:to-transparent",
50306
- children: node
50307
- }
50308
- ) : node;
50309
- if (mode === "menu") {
50310
- return stick(
50311
- /* @__PURE__ */ jsxs40(Fragment12, { children: [
50410
+ if (mode === "sheet") {
50411
+ return /* @__PURE__ */ jsxs40(ToolbarOverflowSheet, { ...overflow?.label ? { label: overflow.label } : {}, top: overflow?.sheetTop, children: [
50412
+ controls,
50413
+ overflow?.pinned,
50414
+ overflow?.sheetExtras
50415
+ ] });
50416
+ }
50417
+ if (!pinnedRowActive) {
50418
+ if (mode === "menu") {
50419
+ return /* @__PURE__ */ jsxs40(Fragment12, { children: [
50312
50420
  overflow?.pinned,
50313
50421
  /* @__PURE__ */ jsxs40(ToolbarOverflowMenu, { children: [
50314
50422
  controls,
50315
50423
  overflow?.sheetExtras
50316
50424
  ] })
50317
- ] })
50318
- );
50319
- }
50320
- if (mode === "sheet") {
50321
- return /* @__PURE__ */ jsxs40(ToolbarOverflowSheet, { ...overflow?.label ? { label: overflow.label } : {}, top: overflow?.sheetTop, children: [
50425
+ ] });
50426
+ }
50427
+ return /* @__PURE__ */ jsxs40(Fragment12, { children: [
50322
50428
  controls,
50323
- overflow?.pinned,
50324
- overflow?.sheetExtras
50429
+ overflow?.pinned
50325
50430
  ] });
50326
50431
  }
50327
- return /* @__PURE__ */ jsxs40(Fragment12, { children: [
50328
- controls,
50329
- overflow?.pinned ? stick(overflow.pinned) : null
50330
- ] });
50432
+ const folded = pinnedFolded;
50433
+ toolbarEnd.node = /* @__PURE__ */ jsx51(
50434
+ "span",
50435
+ {
50436
+ ref: setPinnedEl,
50437
+ "data-matrx-table-toolbar-pinned": "",
50438
+ ...folded ? { "data-matrx-table-toolbar-pinned-folded": "" } : {},
50439
+ className: "sticky right-0 z-[1] -ml-1 flex shrink-0 items-center gap-1 bg-background pl-1 before:pointer-events-none before:absolute before:inset-y-0 before:-left-6 before:w-6 before:bg-gradient-to-l before:from-background before:to-transparent",
50440
+ children: folded ? /* @__PURE__ */ jsxs40(ToolbarOverflowMenu, { children: [
50441
+ controls,
50442
+ overflow?.pinned,
50443
+ overflow?.sheetExtras
50444
+ ] }) : mode === "menu" ? /* @__PURE__ */ jsxs40(Fragment12, { children: [
50445
+ overflow?.pinned,
50446
+ /* @__PURE__ */ jsxs40(ToolbarOverflowMenu, { children: [
50447
+ controls,
50448
+ overflow?.sheetExtras
50449
+ ] })
50450
+ ] }) : overflow?.pinned
50451
+ }
50452
+ );
50453
+ return folded || mode === "menu" ? null : controls;
50331
50454
  };
50332
50455
  const renderRowActions = (row, controls) => {
50333
50456
  const actions = rowActions?.(row, controls);
@@ -50483,7 +50606,7 @@ function MatrxDataTableCore(coreProps) {
50483
50606
  }
50484
50607
  resetToolbarFacets(toolbar?.facets);
50485
50608
  };
50486
- const renderedEmptyState = (remoteQuery === null || remoteQueryUsesLocalColumnFilters) && data.length > 0 && hasActiveFilters ? {
50609
+ const renderedEmptyState = (remoteQuery === null || remoteQueryUsesLocalProcessing) && data.length > 0 && hasActiveFilters ? {
50487
50610
  title: "No matching rows",
50488
50611
  description: "No rows match the current search or filters.",
50489
50612
  action: /* @__PURE__ */ jsx51(Button, { type: "button", variant: "outline", size: "sm", onClick: clearAllFilters, children: "Clear filters" }),
@@ -50576,7 +50699,7 @@ function MatrxDataTableCore(coreProps) {
50576
50699
  }));
50577
50700
  return true;
50578
50701
  };
50579
- const requestCellEditRef = useRef20(requestCellEdit);
50702
+ const requestCellEditRef = useRef21(requestCellEdit);
50580
50703
  requestCellEditRef.current = requestCellEdit;
50581
50704
  const buildRecordControls = (row) => {
50582
50705
  const rowId = getRowId(row);
@@ -50922,16 +51045,16 @@ function MatrxDataTableCore(coreProps) {
50922
51045
  return [];
50923
51046
  }
50924
51047
  };
50925
- const menuSectionsForRef = useRef20(menuSectionsFor);
51048
+ const menuSectionsForRef = useRef21(menuSectionsFor);
50926
51049
  menuSectionsForRef.current = menuSectionsFor;
50927
51050
  const hasMenuSections = Boolean(contextMenu?.sections);
50928
51051
  const boundarySections = useCallback10(
50929
51052
  (target) => menuSectionsForRef.current(target),
50930
51053
  []
50931
51054
  );
50932
- const resolveMenuLevelRef = useRef20(resolveMenuLevel);
51055
+ const resolveMenuLevelRef = useRef21(resolveMenuLevel);
50933
51056
  resolveMenuLevelRef.current = resolveMenuLevel;
50934
- useEffect21(() => {
51057
+ useEffect22(() => {
50935
51058
  if (!host.rowContextRegistry) return;
50936
51059
  return host.rowContextRegistry.register(
50937
51060
  tableContextMenuInstanceId,
@@ -50961,7 +51084,7 @@ function MatrxDataTableCore(coreProps) {
50961
51084
  return true;
50962
51085
  });
50963
51086
  }, [data, getSelectionId, selectedIdSet]);
50964
- const lastToggledIndex = useRef20(null);
51087
+ const lastToggledIndex = useRef21(null);
50965
51088
  const setSelectedIds = (next) => selection?.onSelectedIdsChange([...next]);
50966
51089
  const toggleRowSelected = (index, shiftKey) => {
50967
51090
  if (!selection) return;
@@ -51002,7 +51125,7 @@ function MatrxDataTableCore(coreProps) {
51002
51125
  }
51003
51126
  } : facet
51004
51127
  ) : toolbar?.facets;
51005
- const rowLatest = useRef20(null);
51128
+ const rowLatest = useRef21(null);
51006
51129
  const renderRecordCell = (row, col, index) => {
51007
51130
  const id = getRowId(row);
51008
51131
  const field = col.accessorKey ? String(col.accessorKey) : columnId(col);
@@ -51081,7 +51204,6 @@ function MatrxDataTableCore(coreProps) {
51081
51204
  pageSize: defaultPageSize,
51082
51205
  search: "",
51083
51206
  anyOf: "",
51084
- layeredFilters: [],
51085
51207
  columnFilters: {},
51086
51208
  sort: defaultSort
51087
51209
  },
@@ -51317,6 +51439,7 @@ function MatrxDataTableCore(coreProps) {
51317
51439
  allRowsAreLoaded,
51318
51440
  effectivePageSize,
51319
51441
  safePage,
51442
+ isFetching,
51320
51443
  controlledQuery,
51321
51444
  emitControlledQueryChange,
51322
51445
  ...pageSizeOptions
@@ -51324,6 +51447,8 @@ function MatrxDataTableCore(coreProps) {
51324
51447
  const toolbarReadsRows = showToolbarCopy && copyDrawsFromRows(effectiveCopy);
51325
51448
  const toolbarEpoch = useRenderEpoch([
51326
51449
  hideToolbar,
51450
+ pinnedFolded,
51451
+ pinnedRowActive,
51327
51452
  viewTabs,
51328
51453
  toolbar,
51329
51454
  showSearch,
@@ -51835,43 +51960,40 @@ function MatrxDataTableCore(coreProps) {
51835
51960
  "data-matrx-table-density": resolvedDensity,
51836
51961
  "data-url-state-table": urlState?.id,
51837
51962
  className: cn(
51838
- "flex h-full min-h-0 flex-col gap-2 px-0 py-2",
51963
+ "flex h-full min-h-0 flex-col gap-2 px-0 pt-2 pb-0",
51839
51964
  className
51840
51965
  ),
51841
51966
  children: [
51842
51967
  notice,
51843
51968
  savedViewError ? /* @__PURE__ */ jsx51(ErrorBox, { className: "shrink-0 text-xs text-destructive", message: savedViewError, operation: "Save or apply a saved view", origin: "design-system/MatrxDataTable" }) : null,
51844
51969
  toolbarActionError ? /* @__PURE__ */ jsx51(ErrorBox, { className: "shrink-0 text-xs text-destructive", message: toolbarActionError, operation: "Run a table toolbar action", origin: "design-system/MatrxDataTable" }) : null,
51845
- summaryMetrics.length > 0 ? /* @__PURE__ */ jsxs40(
51970
+ summaryMetrics.length > 0 ? /* @__PURE__ */ jsx51(
51846
51971
  "section",
51847
51972
  {
51848
51973
  "data-matrx-table-summary": true,
51849
51974
  "data-matrx-table-summary-scope": summaryUsesSource ? "source" : summaryCoverage,
51850
51975
  "aria-label": `Table summary: ${summaryCaption}`,
51851
- className: "flex shrink-0 flex-wrap items-stretch gap-2",
51852
- children: [
51853
- /* @__PURE__ */ jsx51("span", { className: "flex items-center px-1 text-xs font-medium text-muted-foreground", children: summaryCaption }),
51854
- summaryMetrics.map((metric) => /* @__PURE__ */ jsxs40("div", { className: "min-w-24 rounded-md border border-border bg-card px-3 py-2 shadow-xs", children: [
51855
- /* @__PURE__ */ jsx51("div", { className: "text-xs text-muted-foreground", children: metric.label }),
51856
- /* @__PURE__ */ jsxs40("div", { className: "mt-0.5 text-sm font-semibold tabular-nums text-foreground", children: [
51857
- metric.value,
51858
- metric.unavailable ? /* @__PURE__ */ jsx51(ErrorBox, { as: "span", className: "sr-only", message: `${metric.label} is unavailable`, operation: "Summarize this table", origin: "design-system/MatrxDataTable" }) : null
51859
- ] })
51860
- ] }, metric.id))
51861
- ]
51976
+ className: "flex w-full min-w-0 shrink-0 flex-nowrap items-stretch gap-2 overflow-x-auto overscroll-x-contain",
51977
+ children: summaryMetrics.map((metric) => /* @__PURE__ */ jsxs40("div", { className: "min-w-24 shrink-0 whitespace-nowrap rounded-md border border-border bg-card px-3 py-2 shadow-xs", children: [
51978
+ /* @__PURE__ */ jsx51("div", { className: "text-xs text-muted-foreground", children: metric.label }),
51979
+ /* @__PURE__ */ jsxs40("div", { className: "mt-0.5 text-sm font-semibold tabular-nums text-foreground", children: [
51980
+ metric.value,
51981
+ metric.unavailable ? /* @__PURE__ */ jsx51(ErrorBox, { as: "span", className: "sr-only", message: `${metric.label} is unavailable`, operation: "Summarize this table", origin: "design-system/MatrxDataTable" }) : null
51982
+ ] })
51983
+ ] }, metric.id))
51862
51984
  }
51863
51985
  ) : null,
51864
- /* @__PURE__ */ jsx51(MatrxTableChrome, { part: "toolbar", epoch: toolbarEpoch, render: () => placeToolbar(!hideToolbar && (viewTabs || toolbar?.title || toolbar?.titleCount || showSearch || toolbar?.customSearch || toolbar?.anyOf || toolbar?.layeredFilters || toolbar?.facets && toolbar.facets.length > 0 || toolbar?.leading || toolbar?.actions || toolbar?.refresh || toolbar?.add || tableId && SavedViews || hasActiveFilters || showToolbarCopy || columns.length > 0) && /* @__PURE__ */ jsxs40(
51986
+ /* @__PURE__ */ jsx51(MatrxTableChrome, { part: "toolbar", epoch: toolbarEpoch, render: () => placeToolbar(!hideToolbar && (showViewTabs || toolbar?.title || toolbar?.titleCount || showSearch || toolbar?.customSearch || toolbar?.anyOf || toolbar?.layeredFilters || toolbar?.facets && toolbar.facets.length > 0 || toolbar?.leading || toolbar?.actions || toolbar?.refresh || toolbar?.add || savedViewsId && SavedViews || hasActiveFilters || showToolbarCopy || columns.length > 0) && /* @__PURE__ */ jsxs40(
51865
51987
  TableTitleRow,
51866
51988
  {
51867
51989
  ...toolbar?.singleRow ? { singleRow: true } : {},
51868
- tabs: viewTabs ? /* @__PURE__ */ jsx51(TableViewWorkspace, { snapshot: currentViewSnapshot, onApply: applyLatestSavedView, related: relatedTableActions, ...viewTabsStore ? { store: viewTabsStore } : {} }, tableId ?? "table") : void 0,
51990
+ tabs: viewTabs && viewTabsStore ? /* @__PURE__ */ jsx51(TableViewWorkspace, { snapshot: currentViewSnapshot, onApply: applyLatestSavedView, related: relatedTableActions, ...viewTabsStore ? { store: viewTabsStore } : {} }, savedViewsId ?? "table") : viewTabs && savedViewsId && SavedViews ? /* @__PURE__ */ jsx51(SavedViews, { tableId: savedViewsId, snapshot: currentViewSnapshot, defaultSnapshot: declaredDefaultViewSnapshot, onApply: applyLatestSavedView, presentation: "tabs", related: relatedTableActions }) : void 0,
51869
51991
  ...toolbar?.title === void 0 ? {} : { title: toolbar.title },
51870
51992
  ...toolbar?.titleCount === void 0 ? {} : { count: toolbar.titleCount },
51871
- context: tableId && SavedViews ? /* @__PURE__ */ jsx51("span", { "data-matrx-table-view-control": true, children: /* @__PURE__ */ jsx51(
51993
+ context: savedViewsId && SavedViews && !viewTabs ? /* @__PURE__ */ jsx51("span", { "data-matrx-table-view-control": true, children: /* @__PURE__ */ jsx51(
51872
51994
  SavedViews,
51873
51995
  {
51874
- tableId,
51996
+ tableId: savedViewsId,
51875
51997
  snapshot: currentViewSnapshot,
51876
51998
  defaultSnapshot: declaredDefaultViewSnapshot,
51877
51999
  onApply: applyLatestSavedView
@@ -52173,7 +52295,8 @@ function MatrxDataTableCore(coreProps) {
52173
52295
  ] }))
52174
52296
  ]
52175
52297
  }
52176
- )
52298
+ ),
52299
+ toolbarEnd.node
52177
52300
  ]
52178
52301
  }
52179
52302
  )) }),
@@ -52487,7 +52610,7 @@ function MatrxDataTableCore(coreProps) {
52487
52610
  {
52488
52611
  label: col.header,
52489
52612
  labelText: headerLabel,
52490
- ...facetsEnabled ? {
52613
+ ...facetsEnabled || meta?.kind !== void 0 && meta.kind !== null && coreSuggestionsEnabled ? {
52491
52614
  facets: facetState[id]?.data ?? null,
52492
52615
  facetsLoading: facetState[id]?.loading ?? false,
52493
52616
  ...facetState[id]?.error === void 0 ? {} : { facetsError: facetState[id]?.error },
@@ -52612,12 +52735,12 @@ function MatrxDataTableCore(coreProps) {
52612
52735
  },
52613
52736
  "matrx-column-spacer-end"
52614
52737
  ) : null
52615
- ] }, `sk-${i}`)) : readFailure ? /* @__PURE__ */ jsx51("tr", { children: /* @__PURE__ */ jsx51("td", { colSpan: renderedColSpan, "data-matrx-table-message-cell": true, className: "px-0 py-12 text-center", children: /* @__PURE__ */ jsx51("div", { className: "sticky left-0 flex flex-col items-center gap-2 whitespace-normal px-4", style: { width: "100cqw", maxWidth: "100%" }, children: readFailure }) }) }) : paginated.length === 0 ? /* @__PURE__ */ jsx51("tr", { children: /* @__PURE__ */ jsx51(
52738
+ ] }, `sk-${i}`)) : readFailure ? /* @__PURE__ */ jsx51("tr", { children: /* @__PURE__ */ jsx51("td", { colSpan: renderedColSpan, "data-matrx-table-message-cell": true, className: "overflow-visible! px-0 py-12 text-center", children: /* @__PURE__ */ jsx51("div", { className: "sticky left-0 flex flex-col items-center gap-2 whitespace-normal px-4", style: { width: "100cqw", maxWidth: "100%" }, children: readFailure }) }) }) : paginated.length === 0 ? /* @__PURE__ */ jsx51("tr", { children: /* @__PURE__ */ jsx51(
52616
52739
  "td",
52617
52740
  {
52618
52741
  colSpan: renderedColSpan,
52619
52742
  "data-matrx-table-message-cell": true,
52620
- className: "px-0 py-12 text-center",
52743
+ className: "overflow-visible! px-0 py-12 text-center",
52621
52744
  children: /* @__PURE__ */ jsxs40("div", { "data-matrx-table-empty-state": true, className: "sticky left-0 flex flex-col items-center gap-2 whitespace-normal px-4", style: { width: "100cqw", maxWidth: "100%" }, children: [
52622
52745
  renderedEmptyState?.icon,
52623
52746
  /* @__PURE__ */ jsx51("p", { className: "text-sm font-medium text-foreground", children: renderedEmptyState?.title ?? "No rows" }),
@@ -52707,62 +52830,61 @@ function MatrxDataTableCore(coreProps) {
52707
52830
  "border-t-2 border-border bg-muted/50 font-semibold",
52708
52831
  hasSummaryTotals && "sticky bottom-0 z-10 bg-muted/95 backdrop-blur-sm"
52709
52832
  ), children: [
52710
- hasSummaryTotals ? /* @__PURE__ */ jsxs40(Fragment12, { children: [
52711
- /* @__PURE__ */ jsx51("tr", { "data-matrx-table-summary-total-caption": true, children: /* @__PURE__ */ jsxs40("td", { colSpan: renderedColSpan, className: "px-2 pt-2 text-xs font-medium text-muted-foreground", children: [
52712
- summaryCaption,
52713
- readView.stale ? /* @__PURE__ */ jsx51("span", { className: "ml-1 text-amber-700 dark:text-amber-300", children: "Retained rows may be out of date." }) : null
52714
- ] }) }),
52715
- /* @__PURE__ */ jsxs40("tr", { "data-matrx-table-summary-totals": true, children: [
52716
- selection ? /* @__PURE__ */ jsx51("td", { className: "px-2 py-2" }) : null,
52717
- columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ jsx51(
52718
- "td",
52719
- {
52720
- "aria-hidden": "true",
52721
- "data-matrx-table-column-spacer": "start",
52722
- className: "border-0 p-0",
52723
- style: { width: `${columnSpacers.start}px`, minWidth: `${columnSpacers.start}px` }
52724
- },
52725
- "matrx-summary-column-spacer-start"
52726
- ) : null,
52727
- renderedColumns.map((column) => {
52728
- const total = summaryTotals.find((candidate) => candidate.id === columnId(column));
52729
- return /* @__PURE__ */ jsxs40(
52730
- "td",
52731
- {
52732
- className: cn(
52733
- "px-2 py-2 align-middle",
52734
- (column.compact || resolveColumnMarker(column) !== void 0) && "px-1",
52735
- column.className,
52736
- column.align === "center" && "text-center",
52737
- column.align === "right" && "text-right"
52738
- ),
52739
- style: columnWidthVar(
52740
- resolveColumnMarker(column) && column.width === void 0 ? 40 : column.width,
52741
- windowedWidthFor(columnId(column), column.width),
52742
- columnId(column),
52743
- resizableColumns && column.resizable !== false
52744
- ),
52745
- children: [
52746
- total?.value,
52747
- total?.unavailable ? /* @__PURE__ */ jsx51(ErrorBox, { as: "span", className: "sr-only", message: `${columnId(column)} total is unavailable`, operation: "Total this column", origin: "design-system/MatrxDataTable" }) : null
52748
- ]
52749
- },
52750
- columnId(column)
52751
- );
52752
- }),
52753
- columnSpacers && columnSpacers.end > 0 ? /* @__PURE__ */ jsx51(
52833
+ hasSummaryTotals ? /* @__PURE__ */ jsx51(Fragment12, { children: /* @__PURE__ */ jsxs40("tr", { "data-matrx-table-summary-totals": true, children: [
52834
+ selection ? /* @__PURE__ */ jsx51("td", { className: "px-2 py-2" }) : null,
52835
+ columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ jsx51(
52836
+ "td",
52837
+ {
52838
+ "aria-hidden": "true",
52839
+ "data-matrx-table-column-spacer": "start",
52840
+ className: "border-0 p-0",
52841
+ style: { width: `${columnSpacers.start}px`, minWidth: `${columnSpacers.start}px` }
52842
+ },
52843
+ "matrx-summary-column-spacer-start"
52844
+ ) : null,
52845
+ renderedColumns.map((column, columnIndex) => {
52846
+ const total = summaryTotals.find((candidate) => candidate.id === columnId(column));
52847
+ return /* @__PURE__ */ jsxs40(
52754
52848
  "td",
52755
52849
  {
52756
- "aria-hidden": "true",
52757
- "data-matrx-table-column-spacer": "end",
52758
- className: "border-0 p-0",
52759
- style: { width: `${columnSpacers.end}px`, minWidth: `${columnSpacers.end}px` }
52850
+ className: cn(
52851
+ "px-2 py-2 align-middle font-semibold",
52852
+ (column.compact || resolveColumnMarker(column) !== void 0) && "px-1",
52853
+ column.className,
52854
+ column.align === "center" && "text-center",
52855
+ column.align === "right" && "text-right"
52856
+ ),
52857
+ style: columnWidthVar(
52858
+ resolveColumnMarker(column) && column.width === void 0 ? 40 : column.width,
52859
+ windowedWidthFor(columnId(column), column.width),
52860
+ columnId(column),
52861
+ resizableColumns && column.resizable !== false
52862
+ ),
52863
+ children: [
52864
+ columnIndex === 0 ? /* @__PURE__ */ jsxs40("span", { "data-matrx-table-summary-total-label": true, className: "text-sm font-semibold text-foreground", children: [
52865
+ summaryCaption,
52866
+ readView.stale ? /* @__PURE__ */ jsx51("span", { className: "ml-1 text-xs text-amber-700 dark:text-amber-300", children: "Retained rows may be out of date." }) : null
52867
+ ] }) : null,
52868
+ columnIndex === 0 && total?.value != null ? /* @__PURE__ */ jsx51("span", { className: "ml-2", children: total.value }) : null,
52869
+ columnIndex !== 0 ? total?.value : null,
52870
+ total?.unavailable ? /* @__PURE__ */ jsx51(ErrorBox, { as: "span", className: "sr-only", message: `${columnId(column)} total is unavailable`, operation: "Total this column", origin: "design-system/MatrxDataTable" }) : null
52871
+ ]
52760
52872
  },
52761
- "matrx-summary-column-spacer-end"
52762
- ) : null,
52763
- showActionsCol ? /* @__PURE__ */ jsx51("td", {}) : null
52764
- ] })
52765
- ] }) : null,
52873
+ columnId(column)
52874
+ );
52875
+ }),
52876
+ columnSpacers && columnSpacers.end > 0 ? /* @__PURE__ */ jsx51(
52877
+ "td",
52878
+ {
52879
+ "aria-hidden": "true",
52880
+ "data-matrx-table-column-spacer": "end",
52881
+ className: "border-0 p-0",
52882
+ style: { width: `${columnSpacers.end}px`, minWidth: `${columnSpacers.end}px` }
52883
+ },
52884
+ "matrx-summary-column-spacer-end"
52885
+ ) : null,
52886
+ showActionsCol ? /* @__PURE__ */ jsx51("td", {}) : null
52887
+ ] }) }) : null,
52766
52888
  footerRows.map((row, index) => /* @__PURE__ */ jsxs40("tr", { children: [
52767
52889
  selection ? /* @__PURE__ */ jsx51("td", { className: "px-2 py-2" }) : null,
52768
52890
  columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ jsx51(
@@ -52992,6 +53114,7 @@ function MatrxDataTableCore(coreProps) {
52992
53114
  showAllOption: allRowsAreLoaded,
52993
53115
  allValue: 0,
52994
53116
  allOptionLabel: "All loaded",
53117
+ isFetching,
52995
53118
  compact: true,
52996
53119
  hideEntriesInfo: false
52997
53120
  }
@@ -53346,7 +53469,7 @@ function HierarchyDragIndicatorLayer({
53346
53469
  scrollRef,
53347
53470
  resolve: resolve2
53348
53471
  }) {
53349
- const [indicator, setIndicator] = useState25(
53472
+ const [indicator, setIndicator] = useState26(
53350
53473
  null
53351
53474
  );
53352
53475
  useDndMonitor2({
@@ -53562,7 +53685,7 @@ function columnWidthVar(width, resizedWidth, id, resizable) {
53562
53685
  };
53563
53686
  }
53564
53687
  function DefaultJsonCell({ value }) {
53565
- const [open, setOpen] = useState25(false);
53688
+ const [open, setOpen] = useState26(false);
53566
53689
  const host = useMatrxDataTableHost();
53567
53690
  const Viewer = host.JsonViewer;
53568
53691
  const text = JSON.stringify(value, null, 2);
@@ -53645,7 +53768,7 @@ function resolveStringTitle(title, fallback) {
53645
53768
  }
53646
53769
 
53647
53770
  // src/data-table/SavedViewsControl.tsx
53648
- import { useId as useId4, useState as useState26 } from "react";
53771
+ import { useId as useId4, useState as useState27 } from "react";
53649
53772
 
53650
53773
  // src/dropdown-menu.tsx
53651
53774
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
@@ -53782,7 +53905,7 @@ var DropdownMenuShortcut = ({
53782
53905
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
53783
53906
 
53784
53907
  // src/data-table/SavedViewsControl.tsx
53785
- import { jsx as jsx53, jsxs as jsxs42 } from "react/jsx-runtime";
53908
+ import { Fragment as Fragment13, jsx as jsx53, jsxs as jsxs42 } from "react/jsx-runtime";
53786
53909
  function SavedViewsControl({
53787
53910
  views,
53788
53911
  activeId = null,
@@ -53792,14 +53915,26 @@ function SavedViewsControl({
53792
53915
  onSelect,
53793
53916
  onSaveNew,
53794
53917
  onUpdate,
53795
- onReload
53918
+ onReload,
53919
+ presentation = "menu",
53920
+ onRename,
53921
+ related
53796
53922
  }) {
53797
53923
  const unsavedChangesId = useId4();
53798
- const [saveOpen, setSaveOpen] = useState26(false);
53799
- const [name, setName] = useState26("");
53800
- const [saving, setSaving] = useState26(false);
53801
- const [actionError, setActionError] = useState26(null);
53924
+ const [saveOpen, setSaveOpen] = useState27(false);
53925
+ const [name, setName] = useState27("");
53926
+ const [saving, setSaving] = useState27(false);
53927
+ const [actionError, setActionError] = useState27(null);
53928
+ const [pendingSelect, setPendingSelect] = useState27(void 0);
53802
53929
  const visibleError = actionError ?? error;
53930
+ const select = (id) => {
53931
+ if (id === activeId) return;
53932
+ if (dirty) {
53933
+ setPendingSelect(id);
53934
+ return;
53935
+ }
53936
+ onSelect(id);
53937
+ };
53803
53938
  const save = async () => {
53804
53939
  const next = name.trim();
53805
53940
  if (!next) return;
@@ -53841,7 +53976,31 @@ function SavedViewsControl({
53841
53976
  };
53842
53977
  const activeName = activeId ? views.find((view) => view.id === activeId)?.name : void 0;
53843
53978
  return /* @__PURE__ */ jsxs42("div", { className: "flex min-w-0 flex-wrap items-center gap-1", "data-matrx-table-saved-views": true, children: [
53844
- /* @__PURE__ */ jsxs42(DropdownMenu, { children: [
53979
+ presentation === "tabs" ? /* @__PURE__ */ jsxs42(Fragment13, { children: [
53980
+ /* @__PURE__ */ jsx53(
53981
+ TableViewTabs,
53982
+ {
53983
+ tabs: [{ id: "default", label: "Default view" }, ...views.map((view) => ({ id: view.id, label: view.name }))],
53984
+ activeId: activeId ?? "default",
53985
+ onSelect: (id) => select(id === "default" ? null : id),
53986
+ onAdd: () => {
53987
+ setActionError(null);
53988
+ setSaveOpen(true);
53989
+ },
53990
+ onClose: () => {
53991
+ },
53992
+ onRename: (id, label) => {
53993
+ if (onRename) void Promise.resolve(onRename(id, label)).catch((cause) => setActionError(cause instanceof Error ? cause.message : String(cause)));
53994
+ },
53995
+ closable: false,
53996
+ renameable: Boolean(onRename),
53997
+ addHint: "Save a named view to your account",
53998
+ related
53999
+ }
54000
+ ),
54001
+ dirty ? onUpdate ? /* @__PURE__ */ jsx53(Button, { type: "button", variant: "ghost", size: "sm", disabled: saving, onClick: () => void update(), className: "h-8 shrink-0 text-xs", children: "Save changes" }) : /* @__PURE__ */ jsx53(Button, { type: "button", variant: "ghost", size: "sm", disabled: saving, onClick: () => setSaveOpen(true), className: "h-8 shrink-0 text-xs", children: "Save as view" }) : null,
54002
+ loading ? /* @__PURE__ */ jsx53("span", { role: "status", className: "text-xs text-muted-foreground", children: "Loading views\u2026" }) : null
54003
+ ] }) : /* @__PURE__ */ jsxs42(DropdownMenu, { children: [
53845
54004
  /* @__PURE__ */ jsxs42(Tooltip, { children: [
53846
54005
  /* @__PURE__ */ jsx53(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx53(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs42(
53847
54006
  Button,
@@ -53864,7 +54023,7 @@ function SavedViewsControl({
53864
54023
  ] }),
53865
54024
  /* @__PURE__ */ jsxs42(DropdownMenuContent, { align: "end", children: [
53866
54025
  /* @__PURE__ */ jsx53(DropdownMenuLabel, { children: "Views" }),
53867
- /* @__PURE__ */ jsxs42(DropdownMenuRadioGroup, { value: activeId ?? "__default__", onValueChange: (value) => onSelect(value === "__default__" ? null : value), children: [
54026
+ /* @__PURE__ */ jsxs42(DropdownMenuRadioGroup, { value: activeId ?? "__default__", onValueChange: (value) => select(value === "__default__" ? null : value), children: [
53868
54027
  /* @__PURE__ */ jsx53(DropdownMenuRadioItem, { value: "__default__", children: "Default view" }),
53869
54028
  views.map((view) => /* @__PURE__ */ jsx53(DropdownMenuRadioItem, { value: view.id, children: view.name }, view.id))
53870
54029
  ] }),
@@ -53877,7 +54036,10 @@ function SavedViewsControl({
53877
54036
  onReload ? /* @__PURE__ */ jsx53(DropdownMenuItem, { disabled: saving || loading, onSelect: () => void reload(), children: "Reload views" }) : null
53878
54037
  ] })
53879
54038
  ] }),
53880
- dirty ? /* @__PURE__ */ jsx53("span", { id: unsavedChangesId, className: "sr-only", children: "This table view has unsaved changes. Open the view menu to save or update it." }) : null,
54039
+ dirty ? /* @__PURE__ */ jsxs42("span", { id: presentation === "menu" ? unsavedChangesId : void 0, role: presentation === "tabs" ? "status" : void 0, className: "sr-only", children: [
54040
+ "This table view has unsaved changes. ",
54041
+ presentation === "tabs" ? onUpdate ? "Use Save changes to update it." : "Use Save as view to keep it." : "Open the view menu to save or update it."
54042
+ ] }) : null,
53881
54043
  visibleError && !saveOpen ? /* @__PURE__ */ jsx53(ErrorBox, { className: "basis-full break-words text-xs text-destructive", message: visibleError, operation: "Load or save a saved view", origin: "design-system/SavedViewsControl" }) : null,
53882
54044
  /* @__PURE__ */ jsx53(Dialog, { open: saveOpen, onOpenChange: setSaveOpen, children: /* @__PURE__ */ jsxs42(DialogContent, { children: [
53883
54045
  /* @__PURE__ */ jsx53(DialogHeader, { children: /* @__PURE__ */ jsx53(DialogTitle, { children: "Save current view" }) }),
@@ -53887,6 +54049,20 @@ function SavedViewsControl({
53887
54049
  /* @__PURE__ */ jsx53(Button, { type: "button", variant: "outline", onClick: () => setSaveOpen(false), children: "Cancel" }),
53888
54050
  /* @__PURE__ */ jsx53(Button, { type: "button", disabled: !name.trim() || saving, onClick: () => void save(), children: saving ? "Saving\u2026" : "Save view" })
53889
54051
  ] })
54052
+ ] }) }),
54053
+ /* @__PURE__ */ jsx53(Dialog, { open: pendingSelect !== void 0, onOpenChange: (open) => {
54054
+ if (!open) setPendingSelect(void 0);
54055
+ }, children: /* @__PURE__ */ jsxs42(DialogContent, { children: [
54056
+ /* @__PURE__ */ jsx53(DialogHeader, { children: /* @__PURE__ */ jsx53(DialogTitle, { children: "Unsaved view changes" }) }),
54057
+ /* @__PURE__ */ jsx53("p", { className: "text-sm text-muted-foreground", children: "Switching views will discard the changes you have not saved." }),
54058
+ /* @__PURE__ */ jsxs42(DialogFooter, { children: [
54059
+ /* @__PURE__ */ jsx53(Button, { type: "button", variant: "outline", onClick: () => setPendingSelect(void 0), children: "Stay on this view" }),
54060
+ /* @__PURE__ */ jsx53(Button, { type: "button", onClick: () => {
54061
+ const next = pendingSelect;
54062
+ setPendingSelect(void 0);
54063
+ if (next !== void 0) onSelect(next);
54064
+ }, children: "Discard changes and switch" })
54065
+ ] })
53890
54066
  ] }) })
53891
54067
  ] });
53892
54068
  }