@ai-matrx/design-system 0.49.12 → 0.49.19

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 +38 -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 +521 -330
  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 +452 -261
  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);
@@ -36620,9 +36624,11 @@ function TableViewTabs({ tabs, activeId, onSelect, onAdd, onClose, onRename, rel
36620
36624
  if (id) onEditCancel?.(id);
36621
36625
  onEditDone?.();
36622
36626
  };
36627
+ const canClose = (id) => closable && tabs.length > 1 && id !== "default";
36628
+ const canRename = (id) => renameable && id !== "default";
36623
36629
  return /* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 shrink-0 items-center border-b", "data-matrx-table-tabs": true, children: [
36624
- /* @__PURE__ */ jsxs16("div", { role: "tablist", "aria-label": "Table views", className: "flex min-w-0 flex-1 items-center overflow-x-auto", children: [
36625
- tabs.map((tab, index) => /* @__PURE__ */ jsxs16("div", { className: "group flex shrink-0 items-center border-r", children: [
36630
+ /* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 flex-1 items-center overflow-x-auto", children: [
36631
+ /* @__PURE__ */ jsx24("div", { role: "tablist", "aria-label": "Table views", className: "flex shrink-0 items-center", children: tabs.map((tab, index) => /* @__PURE__ */ jsxs16("div", { role: "presentation", className: "group flex shrink-0 items-center border-r", children: [
36626
36632
  renaming === tab.id ? /* @__PURE__ */ jsx24(
36627
36633
  "input",
36628
36634
  {
@@ -36646,12 +36652,26 @@ function TableViewTabs({ tabs, activeId, onSelect, onAdd, onClose, onRename, rel
36646
36652
  role: "tab",
36647
36653
  "aria-selected": tab.id === activeId,
36648
36654
  tabIndex: tab.id === activeId ? 0 : -1,
36655
+ "aria-keyshortcuts": [canClose(tab.id) ? "Delete" : "", canRename(tab.id) ? "F2" : ""].filter(Boolean).join(" ") || void 0,
36649
36656
  onClick: () => onSelect(tab.id),
36650
36657
  onDoubleClick: () => {
36651
- setDraft(tab.label);
36652
- setRenaming(tab.id);
36658
+ if (canRename(tab.id)) {
36659
+ setDraft(tab.label);
36660
+ setRenaming(tab.id);
36661
+ }
36653
36662
  },
36654
36663
  onKeyDown: (e) => {
36664
+ if (e.key === "Delete" && canClose(tab.id)) {
36665
+ e.preventDefault();
36666
+ onClose(tab.id);
36667
+ return;
36668
+ }
36669
+ if (e.key === "F2" && canRename(tab.id)) {
36670
+ e.preventDefault();
36671
+ setDraft(tab.label);
36672
+ setRenaming(tab.id);
36673
+ return;
36674
+ }
36655
36675
  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;
36656
36676
  if (next >= 0) {
36657
36677
  e.preventDefault();
@@ -36667,17 +36687,18 @@ function TableViewTabs({ tabs, activeId, onSelect, onAdd, onClose, onRename, rel
36667
36687
  ]
36668
36688
  }
36669
36689
  ),
36670
- tabs.length > 1 && tab.id !== "default" && /* @__PURE__ */ jsxs16(Tooltip, { children: [
36671
- /* @__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" }) }) }),
36690
+ canClose(tab.id) && /* @__PURE__ */ jsxs16(Tooltip, { children: [
36691
+ /* @__PURE__ */ jsx24(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx24("button", { type: "button", "aria-hidden": "true", tabIndex: -1, "data-close-tab": tab.id, onClick: () => onClose(tab.id), className: "flex size-7 items-center justify-center rounded hover:bg-muted", children: /* @__PURE__ */ jsx24(X, { className: "size-4" }) }) }),
36672
36692
  /* @__PURE__ */ jsxs16(TooltipContent, { children: [
36673
36693
  "Close ",
36674
- tab.label
36694
+ tab.label,
36695
+ " (Delete)"
36675
36696
  ] })
36676
36697
  ] })
36677
- ] }, tab.id)),
36698
+ ] }, tab.id)) }),
36678
36699
  /* @__PURE__ */ jsxs16(Tooltip, { children: [
36679
36700
  /* @__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" })
36701
+ /* @__PURE__ */ jsx24(TooltipContent, { children: addHint })
36681
36702
  ] })
36682
36703
  ] }),
36683
36704
  related && /* @__PURE__ */ jsx24("div", { className: "flex shrink-0 items-center gap-1 border-l px-2", children: related })
@@ -42117,6 +42138,7 @@ CommandShortcut.displayName = "CommandShortcut";
42117
42138
  var MAX_LISTABLE_FACET_LENGTH = 300;
42118
42139
  var DEFAULT_FACET_LIMIT = 200;
42119
42140
  var MAX_FACET_LIMIT = 500;
42141
+ var CORE_SUGGESTION_DISTINCT_EXCLUSIVE_LIMIT = 15;
42120
42142
  function facetText(raw) {
42121
42143
  if (raw === null || raw === void 0) return "";
42122
42144
  if (typeof raw === "object") {
@@ -42243,6 +42265,7 @@ function HeaderMenuItems({
42243
42265
  const disabled = Boolean(item.disabledReason);
42244
42266
  const hasSubmenu = Boolean(item.submenu && item.submenu.length > 0);
42245
42267
  return /* @__PURE__ */ jsxs28("div", { className: "flex flex-col", children: [
42268
+ item.separatorBefore ? /* @__PURE__ */ jsx38("div", { role: "separator", className: "-mx-1 my-1 h-px bg-border" }) : null,
42246
42269
  /* @__PURE__ */ jsxs28(
42247
42270
  Button,
42248
42271
  {
@@ -42312,7 +42335,7 @@ function ColumnHeaderCell({
42312
42335
  compact = false,
42313
42336
  marker,
42314
42337
  filterApplyLabel,
42315
- filterShowCancel = false,
42338
+ filterShowCancel,
42316
42339
  filterFooterHint,
42317
42340
  allowNegation = false,
42318
42341
  allowNullModes = false,
@@ -42350,7 +42373,8 @@ function ColumnHeaderCell({
42350
42373
  } : void 0;
42351
42374
  const reorderClass = reorderEnabled ? "touch-none cursor-grab active:cursor-grabbing" : void 0;
42352
42375
  const filterActive = isColumnFilterActive(filterValue);
42353
- const deferredFilter = filterApplyLabel !== void 0 || filterShowCancel || filterFooterHint !== void 0;
42376
+ const deferredFilter = filterKind === "text" || filterApplyLabel !== void 0 || Boolean(filterShowCancel) || filterFooterHint !== void 0;
42377
+ const showFilterCancel = filterShowCancel ?? filterKind === "text";
42354
42378
  const [filterOpen, setFilterOpen] = useState17(false);
42355
42379
  const [pendingNegation, setPendingNegation] = useState17(false);
42356
42380
  const [draftFilter, setDraftFilter] = useState17(filterValue);
@@ -42511,7 +42535,7 @@ function ColumnHeaderCell({
42511
42535
  filterKind && deferredFilter ? /* @__PURE__ */ jsxs28("div", { className: "mt-2 border-t border-border pt-2", children: [
42512
42536
  filterFooterHint ? /* @__PURE__ */ jsx38("div", { className: "mb-2 text-xs text-muted-foreground", children: filterFooterHint }) : null,
42513
42537
  /* @__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,
42538
+ showFilterCancel ? /* @__PURE__ */ jsx38(Button, { type: "button", variant: "ghost", size: "sm", onClick: cancelFilter, children: "Cancel" }) : null,
42515
42539
  /* @__PURE__ */ jsx38(Button, { type: "button", size: "sm", onClick: applyFilter, children: filterApplyLabel ?? "Apply" })
42516
42540
  ] })
42517
42541
  ] }) : null,
@@ -42858,7 +42882,7 @@ function FacetChecklist({
42858
42882
  onChange
42859
42883
  }) {
42860
42884
  const [query, setQuery] = useState17("");
42861
- const selected = value?.kind === "select" ? value.values ?? (value.value && value.value !== "__all__" ? [value.value] : []) : [];
42885
+ const selected = value?.kind === "select" ? (value.values ?? (value.value && value.value !== "__all__" ? [value.value] : [])).map((candidate) => candidate === SELECT_EMPTY_VALUE ? "" : candidate) : [];
42862
42886
  const selectedSet = new Set(selected);
42863
42887
  const rows = useMemo8(() => {
42864
42888
  if (!facets) return [];
@@ -42876,7 +42900,7 @@ function FacetChecklist({
42876
42900
  const next = new Set(selectedSet);
42877
42901
  if (next.has(candidate)) next.delete(candidate);
42878
42902
  else next.add(candidate);
42879
- const values = [...next];
42903
+ const values = [...next].map((value2) => value2 === "" ? SELECT_EMPTY_VALUE : value2);
42880
42904
  onChange(
42881
42905
  values.length === 0 ? void 0 : { kind: "select", value: values[0] ?? "", values }
42882
42906
  );
@@ -45442,6 +45466,62 @@ function ToolbarListedLabel({ label, children }) {
45442
45466
  ] });
45443
45467
  }
45444
45468
 
45469
+ // src/data-table/pinned-fold.ts
45470
+ import { useEffect as useEffect17, useRef as useRef18, useState as useState21 } from "react";
45471
+ function pinnedMustFold(room, full) {
45472
+ if (room <= 0 || full === null) return false;
45473
+ return full > room + 0.5;
45474
+ }
45475
+ function usePinnedFold(el, active) {
45476
+ const [folded, setFolded] = useState21(false);
45477
+ const full = useRef18(null);
45478
+ const current = useRef18(false);
45479
+ useEffect17(() => {
45480
+ if (!active || !el) {
45481
+ if (current.current) {
45482
+ current.current = false;
45483
+ setFolded(false);
45484
+ }
45485
+ return;
45486
+ }
45487
+ const row = el.closest("[data-matrx-table-toolbar]") ?? el.parentElement;
45488
+ if (!row) return;
45489
+ let pending = 0;
45490
+ let stopped = false;
45491
+ const measure = () => {
45492
+ pending = 0;
45493
+ if (stopped) return;
45494
+ if (!current.current) {
45495
+ const width = Math.max(el.getBoundingClientRect().width || 0, el.scrollWidth || 0);
45496
+ if (width > 0) full.current = width;
45497
+ }
45498
+ const next = pinnedMustFold(row.clientWidth, full.current);
45499
+ if (next !== current.current) {
45500
+ current.current = next;
45501
+ setFolded(next);
45502
+ }
45503
+ };
45504
+ const schedule = () => {
45505
+ if (pending) return;
45506
+ pending = typeof requestAnimationFrame === "function" && typeof document !== "undefined" && document.visibilityState !== "hidden" ? requestAnimationFrame(measure) : setTimeout(measure, 0);
45507
+ };
45508
+ const sizes = typeof ResizeObserver === "function" ? new ResizeObserver(schedule) : null;
45509
+ sizes?.observe(row);
45510
+ sizes?.observe(el);
45511
+ const content = typeof MutationObserver === "function" ? new MutationObserver(schedule) : null;
45512
+ content?.observe(el, { childList: true, subtree: true, characterData: true });
45513
+ if (typeof window !== "undefined") window.addEventListener("resize", schedule);
45514
+ measure();
45515
+ return () => {
45516
+ stopped = true;
45517
+ sizes?.disconnect();
45518
+ content?.disconnect();
45519
+ if (typeof window !== "undefined") window.removeEventListener("resize", schedule);
45520
+ };
45521
+ }, [el, active]);
45522
+ return folded;
45523
+ }
45524
+
45445
45525
  // src/data-table/coverage.ts
45446
45526
  var PARTIAL_BADGE = "Partial";
45447
45527
  var UNKNOWN_TOTAL_BADGE = "Unknown total";
@@ -45590,7 +45670,7 @@ function rankTableSearchRows(rows, columns, query, options = {}, extraText) {
45590
45670
  }
45591
45671
 
45592
45672
  // src/data-table/ColumnManager.tsx
45593
- import { useEffect as useEffect17, useMemo as useMemo10, useState as useState21 } from "react";
45673
+ import { useEffect as useEffect18, useMemo as useMemo10, useState as useState22 } from "react";
45594
45674
  import { useDndMonitor, useDraggable as useDraggable2, useDroppable } from "@dnd-kit/core";
45595
45675
  import { jsx as jsx43, jsxs as jsxs32 } from "react/jsx-runtime";
45596
45676
  function ColumnManager({
@@ -45605,11 +45685,11 @@ function ColumnManager({
45605
45685
  () => new Map(columns.map((column) => [columnId(column), column])),
45606
45686
  [columns]
45607
45687
  );
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(() => {
45688
+ const [draftOrder, setDraftOrder] = useState22(order);
45689
+ const [draftHidden, setDraftHidden] = useState22(() => new Set(hidden));
45690
+ const [draggedColumnId, setDraggedColumnId] = useState22(null);
45691
+ const [dropTarget, setDropTarget] = useState22(null);
45692
+ useEffect18(() => {
45613
45693
  if (!open) return;
45614
45694
  setDraftOrder(order);
45615
45695
  setDraftHidden(new Set(hidden));
@@ -46096,7 +46176,7 @@ var layeredRuleSchema = z2.object({ id: z2.string().min(1), field: z2.string().m
46096
46176
  var snapshotSchema = z2.object({
46097
46177
  __kind: z2.literal("matrx-table-view"),
46098
46178
  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() }),
46179
+ 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
46180
  columns: z2.object({
46101
46181
  order: z2.array(z2.string().min(1)).refine((order) => new Set(order).size === order.length, {
46102
46182
  message: "Column order must not contain duplicate IDs"
@@ -46152,9 +46232,9 @@ function parseTableViewSnapshot(raw) {
46152
46232
 
46153
46233
  // src/data-table/MatrxUuidCell.tsx
46154
46234
  import {
46155
- useEffect as useEffect18,
46156
- useRef as useRef18,
46157
- useState as useState22
46235
+ useEffect as useEffect19,
46236
+ useRef as useRef19,
46237
+ useState as useState23
46158
46238
  } from "react";
46159
46239
  import { jsx as jsx44, jsxs as jsxs33 } from "react/jsx-runtime";
46160
46240
  var SHORT_LEN = 8;
@@ -46195,11 +46275,11 @@ function MatrxUuidCell({
46195
46275
  }) {
46196
46276
  const { resolveEntityDoors, ResourcePeek } = useMatrxDataTableHost();
46197
46277
  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(
46278
+ const [copied, setCopied] = useState23(false);
46279
+ const [opening, setOpening] = useState23(false);
46280
+ const [peekOpen, setPeekOpen] = useState23(false);
46281
+ const timer = useRef19(null);
46282
+ useEffect19(
46203
46283
  () => () => {
46204
46284
  if (timer.current) clearTimeout(timer.current);
46205
46285
  },
@@ -46494,7 +46574,7 @@ function DataRowInspector({
46494
46574
  }
46495
46575
 
46496
46576
  // src/data-table/DataRowWindow.tsx
46497
- import { useEffect as useEffect19, useState as useState23 } from "react";
46577
+ import { useEffect as useEffect20, useState as useState24 } from "react";
46498
46578
  import { jsx as jsx46, jsxs as jsxs35 } from "react/jsx-runtime";
46499
46579
  function DataRowWindow({
46500
46580
  isOpen,
@@ -46515,8 +46595,8 @@ function DataRowWindow({
46515
46595
  const hasEdit = editContent != null;
46516
46596
  const hasTabs = hasEdit && children == null;
46517
46597
  const initialTab = defaultTab ?? (hasEdit ? "edit" : "view");
46518
- const [tab, setTab] = useState23(initialTab);
46519
- useEffect19(() => {
46598
+ const [tab, setTab] = useState24(initialTab);
46599
+ useEffect20(() => {
46520
46600
  if (!isOpen) return;
46521
46601
  setTab(defaultTab ?? (hasEdit ? "edit" : "view"));
46522
46602
  }, [isOpen, windowId, hasEdit, defaultTab]);
@@ -47761,7 +47841,7 @@ function DirtySavePill({
47761
47841
  }
47762
47842
 
47763
47843
  // src/data-table/EditableTableCell.tsx
47764
- import { useEffect as useEffect20, useRef as useRef19, useState as useState24 } from "react";
47844
+ import { useEffect as useEffect21, useRef as useRef20, useState as useState25 } from "react";
47765
47845
  import { jsx as jsx49, jsxs as jsxs38 } from "react/jsx-runtime";
47766
47846
  function CellRefusal({ reason }) {
47767
47847
  return /* @__PURE__ */ jsx49(
@@ -47823,12 +47903,12 @@ function EditableTableCell({
47823
47903
  editRequest,
47824
47904
  editSeed
47825
47905
  }) {
47826
- const [open, setOpen] = useState24(false);
47827
- const [refusal, setRefusal] = useState24(null);
47828
- useEffect20(() => {
47906
+ const [open, setOpen] = useState25(false);
47907
+ const [refusal, setRefusal] = useState25(null);
47908
+ useEffect21(() => {
47829
47909
  if (editRequest !== void 0) setOpen(true);
47830
47910
  }, [editRequest]);
47831
- useEffect20(() => {
47911
+ useEffect21(() => {
47832
47912
  if (!open) setRefusal(null);
47833
47913
  }, [open]);
47834
47914
  const usePencil = Boolean(href) || editTrigger === "pencil";
@@ -47932,13 +48012,13 @@ function InlineStringEditor({
47932
48012
  editRequest,
47933
48013
  editSeed
47934
48014
  }) {
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);
48015
+ const [editing, setEditing] = useState25(false);
48016
+ const [draft, setDraft] = useState25(value);
48017
+ const [refusal, setRefusal] = useState25(null);
48018
+ const handledEditRequest = useRef20(void 0);
48019
+ const seedRef = useRef20(editSeed);
47940
48020
  seedRef.current = editSeed;
47941
- useEffect20(() => {
48021
+ useEffect21(() => {
47942
48022
  if (editRequest === void 0 || handledEditRequest.current === editRequest) return;
47943
48023
  handledEditRequest.current = editRequest;
47944
48024
  setDraft(seedRef.current ?? value);
@@ -48098,8 +48178,8 @@ function DateEditor({
48098
48178
  onCommit,
48099
48179
  onCancel
48100
48180
  }) {
48101
- const [draft, setDraft] = useState24(value);
48102
- const done = useRef19(false);
48181
+ const [draft, setDraft] = useState25(value);
48182
+ const done = useRef20(false);
48103
48183
  const finish = () => {
48104
48184
  if (done.current) return;
48105
48185
  done.current = true;
@@ -48134,8 +48214,8 @@ function TagsEditor({
48134
48214
  onCommit,
48135
48215
  onCancel
48136
48216
  }) {
48137
- const [tags, setTags] = useState24(value);
48138
- const [draft, setDraft] = useState24("");
48217
+ const [tags, setTags] = useState25(value);
48218
+ const [draft, setDraft] = useState25("");
48139
48219
  const add = (raw) => {
48140
48220
  const next = raw.trim();
48141
48221
  if (!next || tags.includes(next)) return;
@@ -48232,7 +48312,7 @@ function NumberEditor({
48232
48312
  onCommit,
48233
48313
  onCancel
48234
48314
  }) {
48235
- const [draft, setDraft] = useState24(String(value));
48315
+ const [draft, setDraft] = useState25(String(value));
48236
48316
  return /* @__PURE__ */ jsxs38("div", { className: "flex flex-col gap-2", children: [
48237
48317
  /* @__PURE__ */ jsx49(
48238
48318
  Input,
@@ -48636,6 +48716,7 @@ function safeQueryPage(requestedPage, totalItems, pageSize) {
48636
48716
 
48637
48717
  // src/data-table/MatrxDataTable.tsx
48638
48718
  import { Fragment as Fragment12, jsx as jsx51, jsxs as jsxs40 } from "react/jsx-runtime";
48719
+ var EMPTY_TABLE_ROWS = [];
48639
48720
  function TableToolbarAction({
48640
48721
  HostAction,
48641
48722
  ariaLabel,
@@ -48745,7 +48826,7 @@ function MatrxDataTableWithUrlState({
48745
48826
  ...urlState.history === void 0 ? {} : { history: urlState.history },
48746
48827
  ...urlState.textHistory === void 0 ? {} : { textHistory: urlState.textHistory }
48747
48828
  });
48748
- useEffect21(() => {
48829
+ useEffect22(() => {
48749
48830
  if (activeUrlTableIds.has(urlState.id)) {
48750
48831
  throw new Error(
48751
48832
  `Duplicate MatrxDataTable urlState.id "${urlState.id}" on one page. Give every table a unique stable id.`
@@ -48854,7 +48935,7 @@ var DND_MEASURING = { droppable: { strategy: MeasuringStrategy.Always } };
48854
48935
  var NO_LAYERED_FILTERS = [];
48855
48936
  var NO_GROUPING_VALUE = "__matrx_no_grouping__";
48856
48937
  function useRenderEpoch(values) {
48857
- const held = useRef20(null);
48938
+ const held = useRef21(null);
48858
48939
  const previous = held.current;
48859
48940
  if (previous !== null && previous.values.length === values.length && previous.values.every((value, i) => Object.is(value, values[i]))) {
48860
48941
  return previous.epoch;
@@ -48998,9 +49079,9 @@ function MatrxDataTableCore(coreProps) {
48998
49079
  } = coreProps;
48999
49080
  const appendQuery = query?.mode === "controlled-append" ? query : null;
49000
49081
  const appendQueryKey = appendQuery?.pagination.queryKey ?? null;
49001
- const committedAppendQueryKey = useRef20(appendQueryKey);
49082
+ const committedAppendQueryKey = useRef21(appendQueryKey);
49002
49083
  const appendSourceChanged = appendQuery !== null && committedAppendQueryKey.current !== appendQueryKey;
49003
- const data = (appendQuery ? appendQuery.pagination.rows : suppliedData) ?? [];
49084
+ const data = (appendQuery ? appendQuery.pagination.rows : suppliedData) ?? EMPTY_TABLE_ROWS;
49004
49085
  const readView = tableReadView(read, data.length, appendQuery ? appendQuery.pagination.loading : suppliedLoading);
49005
49086
  const isLoading = readView.loading;
49006
49087
  const isFetching = appendQuery ? appendQuery.pagination.isFetchingNextPage : suppliedFetching;
@@ -49011,19 +49092,21 @@ function MatrxDataTableCore(coreProps) {
49011
49092
  const ContextMenuBoundary = host.ContextMenuBoundary ?? TableContextPassthrough;
49012
49093
  const resolvedDensity = density ?? host.defaultDensity ?? "normal";
49013
49094
  const SavedViews = host.SavedViews;
49095
+ const savedViewsId = tableId ?? urlState?.id;
49096
+ const showViewTabs = viewTabs && Boolean(viewTabsStore || savedViewsId && SavedViews);
49014
49097
  const Link = host.Link ?? DefaultTableLink;
49015
49098
  const SidePanelSurface = host.SidePanelSurface ?? DefaultTableSidePanel;
49016
49099
  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 });
49100
+ const [savedViewError, setSavedViewError] = useState26(null);
49101
+ const [toolbarActionError, setToolbarActionError] = useState26(null);
49102
+ const [toolbarActionPending, setToolbarActionPending] = useState26({ refresh: false, add: false });
49103
+ const toolbarActionPendingRef = useRef21({ refresh: false, add: false });
49021
49104
  const CHECKBOX_TAP_AREA = "h-4 w-4 touch-manipulation";
49022
49105
  const mobileCardsClass = mobileCardsBreakpoint === "lg" ? "lg:hidden" : "sm:hidden";
49023
49106
  const tableWithCardsClass = mobileCardsBreakpoint === "lg" ? "max-lg:hidden" : "max-sm:hidden";
49024
49107
  const cardsQuery = mobileCardsBreakpoint === "lg" ? "(max-width: 1023px)" : "(max-width: 639px)";
49025
- const [cardsActive, setCardsActive] = useState25(null);
49026
- useEffect21(() => {
49108
+ const [cardsActive, setCardsActive] = useState26(null);
49109
+ useEffect22(() => {
49027
49110
  if (!mobileCards || typeof window === "undefined" || !window.matchMedia) return;
49028
49111
  const mql = window.matchMedia(cardsQuery);
49029
49112
  const read2 = () => setCardsActive(mql.matches);
@@ -49039,10 +49122,10 @@ function MatrxDataTableCore(coreProps) {
49039
49122
  const appendDefaultsToSourceProcessing = appendQuery !== null && sourceProcessing === void 0;
49040
49123
  const sourceColumnFilterOwnership = sourceProcessing?.columnFilters;
49041
49124
  const sourceOwnsColumnFilters = appendDefaultsToSourceProcessing ? true : sourceColumnFilterOwnership === "source" || typeof sourceColumnFilterOwnership === "object" && sourceColumnFilterOwnership.source.length > 0;
49042
- const remoteQueryUsesLocalColumnFilters = remoteQuery !== null && sourceColumnFilterOwnership === "local";
49125
+ const remoteQueryUsesLocalProcessing = remoteQuery !== null && (sourceColumnFilterOwnership === "local" || remoteQuery.mode === "controlled" && (sourceProcessing?.search === "local" || sourceProcessing?.sort === "local"));
49043
49126
  const sourceOwnsSort = appendQuery !== null && sourceProcessing === void 0 ? true : sourceProcessing?.sort === "source";
49044
49127
  const sourceOwnsIntelligentSearch = sourceProcessing?.intelligentSearch === "source";
49045
- const sourceOwnsSearch = remoteQuery?.mode === "controlled" || appendQuery !== null && sourceProcessing === void 0 || sourceProcessing?.search === "source" || sourceOwnsIntelligentSearch;
49128
+ const sourceOwnsSearch = remoteQuery?.mode === "controlled" && sourceProcessing?.search !== "local" || appendQuery !== null && sourceProcessing === void 0 || sourceProcessing?.search === "source" || sourceOwnsIntelligentSearch;
49046
49129
  const intelligentSearchEnabled = toolbar?.intelligentSearch !== void 0 && (sourceOwnsIntelligentSearch || remoteQuery === null && !sourceOwnsSearch);
49047
49130
  const emitControlledQueryChange = useCallback10(
49048
49131
  (patch, options) => {
@@ -49053,8 +49136,8 @@ function MatrxDataTableCore(coreProps) {
49053
49136
  },
49054
49137
  [controlledQuery]
49055
49138
  );
49056
- const [internalSearch, setInternalSearch] = useState25("");
49057
- const [draggedRowId, setDraggedRowId] = useState25(null);
49139
+ const [internalSearch, setInternalSearch] = useState26("");
49140
+ const [draggedRowId, setDraggedRowId] = useState26(null);
49058
49141
  const hierarchySensors = useSensors(useSensor(PointerSensor, POINTER_SENSOR_OPTIONS));
49059
49142
  const toolbarSearchControlled = toolbar?.searchValue !== void 0;
49060
49143
  const searchValue = controlledQuery ? controlledQuery.state.search : toolbarSearchControlled ? toolbar?.searchValue ?? "" : internalSearch;
@@ -49066,7 +49149,7 @@ function MatrxDataTableCore(coreProps) {
49066
49149
  }
49067
49150
  toolbar?.onSearchChange?.(v);
49068
49151
  };
49069
- const [internalSearchMatchMode, setInternalSearchMatchMode] = useState25(
49152
+ const [internalSearchMatchMode, setInternalSearchMatchMode] = useState26(
49070
49153
  toolbar?.searchMatch?.defaultMode ?? "contains"
49071
49154
  );
49072
49155
  const searchMatchMode = controlledQuery ? controlledQuery.state.searchMatchMode ?? toolbar?.searchMatch?.defaultMode ?? "contains" : internalSearchMatchMode;
@@ -49077,7 +49160,7 @@ function MatrxDataTableCore(coreProps) {
49077
49160
  }
49078
49161
  setInternalSearchMatchMode(mode);
49079
49162
  };
49080
- const [internalSearchScope, setInternalSearchScope] = useState25("all");
49163
+ const [internalSearchScope, setInternalSearchScope] = useState26("all");
49081
49164
  const searchScope = controlledQuery ? controlledQuery.state.searchScope ?? "all" : internalSearchScope;
49082
49165
  const setSearchScope = (scope) => {
49083
49166
  if (controlledQuery) {
@@ -49086,7 +49169,7 @@ function MatrxDataTableCore(coreProps) {
49086
49169
  }
49087
49170
  setInternalSearchScope(scope);
49088
49171
  };
49089
- const [internalAnyOf, setInternalAnyOf] = useState25("");
49172
+ const [internalAnyOf, setInternalAnyOf] = useState26("");
49090
49173
  const toolbarAnyOfControlled = toolbar?.anyOf?.value !== void 0;
49091
49174
  const anyOfValue = controlledQuery ? controlledQuery.state.anyOf : toolbarAnyOfControlled ? toolbar?.anyOf?.value ?? "" : internalAnyOf;
49092
49175
  const setAnyOfValue = (v) => {
@@ -49097,7 +49180,7 @@ function MatrxDataTableCore(coreProps) {
49097
49180
  }
49098
49181
  toolbar?.anyOf?.onChange?.(v);
49099
49182
  };
49100
- const [internalLayeredFilters, setInternalLayeredFilters] = useState25([]);
49183
+ const [internalLayeredFilters, setInternalLayeredFilters] = useState26([]);
49101
49184
  const layeredFilters = controlledQuery ? controlledQuery.state.layeredFilters ?? NO_LAYERED_FILTERS : internalLayeredFilters;
49102
49185
  const setLayeredFilters = (next) => {
49103
49186
  if (controlledQuery) {
@@ -49106,7 +49189,7 @@ function MatrxDataTableCore(coreProps) {
49106
49189
  }
49107
49190
  setInternalLayeredFilters(next);
49108
49191
  };
49109
- const [internalColumnFilters, setInternalColumnFilters] = useState25({});
49192
+ const [internalColumnFilters, setInternalColumnFilters] = useState26({});
49110
49193
  const columnFilters = controlledQuery ? controlledQuery.state.columnFilters : internalColumnFilters;
49111
49194
  const localColumnFilters = useMemo11(() => {
49112
49195
  if (appendDefaultsToSourceProcessing) return {};
@@ -49130,7 +49213,7 @@ function MatrxDataTableCore(coreProps) {
49130
49213
  }
49131
49214
  setInternalColumnFilters(nextFilters);
49132
49215
  };
49133
- const [internalSort, setInternalSort] = useState25(defaultSort);
49216
+ const [internalSort, setInternalSort] = useState26(defaultSort);
49134
49217
  const sort = controlledQuery ? controlledQuery.state.sort : internalSort;
49135
49218
  const setSort = (next) => {
49136
49219
  if (controlledQuery) {
@@ -49139,7 +49222,7 @@ function MatrxDataTableCore(coreProps) {
49139
49222
  }
49140
49223
  setInternalSort(next);
49141
49224
  };
49142
- const [internalPage, setInternalPage] = useState25(1);
49225
+ const [internalPage, setInternalPage] = useState26(1);
49143
49226
  const page = controlledQuery ? controlledQuery.state.page : internalPage;
49144
49227
  const setPage = (next) => {
49145
49228
  if (controlledQuery) {
@@ -49148,7 +49231,7 @@ function MatrxDataTableCore(coreProps) {
49148
49231
  }
49149
49232
  setInternalPage(next);
49150
49233
  };
49151
- const [internalPageSize, setInternalPageSize] = useState25(
49234
+ const [internalPageSize, setInternalPageSize] = useState26(
49152
49235
  defaultPageSize
49153
49236
  );
49154
49237
  const pageSize = controlledQuery ? controlledQuery.state.pageSize : internalPageSize;
@@ -49159,28 +49242,28 @@ function MatrxDataTableCore(coreProps) {
49159
49242
  }
49160
49243
  setInternalPageSize(next);
49161
49244
  };
49162
- const [uncontrolledSelectedId, setUncontrolledSelectedId] = useState25(null);
49245
+ const [uncontrolledSelectedId, setUncontrolledSelectedId] = useState26(null);
49163
49246
  const rawSelectedId = controlledSelectedId !== void 0 ? controlledSelectedId : uncontrolledSelectedId;
49164
49247
  const selectedId = appendSourceChanged ? null : rawSelectedId;
49165
49248
  const setSelectedId = (id) => {
49166
49249
  if (controlledSelectedId === void 0) setUncontrolledSelectedId(id);
49167
49250
  onSelectedIdChange?.(id);
49168
49251
  };
49169
- const [uncontrolledWindowRowId, setUncontrolledWindowRowId] = useState25(null);
49252
+ const [uncontrolledWindowRowId, setUncontrolledWindowRowId] = useState26(null);
49170
49253
  const rawWindowRowId = controlledWindowRowId !== void 0 ? controlledWindowRowId : uncontrolledWindowRowId;
49171
49254
  const windowRowId = appendSourceChanged ? null : rawWindowRowId;
49172
49255
  const setWindowRowId = (id) => {
49173
49256
  if (controlledWindowRowId === void 0) setUncontrolledWindowRowId(id);
49174
49257
  onWindowRowIdChange?.(id);
49175
49258
  };
49176
- const [windowRowSnapshot, setWindowRowSnapshot] = useState25(null);
49259
+ const [windowRowSnapshot, setWindowRowSnapshot] = useState26(null);
49177
49260
  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);
49261
+ const [editsByScope, setEditsByScope] = useState26({});
49262
+ const editRevisionRef = useRef21({});
49263
+ const [savingByScope, setSavingByScope] = useState26({});
49264
+ const savingScopesRef = useRef21(/* @__PURE__ */ new Set());
49265
+ const [editRequest, setEditRequest] = useState26(null);
49266
+ const [confirmForeignDraftDiscard, setConfirmForeignDraftDiscard] = useState26(false);
49184
49267
  const edits = editsByScope[editScopeKey]?.values ?? {};
49185
49268
  const saving = (savingByScope[editScopeKey] ?? 0) > 0;
49186
49269
  const setEdits = (next) => {
@@ -49247,7 +49330,7 @@ function MatrxDataTableCore(coreProps) {
49247
49330
  rows: Object.entries(draft.values).map(([rowId, columns2]) => ({ rowId, columns: columns2 }))
49248
49331
  }));
49249
49332
  const selection = appendSourceChanged && selectionConfig ? { ...selectionConfig, selectedIds: [] } : selectionConfig;
49250
- useEffect21(() => {
49333
+ useEffect22(() => {
49251
49334
  const previous = committedAppendQueryKey.current;
49252
49335
  committedAppendQueryKey.current = appendQueryKey;
49253
49336
  if (previous === null || appendQueryKey === null || previous === appendQueryKey) {
@@ -49265,13 +49348,13 @@ function MatrxDataTableCore(coreProps) {
49265
49348
  onWindowRowIdChange,
49266
49349
  selectionConfig
49267
49350
  ]);
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);
49351
+ const scrollRef = useRef21(null);
49352
+ const tableRef = useRef21(null);
49353
+ const tableHeaderRef = useRef21(null);
49354
+ const cardsScrollRef = useRef21(null);
49355
+ const [documentStickyHeader, setDocumentStickyHeader] = useState26(false);
49356
+ const documentStickyHeaderRef = useRef21(false);
49357
+ const previousAppendKeyForScrollReset = useRef21(appendQueryKey);
49275
49358
  useLayoutEffect5(() => {
49276
49359
  const previous = previousAppendKeyForScrollReset.current;
49277
49360
  previousAppendKeyForScrollReset.current = appendQueryKey;
@@ -49297,13 +49380,13 @@ function MatrxDataTableCore(coreProps) {
49297
49380
  ...appendScrollPolicy?.mode === "scroll" && appendScrollPolicy.thresholdPx !== void 0 ? { thresholdPx: appendScrollPolicy.thresholdPx } : {},
49298
49381
  ...appendScrollPolicy?.mode === "scroll" && appendScrollPolicy.intentTimeoutMs !== void 0 ? { intentTimeoutMs: appendScrollPolicy.intentTimeoutMs } : {}
49299
49382
  });
49300
- const rootRef = useRef20(null);
49383
+ const rootRef = useRef21(null);
49301
49384
  useClippedContentGuard(rootRef, {
49302
49385
  label: typeof copy === "object" && copy.listLabel ? `Table: ${copy.listLabel}` : "MatrxDataTable"
49303
49386
  });
49304
- const [scrollHintRight, setScrollHintRight] = useState25(false);
49305
- const [scrollHintLeft, setScrollHintLeft] = useState25(false);
49306
- const [scrollHintRightInset, setScrollHintRightInset] = useState25(6);
49387
+ const [scrollHintRight, setScrollHintRight] = useState26(false);
49388
+ const [scrollHintLeft, setScrollHintLeft] = useState26(false);
49389
+ const [scrollHintRightInset, setScrollHintRightInset] = useState26(6);
49307
49390
  const updateScrollHint = useCallback10(() => {
49308
49391
  const el = scrollRef.current;
49309
49392
  if (!el) return;
@@ -49321,7 +49404,7 @@ function MatrxDataTableCore(coreProps) {
49321
49404
  behavior: "smooth"
49322
49405
  });
49323
49406
  };
49324
- useEffect21(() => {
49407
+ useEffect22(() => {
49325
49408
  updateScrollHint();
49326
49409
  window.addEventListener("resize", updateScrollHint);
49327
49410
  const el = scrollRef.current;
@@ -49395,26 +49478,26 @@ function MatrxDataTableCore(coreProps) {
49395
49478
  window.removeEventListener("resize", requestUpdate);
49396
49479
  };
49397
49480
  }, [stickyHeader, data, columns]);
49398
- const [columnOrder, setColumnOrder] = useState25(() => columnState?.order ?? columns.map(columnId));
49399
- const [hiddenColumnIds, setHiddenColumnIds] = useState25(
49481
+ const [columnOrder, setColumnOrder] = useState26(() => columnState?.order ?? columns.map(columnId));
49482
+ const [hiddenColumnIds, setHiddenColumnIds] = useState26(
49400
49483
  () => new Set(columnState?.hidden ?? columns.filter((column) => column.hidden).map(columnId))
49401
49484
  );
49402
- const [columnWidths, setColumnWidths] = useState25(
49485
+ const [columnWidths, setColumnWidths] = useState26(
49403
49486
  () => normalizeColumnWidthsForColumns(columnState?.widths, columns)
49404
49487
  );
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);
49488
+ const [fixedTableGeometry, setFixedTableGeometry] = useState26(null);
49489
+ const knownColumnIds = useRef21(new Set(columns.map(columnId)));
49490
+ const draggedColumnId = useRef21(null);
49491
+ const columnDragActive = useRef21(false);
49492
+ const columnDragRaf = useRef21(null);
49493
+ const columnDragScrollDirection = useRef21(0);
49494
+ const [columnDragPreview, setColumnDragPreview] = useState26(null);
49412
49495
  const stopColumnDragScroll = useCallback10(() => {
49413
49496
  if (columnDragRaf.current !== null) cancelAnimationFrame(columnDragRaf.current);
49414
49497
  columnDragRaf.current = null;
49415
49498
  columnDragScrollDirection.current = 0;
49416
49499
  }, []);
49417
- useEffect21(() => () => {
49500
+ useEffect22(() => () => {
49418
49501
  columnDragActive.current = false;
49419
49502
  stopColumnDragScroll();
49420
49503
  }, [stopColumnDragScroll]);
@@ -49452,7 +49535,7 @@ function MatrxDataTableCore(coreProps) {
49452
49535
  setHiddenColumnIds(hidden);
49453
49536
  }
49454
49537
  }, [columnState]);
49455
- const [internalColumnManagerOpen, setInternalColumnManagerOpen] = useState25(false);
49538
+ const [internalColumnManagerOpen, setInternalColumnManagerOpen] = useState26(false);
49456
49539
  const columnManagerOpen = controlledColumnManager?.open ?? internalColumnManagerOpen;
49457
49540
  const setColumnManagerOpen = controlledColumnManager?.onOpenChange ?? setInternalColumnManagerOpen;
49458
49541
  const columnIds = useMemo11(() => columns.map(columnId), [columns]);
@@ -49462,7 +49545,7 @@ function MatrxDataTableCore(coreProps) {
49462
49545
  () => normalizeColumnWidthsForColumns(columnState?.widths ?? columnWidths, columns),
49463
49546
  [columns, columnState?.widths, columnWidths]
49464
49547
  );
49465
- const resizeGestureSnapshotRef = useRef20(null);
49548
+ const resizeGestureSnapshotRef = useRef21(null);
49466
49549
  const measureVisibleColumnWidths = useCallback10(() => {
49467
49550
  const measured = {};
49468
49551
  const headers = tableRef.current ? Array.from(tableRef.current.querySelectorAll(
@@ -49540,7 +49623,7 @@ function MatrxDataTableCore(coreProps) {
49540
49623
  }
49541
49624
  setColumnWidths(normalized);
49542
49625
  }, [columnIds, columnState, columns, measureFixedTableGeometry, measureVisibleColumnWidths]);
49543
- useEffect21(() => {
49626
+ useEffect22(() => {
49544
49627
  const ids = columns.map(columnId);
49545
49628
  if (columnState) return;
49546
49629
  const previousIds = knownColumnIds.current;
@@ -49607,7 +49690,7 @@ function MatrxDataTableCore(coreProps) {
49607
49690
  const fixedLayoutActive = usesMeasuredFixedLayout && fixedTableGeometry !== null;
49608
49691
  const freezeWanted = visibleColumns.some((column) => column.frozen);
49609
49692
  const selectionColumnWidth = fixedTableGeometry?.selectionWidth ?? (selection && (freezeWanted || fitToWidth) ? SELECTION_COLUMN_PX : void 0);
49610
- const [fitSpace, setFitSpace] = useState25(null);
49693
+ const [fitSpace, setFitSpace] = useState26(null);
49611
49694
  useLayoutEffect5(() => {
49612
49695
  if (!fitToWidth) {
49613
49696
  setFitSpace(null);
@@ -49623,19 +49706,28 @@ function MatrxDataTableCore(coreProps) {
49623
49706
  ...strips.map((strip) => Math.ceil(strip.scrollWidth) + 16),
49624
49707
  actionsHeader ? Math.ceil(actionsHeader.scrollWidth) : 0
49625
49708
  );
49626
- const next = { width: el.clientWidth, actions };
49627
- setFitSpace((now) => now && now.width === next.width && now.actions === next.actions ? now : next);
49709
+ const table2 = el.querySelector(":scope > table");
49710
+ const spill = table2 && table2.hasAttribute("data-matrx-table-fit") ? Math.max(0, el.scrollWidth - el.clientWidth) : 0;
49711
+ setFitSpace((now) => {
49712
+ const sameWidth = now !== null && now.width === el.clientWidth;
49713
+ const slack = sameWidth ? now.slack + spill : spill;
49714
+ const next = { width: el.clientWidth, actions, slack };
49715
+ return now && now.width === next.width && now.actions === next.actions && now.slack === next.slack ? now : next;
49716
+ });
49628
49717
  };
49629
49718
  read2();
49630
49719
  if (typeof ResizeObserver === "undefined") return;
49631
49720
  const observer = new ResizeObserver(read2);
49632
49721
  observer.observe(el);
49722
+ const table = el.querySelector(":scope > table");
49723
+ if (table) observer.observe(table);
49633
49724
  return () => observer.disconnect();
49634
49725
  }, [fitToWidth, data.length]);
49635
49726
  const fittedWidths = useMemo11(() => {
49636
49727
  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);
49728
+ const keepsItsWidth = (col) => resolveColumnMarker(col) !== void 0 || col.resizable === false && pixelWidth(col.width) !== void 0;
49729
+ const scaling = visibleColumns.filter((col) => !keepsItsWidth(col));
49730
+ const fixed = visibleColumns.filter(keepsItsWidth).reduce((sum, col) => sum + (pixelWidth(col.width) ?? 40), 0);
49639
49731
  const utilities = (selection ? selectionColumnWidth ?? SELECTION_COLUMN_PX : 0) + fitSpace.actions;
49640
49732
  return fitColumnWidths(
49641
49733
  scaling.map(columnId),
@@ -49643,7 +49735,7 @@ function MatrxDataTableCore(coreProps) {
49643
49735
  const col = scaling.find((c) => columnId(c) === id);
49644
49736
  return effectiveColumnWidths[id] ?? pixelWidth(col?.width) ?? FIT_DEFAULT_COLUMN_PX;
49645
49737
  },
49646
- fitSpace.width - utilities - fixed
49738
+ fitSpace.width - utilities - fixed - fitSpace.slack
49647
49739
  );
49648
49740
  }, [fitToWidth, fitSpace, visibleColumns, selection, selectionColumnWidth, effectiveColumnWidths]);
49649
49741
  const fitActive = fittedWidths !== null;
@@ -49721,7 +49813,7 @@ function MatrxDataTableCore(coreProps) {
49721
49813
  const effectiveCopy = copy === false ? void 0 : copy ?? defaultCopy;
49722
49814
  const effectiveCopyColumns = copy === void 0 ? declaredVisibleCopyColumns : visibleColumns;
49723
49815
  const copySubsetVariant2 = useCopySubsetVariant();
49724
- const chromeLatest = useRef20({
49816
+ const chromeLatest = useRef21({
49725
49817
  processed: [],
49726
49818
  data: [],
49727
49819
  toggleAllOnPage: () => void 0,
@@ -49765,7 +49857,7 @@ function MatrxDataTableCore(coreProps) {
49765
49857
  [columns, data, toolbar?.intelligentSearch?.roles, toolbar?.intelligentSearch?.scopes]
49766
49858
  );
49767
49859
  const processed = useMemo11(() => {
49768
- if (remoteQuery && !appendUsesLocalProcessing && !remoteQueryUsesLocalColumnFilters) return data;
49860
+ if (remoteQuery && !appendUsesLocalProcessing && !remoteQueryUsesLocalProcessing) return data;
49769
49861
  if (processLocalRows) {
49770
49862
  return processLocalRows(data, {
49771
49863
  page,
@@ -49821,15 +49913,15 @@ function MatrxDataTableCore(coreProps) {
49821
49913
  pageSize,
49822
49914
  remoteQuery,
49823
49915
  appendUsesLocalProcessing,
49824
- remoteQueryUsesLocalColumnFilters,
49916
+ remoteQueryUsesLocalProcessing,
49825
49917
  sourceOwnsColumnFilters,
49826
49918
  sourceOwnsSort,
49827
49919
  sourceOwnsSearch,
49828
49920
  intelligentSearchEnabled,
49829
49921
  searchScope
49830
49922
  ]);
49831
- const lastNotifiedViewRows = useRef20(null);
49832
- useEffect21(() => {
49923
+ const lastNotifiedViewRows = useRef21(null);
49924
+ useEffect22(() => {
49833
49925
  if (!onViewChange) {
49834
49926
  lastNotifiedViewRows.current = null;
49835
49927
  return;
@@ -49838,7 +49930,7 @@ function MatrxDataTableCore(coreProps) {
49838
49930
  lastNotifiedViewRows.current = processed;
49839
49931
  if (changed) onViewChange(processed);
49840
49932
  }, [processed, onViewChange]);
49841
- useEffect21(() => {
49933
+ useEffect22(() => {
49842
49934
  if (controlledQuery) return;
49843
49935
  setInternalPage(1);
49844
49936
  }, [
@@ -49891,7 +49983,7 @@ function MatrxDataTableCore(coreProps) {
49891
49983
  return processed.slice(start, start + effectivePageSize);
49892
49984
  }, [processed, safePage, effectivePageSize, pageSize, remoteQuery, hidePagination, localProgressiveEnabled, progressiveRows.rows]);
49893
49985
  const groupingColumnId = grouping?.columnId ?? null;
49894
- const [uncontrolledCollapsed, setUncontrolledCollapsed] = useState25([]);
49986
+ const [uncontrolledCollapsed, setUncontrolledCollapsed] = useState26([]);
49895
49987
  const collapsedGroups = grouping?.collapsed ?? uncontrolledCollapsed;
49896
49988
  const setCollapsedGroups = useCallback10(
49897
49989
  (next) => {
@@ -49948,9 +50040,9 @@ function MatrxDataTableCore(coreProps) {
49948
50040
  return run;
49949
50041
  }, [visibleColumns, frozenColumns]);
49950
50042
  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({
50043
+ const [rowWindow, setRowWindow] = useState26(null);
50044
+ const [columnWindow, setColumnWindow] = useState26(null);
50045
+ const windowInputs = useRef21({
49954
50046
  virtualizeActive: false,
49955
50047
  bodyEntryCount: 0,
49956
50048
  virtualRowHeight: 40,
@@ -50022,7 +50114,7 @@ function MatrxDataTableCore(coreProps) {
50022
50114
  frozenRunLength
50023
50115
  ]);
50024
50116
  const metricsWanted = virtualizeActive || columnVirtualizeActive;
50025
- useEffect21(() => {
50117
+ useEffect22(() => {
50026
50118
  recomputeWindows();
50027
50119
  }, [
50028
50120
  recomputeWindows,
@@ -50034,7 +50126,7 @@ function MatrxDataTableCore(coreProps) {
50034
50126
  columnWindowWidth,
50035
50127
  frozenRunLength
50036
50128
  ]);
50037
- useEffect21(() => {
50129
+ useEffect22(() => {
50038
50130
  if (!metricsWanted) return;
50039
50131
  const el = scrollRef.current;
50040
50132
  if (!el) return;
@@ -50103,7 +50195,7 @@ function MatrxDataTableCore(coreProps) {
50103
50195
  windowed.push({ kind: "spacer", height: effectiveRowWindow.padEnd, place: "end" });
50104
50196
  return windowed;
50105
50197
  }, [groupedRenderRows, collapsedGroups, paginated, effectiveRowWindow]);
50106
- const getRowIdRef = useRef20(getRowId);
50198
+ const getRowIdRef = useRef21(getRowId);
50107
50199
  getRowIdRef.current = getRowId;
50108
50200
  const spreadsheetRowIds = useMemo11(
50109
50201
  () => paginated.map((row) => getRowIdRef.current(row)),
@@ -50124,7 +50216,7 @@ function MatrxDataTableCore(coreProps) {
50124
50216
  return map;
50125
50217
  }, [visibleColumns]);
50126
50218
  const spreadsheetEnabled = Boolean(spreadsheet && spreadsheet.enabled !== false);
50127
- const openRowRef = useRef20(() => void 0);
50219
+ const openRowRef = useRef21(() => void 0);
50128
50220
  const sheet = useSpreadsheetGrid(
50129
50221
  spreadsheetEnabled && spreadsheet ? {
50130
50222
  rowIds: spreadsheetRowIds,
@@ -50166,12 +50258,12 @@ function MatrxDataTableCore(coreProps) {
50166
50258
  } : null
50167
50259
  );
50168
50260
  if (spreadsheet?.controllerRef) spreadsheet.controllerRef.current = spreadsheetEnabled ? sheet.controller : null;
50169
- const sheetRef = useRef20(sheet);
50261
+ const sheetRef = useRef21(sheet);
50170
50262
  sheetRef.current = sheet;
50171
- const onSheetSelectionRef = useRef20(spreadsheet?.onSelectionChange);
50263
+ const onSheetSelectionRef = useRef21(spreadsheet?.onSelectionChange);
50172
50264
  onSheetSelectionRef.current = spreadsheet?.onSelectionChange;
50173
50265
  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(() => {
50266
+ useEffect22(() => {
50175
50267
  const tell = onSheetSelectionRef.current;
50176
50268
  if (!tell) return;
50177
50269
  const current = sheetRef.current;
@@ -50188,10 +50280,11 @@ function MatrxDataTableCore(coreProps) {
50188
50280
  tsv: current.selectionTsv()
50189
50281
  });
50190
50282
  }, [sheetSelectionKey]);
50191
- const searchValueRef = useRef20(searchValue);
50283
+ const searchValueRef = useRef21(searchValue);
50192
50284
  searchValueRef.current = searchValue;
50193
50285
  const facetsEnabled = Boolean(facets && facets.enabled !== false);
50194
- const [facetState, setFacetState] = useState25({});
50286
+ const coreSuggestionsEnabled = facets?.enabled !== false;
50287
+ const [facetState, setFacetState] = useState26({});
50195
50288
  const facetReadCell = useCallback10(
50196
50289
  (row, colId) => {
50197
50290
  if (facets?.readCell) return facets.readCell(row, colId);
@@ -50200,12 +50293,37 @@ function MatrxDataTableCore(coreProps) {
50200
50293
  },
50201
50294
  [facets, visibleColumns]
50202
50295
  );
50203
- const facetInputsRef = useRef20({ data, facets, facetReadCell });
50204
- facetInputsRef.current = { data, facets, facetReadCell };
50205
- const facetRequestRef = useRef20(/* @__PURE__ */ new Map());
50296
+ const coreFacetTotal = remoteQuery?.mode === "controlled" ? remoteQuery.totalItems : appendQuery?.pagination.sourceRecords?.total ?? coverage?.matched ?? coverage?.total;
50297
+ const coreFacetLoaded = appendQuery?.pagination.sourceRecords?.loaded;
50298
+ const facetInputsRef = useRef21({ data, facets, facetReadCell, coreFacetTotal, coreFacetLoaded });
50299
+ facetInputsRef.current = { data, facets, facetReadCell, coreFacetTotal, coreFacetLoaded };
50300
+ const facetRequestRef = useRef21(/* @__PURE__ */ new Map());
50206
50301
  const requestFacets = useCallback10((colId) => {
50207
- const { data: rows, facets: config, facetReadCell: readCell } = facetInputsRef.current;
50208
- if (!config || config.enabled === false) return;
50302
+ const { data: rows, facets: config, facetReadCell: readCell, coreFacetTotal: total, coreFacetLoaded: loaded } = facetInputsRef.current;
50303
+ if (!config || config.enabled === false) {
50304
+ const complete2 = localFacetsAreComplete(loaded ?? rows.length, total ?? rows.length);
50305
+ const hasArrayValue = rows.some((row) => {
50306
+ try {
50307
+ return Array.isArray(readCell(row, colId));
50308
+ } catch {
50309
+ return false;
50310
+ }
50311
+ });
50312
+ const suggestions = computeColumnFacets({
50313
+ columnId: colId,
50314
+ rows,
50315
+ readValue: readCell,
50316
+ complete: complete2
50317
+ });
50318
+ setFacetState((current) => ({
50319
+ ...current,
50320
+ [colId]: {
50321
+ loading: false,
50322
+ data: !hasArrayValue && suggestions.distinctCount + (suggestions.blank > 0 ? 1 : 0) < CORE_SUGGESTION_DISTINCT_EXCLUSIVE_LIMIT ? suggestions : null
50323
+ }
50324
+ }));
50325
+ return;
50326
+ }
50209
50327
  const complete = localFacetsAreComplete(rows.length, config.totalRows);
50210
50328
  const limit = config.limit;
50211
50329
  if (complete || !config.source) {
@@ -50262,13 +50380,12 @@ function MatrxDataTableCore(coreProps) {
50262
50380
  }));
50263
50381
  });
50264
50382
  }, []);
50265
- useEffect21(() => {
50266
- if (!facetsEnabled) return;
50383
+ useEffect22(() => {
50267
50384
  setFacetState({});
50268
50385
  facetRequestRef.current = /* @__PURE__ */ new Map();
50269
- }, [facetsEnabled, data, searchValue]);
50386
+ }, [facetsEnabled, data, searchValue, coreFacetTotal, coreFacetLoaded]);
50270
50387
  const totalIsKnown = !isLoading && !readView.failure;
50271
- useEffect21(() => {
50388
+ useEffect22(() => {
50272
50389
  if (!controlledQuery || !totalIsKnown || controlledQuery.state.page === safePage) return;
50273
50390
  emitControlledQueryChange({ page: safePage });
50274
50391
  }, [controlledQuery, emitControlledQueryChange, safePage, totalIsKnown]);
@@ -50295,39 +50412,60 @@ function MatrxDataTableCore(coreProps) {
50295
50412
  const target = toolbar.portalInto;
50296
50413
  return target ? createPortal3(node, target) : null;
50297
50414
  };
50415
+ const [pinnedEl, setPinnedEl] = useState26(null);
50416
+ const pinnedRowActive = Boolean(
50417
+ toolbar?.singleRow && toolbar.overflow && toolbar.overflow.mode !== "sheet" && (toolbar.overflow.pinned || toolbar.overflow.mode === "menu")
50418
+ );
50419
+ const pinnedFolded = usePinnedFold(pinnedEl, pinnedRowActive);
50420
+ const toolbarEnd = { node: null };
50298
50421
  const renderToolbarControls = (controls) => {
50422
+ toolbarEnd.node = null;
50299
50423
  const overflow = toolbar?.overflow;
50300
50424
  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: [
50425
+ if (mode === "sheet") {
50426
+ return /* @__PURE__ */ jsxs40(ToolbarOverflowSheet, { ...overflow?.label ? { label: overflow.label } : {}, top: overflow?.sheetTop, children: [
50427
+ controls,
50428
+ overflow?.pinned,
50429
+ overflow?.sheetExtras
50430
+ ] });
50431
+ }
50432
+ if (!pinnedRowActive) {
50433
+ if (mode === "menu") {
50434
+ return /* @__PURE__ */ jsxs40(Fragment12, { children: [
50312
50435
  overflow?.pinned,
50313
50436
  /* @__PURE__ */ jsxs40(ToolbarOverflowMenu, { children: [
50314
50437
  controls,
50315
50438
  overflow?.sheetExtras
50316
50439
  ] })
50317
- ] })
50318
- );
50319
- }
50320
- if (mode === "sheet") {
50321
- return /* @__PURE__ */ jsxs40(ToolbarOverflowSheet, { ...overflow?.label ? { label: overflow.label } : {}, top: overflow?.sheetTop, children: [
50440
+ ] });
50441
+ }
50442
+ return /* @__PURE__ */ jsxs40(Fragment12, { children: [
50322
50443
  controls,
50323
- overflow?.pinned,
50324
- overflow?.sheetExtras
50444
+ overflow?.pinned
50325
50445
  ] });
50326
50446
  }
50327
- return /* @__PURE__ */ jsxs40(Fragment12, { children: [
50328
- controls,
50329
- overflow?.pinned ? stick(overflow.pinned) : null
50330
- ] });
50447
+ const folded = pinnedFolded;
50448
+ toolbarEnd.node = /* @__PURE__ */ jsx51(
50449
+ "span",
50450
+ {
50451
+ ref: setPinnedEl,
50452
+ "data-matrx-table-toolbar-pinned": "",
50453
+ ...folded ? { "data-matrx-table-toolbar-pinned-folded": "" } : {},
50454
+ 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",
50455
+ children: folded ? /* @__PURE__ */ jsxs40(ToolbarOverflowMenu, { children: [
50456
+ controls,
50457
+ overflow?.pinned,
50458
+ overflow?.sheetExtras
50459
+ ] }) : mode === "menu" ? /* @__PURE__ */ jsxs40(Fragment12, { children: [
50460
+ overflow?.pinned,
50461
+ /* @__PURE__ */ jsxs40(ToolbarOverflowMenu, { children: [
50462
+ controls,
50463
+ overflow?.sheetExtras
50464
+ ] })
50465
+ ] }) : overflow?.pinned
50466
+ }
50467
+ );
50468
+ return folded || mode === "menu" ? null : controls;
50331
50469
  };
50332
50470
  const renderRowActions = (row, controls) => {
50333
50471
  const actions = rowActions?.(row, controls);
@@ -50483,7 +50621,7 @@ function MatrxDataTableCore(coreProps) {
50483
50621
  }
50484
50622
  resetToolbarFacets(toolbar?.facets);
50485
50623
  };
50486
- const renderedEmptyState = (remoteQuery === null || remoteQueryUsesLocalColumnFilters) && data.length > 0 && hasActiveFilters ? {
50624
+ const renderedEmptyState = (remoteQuery === null || remoteQueryUsesLocalProcessing) && data.length > 0 && hasActiveFilters ? {
50487
50625
  title: "No matching rows",
50488
50626
  description: "No rows match the current search or filters.",
50489
50627
  action: /* @__PURE__ */ jsx51(Button, { type: "button", variant: "outline", size: "sm", onClick: clearAllFilters, children: "Clear filters" }),
@@ -50576,7 +50714,7 @@ function MatrxDataTableCore(coreProps) {
50576
50714
  }));
50577
50715
  return true;
50578
50716
  };
50579
- const requestCellEditRef = useRef20(requestCellEdit);
50717
+ const requestCellEditRef = useRef21(requestCellEdit);
50580
50718
  requestCellEditRef.current = requestCellEdit;
50581
50719
  const buildRecordControls = (row) => {
50582
50720
  const rowId = getRowId(row);
@@ -50922,16 +51060,16 @@ function MatrxDataTableCore(coreProps) {
50922
51060
  return [];
50923
51061
  }
50924
51062
  };
50925
- const menuSectionsForRef = useRef20(menuSectionsFor);
51063
+ const menuSectionsForRef = useRef21(menuSectionsFor);
50926
51064
  menuSectionsForRef.current = menuSectionsFor;
50927
51065
  const hasMenuSections = Boolean(contextMenu?.sections);
50928
51066
  const boundarySections = useCallback10(
50929
51067
  (target) => menuSectionsForRef.current(target),
50930
51068
  []
50931
51069
  );
50932
- const resolveMenuLevelRef = useRef20(resolveMenuLevel);
51070
+ const resolveMenuLevelRef = useRef21(resolveMenuLevel);
50933
51071
  resolveMenuLevelRef.current = resolveMenuLevel;
50934
- useEffect21(() => {
51072
+ useEffect22(() => {
50935
51073
  if (!host.rowContextRegistry) return;
50936
51074
  return host.rowContextRegistry.register(
50937
51075
  tableContextMenuInstanceId,
@@ -50961,7 +51099,7 @@ function MatrxDataTableCore(coreProps) {
50961
51099
  return true;
50962
51100
  });
50963
51101
  }, [data, getSelectionId, selectedIdSet]);
50964
- const lastToggledIndex = useRef20(null);
51102
+ const lastToggledIndex = useRef21(null);
50965
51103
  const setSelectedIds = (next) => selection?.onSelectedIdsChange([...next]);
50966
51104
  const toggleRowSelected = (index, shiftKey) => {
50967
51105
  if (!selection) return;
@@ -51002,7 +51140,7 @@ function MatrxDataTableCore(coreProps) {
51002
51140
  }
51003
51141
  } : facet
51004
51142
  ) : toolbar?.facets;
51005
- const rowLatest = useRef20(null);
51143
+ const rowLatest = useRef21(null);
51006
51144
  const renderRecordCell = (row, col, index) => {
51007
51145
  const id = getRowId(row);
51008
51146
  const field = col.accessorKey ? String(col.accessorKey) : columnId(col);
@@ -51081,7 +51219,6 @@ function MatrxDataTableCore(coreProps) {
51081
51219
  pageSize: defaultPageSize,
51082
51220
  search: "",
51083
51221
  anyOf: "",
51084
- layeredFilters: [],
51085
51222
  columnFilters: {},
51086
51223
  sort: defaultSort
51087
51224
  },
@@ -51317,6 +51454,7 @@ function MatrxDataTableCore(coreProps) {
51317
51454
  allRowsAreLoaded,
51318
51455
  effectivePageSize,
51319
51456
  safePage,
51457
+ isFetching,
51320
51458
  controlledQuery,
51321
51459
  emitControlledQueryChange,
51322
51460
  ...pageSizeOptions
@@ -51324,6 +51462,8 @@ function MatrxDataTableCore(coreProps) {
51324
51462
  const toolbarReadsRows = showToolbarCopy && copyDrawsFromRows(effectiveCopy);
51325
51463
  const toolbarEpoch = useRenderEpoch([
51326
51464
  hideToolbar,
51465
+ pinnedFolded,
51466
+ pinnedRowActive,
51327
51467
  viewTabs,
51328
51468
  toolbar,
51329
51469
  showSearch,
@@ -51835,43 +51975,40 @@ function MatrxDataTableCore(coreProps) {
51835
51975
  "data-matrx-table-density": resolvedDensity,
51836
51976
  "data-url-state-table": urlState?.id,
51837
51977
  className: cn(
51838
- "flex h-full min-h-0 flex-col gap-2 px-0 py-2",
51978
+ "flex h-full min-h-0 flex-col gap-2 px-0 pt-2 pb-0",
51839
51979
  className
51840
51980
  ),
51841
51981
  children: [
51842
51982
  notice,
51843
51983
  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
51984
  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(
51985
+ summaryMetrics.length > 0 ? /* @__PURE__ */ jsx51(
51846
51986
  "section",
51847
51987
  {
51848
51988
  "data-matrx-table-summary": true,
51849
51989
  "data-matrx-table-summary-scope": summaryUsesSource ? "source" : summaryCoverage,
51850
51990
  "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
- ]
51991
+ className: "flex w-full min-w-0 shrink-0 flex-nowrap items-stretch gap-2 overflow-x-auto overscroll-x-contain",
51992
+ 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: [
51993
+ /* @__PURE__ */ jsx51("div", { className: "text-xs text-muted-foreground", children: metric.label }),
51994
+ /* @__PURE__ */ jsxs40("div", { className: "mt-0.5 text-sm font-semibold tabular-nums text-foreground", children: [
51995
+ metric.value,
51996
+ metric.unavailable ? /* @__PURE__ */ jsx51(ErrorBox, { as: "span", className: "sr-only", message: `${metric.label} is unavailable`, operation: "Summarize this table", origin: "design-system/MatrxDataTable" }) : null
51997
+ ] })
51998
+ ] }, metric.id))
51862
51999
  }
51863
52000
  ) : 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(
52001
+ /* @__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
52002
  TableTitleRow,
51866
52003
  {
51867
52004
  ...toolbar?.singleRow ? { singleRow: true } : {},
51868
- tabs: viewTabs ? /* @__PURE__ */ jsx51(TableViewWorkspace, { snapshot: currentViewSnapshot, onApply: applyLatestSavedView, related: relatedTableActions, ...viewTabsStore ? { store: viewTabsStore } : {} }, tableId ?? "table") : void 0,
52005
+ 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
52006
  ...toolbar?.title === void 0 ? {} : { title: toolbar.title },
51870
52007
  ...toolbar?.titleCount === void 0 ? {} : { count: toolbar.titleCount },
51871
- context: tableId && SavedViews ? /* @__PURE__ */ jsx51("span", { "data-matrx-table-view-control": true, children: /* @__PURE__ */ jsx51(
52008
+ context: savedViewsId && SavedViews && !viewTabs ? /* @__PURE__ */ jsx51("span", { "data-matrx-table-view-control": true, children: /* @__PURE__ */ jsx51(
51872
52009
  SavedViews,
51873
52010
  {
51874
- tableId,
52011
+ tableId: savedViewsId,
51875
52012
  snapshot: currentViewSnapshot,
51876
52013
  defaultSnapshot: declaredDefaultViewSnapshot,
51877
52014
  onApply: applyLatestSavedView
@@ -52173,7 +52310,8 @@ function MatrxDataTableCore(coreProps) {
52173
52310
  ] }))
52174
52311
  ]
52175
52312
  }
52176
- )
52313
+ ),
52314
+ toolbarEnd.node
52177
52315
  ]
52178
52316
  }
52179
52317
  )) }),
@@ -52487,7 +52625,7 @@ function MatrxDataTableCore(coreProps) {
52487
52625
  {
52488
52626
  label: col.header,
52489
52627
  labelText: headerLabel,
52490
- ...facetsEnabled ? {
52628
+ ...facetsEnabled || meta?.kind !== void 0 && meta.kind !== null && coreSuggestionsEnabled ? {
52491
52629
  facets: facetState[id]?.data ?? null,
52492
52630
  facetsLoading: facetState[id]?.loading ?? false,
52493
52631
  ...facetState[id]?.error === void 0 ? {} : { facetsError: facetState[id]?.error },
@@ -52612,12 +52750,12 @@ function MatrxDataTableCore(coreProps) {
52612
52750
  },
52613
52751
  "matrx-column-spacer-end"
52614
52752
  ) : 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(
52753
+ ] }, `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
52754
  "td",
52617
52755
  {
52618
52756
  colSpan: renderedColSpan,
52619
52757
  "data-matrx-table-message-cell": true,
52620
- className: "px-0 py-12 text-center",
52758
+ className: "overflow-visible! px-0 py-12 text-center",
52621
52759
  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
52760
  renderedEmptyState?.icon,
52623
52761
  /* @__PURE__ */ jsx51("p", { className: "text-sm font-medium text-foreground", children: renderedEmptyState?.title ?? "No rows" }),
@@ -52707,62 +52845,61 @@ function MatrxDataTableCore(coreProps) {
52707
52845
  "border-t-2 border-border bg-muted/50 font-semibold",
52708
52846
  hasSummaryTotals && "sticky bottom-0 z-10 bg-muted/95 backdrop-blur-sm"
52709
52847
  ), 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(
52848
+ hasSummaryTotals ? /* @__PURE__ */ jsx51(Fragment12, { children: /* @__PURE__ */ jsxs40("tr", { "data-matrx-table-summary-totals": true, children: [
52849
+ selection ? /* @__PURE__ */ jsx51("td", { className: "px-2 py-2" }) : null,
52850
+ columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ jsx51(
52851
+ "td",
52852
+ {
52853
+ "aria-hidden": "true",
52854
+ "data-matrx-table-column-spacer": "start",
52855
+ className: "border-0 p-0",
52856
+ style: { width: `${columnSpacers.start}px`, minWidth: `${columnSpacers.start}px` }
52857
+ },
52858
+ "matrx-summary-column-spacer-start"
52859
+ ) : null,
52860
+ renderedColumns.map((column, columnIndex) => {
52861
+ const total = summaryTotals.find((candidate) => candidate.id === columnId(column));
52862
+ return /* @__PURE__ */ jsxs40(
52754
52863
  "td",
52755
52864
  {
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` }
52865
+ className: cn(
52866
+ "px-2 py-2 align-middle font-semibold",
52867
+ (column.compact || resolveColumnMarker(column) !== void 0) && "px-1",
52868
+ column.className,
52869
+ column.align === "center" && "text-center",
52870
+ column.align === "right" && "text-right"
52871
+ ),
52872
+ style: columnWidthVar(
52873
+ resolveColumnMarker(column) && column.width === void 0 ? 40 : column.width,
52874
+ windowedWidthFor(columnId(column), column.width),
52875
+ columnId(column),
52876
+ resizableColumns && column.resizable !== false
52877
+ ),
52878
+ children: [
52879
+ columnIndex === 0 ? /* @__PURE__ */ jsxs40("span", { "data-matrx-table-summary-total-label": true, className: "text-sm font-semibold text-foreground", children: [
52880
+ summaryCaption,
52881
+ 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
52882
+ ] }) : null,
52883
+ columnIndex === 0 && total?.value != null ? /* @__PURE__ */ jsx51("span", { className: "ml-2", children: total.value }) : null,
52884
+ columnIndex !== 0 ? total?.value : null,
52885
+ 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
52886
+ ]
52760
52887
  },
52761
- "matrx-summary-column-spacer-end"
52762
- ) : null,
52763
- showActionsCol ? /* @__PURE__ */ jsx51("td", {}) : null
52764
- ] })
52765
- ] }) : null,
52888
+ columnId(column)
52889
+ );
52890
+ }),
52891
+ columnSpacers && columnSpacers.end > 0 ? /* @__PURE__ */ jsx51(
52892
+ "td",
52893
+ {
52894
+ "aria-hidden": "true",
52895
+ "data-matrx-table-column-spacer": "end",
52896
+ className: "border-0 p-0",
52897
+ style: { width: `${columnSpacers.end}px`, minWidth: `${columnSpacers.end}px` }
52898
+ },
52899
+ "matrx-summary-column-spacer-end"
52900
+ ) : null,
52901
+ showActionsCol ? /* @__PURE__ */ jsx51("td", {}) : null
52902
+ ] }) }) : null,
52766
52903
  footerRows.map((row, index) => /* @__PURE__ */ jsxs40("tr", { children: [
52767
52904
  selection ? /* @__PURE__ */ jsx51("td", { className: "px-2 py-2" }) : null,
52768
52905
  columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ jsx51(
@@ -52992,6 +53129,7 @@ function MatrxDataTableCore(coreProps) {
52992
53129
  showAllOption: allRowsAreLoaded,
52993
53130
  allValue: 0,
52994
53131
  allOptionLabel: "All loaded",
53132
+ isFetching,
52995
53133
  compact: true,
52996
53134
  hideEntriesInfo: false
52997
53135
  }
@@ -53346,7 +53484,7 @@ function HierarchyDragIndicatorLayer({
53346
53484
  scrollRef,
53347
53485
  resolve: resolve2
53348
53486
  }) {
53349
- const [indicator, setIndicator] = useState25(
53487
+ const [indicator, setIndicator] = useState26(
53350
53488
  null
53351
53489
  );
53352
53490
  useDndMonitor2({
@@ -53562,7 +53700,7 @@ function columnWidthVar(width, resizedWidth, id, resizable) {
53562
53700
  };
53563
53701
  }
53564
53702
  function DefaultJsonCell({ value }) {
53565
- const [open, setOpen] = useState25(false);
53703
+ const [open, setOpen] = useState26(false);
53566
53704
  const host = useMatrxDataTableHost();
53567
53705
  const Viewer = host.JsonViewer;
53568
53706
  const text = JSON.stringify(value, null, 2);
@@ -53645,7 +53783,7 @@ function resolveStringTitle(title, fallback) {
53645
53783
  }
53646
53784
 
53647
53785
  // src/data-table/SavedViewsControl.tsx
53648
- import { useId as useId4, useState as useState26 } from "react";
53786
+ import { useId as useId4, useState as useState27 } from "react";
53649
53787
 
53650
53788
  // src/dropdown-menu.tsx
53651
53789
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
@@ -53782,7 +53920,7 @@ var DropdownMenuShortcut = ({
53782
53920
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
53783
53921
 
53784
53922
  // src/data-table/SavedViewsControl.tsx
53785
- import { jsx as jsx53, jsxs as jsxs42 } from "react/jsx-runtime";
53923
+ import { Fragment as Fragment13, jsx as jsx53, jsxs as jsxs42 } from "react/jsx-runtime";
53786
53924
  function SavedViewsControl({
53787
53925
  views,
53788
53926
  activeId = null,
@@ -53792,14 +53930,26 @@ function SavedViewsControl({
53792
53930
  onSelect,
53793
53931
  onSaveNew,
53794
53932
  onUpdate,
53795
- onReload
53933
+ onReload,
53934
+ presentation = "menu",
53935
+ onRename,
53936
+ related
53796
53937
  }) {
53797
53938
  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);
53939
+ const [saveOpen, setSaveOpen] = useState27(false);
53940
+ const [name, setName] = useState27("");
53941
+ const [saving, setSaving] = useState27(false);
53942
+ const [actionError, setActionError] = useState27(null);
53943
+ const [pendingSelect, setPendingSelect] = useState27(void 0);
53802
53944
  const visibleError = actionError ?? error;
53945
+ const select = (id) => {
53946
+ if (id === activeId) return;
53947
+ if (dirty) {
53948
+ setPendingSelect(id);
53949
+ return;
53950
+ }
53951
+ onSelect(id);
53952
+ };
53803
53953
  const save = async () => {
53804
53954
  const next = name.trim();
53805
53955
  if (!next) return;
@@ -53841,7 +53991,31 @@ function SavedViewsControl({
53841
53991
  };
53842
53992
  const activeName = activeId ? views.find((view) => view.id === activeId)?.name : void 0;
53843
53993
  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: [
53994
+ presentation === "tabs" ? /* @__PURE__ */ jsxs42(Fragment13, { children: [
53995
+ /* @__PURE__ */ jsx53(
53996
+ TableViewTabs,
53997
+ {
53998
+ tabs: [{ id: "default", label: "Default view" }, ...views.map((view) => ({ id: view.id, label: view.name }))],
53999
+ activeId: activeId ?? "default",
54000
+ onSelect: (id) => select(id === "default" ? null : id),
54001
+ onAdd: () => {
54002
+ setActionError(null);
54003
+ setSaveOpen(true);
54004
+ },
54005
+ onClose: () => {
54006
+ },
54007
+ onRename: (id, label) => {
54008
+ if (onRename) void Promise.resolve(onRename(id, label)).catch((cause) => setActionError(cause instanceof Error ? cause.message : String(cause)));
54009
+ },
54010
+ closable: false,
54011
+ renameable: Boolean(onRename),
54012
+ addHint: "Save a named view to your account",
54013
+ related
54014
+ }
54015
+ ),
54016
+ 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,
54017
+ loading ? /* @__PURE__ */ jsx53("span", { role: "status", className: "text-xs text-muted-foreground", children: "Loading views\u2026" }) : null
54018
+ ] }) : /* @__PURE__ */ jsxs42(DropdownMenu, { children: [
53845
54019
  /* @__PURE__ */ jsxs42(Tooltip, { children: [
53846
54020
  /* @__PURE__ */ jsx53(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx53(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs42(
53847
54021
  Button,
@@ -53864,7 +54038,7 @@ function SavedViewsControl({
53864
54038
  ] }),
53865
54039
  /* @__PURE__ */ jsxs42(DropdownMenuContent, { align: "end", children: [
53866
54040
  /* @__PURE__ */ jsx53(DropdownMenuLabel, { children: "Views" }),
53867
- /* @__PURE__ */ jsxs42(DropdownMenuRadioGroup, { value: activeId ?? "__default__", onValueChange: (value) => onSelect(value === "__default__" ? null : value), children: [
54041
+ /* @__PURE__ */ jsxs42(DropdownMenuRadioGroup, { value: activeId ?? "__default__", onValueChange: (value) => select(value === "__default__" ? null : value), children: [
53868
54042
  /* @__PURE__ */ jsx53(DropdownMenuRadioItem, { value: "__default__", children: "Default view" }),
53869
54043
  views.map((view) => /* @__PURE__ */ jsx53(DropdownMenuRadioItem, { value: view.id, children: view.name }, view.id))
53870
54044
  ] }),
@@ -53877,7 +54051,10 @@ function SavedViewsControl({
53877
54051
  onReload ? /* @__PURE__ */ jsx53(DropdownMenuItem, { disabled: saving || loading, onSelect: () => void reload(), children: "Reload views" }) : null
53878
54052
  ] })
53879
54053
  ] }),
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,
54054
+ dirty ? /* @__PURE__ */ jsxs42("span", { id: presentation === "menu" ? unsavedChangesId : void 0, role: presentation === "tabs" ? "status" : void 0, className: "sr-only", children: [
54055
+ "This table view has unsaved changes. ",
54056
+ 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."
54057
+ ] }) : null,
53881
54058
  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
54059
  /* @__PURE__ */ jsx53(Dialog, { open: saveOpen, onOpenChange: setSaveOpen, children: /* @__PURE__ */ jsxs42(DialogContent, { children: [
53883
54060
  /* @__PURE__ */ jsx53(DialogHeader, { children: /* @__PURE__ */ jsx53(DialogTitle, { children: "Save current view" }) }),
@@ -53887,6 +54064,20 @@ function SavedViewsControl({
53887
54064
  /* @__PURE__ */ jsx53(Button, { type: "button", variant: "outline", onClick: () => setSaveOpen(false), children: "Cancel" }),
53888
54065
  /* @__PURE__ */ jsx53(Button, { type: "button", disabled: !name.trim() || saving, onClick: () => void save(), children: saving ? "Saving\u2026" : "Save view" })
53889
54066
  ] })
54067
+ ] }) }),
54068
+ /* @__PURE__ */ jsx53(Dialog, { open: pendingSelect !== void 0, onOpenChange: (open) => {
54069
+ if (!open) setPendingSelect(void 0);
54070
+ }, children: /* @__PURE__ */ jsxs42(DialogContent, { children: [
54071
+ /* @__PURE__ */ jsx53(DialogHeader, { children: /* @__PURE__ */ jsx53(DialogTitle, { children: "Unsaved view changes" }) }),
54072
+ /* @__PURE__ */ jsx53("p", { className: "text-sm text-muted-foreground", children: "Switching views will discard the changes you have not saved." }),
54073
+ /* @__PURE__ */ jsxs42(DialogFooter, { children: [
54074
+ /* @__PURE__ */ jsx53(Button, { type: "button", variant: "outline", onClick: () => setPendingSelect(void 0), children: "Stay on this view" }),
54075
+ /* @__PURE__ */ jsx53(Button, { type: "button", onClick: () => {
54076
+ const next = pendingSelect;
54077
+ setPendingSelect(void 0);
54078
+ if (next !== void 0) onSelect(next);
54079
+ }, children: "Discard changes and switch" })
54080
+ ] })
53890
54081
  ] }) })
53891
54082
  ] });
53892
54083
  }