@ai-matrx/design-system 0.56.2 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34543,9 +34543,9 @@ function TableIconActions({ actions }) {
34543
34543
 
34544
34544
  // src/data-table/MatrxDataTable.tsx
34545
34545
  import {
34546
- cloneElement as cloneElement2,
34546
+ cloneElement as cloneElement3,
34547
34547
  Fragment as Fragment18,
34548
- isValidElement as isValidElement2,
34548
+ isValidElement as isValidElement3,
34549
34549
  memo,
34550
34550
  useCallback as useCallback15,
34551
34551
  useEffect as useEffect26,
@@ -35451,6 +35451,162 @@ function Skeleton({ className, animated = true, ...props }) {
35451
35451
  );
35452
35452
  }
35453
35453
 
35454
+ // src/data-table/row-drawing.ts
35455
+ import { cloneElement, isValidElement } from "react";
35456
+ var LAZY = /* @__PURE__ */ Symbol.for("@ai-matrx/design-system/data-table/lazy-callback");
35457
+ var MAX_DEPTH = 32;
35458
+ var HANDLER_KEY = /^on[A-Z]/;
35459
+ function lazyCallback(fn) {
35460
+ fn[LAZY] = true;
35461
+ return fn;
35462
+ }
35463
+ function isLazy(fn) {
35464
+ return fn[LAZY] === true;
35465
+ }
35466
+ function trampolinable(key, fn) {
35467
+ return isLazy(fn) || HANDLER_KEY.test(key);
35468
+ }
35469
+ function isPlainObject(value) {
35470
+ if (value === null || typeof value !== "object") return false;
35471
+ const proto = Object.getPrototypeOf(value);
35472
+ return proto === Object.prototype || proto === null;
35473
+ }
35474
+ function makeSlot(fn) {
35475
+ const slot = {
35476
+ fn,
35477
+ // A Proxy rather than a bare wrapper: a handler that carries its own members (a debounced
35478
+ // function's `cancel`) keeps them, read from the latest function.
35479
+ stable: new Proxy((() => void 0), {
35480
+ apply: (_target, thisArg, args) => Reflect.apply(slot.fn, thisArg, args),
35481
+ get: (_target, key) => Reflect.get(slot.fn, key)
35482
+ })
35483
+ };
35484
+ return slot;
35485
+ }
35486
+ function sameEntries(a, b, path2, depth, updates) {
35487
+ const keys2 = Object.keys(a);
35488
+ if (keys2.length !== Object.keys(b).length) return false;
35489
+ for (const key of keys2) {
35490
+ if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
35491
+ if (key === "ref") {
35492
+ if (!Object.is(a[key], b[key])) return false;
35493
+ continue;
35494
+ }
35495
+ if (!sameDrawing(a[key], b[key], key, `${path2}/${key}`, depth + 1, updates)) return false;
35496
+ }
35497
+ return true;
35498
+ }
35499
+ function sameDrawing(previous, next, key, path2, depth, updates) {
35500
+ if (Object.is(previous, next)) return true;
35501
+ if (typeof previous === "function" && typeof next === "function") {
35502
+ if (trampolinable(key, previous) && trampolinable(key, next)) {
35503
+ updates.push([path2, next]);
35504
+ return true;
35505
+ }
35506
+ return false;
35507
+ }
35508
+ if (depth > MAX_DEPTH) return false;
35509
+ if (isValidElement(previous) && isValidElement(next)) {
35510
+ if (previous.type !== next.type || previous.key !== next.key) return false;
35511
+ return sameEntries(
35512
+ previous.props,
35513
+ next.props,
35514
+ path2,
35515
+ depth,
35516
+ updates
35517
+ );
35518
+ }
35519
+ if (Array.isArray(previous) && Array.isArray(next)) {
35520
+ if (previous.length !== next.length) return false;
35521
+ for (let i = 0; i < previous.length; i += 1) {
35522
+ if (!sameDrawing(previous[i], next[i], key, `${path2}/${i}`, depth + 1, updates)) return false;
35523
+ }
35524
+ return true;
35525
+ }
35526
+ if (isPlainObject(previous) && isPlainObject(next)) return sameEntries(previous, next, path2, depth, updates);
35527
+ return false;
35528
+ }
35529
+ function stabilize(value, key, path2, depth, slots, reuse) {
35530
+ if (typeof value === "function") {
35531
+ if (!trampolinable(key, value)) return value;
35532
+ const fn = value;
35533
+ const kept = reuse?.get(path2);
35534
+ const slot = kept ?? makeSlot(fn);
35535
+ slot.fn = fn;
35536
+ slots.set(path2, slot);
35537
+ return slot.stable;
35538
+ }
35539
+ if (depth > MAX_DEPTH) return value;
35540
+ if (isValidElement(value)) {
35541
+ const props = value.props;
35542
+ let changed = null;
35543
+ for (const propKey of Object.keys(props)) {
35544
+ if (propKey === "ref") continue;
35545
+ const before2 = props[propKey];
35546
+ const after2 = stabilize(before2, propKey, `${path2}/${propKey}`, depth + 1, slots, reuse);
35547
+ if (after2 !== before2) (changed ??= {})[propKey] = after2;
35548
+ }
35549
+ if (!changed) return value;
35550
+ const clone = cloneElement(value, changed);
35551
+ const before = value._store;
35552
+ const after = clone._store;
35553
+ if (before && after && "validated" in before) {
35554
+ try {
35555
+ after.validated = before.validated;
35556
+ } catch {
35557
+ }
35558
+ }
35559
+ return clone;
35560
+ }
35561
+ if (Array.isArray(value)) {
35562
+ let out = null;
35563
+ for (let i = 0; i < value.length; i += 1) {
35564
+ const after = stabilize(value[i], key, `${path2}/${i}`, depth + 1, slots, reuse);
35565
+ if (after !== value[i]) (out ??= value.slice())[i] = after;
35566
+ }
35567
+ return out ?? value;
35568
+ }
35569
+ if (isPlainObject(value)) {
35570
+ let out = null;
35571
+ for (const entryKey of Object.keys(value)) {
35572
+ const before = value[entryKey];
35573
+ const after = stabilize(before, entryKey, `${path2}/${entryKey}`, depth + 1, slots, reuse);
35574
+ if (after !== before) (out ??= { ...value })[entryKey] = after;
35575
+ }
35576
+ return out ?? value;
35577
+ }
35578
+ return value;
35579
+ }
35580
+ var RowDrawings = class {
35581
+ rows = /* @__PURE__ */ new Map();
35582
+ /**
35583
+ * The element to hand React for this row. The SAME object as last time when `raw` draws what the
35584
+ * last one drew (its handlers are re-pointed); a new one otherwise.
35585
+ */
35586
+ draw(rowId, raw) {
35587
+ const previous = this.rows.get(rowId);
35588
+ if (previous) {
35589
+ const updates = [];
35590
+ if (sameDrawing(previous.raw, raw, "", "", 0, updates) && updates.every(([path2]) => previous.slots.has(path2))) {
35591
+ for (const [path2, fn] of updates) previous.slots.get(path2).fn = fn;
35592
+ previous.raw = raw;
35593
+ return previous.out;
35594
+ }
35595
+ }
35596
+ const slots = /* @__PURE__ */ new Map();
35597
+ const out = stabilize(raw, "", "", 0, slots, previous?.slots);
35598
+ this.rows.set(rowId, { raw, out, slots });
35599
+ return out;
35600
+ }
35601
+ /** Forget rows that are no longer in the table (bounded by what was ever drawn). */
35602
+ prune(liveIds) {
35603
+ for (const id of this.rows.keys()) if (!liveIds.has(id)) this.rows.delete(id);
35604
+ }
35605
+ get size() {
35606
+ return this.rows.size;
35607
+ }
35608
+ };
35609
+
35454
35610
  // src/data-table/TableTitleRow.tsx
35455
35611
  import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
35456
35612
  function TableTitleRow({
@@ -40702,9 +40858,9 @@ function WorkspaceWindowSlot({ onNode, sessionKey, onClose }) {
40702
40858
 
40703
40859
  // src/tap-target/tap-target-button.tsx
40704
40860
  import {
40705
- cloneElement,
40861
+ cloneElement as cloneElement2,
40706
40862
  forwardRef as forwardRef13,
40707
- isValidElement,
40863
+ isValidElement as isValidElement2,
40708
40864
  useCallback as useCallback9,
40709
40865
  useRef as useRef15
40710
40866
  } from "react";
@@ -41115,8 +41271,8 @@ function IconContent({
41115
41271
  className
41116
41272
  }) {
41117
41273
  if (icon) {
41118
- if (isValidElement(icon)) {
41119
- return cloneElement(icon, {
41274
+ if (isValidElement2(icon)) {
41275
+ return cloneElement2(icon, {
41120
41276
  className: cn2(className, icon.props.className)
41121
41277
  });
41122
41278
  }
@@ -49896,7 +50052,7 @@ function formatValue2(value) {
49896
50052
  return String(value);
49897
50053
  }
49898
50054
  }
49899
- function isPlainObject(value) {
50055
+ function isPlainObject2(value) {
49900
50056
  return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date);
49901
50057
  }
49902
50058
  function DataRowInspector({
@@ -49909,7 +50065,7 @@ function DataRowInspector({
49909
50065
  location,
49910
50066
  tokenForField = noFieldToken
49911
50067
  }) {
49912
- const entries = isPlainObject(row) ? Object.entries(row) : [["value", row]];
50068
+ const entries = isPlainObject2(row) ? Object.entries(row) : [["value", row]];
49913
50069
  const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ jsx53("div", { className: "absolute right-1 top-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover/field:opacity-100", children: /* @__PURE__ */ jsx53(
49914
50070
  CopyButtons,
49915
50071
  {
@@ -52149,7 +52305,7 @@ function TableToolbarAction({
52149
52305
  disabled,
52150
52306
  onClick,
52151
52307
  children: [
52152
- isValidElement2(children) ? cloneElement2(children, { className: cn("h-4 w-4", children.props.className) }) : children,
52308
+ isValidElement3(children) ? cloneElement3(children, { className: cn("h-4 w-4", children.props.className) }) : children,
52153
52309
  /* @__PURE__ */ jsx59("span", { children: ariaLabel })
52154
52310
  ]
52155
52311
  }
@@ -52171,7 +52327,7 @@ function TableToolbarAction({
52171
52327
  "aria-busy": busy || void 0,
52172
52328
  disabled,
52173
52329
  onClick,
52174
- children: isValidElement2(children) ? cloneElement2(children, { className: cn("h-5 w-5", children.props.className) }) : children
52330
+ children: isValidElement3(children) ? cloneElement3(children, { className: cn("h-5 w-5", children.props.className) }) : children
52175
52331
  }
52176
52332
  ) }) }),
52177
52333
  /* @__PURE__ */ jsx59(TooltipContent, { children: tooltip ?? ariaLabel })
@@ -52200,9 +52356,10 @@ function tableRowCopyProps(copy, row, sourceId, defaultColumns) {
52200
52356
  label: copy.label,
52201
52357
  ...copy.rowReferences ? { references: copy.rowReferences(row) } : {},
52202
52358
  ...copy.triggerVariant ? { triggerVariant: copy.triggerVariant } : {},
52203
- human: () => copy.humanRow(row),
52204
- json: () => copy.agentRow ? copy.agentRow(row) : row,
52205
- agent: () => defaultColumns ? buildDefaultTableRowAgentInput(copy, row, defaultColumns) : buildRowAgentInput(copy, row),
52359
+ // Run on a copy, never while the menu renders: a row may keep a trampoline to them.
52360
+ human: lazyCallback(() => copy.humanRow(row)),
52361
+ json: lazyCallback(() => copy.agentRow ? copy.agentRow(row) : row),
52362
+ agent: lazyCallback(() => defaultColumns ? buildDefaultTableRowAgentInput(copy, row, defaultColumns()) : buildRowAgentInput(copy, row)),
52206
52363
  ...aiVariants === void 0 ? {} : { aiVariants }
52207
52364
  };
52208
52365
  }
@@ -52435,10 +52592,10 @@ function versionFacts(version2) {
52435
52592
  return Array.isArray(version2) ? ["rowVersion", ...version2] : ["rowVersion", version2];
52436
52593
  }
52437
52594
  function sameBodyRow(a, b) {
52438
- return a.row === b.row && a.index === b.index && a.epoch === b.epoch && a.rowId === b.rowId && a.facts.length === b.facts.length && a.facts.every((fact, i) => Object.is(fact, b.facts[i]));
52595
+ return a.row === b.row && a.index === b.index && a.epoch === b.epoch && a.probe === b.probe && a.rowId === b.rowId && a.facts.length === b.facts.length && a.facts.every((fact, i) => Object.is(fact, b.facts[i]));
52439
52596
  }
52440
- var MatrxTableBodyRow = memo(function MatrxTableBodyRow2({ row, index, render }) {
52441
- return /* @__PURE__ */ jsx59(Fragment19, { children: render(row, index) });
52597
+ var MatrxTableBodyRow = memo(function MatrxTableBodyRow2({ rowId, row, index, draw }) {
52598
+ return draw(rowId, row, index);
52442
52599
  }, sameBodyRow);
52443
52600
  var MatrxTableChrome = memo(function MatrxTableChrome2({ render }) {
52444
52601
  return /* @__PURE__ */ jsx59(Fragment19, { children: render() });
@@ -52873,7 +53030,7 @@ function MatrxDataTableCore(coreProps) {
52873
53030
  if (!el) return;
52874
53031
  hintScrollLeft.current = el.scrollLeft;
52875
53032
  const hasRows = Boolean(el.querySelector("tbody tr[data-row-id]"));
52876
- const actions = el.querySelector("th[data-matrx-table-actions-column]");
53033
+ const actions = el.querySelector("th[data-matrx-table-actions-column], th[data-matrx-table-pinned-actions]");
52877
53034
  setScrollHintRight(hasRows && el.scrollLeft + el.clientWidth < el.scrollWidth - 2);
52878
53035
  setScrollHintLeft(hasRows && el.scrollLeft > 2);
52879
53036
  setScrollHintRightInset(actions ? Math.ceil(actions.getBoundingClientRect().width) + 6 : 6);
@@ -53193,13 +53350,24 @@ function MatrxDataTableCore(coreProps) {
53193
53350
  ...strips.map((strip) => Math.ceil(strip.scrollWidth) + 16),
53194
53351
  actionsHeader ? Math.ceil(actionsHeader.scrollWidth) : 0
53195
53352
  );
53353
+ const custom = {};
53354
+ for (const strip of Array.from(el.querySelectorAll("[data-matrx-table-custom-actions]"))) {
53355
+ const id = strip.closest("td")?.getAttribute("data-matrx-table-column-id");
53356
+ if (id) custom[id] = Math.max(custom[id] ?? 0, Math.ceil(strip.scrollWidth) + 16);
53357
+ }
53358
+ for (const id of Object.keys(custom)) {
53359
+ const header = Array.from(el.querySelectorAll("thead th[data-matrx-table-column-id]")).find((th) => th.getAttribute("data-matrx-table-column-id") === id);
53360
+ const inner = header?.firstElementChild;
53361
+ if (inner) custom[id] = Math.max(custom[id], Math.ceil(inner.scrollWidth) + 16);
53362
+ }
53196
53363
  const table2 = el.querySelector(":scope > table");
53197
53364
  const spill = table2 && table2.hasAttribute("data-matrx-table-fit") ? Math.max(0, el.scrollWidth - el.clientWidth) : 0;
53198
53365
  setFitSpace((now) => {
53199
53366
  const sameWidth = now !== null && now.width === el.clientWidth;
53200
53367
  const slack = sameWidth ? now.slack + spill : spill;
53201
- const next = { width: el.clientWidth, actions, slack };
53202
- return now && now.width === next.width && now.actions === next.actions && now.slack === next.slack ? now : next;
53368
+ const next = { width: el.clientWidth, actions, slack, custom };
53369
+ const sameCustom = now !== null && Object.keys(now.custom).length === Object.keys(custom).length && Object.entries(custom).every(([id, w]) => now.custom[id] === w);
53370
+ return now && sameCustom && now.width === next.width && now.actions === next.actions && now.slack === next.slack ? now : next;
53203
53371
  });
53204
53372
  };
53205
53373
  read2();
@@ -53212,11 +53380,12 @@ function MatrxDataTableCore(coreProps) {
53212
53380
  }, [fitToWidth, data.length]);
53213
53381
  const fittedWidths = useMemo12(() => {
53214
53382
  if (!fitToWidth || !fitSpace) return null;
53215
- const keepsItsWidth = (col) => resolveColumnMarker(col) !== void 0 || col.resizable === false && pixelWidth(col.width) !== void 0;
53383
+ const contentWidth = (col) => col.customActions ? fitSpace.custom[columnId(col)] : void 0;
53384
+ const keepsItsWidth = (col) => resolveColumnMarker(col) !== void 0 || col.resizable === false && pixelWidth(col.width) !== void 0 || contentWidth(col) !== void 0;
53216
53385
  const scaling = visibleColumns.filter((col) => !keepsItsWidth(col));
53217
- const fixed = visibleColumns.filter(keepsItsWidth).reduce((sum, col) => sum + (pixelWidth(col.width) ?? 40), 0);
53386
+ const fixed = visibleColumns.filter(keepsItsWidth).reduce((sum, col) => sum + (contentWidth(col) ?? pixelWidth(col.width) ?? 40), 0);
53218
53387
  const utilities = (selection ? selectionColumnWidth ?? SELECTION_COLUMN_PX : 0) + fitSpace.actions;
53219
- return fitColumnWidths(
53388
+ const shares = fitColumnWidths(
53220
53389
  scaling.map(columnId),
53221
53390
  (id) => {
53222
53391
  const col = scaling.find((c) => columnId(c) === id);
@@ -53224,6 +53393,13 @@ function MatrxDataTableCore(coreProps) {
53224
53393
  },
53225
53394
  fitSpace.width - utilities - fixed - fitSpace.slack
53226
53395
  );
53396
+ if (!shares) return null;
53397
+ const out = { ...shares };
53398
+ for (const col of visibleColumns) {
53399
+ const w = contentWidth(col);
53400
+ if (w !== void 0) out[columnId(col)] = w;
53401
+ }
53402
+ return out;
53227
53403
  }, [fitToWidth, fitSpace, visibleColumns, selection, selectionColumnWidth, effectiveColumnWidths]);
53228
53404
  const fitActive = fittedWidths !== null;
53229
53405
  const actionsColumnWidth = fitActive && fitSpace ? fitSpace.actions : fixedTableGeometry?.actionsWidth;
@@ -53283,6 +53459,9 @@ function MatrxDataTableCore(coreProps) {
53283
53459
  const tableContextMenuInstanceId = useId4();
53284
53460
  const tableDndContextId = useId4();
53285
53461
  const defaultCopyTitle = toolbar?.title || "Table";
53462
+ const copyColumnsLatest = useRef28(declaredVisibleCopyColumns);
53463
+ copyColumnsLatest.current = declaredVisibleCopyColumns;
53464
+ const readDeclaredCopyColumns = lazyCallback(() => copyColumnsLatest.current);
53286
53465
  const defaultCopy = useMemo12(() => ({
53287
53466
  label: defaultCopyTitle,
53288
53467
  listLabel: defaultCopyTitle,
@@ -53292,11 +53471,11 @@ function MatrxDataTableCore(coreProps) {
53292
53471
  listDescription: `${defaultCopyTitle} \u2014 ${remoteQuery ? "current filtered/sorted loaded view" : "current filtered/sorted view"}.`,
53293
53472
  listAttributes: (_visible, loaded) => remoteQuery ? { coverage: "loaded-current-view", loaded_count: loaded.length } : { coverage: "current-view" },
53294
53473
  humanRow: (row) => formatDefaultTableCopyRecord(
53295
- projectDefaultTableCopyRow(row, declaredVisibleCopyColumns),
53296
- declaredVisibleCopyColumns
53474
+ projectDefaultTableCopyRow(row, copyColumnsLatest.current),
53475
+ copyColumnsLatest.current
53297
53476
  ),
53298
- agentRow: (row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)
53299
- }), [defaultCopyTitle, declaredVisibleCopyColumns, remoteQuery]);
53477
+ agentRow: (row) => projectDefaultTableCopyRow(row, copyColumnsLatest.current)
53478
+ }), [defaultCopyTitle, remoteQuery]);
53300
53479
  const effectiveCopy = copy === false ? void 0 : copy ?? defaultCopy;
53301
53480
  const visibleDataColumns = useMemo12(() => visibleColumns.filter((column) => !column.customActions), [visibleColumns]);
53302
53481
  const effectiveCopyColumns = copy === void 0 ? declaredVisibleCopyColumns : visibleDataColumns;
@@ -53906,7 +54085,8 @@ function MatrxDataTableCore(coreProps) {
53906
54085
  const showRowCopy = effectiveCopy !== void 0 && effectiveCopy.showRow !== false;
53907
54086
  const menuActionsColumn = visibleColumns.find((column) => column.customActions);
53908
54087
  const rowCopyInMenu = rowCopyPlacement === "menu" && menuActionsColumn !== void 0;
53909
- const showInlineRowCopy = showRowCopy && !rowCopyInMenu;
54088
+ const rowCopyInCustomColumn = showRowCopy && !rowCopyInMenu && menuActionsColumn !== void 0;
54089
+ const showInlineRowCopy = showRowCopy && !rowCopyInMenu && !rowCopyInCustomColumn;
53910
54090
  const showToolbarCopy = effectiveCopy !== void 0 && effectiveCopy.showToolbar !== false;
53911
54091
  const placeToolbar = (node) => {
53912
54092
  if (toolbar && "portalInto" in toolbar) {
@@ -53990,7 +54170,7 @@ function MatrxDataTableCore(coreProps) {
53990
54170
  return /* @__PURE__ */ jsx59(
53991
54171
  MatrxTableRowAlchemyProvider,
53992
54172
  {
53993
- copy: tableRowCopyProps(effectiveCopy, row, `${tableCopySourceNamespace}:row:${getRowId(row)}`, copy === void 0 ? declaredVisibleCopyColumns : void 0),
54173
+ copy: tableRowCopyProps(effectiveCopy, row, `${tableCopySourceNamespace}:row:${getRowId(row)}`, copy === void 0 ? readDeclaredCopyColumns : void 0),
53994
54174
  placement: rowCopyInMenu ? "menu" : "inline",
53995
54175
  controls,
53996
54176
  children: scopedActions
@@ -54594,6 +54774,8 @@ function MatrxDataTableCore(coreProps) {
54594
54774
  );
54595
54775
  }, [host.rowContextRegistry, tableContextMenuInstanceId]);
54596
54776
  const showActionsCol = windowEnabled || Boolean(rowActions) || showInlineRowCopy;
54777
+ const lastVisibleColumn = visibleColumns[visibleColumns.length - 1];
54778
+ const pinnedActionsColumnId = !showActionsCol && lastVisibleColumn?.customActions ? columnId(lastVisibleColumn) : void 0;
54597
54779
  const getSelectionId = selection?.getSelectionId ?? getRowId;
54598
54780
  const selectedIdSet = useMemo12(
54599
54781
  () => new Set(selection?.selectedIds ?? []),
@@ -54666,15 +54848,28 @@ function MatrxDataTableCore(coreProps) {
54666
54848
  if (col.customActions) {
54667
54849
  const controls = suppliedControls ?? liveRecordControls(displayRow);
54668
54850
  const content = /* @__PURE__ */ jsx59(MatrxTableRowControlsScope, { value: controls, children: col.customActions(displayRow, controls) });
54669
- return /* @__PURE__ */ jsx59("div", { "data-matrx-table-custom-actions": true, "data-matrx-cell-control": true, className: "inline-flex items-center justify-end gap-0", onClick: (event) => event.stopPropagation(), children: effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx59(
54670
- MatrxTableRowAlchemyProvider,
54671
- {
54672
- copy: tableRowCopyProps(effectiveCopy, displayRow, `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`, copy === void 0 ? declaredVisibleCopyColumns : void 0),
54673
- placement: rowCopyInMenu && columnId(col) === (menuActionsColumn ? columnId(menuActionsColumn) : void 0) ? "menu" : "inline",
54674
- controls,
54675
- children: content
54676
- }
54677
- ) : content });
54851
+ const copyHere = rowCopyInCustomColumn && effectiveCopy && menuActionsColumn !== void 0 && columnId(col) === columnId(menuActionsColumn);
54852
+ return /* @__PURE__ */ jsxs48("div", { "data-matrx-table-custom-actions": true, "data-matrx-cell-control": true, className: cn("inline-flex items-center justify-end gap-0", compactRows && "[&_button]:h-6 [&_button]:min-h-6"), onClick: (event) => event.stopPropagation(), children: [
54853
+ copyHere && effectiveCopy ? /* @__PURE__ */ jsx59(
54854
+ TableRowCopyControl,
54855
+ {
54856
+ size: "toolbar",
54857
+ copy: effectiveCopy,
54858
+ row: displayRow,
54859
+ sourceId: `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`,
54860
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
54861
+ }
54862
+ ) : null,
54863
+ effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx59(
54864
+ MatrxTableRowAlchemyProvider,
54865
+ {
54866
+ copy: tableRowCopyProps(effectiveCopy, displayRow, `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`, copy === void 0 ? readDeclaredCopyColumns : void 0),
54867
+ placement: rowCopyInMenu && columnId(col) === (menuActionsColumn ? columnId(menuActionsColumn) : void 0) ? "menu" : "inline",
54868
+ controls,
54869
+ children: content
54870
+ }
54871
+ ) : content
54872
+ ] });
54678
54873
  }
54679
54874
  const display = renderCell(displayRow, col, index);
54680
54875
  const href = col.href?.(row) ?? void 0;
@@ -54842,15 +55037,15 @@ function MatrxDataTableCore(coreProps) {
54842
55037
  const drawn = buildRecordControls(row);
54843
55038
  const live = {};
54844
55039
  for (const [key, value] of Object.entries(drawn)) {
54845
- live[key] = typeof value === "function" ? (...args) => {
55040
+ live[key] = typeof value === "function" ? lazyCallback((...args) => {
54846
55041
  const now = rowLatest.current.buildRecordControls(row);
54847
55042
  const handler = now[key];
54848
55043
  return typeof handler === "function" ? handler(...args) : void 0;
54849
- } : value;
55044
+ }) : value;
54850
55045
  }
54851
55046
  return live;
54852
55047
  };
54853
- const rowEpoch = useRenderEpoch([
55048
+ const rowShape = [
54854
55049
  // WHAT A BODY ROW READS FROM THIS TABLE'S PROPS — and nothing it does not, so a host that
54855
55050
  // rebuilds its toolbar, its query or its empty state on every render redraws no row. Handlers
54856
55051
  // are absent on purpose: they run through `rowLatest`. Columns count by what a body cell
@@ -54914,7 +55109,12 @@ function MatrxDataTableCore(coreProps) {
54914
55109
  hierarchyIndex,
54915
55110
  hierarchyBlockedIds,
54916
55111
  draggedRowId
54917
- ]);
55112
+ ];
55113
+ const rowEpoch = useRenderEpoch(rowShape.filter((value) => typeof value !== "function" && (typeof value !== "object" || value === null)));
55114
+ const rowProbe = useRenderEpoch(rowShape.filter((value) => typeof value === "function" || typeof value === "object" && value !== null));
55115
+ const rowDrawings = useRef28(null);
55116
+ rowDrawings.current ??= new RowDrawings();
55117
+ const drawBodyRow = (rowId, row, index) => rowDrawings.current.draw(rowId, renderRecordRow(row, index));
54918
55118
  chromeLatest.current = { processed, data, toggleAllOnPage, showMore: progressiveRows.showMore, applySavedView };
54919
55119
  const chromeGeometry = [
54920
55120
  ...Object.entries(effectiveColumnWidths).flat(),
@@ -55178,6 +55378,7 @@ function MatrxDataTableCore(coreProps) {
55178
55378
  "td",
55179
55379
  {
55180
55380
  "data-matrx-table-column-id": columnId(col),
55381
+ "data-matrx-table-pinned-actions": pinnedActionsColumnId === columnId(col) ? "" : void 0,
55181
55382
  "data-matrx-column-drag-shadow": isColumnDragShadow ? "true" : void 0,
55182
55383
  ...sheetCell ? {
55183
55384
  "data-matrx-cell-row": sheetCell["data-matrx-cell-row"],
@@ -55216,6 +55417,11 @@ function MatrxDataTableCore(coreProps) {
55216
55417
  frozen && sheetCell?.["data-matrx-cell-selected"] && "sm:bg-[color-mix(in_oklab,var(--color-primary)_10%,var(--color-card))]",
55217
55418
  frozen && canHoverFrozenCell && "sm:group-hover/matrx-row:bg-[color-mix(in_oklab,var(--color-muted)_50%,var(--color-card))]",
55218
55419
  frozenEdgeId === columnId(col) && FROZEN_EDGE_CLASS,
55420
+ pinnedActionsColumnId === columnId(col) && [
55421
+ "text-right sm:sticky sm:right-0 sm:z-20 sm:shadow-[inset_1px_0_0_var(--color-border)]",
55422
+ frozenRowBackgroundClass,
55423
+ canHoverFrozenCell && "sm:group-hover/matrx-row:bg-[color-mix(in_oklab,var(--color-muted)_50%,var(--color-card))]"
55424
+ ],
55219
55425
  // A cell tint paints OVER the row tint beneath
55220
55426
  // it, and the consumer's own hook comes last so
55221
55427
  // it can always win.
@@ -55350,7 +55556,7 @@ function MatrxDataTableCore(coreProps) {
55350
55556
  copy: effectiveCopy,
55351
55557
  row: displayRow,
55352
55558
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`,
55353
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
55559
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
55354
55560
  }
55355
55561
  ) : null,
55356
55562
  renderRowActions(displayRow, controls),
@@ -55986,7 +56192,7 @@ function MatrxDataTableCore(coreProps) {
55986
56192
  copy: effectiveCopy,
55987
56193
  row: displayRow,
55988
56194
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`,
55989
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
56195
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
55990
56196
  }
55991
56197
  ) : null,
55992
56198
  renderRowActions(displayRow, controls),
@@ -56198,6 +56404,7 @@ function MatrxDataTableCore(coreProps) {
56198
56404
  {
56199
56405
  "data-matrx-table-column-id": id,
56200
56406
  "data-matrx-header-column-id": id,
56407
+ "data-matrx-table-pinned-actions": pinnedActionsColumnId === id ? "" : void 0,
56201
56408
  "data-matrx-column-drag-shadow": isColumnDragShadow ? "true" : void 0,
56202
56409
  "aria-sort": isSorted ? sort?.direction === "asc" ? "ascending" : "descending" : void 0,
56203
56410
  className: cn(
@@ -56225,7 +56432,9 @@ function MatrxDataTableCore(coreProps) {
56225
56432
  frozenColumns.offsets[id] !== void 0 && FROZEN_HEADER_CLASS,
56226
56433
  phoneFrozenId === id && FROZEN_PHONE_HEADER_CLASS,
56227
56434
  embedded && (frozenColumns.offsets[id] !== void 0 || phoneFrozenId === id) && "sm:bg-card max-sm:bg-card",
56228
- frozenEdgeId === id && FROZEN_EDGE_CLASS
56435
+ frozenEdgeId === id && FROZEN_EDGE_CLASS,
56436
+ pinnedActionsColumnId === id && "sm:sticky sm:right-0 sm:z-30 sm:bg-muted sm:shadow-[inset_1px_0_0_var(--color-border)]",
56437
+ pinnedActionsColumnId === id && embedded && "sm:bg-card"
56229
56438
  ),
56230
56439
  style: {
56231
56440
  ...columnWidthVar(width, windowedWidthFor(id, width), id, columnResizable),
@@ -56424,8 +56633,9 @@ function MatrxDataTableCore(coreProps) {
56424
56633
  row,
56425
56634
  index,
56426
56635
  epoch: rowEpoch,
56636
+ probe: rowProbe,
56427
56637
  facts: rowFactsFor(row, id, index),
56428
- render: renderRecordRow
56638
+ draw: drawBodyRow
56429
56639
  },
56430
56640
  id
56431
56641
  );
@@ -56876,7 +57086,7 @@ function MatrxDataTableCore(coreProps) {
56876
57086
  copy: effectiveCopy,
56877
57087
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(selectedRow)}`,
56878
57088
  row: selectedRow,
56879
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
57089
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
56880
57090
  }
56881
57091
  ) : null,
56882
57092
  detail?.headerActions?.(selectedRow),
@@ -56964,7 +57174,7 @@ function MatrxDataTableCore(coreProps) {
56964
57174
  copy: effectiveCopy,
56965
57175
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(windowRow)}`,
56966
57176
  row: windowRow,
56967
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
57177
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
56968
57178
  }
56969
57179
  ) : null
56970
57180
  ] }),
@@ -57231,9 +57441,9 @@ function HierarchyDroppableRow({
57231
57441
  children
57232
57442
  }) {
57233
57443
  const { setNodeRef } = useDroppable2({ id, disabled });
57234
- if (!isValidElement2(children) || children.type !== "tr") return children;
57444
+ if (!isValidElement3(children) || children.type !== "tr") return children;
57235
57445
  const row = children;
57236
- return cloneElement2(row, {
57446
+ return cloneElement3(row, {
57237
57447
  ref: setNodeRef,
57238
57448
  className: row.props.className
57239
57449
  });