@ai-matrx/design-system 0.35.0 → 0.37.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 (35) hide show
  1. package/CHANGELOG.md +48 -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 +63 -7
  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 +63 -7
  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/spreadsheet.cjs +18 -0
  21. package/dist/data-table/spreadsheet.cjs.map +1 -1
  22. package/dist/data-table/spreadsheet.d.cts +5 -0
  23. package/dist/data-table/spreadsheet.d.ts +5 -0
  24. package/dist/data-table/spreadsheet.js +18 -0
  25. package/dist/data-table/spreadsheet.js.map +1 -1
  26. package/dist/data-table/types.cjs.map +1 -1
  27. package/dist/data-table/types.d.cts +1 -1
  28. package/dist/data-table/types.d.ts +1 -1
  29. package/dist/data-table/url-state.d.cts +1 -1
  30. package/dist/data-table/url-state.d.ts +1 -1
  31. package/dist/data-table/xlsx.d.cts +1 -1
  32. package/dist/data-table/xlsx.d.ts +1 -1
  33. package/dist/{types-Cxm5XK0L.d.ts → types-B8vwElPz.d.ts} +25 -1
  34. package/dist/{types-kiV-CAuZ.d.cts → types-BuMHbFjs.d.cts} +25 -1
  35. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.37.1 — 2026-09-23 (0.37.0 was tagged but its dts build failed under TypeScript 6 before the registry; same contents)
4
+
5
+ **Four data-table changes that were on main and never published.** (published by lane
6
+ PUBLISH-SWEEP-4.)
7
+
8
+ * **Keyboard multi-expand restored** — expanded-detail rows open and close from the keyboard in
9
+ the multi-expand arm again (`MatrxDataTable.expanded-detail.test.tsx`).
10
+ * **`coverage.loaded`** — the number of rows loaded from the source BEFORE a host narrows `data`
11
+ with a domain filter; defaults to `data.length`, so a filtered page no longer reports the
12
+ filtered count as what was loaded.
13
+ * **`toolbar.titleCount`** — a source-owned total shown beside the shared title.
14
+ * **`toolbar.customSearch`** — a caller-owned search control in the canonical title-row search
15
+ slot, for a deliberately narrower query contract; it never changes table query state.
16
+
17
+ No consumer action; every addition is optional. Toolchain moved to TypeScript 6.
18
+
19
+ ## 0.36.0 — 2026-09-23
20
+
21
+ **A press inside a popover a grid cell opened is no longer a press on the cell.** (lane
22
+ FIX-15.)
23
+
24
+ React synthetic events propagate through the REACT tree, not the DOM tree. A Radix Popover
25
+ portals its content to `document.body`, but that content is still a React child of the
26
+ table cell that rendered it — so every mousedown, keystroke and clipboard event inside the
27
+ popover was delivered to `useSpreadsheetGrid`'s own handlers as if the person had pressed
28
+ the cell.
29
+
30
+ On production (build `93970125f9`, 2026-09-22) that made the relation picker unusable: one
31
+ real mouse click in its own `Search` box ran `cellProps.onMouseDown`, whose
32
+ `preventDefault()` stopped the input taking focus and whose `focus()` moved focus to the
33
+ spreadsheet scroll container; Radix saw focus leave its layer and dismissed the picker. The
34
+ box could not be typed into at all, so 0.35.0's un-clipped Create offer behind it was
35
+ unreachable by any person.
36
+
37
+ * `useSpreadsheetGrid` now ignores any mouse, key or clipboard event whose real DOM target
38
+ is not inside the element the handler is bound to (`camePastAPortal`) — the test is DOM
39
+ containment, not a list of known overlays, so it covers a relation picker, a person
40
+ picker, a select, a date picker and a menu alike, today and tomorrow.
41
+ * No consumer action. A table with no `spreadsheet` prop is untouched.
42
+
43
+ Proof: `MatrxDataTable.sheet.test.tsx` clause 15 mounts a cell whose content is a real
44
+ `createPortal` into `document.body` and fails on the pre-fix bytes (focus moved to the
45
+ scroller) — RED then GREEN. Headless, against the live store on the records-ui grid harness
46
+ at 1600×1000 and 375 wide: a real click leaves focus in the box, three typed characters
47
+ keep the picker open and land in it, and the Create offer is hit-testable
48
+ (`matrx-frontend/scripts/campaign-tests/fix15_the_pickers_search_box_survives_typing.mjs`;
49
+ 12 clauses fail on the pre-fix bytes).
50
+
3
51
  ## 0.35.0 — 2026-09-22
4
52
 
5
53
  **A popover may now be sized by its CONTENT, because a fixed width cannot be right for a
@@ -1,5 +1,5 @@
1
1
  import { AgentPayloadInput } from './copy-types.cjs';
2
- import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-kiV-CAuZ.cjs';
2
+ import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-BuMHbFjs.cjs';
3
3
  import '../content-transfer.cjs';
4
4
  import 'react';
5
5
  import '@ai-matrx/kit/content-transfer';
@@ -1,5 +1,5 @@
1
1
  import { AgentPayloadInput } from './copy-types.js';
2
- import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-Cxm5XK0L.js';
2
+ import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-B8vwElPz.js';
3
3
  import '../content-transfer.js';
4
4
  import 'react';
5
5
  import '@ai-matrx/kit/content-transfer';
@@ -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-kiV-CAuZ.cjs';
1
+ import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-BuMHbFjs.cjs';
2
2
  import '../content-transfer.cjs';
3
3
  import 'react';
4
4
  import '@ai-matrx/kit/content-transfer';
@@ -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-Cxm5XK0L.js';
1
+ import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-B8vwElPz.js';
2
2
  import '../content-transfer.js';
3
3
  import 'react';
4
4
  import '@ai-matrx/kit/content-transfer';
@@ -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, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-kiV-CAuZ.cjs';
5
+ import { b as TableSavedViewsProps, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-BuMHbFjs.cjs';
6
6
  import { MatrxTableMenuTarget, MatrxTableMenuPayload } from './menu-targets.cjs';
7
7
  import '../content-transfer.cjs';
8
8
  import '@ai-matrx/kit/content-transfer';
@@ -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, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-Cxm5XK0L.js';
5
+ import { b as TableSavedViewsProps, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-B8vwElPz.js';
6
6
  import { MatrxTableMenuTarget, MatrxTableMenuPayload } from './menu-targets.js';
7
7
  import '../content-transfer.js';
8
8
  import '@ai-matrx/kit/content-transfer';
@@ -8439,6 +8439,19 @@ function targetsAnEditor(target) {
8439
8439
  if (!element) return false;
8440
8440
  return element.closest("input, textarea, select, [contenteditable='true']") !== null;
8441
8441
  }
8442
+ function camePastAPortal(target, host) {
8443
+ if (typeof Element === "undefined") return false;
8444
+ const element = target instanceof Element ? target : null;
8445
+ const owner = host instanceof Element ? host : null;
8446
+ if (!element || !owner) return false;
8447
+ return !owner.contains(element);
8448
+ }
8449
+ function camePastAPortalIntoTheContainer(target) {
8450
+ if (typeof Element === "undefined") return false;
8451
+ const element = target instanceof Element ? target : null;
8452
+ if (!element) return false;
8453
+ return element.closest('[data-matrx-table-spreadsheet="true"]') === null;
8454
+ }
8442
8455
  function useSpreadsheetGrid(options) {
8443
8456
  const [range, setRange] = (0, import_react15.useState)(null);
8444
8457
  const [fillTarget, setFillTarget] = (0, import_react15.useState)(null);
@@ -8610,6 +8623,7 @@ function useSpreadsheetGrid(options) {
8610
8623
  const current = optionsRef.current;
8611
8624
  if (!current) return;
8612
8625
  if (targetsAnEditor(event.target)) return;
8626
+ if (camePastAPortalIntoTheContainer(event.target)) return;
8613
8627
  const accel = event.metaKey || event.ctrlKey;
8614
8628
  if (accel && (event.key === "z" || event.key === "Z")) {
8615
8629
  event.preventDefault();
@@ -8696,6 +8710,7 @@ function useSpreadsheetGrid(options) {
8696
8710
  const onCopy = (0, import_react15.useCallback)(
8697
8711
  (event) => {
8698
8712
  if (!optionsRef.current || !range || targetsAnEditor(event.target)) return;
8713
+ if (camePastAPortalIntoTheContainer(event.target)) return;
8699
8714
  const text = selectionAsTsv();
8700
8715
  if (!text) return;
8701
8716
  event.preventDefault();
@@ -8706,6 +8721,7 @@ function useSpreadsheetGrid(options) {
8706
8721
  const onCut = (0, import_react15.useCallback)(
8707
8722
  (event) => {
8708
8723
  if (!optionsRef.current || !range || targetsAnEditor(event.target)) return;
8724
+ if (camePastAPortalIntoTheContainer(event.target)) return;
8709
8725
  const text = selectionAsTsv();
8710
8726
  if (!text) return;
8711
8727
  event.preventDefault();
@@ -8718,6 +8734,7 @@ function useSpreadsheetGrid(options) {
8718
8734
  (event) => {
8719
8735
  const current = optionsRef.current;
8720
8736
  if (!current || current.paste === false || !range || targetsAnEditor(event.target)) return;
8737
+ if (camePastAPortalIntoTheContainer(event.target)) return;
8721
8738
  const text = event.clipboardData?.getData("text/plain") ?? "";
8722
8739
  if (!text) return;
8723
8740
  event.preventDefault();
@@ -8801,6 +8818,7 @@ function useSpreadsheetGrid(options) {
8801
8818
  ...inFillPreview ? { "data-matrx-cell-fill-preview": "true" } : {},
8802
8819
  onMouseDown: (event) => {
8803
8820
  if (event.button !== 0) return;
8821
+ if (camePastAPortal(event.target ?? null, event.currentTarget)) return;
8804
8822
  event.preventDefault();
8805
8823
  const origin = event.currentTarget;
8806
8824
  if (typeof HTMLElement !== "undefined" && origin instanceof HTMLElement) {
@@ -12126,6 +12144,7 @@ function MatrxDataTableCore({
12126
12144
  toolbar,
12127
12145
  hideToolbar = false,
12128
12146
  hidePagination = false,
12147
+ paginationLabelFormat,
12129
12148
  filterUi,
12130
12149
  detail,
12131
12150
  expandedDetail,
@@ -13162,7 +13181,7 @@ function MatrxDataTableCore({
13162
13181
  const coverageResult = (0, import_react21.useMemo)(() => {
13163
13182
  if (!coverage) return null;
13164
13183
  return describeCoverage({
13165
- loaded: data.length,
13184
+ loaded: coverage.loaded ?? data.length,
13166
13185
  ...coverage.matched === void 0 ? {} : { matched: coverage.matched },
13167
13186
  ...coverage.total === void 0 ? {} : { total: coverage.total },
13168
13187
  ...coverage.cap === void 0 ? {} : { cap: coverage.cap },
@@ -14165,11 +14184,12 @@ function MatrxDataTableCore({
14165
14184
  notice,
14166
14185
  savedViewError ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { role: "alert", className: "shrink-0 text-xs text-destructive", children: savedViewError }) : null,
14167
14186
  toolbarActionError ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { role: "alert", className: "shrink-0 text-xs text-destructive", children: toolbarActionError }) : null,
14168
- !hideToolbar && (viewTabs || toolbar?.title || showSearch || 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__ */ (0, import_jsx_runtime42.jsxs)(
14187
+ !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__ */ (0, import_jsx_runtime42.jsxs)(
14169
14188
  TableTitleRow,
14170
14189
  {
14171
14190
  tabs: viewTabs ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(TableViewWorkspace, { snapshot: currentViewSnapshot, onApply: applySavedView, related: relatedTableActions }, tableId ?? "table") : void 0,
14172
14191
  ...toolbar?.title === void 0 ? {} : { title: toolbar.title },
14192
+ ...toolbar?.titleCount === void 0 ? {} : { count: toolbar.titleCount },
14173
14193
  context: tableId && SavedViews ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { "data-matrx-table-view-control": true, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
14174
14194
  SavedViews,
14175
14195
  {
@@ -14179,7 +14199,7 @@ function MatrxDataTableCore({
14179
14199
  onApply: applySavedView
14180
14200
  }
14181
14201
  ) }) : void 0,
14182
- search: showSearch ? intelligentSearchEnabled ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
14202
+ search: toolbar?.customSearch ?? (showSearch ? intelligentSearchEnabled ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
14183
14203
  TableSearch,
14184
14204
  {
14185
14205
  value: searchValue,
@@ -14250,7 +14270,7 @@ function MatrxDataTableCore({
14250
14270
  ] }) : null
14251
14271
  ]
14252
14272
  }
14253
- ) : null,
14273
+ ) : null),
14254
14274
  children: [
14255
14275
  toolbar?.layeredFilters ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
14256
14276
  LayeredFilterBuilder,
@@ -14904,6 +14924,7 @@ function MatrxDataTableCore({
14904
14924
  leadingCols,
14905
14925
  showActionsCol,
14906
14926
  rowNoun: grouping?.rowNoun ?? "row",
14927
+ ...grouping?.renderLabel ? { renderLabel: grouping.renderLabel } : {},
14907
14928
  onToggle: () => setCollapsedGroups(toggleGroupCollapsed(collapsedGroups, entry.group.key))
14908
14929
  },
14909
14930
  `matrx-group-${entry.group.key}`
@@ -15077,7 +15098,7 @@ function MatrxDataTableCore({
15077
15098
  "div",
15078
15099
  {
15079
15100
  className: cn(
15080
- colIdx === 0 && hierarchy && "flex min-w-0 items-center"
15101
+ colIdx === 0 && (hierarchy || canExpandRow(row)) && "flex min-w-0 items-center"
15081
15102
  ),
15082
15103
  children: [
15083
15104
  colIdx === 0 && hierarchy ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
@@ -15088,6 +15109,40 @@ function MatrxDataTableCore({
15088
15109
  disabled: !(hierarchy.canReparent?.(row) ?? true)
15089
15110
  }
15090
15111
  ) : null,
15112
+ colIdx === 0 && canExpandRow(row) ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(Tooltip, { children: [
15113
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
15114
+ Button,
15115
+ {
15116
+ type: "button",
15117
+ variant: "ghost",
15118
+ size: "icon",
15119
+ "data-matrx-table-expand-toggle": true,
15120
+ className: "mr-1 h-7 w-7 shrink-0 text-muted-foreground hover:text-foreground [&_svg]:size-4",
15121
+ "aria-label": isRowExpanded(row) ? "Collapse row details" : "Expand row details",
15122
+ "aria-expanded": isRowExpanded(row),
15123
+ onClick: (event) => {
15124
+ event.stopPropagation();
15125
+ toggleExpanded(row);
15126
+ },
15127
+ onKeyDown: (event) => {
15128
+ if (event.key !== "Enter" && event.key !== " ") return;
15129
+ event.preventDefault();
15130
+ event.stopPropagation();
15131
+ toggleExpanded(row);
15132
+ },
15133
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
15134
+ ChevronRight,
15135
+ {
15136
+ className: cn(
15137
+ "transition-transform",
15138
+ isRowExpanded(row) && "rotate-90"
15139
+ )
15140
+ }
15141
+ )
15142
+ }
15143
+ ) }),
15144
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(TooltipContent, { children: isRowExpanded(row) ? "Collapse details" : "Expand details" })
15145
+ ] }) : null,
15091
15146
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
15092
15147
  "div",
15093
15148
  {
@@ -15430,7 +15485,7 @@ function MatrxDataTableCore({
15430
15485
  GenericTablePagination,
15431
15486
  {
15432
15487
  totalItems,
15433
- ...sourceTotal === void 0 ? {} : { labelFormat: (start, end, total) => `${(0, import_format5.formatCount)(start)}\u2013${(0, import_format5.formatCount)(end)} of ${(0, import_format5.formatCount)(total)} matching \xB7 ${(0, import_format5.formatCount)(data.length)} / ${(0, import_format5.formatCount)(sourceTotal)} loaded` },
15488
+ ...paginationLabelFormat ? { labelFormat: paginationLabelFormat } : sourceTotal === void 0 ? {} : { labelFormat: (start, end, total) => `${(0, import_format5.formatCount)(start)}\u2013${(0, import_format5.formatCount)(end)} of ${(0, import_format5.formatCount)(total)} matching \xB7 ${(0, import_format5.formatCount)(data.length)} / ${(0, import_format5.formatCount)(sourceTotal)} loaded` },
15434
15489
  ...localProgressiveEnabled ? { progressive: {
15435
15490
  shownCount: progressiveRows.shownCount,
15436
15491
  loadedCount: data.length,
@@ -15948,6 +16003,7 @@ function TableGroupHeaderRow({
15948
16003
  leadingCols,
15949
16004
  showActionsCol,
15950
16005
  rowNoun,
16006
+ renderLabel,
15951
16007
  onToggle
15952
16008
  }) {
15953
16009
  const count = group.rows.length;
@@ -15978,7 +16034,7 @@ function TableGroupHeaderRow({
15978
16034
  children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ChevronRight, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ChevronDown, { className: "h-4 w-4" })
15979
16035
  }
15980
16036
  ),
15981
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "truncate text-sm font-semibold text-foreground", children: group.label }),
16037
+ renderLabel ? renderLabel(group) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "truncate text-sm font-semibold text-foreground", children: group.label }),
15982
16038
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "whitespace-nowrap text-xs text-muted-foreground", children: summary })
15983
16039
  ] }) }, id);
15984
16040
  }