@ai-matrx/design-system 0.28.0 → 0.31.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +71 -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 +39 -7
  9. package/dist/data-table/index.cjs.map +1 -1
  10. package/dist/data-table/index.d.cts +3 -3
  11. package/dist/data-table/index.d.ts +3 -3
  12. package/dist/data-table/index.js +39 -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 +37 -6
  21. package/dist/data-table/spreadsheet.cjs.map +1 -1
  22. package/dist/data-table/spreadsheet.d.cts +46 -1
  23. package/dist/data-table/spreadsheet.d.ts +46 -1
  24. package/dist/data-table/spreadsheet.js +37 -6
  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 +2 -2
  28. package/dist/data-table/types.d.ts +2 -2
  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/index.cjs +8 -4
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.js +8 -4
  36. package/dist/index.js.map +1 -1
  37. package/dist/{types-D9JBR6ZU.d.ts → types-CFmCZXVn.d.ts} +24 -1
  38. package/dist/{types-jQddSUnj.d.cts → types-CYkwg9jR.d.cts} +24 -1
  39. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,76 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.31.0 — 2026-09-21
4
+
5
+ **A paste refusal now carries the value it refused.**
6
+
7
+ `SpreadsheetPastePlan.refusals` named a row and a column and dropped the cell's
8
+ value, so a consumer showing a person their fifty pasted rows could say a cell
9
+ was skipped but not what was in it — and, if it re-planned the block, could not
10
+ put the cell back where it belonged. Measured on Rincon Plumbing's September
11
+ billing run: every refusal on an existing record read "Row 0, amount_due",
12
+ because the value never reached the code that knew the line number and the
13
+ column's name. A refusal nobody can locate is half a refusal.
14
+
15
+ `PasteRefusal.value` is what `validateCell` turned away. Additive; nothing that
16
+ ignores it changes.
17
+
18
+ ## 0.30.0 — 2026-09-21
19
+
20
+ **"Set as my default" had not picked an organization for anybody since
21
+ 2026-09-19, and went on saying it would.**
22
+
23
+ The owner deleted the durable-default rung from the platform's org resolver on
24
+ 2026-09-19 — *"a default organization is at most a per-client DISPLAY
25
+ preference; the org picker may show it and nothing else may read it"* — and
26
+ nobody changed this switch's words. It still read **Set as my default**, with
27
+ *"Next startup opens Acme"* and *"Auto-select this at startup"* underneath.
28
+
29
+ Crew D2 met that on 2026-09-21 and reported it as a persistence bug: the
30
+ selection gone on a fresh browser profile *"with no persistence despite a 'Set
31
+ as my default' toggle implying it should stick"*. Measured on production, the
32
+ selection persists perfectly on the machine that made it — across navigation, a
33
+ fresh tab, the record's own URL and a reload, restored from the apex cookie even
34
+ with the browser cache emptied. What was broken was the sentence.
35
+
36
+ So the switch says what it does — **Keep it at the top** — and it now DOES
37
+ something, which it never did: the starred organization is drawn **first** in
38
+ the list, every other row left in the host's order. With ninety organizations
39
+ in the picker, the one you work in every day was somewhere in the middle of it.
40
+ That is what a star is for in Slack and in Linear.
41
+
42
+ A clause holds the line: no sentence on that control may contain *startup*,
43
+ *next time*, *automatic*, *auto-select* or *by default* again.
44
+
45
+ ## 0.29.0 — 2026-09-21
46
+
47
+ **A paste of fifty spreadsheet rows stopped throwing forty-six of them away.**
48
+
49
+ Real-data crew C copied fifty US airports out of a spreadsheet and pasted them
50
+ into a table that held four rows. Four rows were written, and the other
51
+ forty-six came back as *"46 landed past the edge of the table and were
52
+ ignored"* — an honest sentence about a useless outcome. The grid is the one
53
+ thing that knows which rows they were, and it was counting them and dropping
54
+ them.
55
+
56
+ It still does not create rows: the table owns the gestures and the consumer
57
+ owns the writes, and that boundary is what keeps every table's persistence its
58
+ own. So it hands the rows over instead. `spreadsheet.onPastePlan` is the new
59
+ half of the contract:
60
+
61
+ * absent — byte-for-byte the paste that existed before, screened and applied;
62
+ * present — the table computes the plan, applies **nothing**, and hands over
63
+ `accepted` (the cells it would write, already screened by `validateCell`),
64
+ `refusals` (each with the row it belongs to, which they did not carry before,
65
+ and the sentence that says why), `overflow` (the rows past the last row,
66
+ whole, in the grid's current column order) and `pastRightEdge` (cells with no
67
+ column to hold them — those there will never be a home for). `apply()` writes
68
+ the accepted cells exactly as an unconfirmed paste would.
69
+
70
+ That is what lets a surface show a person what is about to be written before it
71
+ is written, and what lets one that knows how to make a row make the other
72
+ forty-six.
73
+
3
74
  ## 0.28.0 — 2026-09-21
4
75
 
5
76
  **Two organizations with the same name were indistinguishable in the picker.**
@@ -1,5 +1,5 @@
1
1
  import { AgentPayloadInput } from './copy-types.cjs';
2
- import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-jQddSUnj.cjs';
2
+ import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-CYkwg9jR.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-D9JBR6ZU.js';
2
+ import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-CFmCZXVn.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-jQddSUnj.cjs';
1
+ import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-CYkwg9jR.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-D9JBR6ZU.js';
1
+ import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-CFmCZXVn.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-jQddSUnj.cjs';
5
+ import { b as TableSavedViewsProps, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-CYkwg9jR.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-D9JBR6ZU.js';
5
+ import { b as TableSavedViewsProps, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-CFmCZXVn.js';
6
6
  import { MatrxTableMenuTarget, MatrxTableMenuPayload } from './menu-targets.js';
7
7
  import '../content-transfer.js';
8
8
  import '@ai-matrx/kit/content-transfer';
@@ -8482,7 +8482,7 @@ function useSpreadsheetGrid(options) {
8482
8482
  } catch {
8483
8483
  reason = void 0;
8484
8484
  }
8485
- if (reason) refusals.push({ columnId: patch.columnId, reason });
8485
+ if (reason) refusals.push({ rowId: patch.rowId, columnId: patch.columnId, reason, value: patch.value });
8486
8486
  else accepted.push(patch);
8487
8487
  }
8488
8488
  return { accepted, refusals };
@@ -8561,6 +8561,7 @@ function useSpreadsheetGrid(options) {
8561
8561
  if (rowId === void 0 || columnId2 === void 0) continue;
8562
8562
  if (!current.isColumnWritable(columnId2)) {
8563
8563
  skipped.push({
8564
+ rowId,
8564
8565
  columnId: columnId2,
8565
8566
  reason: current.columnRefusal?.(columnId2) ?? `${columnId2} cannot be cleared.`
8566
8567
  });
@@ -8724,18 +8725,33 @@ function useSpreadsheetGrid(options) {
8724
8725
  if (startRow === -1 || startCol === -1) return;
8725
8726
  const patches = [];
8726
8727
  const skipped = [];
8727
- let outside = 0;
8728
+ let pastRightEdge = 0;
8729
+ const overflow = [];
8728
8730
  for (let r = 0; r < block.length; r += 1) {
8729
8731
  const line = block[r] ?? [];
8732
+ const rowId = rowIds[startRow + r];
8733
+ if (rowId === void 0) {
8734
+ const beyond = {};
8735
+ for (let c = 0; c < line.length; c += 1) {
8736
+ const columnId2 = columnIds[startCol + c];
8737
+ if (columnId2 === void 0) {
8738
+ pastRightEdge += 1;
8739
+ continue;
8740
+ }
8741
+ beyond[columnId2] = line[c] ?? "";
8742
+ }
8743
+ overflow.push(beyond);
8744
+ continue;
8745
+ }
8730
8746
  for (let c = 0; c < line.length; c += 1) {
8731
- const rowId = rowIds[startRow + r];
8732
8747
  const columnId2 = columnIds[startCol + c];
8733
- if (rowId === void 0 || columnId2 === void 0) {
8734
- outside += 1;
8748
+ if (columnId2 === void 0) {
8749
+ pastRightEdge += 1;
8735
8750
  continue;
8736
8751
  }
8737
8752
  if (!current.isColumnWritable(columnId2)) {
8738
8753
  skipped.push({
8754
+ rowId,
8739
8755
  columnId: columnId2,
8740
8756
  reason: current.columnRefusal?.(columnId2) ?? `${columnId2} cannot take a pasted value.`
8741
8757
  });
@@ -8745,9 +8761,24 @@ function useSpreadsheetGrid(options) {
8745
8761
  }
8746
8762
  }
8747
8763
  const screened = screenPatches(patches);
8764
+ const refusals = [...skipped, ...screened.refusals];
8765
+ if (current.onPastePlan) {
8766
+ const accepted = screened.accepted;
8767
+ current.onPastePlan({
8768
+ accepted,
8769
+ refusals,
8770
+ overflow,
8771
+ pastRightEdge,
8772
+ apply: async () => {
8773
+ await applyPatches(accepted, "paste", "Pasted");
8774
+ }
8775
+ });
8776
+ return;
8777
+ }
8748
8778
  void applyPatches(screened.accepted, "paste", "Pasted");
8779
+ const outside = pastRightEdge + overflow.reduce((n2, row) => n2 + Object.keys(row).length, 0);
8749
8780
  const tail = outside > 0 ? ` ${outside} landed past the edge of the table and were ignored.` : "";
8750
- announceSkips([...skipped, ...screened.refusals], `Pasted ${screened.accepted.length} cells.${tail}`);
8781
+ announceSkips(refusals, `Pasted ${screened.accepted.length} cells.${tail}`);
8751
8782
  },
8752
8783
  [range, rowIds, columnIds, applyPatches, announceSkips, screenPatches]
8753
8784
  );
@@ -13172,7 +13203,8 @@ function MatrxDataTableCore({
13172
13203
  ...spreadsheet.paste === void 0 ? {} : { paste: spreadsheet.paste },
13173
13204
  notify: spreadsheet.notify ?? ((message) => toast.success(message)),
13174
13205
  onEditRequest: (address, seed) => requestCellEditRef.current(address, seed),
13175
- ...spreadsheet.validateCell ? { validateCell: spreadsheet.validateCell } : {}
13206
+ ...spreadsheet.validateCell ? { validateCell: spreadsheet.validateCell } : {},
13207
+ ...spreadsheet.onPastePlan ? { onPastePlan: spreadsheet.onPastePlan } : {}
13176
13208
  } : null
13177
13209
  );
13178
13210
  const sheetRef = (0, import_react21.useRef)(sheet);