@ai-matrx/design-system 0.19.0 → 0.19.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +20 -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/filter-engine.d.cts +1 -1
  5. package/dist/data-table/filter-engine.d.ts +1 -1
  6. package/dist/data-table/host.d.cts +1 -1
  7. package/dist/data-table/host.d.ts +1 -1
  8. package/dist/data-table/index.cjs +45 -13
  9. package/dist/data-table/index.cjs.map +1 -1
  10. package/dist/data-table/index.d.cts +2 -2
  11. package/dist/data-table/index.d.ts +2 -2
  12. package/dist/data-table/index.js +45 -13
  13. package/dist/data-table/index.js.map +1 -1
  14. package/dist/data-table/infer-filter.d.cts +1 -1
  15. package/dist/data-table/infer-filter.d.ts +1 -1
  16. package/dist/data-table/layered-filters.d.cts +1 -1
  17. package/dist/data-table/layered-filters.d.ts +1 -1
  18. package/dist/data-table/query-control.d.cts +1 -1
  19. package/dist/data-table/query-control.d.ts +1 -1
  20. package/dist/data-table/scroll-pagination.cjs +10 -7
  21. package/dist/data-table/scroll-pagination.cjs.map +1 -1
  22. package/dist/data-table/scroll-pagination.js +10 -7
  23. package/dist/data-table/scroll-pagination.js.map +1 -1
  24. package/dist/data-table/types.cjs.map +1 -1
  25. package/dist/data-table/types.d.cts +1 -1
  26. package/dist/data-table/types.d.ts +1 -1
  27. package/dist/data-table/url-state.d.cts +1 -1
  28. package/dist/data-table/url-state.d.ts +1 -1
  29. package/dist/data-table/xlsx.d.cts +1 -1
  30. package/dist/data-table/xlsx.d.ts +1 -1
  31. package/dist/{types-Di6QT0P1.d.cts → types-BcIcmIxd.d.cts} +5 -0
  32. package/dist/{types-D1m14boM.d.ts → types-xTXSqmR7.d.ts} +5 -0
  33. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.1 — 2026-09-13
4
+
5
+ ### Data-table interaction and pagination
6
+
7
+ MatrxDataTable now supports desktop column resizing with pointer and keyboard
8
+ separators, progressive rendering for complete local datasets, and scroll
9
+ append that recognizes the actual table, ancestor, or document scroll owner
10
+ only after a fresh user-driven downward movement. Mobile keeps content-sized
11
+ columns and hides resize handles. Manual Load more remains available whenever
12
+ automatic pagination is suspended.
13
+
14
+ Table toolbar and pagination controls use the canonical 44px target and 14px
15
+ icon geometry, and shared SVG icons use rounded caps and joins.
16
+
17
+ ### Consumer action
18
+
19
+ Update `@ai-matrx/data` with this package. Hosts that pass a manual pagination
20
+ policy must provide its documented reason and `approvedBy`; use `suspended` for
21
+ unavailable configuration.
22
+
3
23
  ## 0.19.0
4
24
 
5
25
  Alchemy uses the canonical Tap Target primitive with Portal by default and glass or transparent presentation. Adds native AI-context copy, preparation recipes, content limits, and grouped Matrx destinations using the exact prepared revision. Destination handoff releases the dialog focus trap and saved artifacts expose their receipt. Copy + Transform remains an optional packaged icon.
@@ -1,5 +1,5 @@
1
1
  import { AgentPayloadInput } from './copy-types.cjs';
2
- import { e as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-Di6QT0P1.cjs';
2
+ import { e as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-BcIcmIxd.cjs';
3
3
  import 'react';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { AgentPayloadInput } from './copy-types.js';
2
- import { e as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-D1m14boM.js';
2
+ import { e as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-xTXSqmR7.js';
3
3
  import 'react';
4
4
 
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-Di6QT0P1.cjs';
1
+ import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-BcIcmIxd.cjs';
2
2
  import 'react';
3
3
  import './copy-types.cjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-D1m14boM.js';
1
+ import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-xTXSqmR7.js';
2
2
  import 'react';
3
3
  import './copy-types.js';
4
4
 
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { ComponentType, ReactNode, MouseEventHandler } from 'react';
3
3
  import { CopyControlProps } from './copy-types.cjs';
4
4
  export { AgentPayloadInput, AiCustomSource, AiVariant, CopyExportConfig } from './copy-types.cjs';
5
- import { b as TableSavedViewsProps } from '../types-Di6QT0P1.cjs';
5
+ import { b as TableSavedViewsProps } from '../types-BcIcmIxd.cjs';
6
6
 
7
7
  interface TableLinkProps {
8
8
  href: string;
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { ComponentType, ReactNode, MouseEventHandler } from 'react';
3
3
  import { CopyControlProps } from './copy-types.js';
4
4
  export { AgentPayloadInput, AiCustomSource, AiVariant, CopyExportConfig } from './copy-types.js';
5
- import { b as TableSavedViewsProps } from '../types-D1m14boM.js';
5
+ import { b as TableSavedViewsProps } from '../types-xTXSqmR7.js';
6
6
 
7
7
  interface TableLinkProps {
8
8
  href: string;
@@ -1070,12 +1070,16 @@ function isVerticallyScrollable(element) {
1070
1070
  return (overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay") && element.scrollHeight > element.clientHeight;
1071
1071
  }
1072
1072
  function resolveScrollOwner(source) {
1073
+ const documentOwner = document.scrollingElement instanceof HTMLElement ? document.scrollingElement : document.documentElement;
1073
1074
  for (let node = source; node; node = node.parentElement) {
1075
+ if (node === documentOwner || node === document.documentElement || node === document.body) {
1076
+ return { element: documentOwner, document: true };
1077
+ }
1074
1078
  if (node === source && node.scrollHeight > node.clientHeight || isVerticallyScrollable(node)) {
1075
1079
  return { element: node, document: false };
1076
1080
  }
1077
1081
  }
1078
- return { element: document.scrollingElement instanceof HTMLElement ? document.scrollingElement : document.documentElement, document: true };
1082
+ return { element: documentOwner, document: true };
1079
1083
  }
1080
1084
  function ownerScrollTop(owner) {
1081
1085
  return owner.document ? window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0 : owner.element.scrollTop;
@@ -1202,7 +1206,7 @@ function useScrollPagination({
1202
1206
  else owner.element.removeEventListener("scroll", onOwnerScroll);
1203
1207
  });
1204
1208
  };
1205
- const setIntent = (source, startTop) => {
1209
+ const setIntent = (source) => {
1206
1210
  const current = latestRef.current;
1207
1211
  const owner = resolveScrollOwner(source);
1208
1212
  if (!isVisibleContainer(source) || current.loading || current.isFetchingNextPage || inFlightGenerationRef.current !== null) return;
@@ -1215,9 +1219,8 @@ function useScrollPagination({
1215
1219
  };
1216
1220
  const cleanups = attachable.map((source) => {
1217
1221
  if (!observedTopRef.current.has(source)) observedTopRef.current.set(source, source.scrollTop);
1218
- const lastObservedTop = () => observedTopRef.current.get(source) ?? source.scrollTop;
1219
1222
  const onWheel = (event) => {
1220
- if (event.deltaY > 0 && Math.abs(event.deltaY) > Math.abs(event.deltaX)) setIntent(source, lastObservedTop());
1223
+ if (event.deltaY > 0 && Math.abs(event.deltaY) > Math.abs(event.deltaX)) setIntent(source);
1221
1224
  };
1222
1225
  const onTouchStart = (event) => {
1223
1226
  const touch = event.touches.item(0);
@@ -1226,16 +1229,16 @@ function useScrollPagination({
1226
1229
  const onTouchMove = (event) => {
1227
1230
  const touch = event.touches.item(0);
1228
1231
  const startY = Number(source.dataset.matrxPaginationTouchY);
1229
- if (touch && Number.isFinite(startY) && startY - touch.clientY > 0) setIntent(source, lastObservedTop());
1232
+ if (touch && Number.isFinite(startY) && startY - touch.clientY > 0) setIntent(source);
1230
1233
  };
1231
1234
  const onTouchEnd = () => {
1232
1235
  delete source.dataset.matrxPaginationTouchY;
1233
1236
  };
1234
1237
  const onKeyDown = (event) => {
1235
- if (isDownwardKeyboardInput(event)) setIntent(source, lastObservedTop());
1238
+ if (isDownwardKeyboardInput(event)) setIntent(source);
1236
1239
  };
1237
1240
  const onPointerDown = (event) => {
1238
- if (isNativeScrollbarPointer(event, source)) setIntent(source, lastObservedTop());
1241
+ if (isNativeScrollbarPointer(event, source)) setIntent(source);
1239
1242
  };
1240
1243
  const onScroll = () => {
1241
1244
  handleScroll(source, { element: source, document: false });
@@ -5957,6 +5960,8 @@ function ColumnResizeHandle({
5957
5960
  minWidth,
5958
5961
  maxWidth,
5959
5962
  disabled = false,
5963
+ onResizeStart,
5964
+ onResizeCancel,
5960
5965
  onResizeCommit
5961
5966
  }) {
5962
5967
  const handleRef = (0, import_react11.useRef)(null);
@@ -6001,6 +6006,7 @@ function ColumnResizeHandle({
6001
6006
  if (!commit) {
6002
6007
  if (active.priorPreview) table?.style.setProperty(cssVar, active.priorPreview);
6003
6008
  else table?.style.removeProperty(cssVar);
6009
+ onResizeCancel?.();
6004
6010
  } else {
6005
6011
  writePreview(width);
6006
6012
  setAnnouncedWidth(width);
@@ -6009,7 +6015,7 @@ function ColumnResizeHandle({
6009
6015
  if (handleRef.current?.hasPointerCapture(active.pointerId)) {
6010
6016
  handleRef.current.releasePointerCapture(active.pointerId);
6011
6017
  }
6012
- }, [clearQueuedPreview, columnId2, cssVar, onResizeCommit, tableRef, writePreview]);
6018
+ }, [clearQueuedPreview, columnId2, cssVar, onResizeCancel, onResizeCommit, tableRef, writePreview]);
6013
6019
  (0, import_react11.useEffect)(() => () => clearQueuedPreview(), [clearQueuedPreview]);
6014
6020
  const onPointerDown = (event) => {
6015
6021
  if (disabled || event.button !== 0 || !event.isPrimary) return;
@@ -6017,6 +6023,7 @@ function ColumnResizeHandle({
6017
6023
  event.stopPropagation();
6018
6024
  const startWidth = readWidth();
6019
6025
  keyboardWidthRef.current = startWidth;
6026
+ onResizeStart?.();
6020
6027
  activeResizeRef.current = {
6021
6028
  pointerId: event.pointerId,
6022
6029
  startX: event.clientX,
@@ -6056,6 +6063,7 @@ function ColumnResizeHandle({
6056
6063
  event.stopPropagation();
6057
6064
  const nextWidth = clampColumnWidth(width, bounds);
6058
6065
  keyboardWidthRef.current = nextWidth;
6066
+ onResizeStart?.();
6059
6067
  writePreview(nextWidth);
6060
6068
  setAnnouncedWidth(nextWidth);
6061
6069
  onResizeCommit(columnId2, nextWidth);
@@ -8314,6 +8322,7 @@ function MatrxDataTableCore({
8314
8322
  if (scrollRef.current) scrollRef.current.scrollTop = 0;
8315
8323
  if (cardsScrollRef.current) cardsScrollRef.current.scrollTop = 0;
8316
8324
  }, [appendQueryKey]);
8325
+ const appendScrollPolicy = appendQuery?.scroll;
8317
8326
  const scrollPagination = useScrollPagination({
8318
8327
  containers: [scrollRef, cardsScrollRef],
8319
8328
  queryKey: appendQuery?.pagination.queryKey ?? "",
@@ -8323,7 +8332,11 @@ function MatrxDataTableCore({
8323
8332
  error: appendQuery?.pagination.error ?? null,
8324
8333
  loadNextPage: appendQuery?.pagination.loadNextPage ?? (() => void 0),
8325
8334
  enabled: appendQuery !== null,
8326
- ...appendQuery?.scroll
8335
+ // Suspended policy is deliberately manual at the hook boundary: its
8336
+ // reason remains visible in the footer while automatic listeners stay off.
8337
+ mode: appendScrollPolicy?.mode === "suspended" ? "manual" : appendScrollPolicy?.mode ?? "scroll",
8338
+ ...appendScrollPolicy?.mode === "scroll" && appendScrollPolicy.thresholdPx !== void 0 ? { thresholdPx: appendScrollPolicy.thresholdPx } : {},
8339
+ ...appendScrollPolicy?.mode === "scroll" && appendScrollPolicy.intentTimeoutMs !== void 0 ? { intentTimeoutMs: appendScrollPolicy.intentTimeoutMs } : {}
8327
8340
  });
8328
8341
  const rootRef = (0, import_react17.useRef)(null);
8329
8342
  const actionDiagnosticObserver = (0, import_react17.useRef)(null);
@@ -8465,6 +8478,7 @@ function MatrxDataTableCore({
8465
8478
  () => normalizeColumnWidthsForColumns(columnState?.widths ?? columnWidths, columns),
8466
8479
  [columns, columnState?.widths, columnWidths]
8467
8480
  );
8481
+ const resizeGestureSnapshotRef = (0, import_react17.useRef)(null);
8468
8482
  const measureVisibleColumnWidths = (0, import_react17.useCallback)(() => {
8469
8483
  const measured = {};
8470
8484
  const headers = tableRef.current ? Array.from(tableRef.current.querySelectorAll(
@@ -8499,13 +8513,25 @@ function MatrxDataTableCore({
8499
8513
  ...actionsWidth === void 0 ? {} : { actionsWidth }
8500
8514
  };
8501
8515
  }, []);
8516
+ const captureResizeGestureSnapshot = (0, import_react17.useCallback)(() => {
8517
+ resizeGestureSnapshotRef.current = {
8518
+ widths: measureVisibleColumnWidths(),
8519
+ geometry: measureFixedTableGeometry()
8520
+ };
8521
+ }, [measureFixedTableGeometry, measureVisibleColumnWidths]);
8522
+ const clearResizeGestureSnapshot = (0, import_react17.useCallback)(() => {
8523
+ resizeGestureSnapshotRef.current = null;
8524
+ }, []);
8502
8525
  const commitColumnWidths = (0, import_react17.useCallback)((next, captureInitialWidths = false) => {
8526
+ const gestureSnapshot = captureInitialWidths ? resizeGestureSnapshotRef.current : null;
8527
+ resizeGestureSnapshotRef.current = null;
8503
8528
  const normalized = normalizeColumnWidthsForColumns(
8504
- captureInitialWidths ? { ...measureVisibleColumnWidths(), ...next } : next,
8529
+ captureInitialWidths ? { ...gestureSnapshot?.widths ?? measureVisibleColumnWidths(), ...next } : next,
8505
8530
  columns
8506
8531
  );
8507
- if (captureInitialWidths) setFixedTableGeometry(measureFixedTableGeometry());
8508
- else setFixedTableGeometry(null);
8532
+ if (captureInitialWidths) {
8533
+ setFixedTableGeometry(gestureSnapshot?.geometry ?? measureFixedTableGeometry());
8534
+ } else setFixedTableGeometry(null);
8509
8535
  for (const id of columnIds) {
8510
8536
  tableRef.current?.style.removeProperty(columnResizeCssVar(id));
8511
8537
  }
@@ -9967,6 +9993,8 @@ function MatrxDataTableCore({
9967
9993
  tableRef,
9968
9994
  minWidth: col.minWidth,
9969
9995
  maxWidth: col.maxWidth,
9996
+ onResizeStart: captureResizeGestureSnapshot,
9997
+ onResizeCancel: clearResizeGestureSnapshot,
9970
9998
  onResizeCommit: (columnId2, width) => commitColumnWidths(
9971
9999
  { ...effectiveColumnWidths, [columnId2]: width },
9972
10000
  true
@@ -10309,7 +10337,11 @@ function MatrxDataTableCore({
10309
10337
  "."
10310
10338
  ] }) : null,
10311
10339
  !isLoading && !isFetching && !appendQuery.pagination.loadAll?.isLoading && !scrollPagination.error && !appendQuery.pagination.hasNextPage && appendQuery.pagination.totalItems !== void 0 && data.length === appendQuery.pagination.totalItems ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { children: "All source rows are loaded." }) : appendUsesLocalProcessing ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { children: "Local search and filters cover loaded rows." }) : null,
10312
- scrollPagination.error ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { role: "alert", className: "break-words text-destructive", children: scrollPagination.error.message }) : null
10340
+ scrollPagination.error ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { role: "alert", className: "break-words text-destructive", children: scrollPagination.error.message }) : null,
10341
+ appendScrollPolicy?.mode === "suspended" ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("p", { role: "status", className: "break-words", children: [
10342
+ appendScrollPolicy.reason,
10343
+ " Load more remains available."
10344
+ ] }) : null
10313
10345
  ] })
10314
10346
  ]
10315
10347
  }