@ai-matrx/design-system 0.17.1 → 0.17.3

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.3 — 2026-09-12
4
+
5
+ `MatrxDataTable` now keeps a fixed-height append status area at the bottom of
6
+ automatic and manual append surfaces. Active loads show an accessible spinner
7
+ without replacing already loaded rows or shifting the footer, including in
8
+ dark mode and reduced-motion environments.
9
+
10
+ ### Consumer action
11
+
12
+ Update to 0.17.3 for visible, layout-stable feedback while additional table
13
+ rows load. No query, pagination, or API changes are required.
14
+
15
+ ## 0.17.2 — 2026-09-12
16
+
17
+ `MatrxDataTable` now resets the vertical scroll position of both its desktop
18
+ table and mobile card scrollers before paint when a non-initial
19
+ `controlled-append` source key changes. Same-source appends and horizontal
20
+ scroll position remain untouched in both automatic and manual modes.
21
+
22
+ ### Consumer action
23
+
24
+ Update to 0.17.2 so refreshed or replaced append sources begin at their first
25
+ row instead of retaining the previous source's bottom position. No API or
26
+ configuration change is required.
27
+
3
28
  ## 0.17.1 — 2026-09-12
4
29
 
5
30
  `useScrollPagination` now retains each container's last observed scroll position
@@ -5469,6 +5469,16 @@ function MatrxDataTableCore({
5469
5469
  ]);
5470
5470
  const scrollRef = (0, import_react14.useRef)(null);
5471
5471
  const cardsScrollRef = (0, import_react14.useRef)(null);
5472
+ const previousAppendKeyForScrollReset = (0, import_react14.useRef)(appendQueryKey);
5473
+ (0, import_react14.useLayoutEffect)(() => {
5474
+ const previous = previousAppendKeyForScrollReset.current;
5475
+ previousAppendKeyForScrollReset.current = appendQueryKey;
5476
+ if (previous === null || appendQueryKey === null || previous === appendQueryKey) {
5477
+ return;
5478
+ }
5479
+ if (scrollRef.current) scrollRef.current.scrollTop = 0;
5480
+ if (cardsScrollRef.current) cardsScrollRef.current.scrollTop = 0;
5481
+ }, [appendQueryKey]);
5472
5482
  const scrollPagination = useScrollPagination({
5473
5483
  containers: [scrollRef, cardsScrollRef],
5474
5484
  queryKey: appendQuery?.pagination.queryKey ?? "",
@@ -6506,7 +6516,7 @@ function MatrxDataTableCore({
6506
6516
  mobileCardsClass
6507
6517
  ),
6508
6518
  children: [
6509
- isFetching && !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6519
+ isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6510
6520
  "div",
6511
6521
  {
6512
6522
  role: "status",
@@ -6601,7 +6611,7 @@ function MatrxDataTableCore({
6601
6611
  resolve: resolveHierarchyMove
6602
6612
  }
6603
6613
  ) : null,
6604
- isFetching && !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6614
+ isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6605
6615
  "div",
6606
6616
  {
6607
6617
  role: "status",
@@ -6962,13 +6972,56 @@ function MatrxDataTableCore({
6962
6972
  }
6963
6973
  ) : null
6964
6974
  ] }),
6965
- appendQuery ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { "data-matrx-table-footer": true, className: "flex min-h-16 shrink-0 items-center justify-between gap-3 border-t border-border px-3 py-2", "aria-busy": isLoading || isFetching, children: [
6966
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { role: "status", "aria-live": "polite", className: "text-xs text-muted-foreground", children: [
6967
- isFetching ? "Loading more rows\u2026" : isLoading ? "Loading rows\u2026" : `${data.length.toLocaleString()} loaded${appendQuery.pagination.totalItems === void 0 ? "" : ` of ${appendQuery.pagination.totalItems.toLocaleString()}`}`,
6968
- scrollPagination.error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { role: "alert", className: "text-destructive", children: scrollPagination.error.message }) : null
6969
- ] }),
6970
- scrollPagination.error && !appendQuery.pagination.hasNextPage ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Button, { type: "button", variant: "outline", onClick: appendQuery.pagination.refresh, children: "Reload rows" }) : appendQuery.pagination.hasNextPage || scrollPagination.error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Button, { type: "button", variant: "outline", disabled: isLoading || isFetching, onClick: () => void scrollPagination.requestNextPage(), children: scrollPagination.error ? "Retry" : "Load more" }) : !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-xs text-muted-foreground", children: "All rows loaded" }) : null
6971
- ] }) : !hidePagination && totalItems > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6975
+ appendQuery ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6976
+ "div",
6977
+ {
6978
+ "data-matrx-table-footer": true,
6979
+ className: "flex min-h-16 shrink-0 items-center justify-between gap-3 border-t border-border px-3 py-2",
6980
+ "aria-busy": isLoading || isFetching,
6981
+ children: [
6982
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6983
+ "div",
6984
+ {
6985
+ role: "status",
6986
+ "aria-live": "polite",
6987
+ className: "flex min-w-0 flex-1 items-center gap-2 text-xs text-muted-foreground",
6988
+ children: [
6989
+ isLoading || isFetching ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6990
+ Loader2,
6991
+ {
6992
+ "data-matrx-table-append-loader": true,
6993
+ "aria-hidden": "true",
6994
+ className: "h-5 w-5 shrink-0 animate-spin text-primary motion-reduce:animate-none"
6995
+ }
6996
+ ) : null,
6997
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "min-w-0", children: [
6998
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "break-words font-medium text-foreground", children: isFetching ? "Loading more rows\u2026" : isLoading ? "Loading rows\u2026" : `${data.length.toLocaleString()} loaded${appendQuery.pagination.totalItems === void 0 ? "" : ` of ${appendQuery.pagination.totalItems.toLocaleString()}`}` }),
6999
+ scrollPagination.error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { role: "alert", className: "break-words text-destructive", children: scrollPagination.error.message }) : null
7000
+ ] })
7001
+ ]
7002
+ }
7003
+ ),
7004
+ scrollPagination.error && !appendQuery.pagination.hasNextPage ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7005
+ Button,
7006
+ {
7007
+ type: "button",
7008
+ variant: "outline",
7009
+ onClick: appendQuery.pagination.refresh,
7010
+ children: "Reload rows"
7011
+ }
7012
+ ) : appendQuery.pagination.hasNextPage || scrollPagination.error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7013
+ Button,
7014
+ {
7015
+ type: "button",
7016
+ variant: "outline",
7017
+ disabled: isLoading || isFetching,
7018
+ onClick: () => void scrollPagination.requestNextPage(),
7019
+ children: scrollPagination.error ? "Retry" : "Load more"
7020
+ }
7021
+ ) : !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-xs text-muted-foreground", children: "All rows loaded" }) : null
7022
+ ]
7023
+ }
7024
+ ) : !hidePagination && totalItems > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6972
7025
  GenericTablePagination,
6973
7026
  {
6974
7027
  totalItems,