@ai-matrx/design-system 0.57.0 → 0.59.1

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, fresh = false) {
35587
+ const previous = this.rows.get(rowId);
35588
+ if (previous && !fresh) {
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,14 @@ 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]));
52439
- }
52440
- var MatrxTableBodyRow = memo(function MatrxTableBodyRow2({ row, index, render }) {
52441
- return /* @__PURE__ */ jsx59(Fragment19, { children: render(row, index) });
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]));
52596
+ }
52597
+ var MatrxTableBodyRow = memo(function MatrxTableBodyRow2(props) {
52598
+ const { rowId, row, index, draw } = props;
52599
+ const last = useRef28(null);
52600
+ const fresh = last.current === null || !sameBodyRow({ ...last.current, probe: props.probe }, props);
52601
+ last.current = props;
52602
+ return draw(rowId, row, index, fresh);
52442
52603
  }, sameBodyRow);
52443
52604
  var MatrxTableChrome = memo(function MatrxTableChrome2({ render }) {
52444
52605
  return /* @__PURE__ */ jsx59(Fragment19, { children: render() });
@@ -53302,6 +53463,9 @@ function MatrxDataTableCore(coreProps) {
53302
53463
  const tableContextMenuInstanceId = useId4();
53303
53464
  const tableDndContextId = useId4();
53304
53465
  const defaultCopyTitle = toolbar?.title || "Table";
53466
+ const copyColumnsLatest = useRef28(declaredVisibleCopyColumns);
53467
+ copyColumnsLatest.current = declaredVisibleCopyColumns;
53468
+ const readDeclaredCopyColumns = lazyCallback(() => copyColumnsLatest.current);
53305
53469
  const defaultCopy = useMemo12(() => ({
53306
53470
  label: defaultCopyTitle,
53307
53471
  listLabel: defaultCopyTitle,
@@ -53311,11 +53475,11 @@ function MatrxDataTableCore(coreProps) {
53311
53475
  listDescription: `${defaultCopyTitle} \u2014 ${remoteQuery ? "current filtered/sorted loaded view" : "current filtered/sorted view"}.`,
53312
53476
  listAttributes: (_visible, loaded) => remoteQuery ? { coverage: "loaded-current-view", loaded_count: loaded.length } : { coverage: "current-view" },
53313
53477
  humanRow: (row) => formatDefaultTableCopyRecord(
53314
- projectDefaultTableCopyRow(row, declaredVisibleCopyColumns),
53315
- declaredVisibleCopyColumns
53478
+ projectDefaultTableCopyRow(row, copyColumnsLatest.current),
53479
+ copyColumnsLatest.current
53316
53480
  ),
53317
- agentRow: (row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)
53318
- }), [defaultCopyTitle, declaredVisibleCopyColumns, remoteQuery]);
53481
+ agentRow: (row) => projectDefaultTableCopyRow(row, copyColumnsLatest.current)
53482
+ }), [defaultCopyTitle, remoteQuery]);
53319
53483
  const effectiveCopy = copy === false ? void 0 : copy ?? defaultCopy;
53320
53484
  const visibleDataColumns = useMemo12(() => visibleColumns.filter((column) => !column.customActions), [visibleColumns]);
53321
53485
  const effectiveCopyColumns = copy === void 0 ? declaredVisibleCopyColumns : visibleDataColumns;
@@ -54010,7 +54174,7 @@ function MatrxDataTableCore(coreProps) {
54010
54174
  return /* @__PURE__ */ jsx59(
54011
54175
  MatrxTableRowAlchemyProvider,
54012
54176
  {
54013
- copy: tableRowCopyProps(effectiveCopy, row, `${tableCopySourceNamespace}:row:${getRowId(row)}`, copy === void 0 ? declaredVisibleCopyColumns : void 0),
54177
+ copy: tableRowCopyProps(effectiveCopy, row, `${tableCopySourceNamespace}:row:${getRowId(row)}`, copy === void 0 ? readDeclaredCopyColumns : void 0),
54014
54178
  placement: rowCopyInMenu ? "menu" : "inline",
54015
54179
  controls,
54016
54180
  children: scopedActions
@@ -54697,13 +54861,13 @@ function MatrxDataTableCore(coreProps) {
54697
54861
  copy: effectiveCopy,
54698
54862
  row: displayRow,
54699
54863
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`,
54700
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
54864
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
54701
54865
  }
54702
54866
  ) : null,
54703
54867
  effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx59(
54704
54868
  MatrxTableRowAlchemyProvider,
54705
54869
  {
54706
- copy: tableRowCopyProps(effectiveCopy, displayRow, `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`, copy === void 0 ? declaredVisibleCopyColumns : void 0),
54870
+ copy: tableRowCopyProps(effectiveCopy, displayRow, `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`, copy === void 0 ? readDeclaredCopyColumns : void 0),
54707
54871
  placement: rowCopyInMenu && columnId(col) === (menuActionsColumn ? columnId(menuActionsColumn) : void 0) ? "menu" : "inline",
54708
54872
  controls,
54709
54873
  children: content
@@ -54877,15 +55041,15 @@ function MatrxDataTableCore(coreProps) {
54877
55041
  const drawn = buildRecordControls(row);
54878
55042
  const live = {};
54879
55043
  for (const [key, value] of Object.entries(drawn)) {
54880
- live[key] = typeof value === "function" ? (...args) => {
55044
+ live[key] = typeof value === "function" ? lazyCallback((...args) => {
54881
55045
  const now = rowLatest.current.buildRecordControls(row);
54882
55046
  const handler = now[key];
54883
55047
  return typeof handler === "function" ? handler(...args) : void 0;
54884
- } : value;
55048
+ }) : value;
54885
55049
  }
54886
55050
  return live;
54887
55051
  };
54888
- const rowEpoch = useRenderEpoch([
55052
+ const rowShape = [
54889
55053
  // WHAT A BODY ROW READS FROM THIS TABLE'S PROPS — and nothing it does not, so a host that
54890
55054
  // rebuilds its toolbar, its query or its empty state on every render redraws no row. Handlers
54891
55055
  // are absent on purpose: they run through `rowLatest`. Columns count by what a body cell
@@ -54949,7 +55113,12 @@ function MatrxDataTableCore(coreProps) {
54949
55113
  hierarchyIndex,
54950
55114
  hierarchyBlockedIds,
54951
55115
  draggedRowId
54952
- ]);
55116
+ ];
55117
+ const rowEpoch = useRenderEpoch(rowShape.filter((value) => typeof value !== "function" && (typeof value !== "object" || value === null)));
55118
+ const rowProbe = useRenderEpoch(rowShape.filter((value) => typeof value === "function" || typeof value === "object" && value !== null));
55119
+ const rowDrawings = useRef28(null);
55120
+ rowDrawings.current ??= new RowDrawings();
55121
+ const drawBodyRow = (rowId, row, index, fresh) => rowDrawings.current.draw(rowId, renderRecordRow(row, index), fresh);
54953
55122
  chromeLatest.current = { processed, data, toggleAllOnPage, showMore: progressiveRows.showMore, applySavedView };
54954
55123
  const chromeGeometry = [
54955
55124
  ...Object.entries(effectiveColumnWidths).flat(),
@@ -55391,7 +55560,7 @@ function MatrxDataTableCore(coreProps) {
55391
55560
  copy: effectiveCopy,
55392
55561
  row: displayRow,
55393
55562
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`,
55394
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
55563
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
55395
55564
  }
55396
55565
  ) : null,
55397
55566
  renderRowActions(displayRow, controls),
@@ -56027,7 +56196,7 @@ function MatrxDataTableCore(coreProps) {
56027
56196
  copy: effectiveCopy,
56028
56197
  row: displayRow,
56029
56198
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`,
56030
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
56199
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
56031
56200
  }
56032
56201
  ) : null,
56033
56202
  renderRowActions(displayRow, controls),
@@ -56468,8 +56637,9 @@ function MatrxDataTableCore(coreProps) {
56468
56637
  row,
56469
56638
  index,
56470
56639
  epoch: rowEpoch,
56640
+ probe: rowProbe,
56471
56641
  facts: rowFactsFor(row, id, index),
56472
- render: renderRecordRow
56642
+ draw: drawBodyRow
56473
56643
  },
56474
56644
  id
56475
56645
  );
@@ -56920,7 +57090,7 @@ function MatrxDataTableCore(coreProps) {
56920
57090
  copy: effectiveCopy,
56921
57091
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(selectedRow)}`,
56922
57092
  row: selectedRow,
56923
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
57093
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
56924
57094
  }
56925
57095
  ) : null,
56926
57096
  detail?.headerActions?.(selectedRow),
@@ -57008,7 +57178,7 @@ function MatrxDataTableCore(coreProps) {
57008
57178
  copy: effectiveCopy,
57009
57179
  sourceId: `${tableCopySourceNamespace}:row:${getRowId(windowRow)}`,
57010
57180
  row: windowRow,
57011
- ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
57181
+ ...copy === void 0 ? { defaultColumns: readDeclaredCopyColumns } : {}
57012
57182
  }
57013
57183
  ) : null
57014
57184
  ] }),
@@ -57275,9 +57445,9 @@ function HierarchyDroppableRow({
57275
57445
  children
57276
57446
  }) {
57277
57447
  const { setNodeRef } = useDroppable2({ id, disabled });
57278
- if (!isValidElement2(children) || children.type !== "tr") return children;
57448
+ if (!isValidElement3(children) || children.type !== "tr") return children;
57279
57449
  const row = children;
57280
- return cloneElement2(row, {
57450
+ return cloneElement3(row, {
57281
57451
  ref: setNodeRef,
57282
57452
  className: row.props.className
57283
57453
  });