@ai-matrx/design-system 0.22.0 → 0.26.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 (115) hide show
  1. package/CHANGELOG.md +227 -0
  2. package/dist/data-table/cell-undo.cjs +98 -0
  3. package/dist/data-table/cell-undo.cjs.map +1 -0
  4. package/dist/data-table/cell-undo.d.cts +85 -0
  5. package/dist/data-table/cell-undo.d.ts +85 -0
  6. package/dist/data-table/cell-undo.js +78 -0
  7. package/dist/data-table/cell-undo.js.map +1 -0
  8. package/dist/data-table/copy-helpers.d.cts +7 -2
  9. package/dist/data-table/copy-helpers.d.ts +7 -2
  10. package/dist/data-table/coverage.cjs +116 -0
  11. package/dist/data-table/coverage.cjs.map +1 -0
  12. package/dist/data-table/coverage.d.cts +65 -0
  13. package/dist/data-table/coverage.d.ts +65 -0
  14. package/dist/data-table/coverage.js +96 -0
  15. package/dist/data-table/coverage.js.map +1 -0
  16. package/dist/data-table/data-row-inspector.cjs.map +1 -1
  17. package/dist/data-table/data-row-inspector.js.map +1 -1
  18. package/dist/data-table/data-row-window.cjs.map +1 -1
  19. package/dist/data-table/data-row-window.js.map +1 -1
  20. package/dist/data-table/facets.cjs +118 -0
  21. package/dist/data-table/facets.cjs.map +1 -0
  22. package/dist/data-table/facets.d.cts +100 -0
  23. package/dist/data-table/facets.d.ts +100 -0
  24. package/dist/data-table/facets.js +98 -0
  25. package/dist/data-table/facets.js.map +1 -0
  26. package/dist/data-table/fill.cjs +299 -0
  27. package/dist/data-table/fill.cjs.map +1 -0
  28. package/dist/data-table/fill.d.cts +129 -0
  29. package/dist/data-table/fill.d.ts +129 -0
  30. package/dist/data-table/fill.js +277 -0
  31. package/dist/data-table/fill.js.map +1 -0
  32. package/dist/data-table/filter-engine.d.cts +7 -2
  33. package/dist/data-table/filter-engine.d.ts +7 -2
  34. package/dist/data-table/grid-clipboard.cjs +165 -0
  35. package/dist/data-table/grid-clipboard.cjs.map +1 -0
  36. package/dist/data-table/grid-clipboard.d.cts +85 -0
  37. package/dist/data-table/grid-clipboard.d.ts +85 -0
  38. package/dist/data-table/grid-clipboard.js +145 -0
  39. package/dist/data-table/grid-clipboard.js.map +1 -0
  40. package/dist/data-table/grid-selection.cjs +258 -0
  41. package/dist/data-table/grid-selection.cjs.map +1 -0
  42. package/dist/data-table/grid-selection.d.cts +166 -0
  43. package/dist/data-table/grid-selection.d.ts +166 -0
  44. package/dist/data-table/grid-selection.js +238 -0
  45. package/dist/data-table/grid-selection.js.map +1 -0
  46. package/dist/data-table/grouping.cjs +302 -0
  47. package/dist/data-table/grouping.cjs.map +1 -0
  48. package/dist/data-table/grouping.d.cts +119 -0
  49. package/dist/data-table/grouping.d.ts +119 -0
  50. package/dist/data-table/grouping.js +282 -0
  51. package/dist/data-table/grouping.js.map +1 -0
  52. package/dist/data-table/host.cjs.map +1 -1
  53. package/dist/data-table/host.d.cts +18 -4
  54. package/dist/data-table/host.d.ts +18 -4
  55. package/dist/data-table/host.js.map +1 -1
  56. package/dist/data-table/index.cjs +3173 -451
  57. package/dist/data-table/index.cjs.map +1 -1
  58. package/dist/data-table/index.d.cts +13 -3
  59. package/dist/data-table/index.d.ts +13 -3
  60. package/dist/data-table/index.js +3174 -451
  61. package/dist/data-table/index.js.map +1 -1
  62. package/dist/data-table/infer-filter.d.cts +7 -2
  63. package/dist/data-table/infer-filter.d.ts +7 -2
  64. package/dist/data-table/layered-filters.d.cts +7 -2
  65. package/dist/data-table/layered-filters.d.ts +7 -2
  66. package/dist/data-table/menu-targets.cjs +77 -0
  67. package/dist/data-table/menu-targets.cjs.map +1 -0
  68. package/dist/data-table/menu-targets.d.cts +108 -0
  69. package/dist/data-table/menu-targets.d.ts +108 -0
  70. package/dist/data-table/menu-targets.js +57 -0
  71. package/dist/data-table/menu-targets.js.map +1 -0
  72. package/dist/data-table/pagination.cjs.map +1 -1
  73. package/dist/data-table/pagination.js.map +1 -1
  74. package/dist/data-table/query-control.d.cts +7 -2
  75. package/dist/data-table/query-control.d.ts +7 -2
  76. package/dist/data-table/spreadsheet.cjs +1062 -0
  77. package/dist/data-table/spreadsheet.cjs.map +1 -0
  78. package/dist/data-table/spreadsheet.d.cts +153 -0
  79. package/dist/data-table/spreadsheet.d.ts +153 -0
  80. package/dist/data-table/spreadsheet.js +1042 -0
  81. package/dist/data-table/spreadsheet.js.map +1 -0
  82. package/dist/data-table/types.cjs.map +1 -1
  83. package/dist/data-table/types.d.cts +7 -2
  84. package/dist/data-table/types.d.ts +7 -2
  85. package/dist/data-table/url-state.d.cts +7 -2
  86. package/dist/data-table/url-state.d.ts +7 -2
  87. package/dist/data-table/uuid-cell.cjs.map +1 -1
  88. package/dist/data-table/uuid-cell.js.map +1 -1
  89. package/dist/data-table/validation.cjs +229 -0
  90. package/dist/data-table/validation.cjs.map +1 -0
  91. package/dist/data-table/validation.d.cts +125 -0
  92. package/dist/data-table/validation.d.ts +125 -0
  93. package/dist/data-table/validation.js +209 -0
  94. package/dist/data-table/validation.js.map +1 -0
  95. package/dist/data-table/virtual-window.cjs +203 -0
  96. package/dist/data-table/virtual-window.cjs.map +1 -0
  97. package/dist/data-table/virtual-window.d.cts +84 -0
  98. package/dist/data-table/virtual-window.d.ts +84 -0
  99. package/dist/data-table/virtual-window.js +183 -0
  100. package/dist/data-table/virtual-window.js.map +1 -0
  101. package/dist/data-table/xlsx.d.cts +7 -2
  102. package/dist/data-table/xlsx.d.ts +7 -2
  103. package/dist/field-formats/index.d.cts +2 -2
  104. package/dist/field-formats/index.d.ts +2 -2
  105. package/dist/formulas/index.cjs +1041 -0
  106. package/dist/formulas/index.cjs.map +1 -0
  107. package/dist/formulas/index.d.cts +389 -0
  108. package/dist/formulas/index.d.ts +389 -0
  109. package/dist/formulas/index.js +1019 -0
  110. package/dist/formulas/index.js.map +1 -0
  111. package/dist/{types-BdbvlF9-.d.cts → types-CJWU1Gae.d.cts} +1 -1
  112. package/dist/{types-BdbvlF9-.d.ts → types-CJWU1Gae.d.ts} +1 -1
  113. package/dist/{types-D-flTpK0.d.ts → types-Cu5_eUG1.d.ts} +268 -4
  114. package/dist/{types-Sn249eoy.d.cts → types-DrJXAAoD.d.cts} +268 -4
  115. package/package.json +129 -2
@@ -1,10 +1,15 @@
1
- import { M as MatrxColumnDef, f as ColumnFilterKind } from '../types-Sn249eoy.cjs';
1
+ import { M as MatrxColumnDef, f as ColumnFilterKind } from '../types-DrJXAAoD.cjs';
2
2
  import '../content-transfer.cjs';
3
3
  import 'react';
4
4
  import '@ai-matrx/kit/content-transfer';
5
5
  import '../content-transfer/icon.cjs';
6
6
  import './copy-types.cjs';
7
- import '../types-BdbvlF9-.cjs';
7
+ import '../types-CJWU1Gae.cjs';
8
+ import './grouping.cjs';
9
+ import './fill.cjs';
10
+ import './facets.cjs';
11
+ import './spreadsheet.cjs';
12
+ import './grid-selection.cjs';
8
13
 
9
14
  type ResolvedFilterKind = "text" | "select" | "boolean" | "number";
10
15
  /**
@@ -1,10 +1,15 @@
1
- import { M as MatrxColumnDef, f as ColumnFilterKind } from '../types-D-flTpK0.js';
1
+ import { M as MatrxColumnDef, f as ColumnFilterKind } from '../types-Cu5_eUG1.js';
2
2
  import '../content-transfer.js';
3
3
  import 'react';
4
4
  import '@ai-matrx/kit/content-transfer';
5
5
  import '../content-transfer/icon.js';
6
6
  import './copy-types.js';
7
- import '../types-BdbvlF9-.js';
7
+ import '../types-CJWU1Gae.js';
8
+ import './grouping.js';
9
+ import './fill.js';
10
+ import './facets.js';
11
+ import './spreadsheet.js';
12
+ import './grid-selection.js';
8
13
 
9
14
  type ResolvedFilterKind = "text" | "select" | "boolean" | "number";
10
15
  /**
@@ -1,7 +1,12 @@
1
- export { al as LAYERED_FILTER_OPERATORS, am as LAYERED_FILTER_OPERATOR_LABELS, an as LayeredFilterField, ao as LayeredFilterOperator, L as LayeredFilterRule, ap as columnFiltersToLayeredRules, aq as completeLayeredFilterRules, ar as decodeLayeredFilterRules, as as encodeLayeredFilterRules, at as isCompleteLayeredFilterRule, au as isLayeredFilterOperator, av as layeredFilterMatchesValue, aw as layeredFilterNeedsValue, ax as layeredFilterRuleSummary, ay as operatorsForLayeredField } from '../types-Sn249eoy.cjs';
1
+ export { aq as LAYERED_FILTER_OPERATORS, ar as LAYERED_FILTER_OPERATOR_LABELS, as as LayeredFilterField, at as LayeredFilterOperator, L as LayeredFilterRule, au as columnFiltersToLayeredRules, av as completeLayeredFilterRules, aw as decodeLayeredFilterRules, ax as encodeLayeredFilterRules, ay as isCompleteLayeredFilterRule, az as isLayeredFilterOperator, aA as layeredFilterMatchesValue, aB as layeredFilterNeedsValue, aC as layeredFilterRuleSummary, aD as operatorsForLayeredField } from '../types-DrJXAAoD.cjs';
2
2
  import '../content-transfer.cjs';
3
3
  import 'react';
4
4
  import '@ai-matrx/kit/content-transfer';
5
5
  import '../content-transfer/icon.cjs';
6
6
  import './copy-types.cjs';
7
- import '../types-BdbvlF9-.cjs';
7
+ import '../types-CJWU1Gae.cjs';
8
+ import './grouping.cjs';
9
+ import './fill.cjs';
10
+ import './facets.cjs';
11
+ import './spreadsheet.cjs';
12
+ import './grid-selection.cjs';
@@ -1,7 +1,12 @@
1
- export { al as LAYERED_FILTER_OPERATORS, am as LAYERED_FILTER_OPERATOR_LABELS, an as LayeredFilterField, ao as LayeredFilterOperator, L as LayeredFilterRule, ap as columnFiltersToLayeredRules, aq as completeLayeredFilterRules, ar as decodeLayeredFilterRules, as as encodeLayeredFilterRules, at as isCompleteLayeredFilterRule, au as isLayeredFilterOperator, av as layeredFilterMatchesValue, aw as layeredFilterNeedsValue, ax as layeredFilterRuleSummary, ay as operatorsForLayeredField } from '../types-D-flTpK0.js';
1
+ export { aq as LAYERED_FILTER_OPERATORS, ar as LAYERED_FILTER_OPERATOR_LABELS, as as LayeredFilterField, at as LayeredFilterOperator, L as LayeredFilterRule, au as columnFiltersToLayeredRules, av as completeLayeredFilterRules, aw as decodeLayeredFilterRules, ax as encodeLayeredFilterRules, ay as isCompleteLayeredFilterRule, az as isLayeredFilterOperator, aA as layeredFilterMatchesValue, aB as layeredFilterNeedsValue, aC as layeredFilterRuleSummary, aD as operatorsForLayeredField } from '../types-Cu5_eUG1.js';
2
2
  import '../content-transfer.js';
3
3
  import 'react';
4
4
  import '@ai-matrx/kit/content-transfer';
5
5
  import '../content-transfer/icon.js';
6
6
  import './copy-types.js';
7
- import '../types-BdbvlF9-.js';
7
+ import '../types-CJWU1Gae.js';
8
+ import './grouping.js';
9
+ import './fill.js';
10
+ import './facets.js';
11
+ import './spreadsheet.js';
12
+ import './grid-selection.js';
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/data-table/menu-targets.ts
21
+ var menu_targets_exports = {};
22
+ __export(menu_targets_exports, {
23
+ MATRX_CELL_COLUMN_ATTR: () => MATRX_CELL_COLUMN_ATTR,
24
+ MATRX_CELL_ROW_ATTR: () => MATRX_CELL_ROW_ATTR,
25
+ MATRX_CELL_SELECTED_ATTR: () => MATRX_CELL_SELECTED_ATTR,
26
+ MATRX_HEADER_COLUMN_ATTR: () => MATRX_HEADER_COLUMN_ATTR,
27
+ MATRX_ROW_ID_ATTR: () => MATRX_ROW_ID_ATTR,
28
+ MATRX_TABLE_ID_ATTR: () => MATRX_TABLE_ID_ATTR,
29
+ describeMenuLevel: () => describeMenuLevel,
30
+ readMenuTarget: () => readMenuTarget
31
+ });
32
+ module.exports = __toCommonJS(menu_targets_exports);
33
+ var MATRX_TABLE_ID_ATTR = "data-matrx-table-id";
34
+ var MATRX_ROW_ID_ATTR = "data-row-id";
35
+ var MATRX_CELL_ROW_ATTR = "data-matrx-cell-row";
36
+ var MATRX_CELL_COLUMN_ATTR = "data-matrx-table-column-id";
37
+ var MATRX_HEADER_COLUMN_ATTR = "data-matrx-header-column-id";
38
+ var MATRX_CELL_SELECTED_ATTR = "data-matrx-cell-selected";
39
+ function attr(element, name) {
40
+ if (!element) return void 0;
41
+ const found = element.closest(`[${name}]`);
42
+ const value = found?.getAttribute(name);
43
+ return value === null || value === void 0 || value === "" ? void 0 : value;
44
+ }
45
+ function readMenuTarget(target) {
46
+ const tableId = attr(target, MATRX_TABLE_ID_ATTR);
47
+ if (!tableId) return null;
48
+ const headerColumnId = attr(target, MATRX_HEADER_COLUMN_ATTR);
49
+ if (headerColumnId) return { tableId, level: "column", columnId: headerColumnId };
50
+ const cellColumnId = attr(target, MATRX_CELL_COLUMN_ATTR);
51
+ const cellRowId = attr(target, MATRX_ROW_ID_ATTR) ?? attr(target, MATRX_CELL_ROW_ATTR);
52
+ const rowId = cellRowId;
53
+ if (cellRowId && cellColumnId) {
54
+ const selected = attr(target, MATRX_CELL_SELECTED_ATTR) === "true";
55
+ if (selected) return { tableId, level: "selection", rowId: cellRowId, columnId: cellColumnId };
56
+ return { tableId, level: "cell", rowId: cellRowId, columnId: cellColumnId };
57
+ }
58
+ if (rowId) return { tableId, level: "row", rowId };
59
+ return { tableId, level: "table" };
60
+ }
61
+ function describeMenuLevel(payload) {
62
+ switch (payload.level) {
63
+ case "cell":
64
+ return payload.columnLabel;
65
+ case "row":
66
+ return "Row";
67
+ case "column":
68
+ return payload.columnLabel;
69
+ case "selection": {
70
+ const cells = payload.cellCount;
71
+ return `${cells} ${cells === 1 ? "cell" : "cells"}`;
72
+ }
73
+ case "table":
74
+ return "Table";
75
+ }
76
+ }
77
+ //# sourceMappingURL=menu-targets.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/data-table/menu-targets.ts"],"sourcesContent":["/**\n * @ai-matrx/design-system/data-table — WHAT WAS RIGHT-CLICKED.\n *\n * A spreadsheet's right-click menu is not one menu: it is four, and which one\n * you get is decided by where the pointer was. A cell, the row it sits in, the\n * column it sits under, and — when the click lands inside an extended range —\n * the selection. The canonical table used to expose exactly ONE of those four\n * (the row), so every surface that wanted the other three forked the table.\n *\n * This module is the pure half of the fix: it reads the four levels off the\n * DOM anchors the table already renders, and nothing more. It does not build a\n * menu, name an action, or know what a menu is — the platform's universal\n * right-click menu is an application concern and stays there. The table's job\n * is to answer, truthfully, WHICH thing the person aimed at.\n *\n * THE PRECEDENCE, and why it is this way:\n *\n * selection > cell > column > row > table\n *\n * A click inside an extended range means the range, because that is what the\n * person is looking at and what every spreadsheet acts on — taking the single\n * cell under the cursor there would silently throw away their selection. A\n * header click is the column even though the header is inside the table. A\n * click on a row but outside any cell (the checkbox gutter, the actions cell)\n * is the row. Anything else in the table is the table.\n *\n * Pure: no React, no package state. It reads `data-*` attributes and returns a\n * plain object. Nothing here throws on any input.\n */\n\n/** Which of the four things the pointer was aimed at. */\nexport type MatrxTableMenuLevel = \"cell\" | \"row\" | \"column\" | \"selection\" | \"table\";\n\nexport interface MatrxTableMenuTarget {\n /** The table instance the click landed in. */\n tableId: string;\n level: MatrxTableMenuLevel;\n /** Present for \"cell\" and \"row\". */\n rowId?: string;\n /** Present for \"cell\" and \"column\". */\n columnId?: string;\n}\n\n/**\n * Attribute names, in one place, so the renderer and the reader cannot drift.\n * `data-row-id` predates this module and keeps its name: it is already read by\n * the row-drag preview and by every host that wired the row menu.\n */\nexport const MATRX_TABLE_ID_ATTR = \"data-matrx-table-id\";\nexport const MATRX_ROW_ID_ATTR = \"data-row-id\";\nexport const MATRX_CELL_ROW_ATTR = \"data-matrx-cell-row\";\nexport const MATRX_CELL_COLUMN_ATTR = \"data-matrx-table-column-id\";\nexport const MATRX_HEADER_COLUMN_ATTR = \"data-matrx-header-column-id\";\n/** Marks a cell that is inside the current extended range. */\nexport const MATRX_CELL_SELECTED_ATTR = \"data-matrx-cell-selected\";\n\ninterface MinimalElement {\n closest(selector: string): MinimalElement | null;\n getAttribute(name: string): string | null;\n}\n\nfunction attr(element: MinimalElement | null, name: string): string | undefined {\n if (!element) return undefined;\n const found = element.closest(`[${name}]`);\n const value = found?.getAttribute(name);\n return value === null || value === undefined || value === \"\" ? undefined : value;\n}\n\n/**\n * Read the four levels off the clicked element.\n *\n * Returns null when the click did not land in a canonical table at all — which\n * is the signal a host needs to leave its own page-level menu alone.\n */\nexport function readMenuTarget(\n target: MinimalElement | null,\n): MatrxTableMenuTarget | null {\n const tableId = attr(target, MATRX_TABLE_ID_ATTR);\n if (!tableId) return null;\n\n const headerColumnId = attr(target, MATRX_HEADER_COLUMN_ATTR);\n if (headerColumnId) return { tableId, level: \"column\", columnId: headerColumnId };\n\n // A cell's row comes from the `<tr>` it is in, which every table renders —\n // the spreadsheet cursor's own row attribute is a second opinion, used only\n // when the table is windowed sideways and the row wrapper is not an ancestor.\n const cellColumnId = attr(target, MATRX_CELL_COLUMN_ATTR);\n const cellRowId = attr(target, MATRX_ROW_ID_ATTR) ?? attr(target, MATRX_CELL_ROW_ATTR);\n const rowId = cellRowId;\n\n if (cellRowId && cellColumnId) {\n // Inside an extended range the SELECTION is what the person sees and what\n // the menu must act on. A range of one cell is not a range — acting on it\n // as a selection would give a lone cell the plural verbs.\n const selected = attr(target, MATRX_CELL_SELECTED_ATTR) === \"true\";\n if (selected) return { tableId, level: \"selection\", rowId: cellRowId, columnId: cellColumnId };\n return { tableId, level: \"cell\", rowId: cellRowId, columnId: cellColumnId };\n }\n\n if (rowId) return { tableId, level: \"row\", rowId };\n return { tableId, level: \"table\" };\n}\n\n/**\n * The payload the table hands its host for the level that was clicked.\n *\n * The host builds the menu from this and never reaches back into the table.\n * Every level carries the table's own count of what it is acting on, because a\n * menu that says \"Clear 12 cells\" and clears 40 is worse than one that says\n * nothing.\n */\nexport type MatrxTableMenuPayload<T = unknown> =\n | {\n level: \"cell\";\n row: T;\n rowId: string;\n columnId: string;\n columnLabel: string;\n value: unknown;\n /** The cell's value as the table displays it, for Copy. */\n text: string;\n controls: unknown;\n }\n | { level: \"row\"; row: T; rowId: string; controls: unknown }\n | {\n level: \"column\";\n columnId: string;\n columnLabel: string;\n /** Every rendered row's value for this column, in visual order. */\n values: unknown[];\n }\n | {\n level: \"selection\";\n rowIds: string[];\n columnIds: string[];\n /** The selected rectangle as an Excel/Sheets-compatible TSV block. */\n tsv: string;\n cellCount: number;\n }\n | { level: \"table\"; rowCount: number; columnIds: string[] };\n\n/** Plain-English name for a level, for a host that labels its sections. */\nexport function describeMenuLevel(payload: MatrxTableMenuPayload): string {\n switch (payload.level) {\n case \"cell\":\n return payload.columnLabel;\n case \"row\":\n return \"Row\";\n case \"column\":\n return payload.columnLabel;\n case \"selection\": {\n const cells = payload.cellCount;\n return `${cells} ${cells === 1 ? \"cell\" : \"cells\"}`;\n }\n case \"table\":\n return \"Table\";\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgDO,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAC5B,IAAM,yBAAyB;AAC/B,IAAM,2BAA2B;AAEjC,IAAM,2BAA2B;AAOxC,SAAS,KAAK,SAAgC,MAAkC;AAC9E,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,QAAQ,QAAQ,QAAQ,IAAI,IAAI,GAAG;AACzC,QAAM,QAAQ,OAAO,aAAa,IAAI;AACtC,SAAO,UAAU,QAAQ,UAAU,UAAa,UAAU,KAAK,SAAY;AAC7E;AAQO,SAAS,eACd,QAC6B;AAC7B,QAAM,UAAU,KAAK,QAAQ,mBAAmB;AAChD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,iBAAiB,KAAK,QAAQ,wBAAwB;AAC5D,MAAI,eAAgB,QAAO,EAAE,SAAS,OAAO,UAAU,UAAU,eAAe;AAKhF,QAAM,eAAe,KAAK,QAAQ,sBAAsB;AACxD,QAAM,YAAY,KAAK,QAAQ,iBAAiB,KAAK,KAAK,QAAQ,mBAAmB;AACrF,QAAM,QAAQ;AAEd,MAAI,aAAa,cAAc;AAI7B,UAAM,WAAW,KAAK,QAAQ,wBAAwB,MAAM;AAC5D,QAAI,SAAU,QAAO,EAAE,SAAS,OAAO,aAAa,OAAO,WAAW,UAAU,aAAa;AAC7F,WAAO,EAAE,SAAS,OAAO,QAAQ,OAAO,WAAW,UAAU,aAAa;AAAA,EAC5E;AAEA,MAAI,MAAO,QAAO,EAAE,SAAS,OAAO,OAAO,MAAM;AACjD,SAAO,EAAE,SAAS,OAAO,QAAQ;AACnC;AAyCO,SAAS,kBAAkB,SAAwC;AACxE,UAAQ,QAAQ,OAAO;AAAA,IACrB,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK,aAAa;AAChB,YAAM,QAAQ,QAAQ;AACtB,aAAO,GAAG,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;AAAA,IACnD;AAAA,IACA,KAAK;AACH,aAAO;AAAA,EACX;AACF;","names":[]}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @ai-matrx/design-system/data-table — WHAT WAS RIGHT-CLICKED.
3
+ *
4
+ * A spreadsheet's right-click menu is not one menu: it is four, and which one
5
+ * you get is decided by where the pointer was. A cell, the row it sits in, the
6
+ * column it sits under, and — when the click lands inside an extended range —
7
+ * the selection. The canonical table used to expose exactly ONE of those four
8
+ * (the row), so every surface that wanted the other three forked the table.
9
+ *
10
+ * This module is the pure half of the fix: it reads the four levels off the
11
+ * DOM anchors the table already renders, and nothing more. It does not build a
12
+ * menu, name an action, or know what a menu is — the platform's universal
13
+ * right-click menu is an application concern and stays there. The table's job
14
+ * is to answer, truthfully, WHICH thing the person aimed at.
15
+ *
16
+ * THE PRECEDENCE, and why it is this way:
17
+ *
18
+ * selection > cell > column > row > table
19
+ *
20
+ * A click inside an extended range means the range, because that is what the
21
+ * person is looking at and what every spreadsheet acts on — taking the single
22
+ * cell under the cursor there would silently throw away their selection. A
23
+ * header click is the column even though the header is inside the table. A
24
+ * click on a row but outside any cell (the checkbox gutter, the actions cell)
25
+ * is the row. Anything else in the table is the table.
26
+ *
27
+ * Pure: no React, no package state. It reads `data-*` attributes and returns a
28
+ * plain object. Nothing here throws on any input.
29
+ */
30
+ /** Which of the four things the pointer was aimed at. */
31
+ type MatrxTableMenuLevel = "cell" | "row" | "column" | "selection" | "table";
32
+ interface MatrxTableMenuTarget {
33
+ /** The table instance the click landed in. */
34
+ tableId: string;
35
+ level: MatrxTableMenuLevel;
36
+ /** Present for "cell" and "row". */
37
+ rowId?: string;
38
+ /** Present for "cell" and "column". */
39
+ columnId?: string;
40
+ }
41
+ /**
42
+ * Attribute names, in one place, so the renderer and the reader cannot drift.
43
+ * `data-row-id` predates this module and keeps its name: it is already read by
44
+ * the row-drag preview and by every host that wired the row menu.
45
+ */
46
+ declare const MATRX_TABLE_ID_ATTR = "data-matrx-table-id";
47
+ declare const MATRX_ROW_ID_ATTR = "data-row-id";
48
+ declare const MATRX_CELL_ROW_ATTR = "data-matrx-cell-row";
49
+ declare const MATRX_CELL_COLUMN_ATTR = "data-matrx-table-column-id";
50
+ declare const MATRX_HEADER_COLUMN_ATTR = "data-matrx-header-column-id";
51
+ /** Marks a cell that is inside the current extended range. */
52
+ declare const MATRX_CELL_SELECTED_ATTR = "data-matrx-cell-selected";
53
+ interface MinimalElement {
54
+ closest(selector: string): MinimalElement | null;
55
+ getAttribute(name: string): string | null;
56
+ }
57
+ /**
58
+ * Read the four levels off the clicked element.
59
+ *
60
+ * Returns null when the click did not land in a canonical table at all — which
61
+ * is the signal a host needs to leave its own page-level menu alone.
62
+ */
63
+ declare function readMenuTarget(target: MinimalElement | null): MatrxTableMenuTarget | null;
64
+ /**
65
+ * The payload the table hands its host for the level that was clicked.
66
+ *
67
+ * The host builds the menu from this and never reaches back into the table.
68
+ * Every level carries the table's own count of what it is acting on, because a
69
+ * menu that says "Clear 12 cells" and clears 40 is worse than one that says
70
+ * nothing.
71
+ */
72
+ type MatrxTableMenuPayload<T = unknown> = {
73
+ level: "cell";
74
+ row: T;
75
+ rowId: string;
76
+ columnId: string;
77
+ columnLabel: string;
78
+ value: unknown;
79
+ /** The cell's value as the table displays it, for Copy. */
80
+ text: string;
81
+ controls: unknown;
82
+ } | {
83
+ level: "row";
84
+ row: T;
85
+ rowId: string;
86
+ controls: unknown;
87
+ } | {
88
+ level: "column";
89
+ columnId: string;
90
+ columnLabel: string;
91
+ /** Every rendered row's value for this column, in visual order. */
92
+ values: unknown[];
93
+ } | {
94
+ level: "selection";
95
+ rowIds: string[];
96
+ columnIds: string[];
97
+ /** The selected rectangle as an Excel/Sheets-compatible TSV block. */
98
+ tsv: string;
99
+ cellCount: number;
100
+ } | {
101
+ level: "table";
102
+ rowCount: number;
103
+ columnIds: string[];
104
+ };
105
+ /** Plain-English name for a level, for a host that labels its sections. */
106
+ declare function describeMenuLevel(payload: MatrxTableMenuPayload): string;
107
+
108
+ export { MATRX_CELL_COLUMN_ATTR, MATRX_CELL_ROW_ATTR, MATRX_CELL_SELECTED_ATTR, MATRX_HEADER_COLUMN_ATTR, MATRX_ROW_ID_ATTR, MATRX_TABLE_ID_ATTR, type MatrxTableMenuLevel, type MatrxTableMenuPayload, type MatrxTableMenuTarget, describeMenuLevel, readMenuTarget };
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @ai-matrx/design-system/data-table — WHAT WAS RIGHT-CLICKED.
3
+ *
4
+ * A spreadsheet's right-click menu is not one menu: it is four, and which one
5
+ * you get is decided by where the pointer was. A cell, the row it sits in, the
6
+ * column it sits under, and — when the click lands inside an extended range —
7
+ * the selection. The canonical table used to expose exactly ONE of those four
8
+ * (the row), so every surface that wanted the other three forked the table.
9
+ *
10
+ * This module is the pure half of the fix: it reads the four levels off the
11
+ * DOM anchors the table already renders, and nothing more. It does not build a
12
+ * menu, name an action, or know what a menu is — the platform's universal
13
+ * right-click menu is an application concern and stays there. The table's job
14
+ * is to answer, truthfully, WHICH thing the person aimed at.
15
+ *
16
+ * THE PRECEDENCE, and why it is this way:
17
+ *
18
+ * selection > cell > column > row > table
19
+ *
20
+ * A click inside an extended range means the range, because that is what the
21
+ * person is looking at and what every spreadsheet acts on — taking the single
22
+ * cell under the cursor there would silently throw away their selection. A
23
+ * header click is the column even though the header is inside the table. A
24
+ * click on a row but outside any cell (the checkbox gutter, the actions cell)
25
+ * is the row. Anything else in the table is the table.
26
+ *
27
+ * Pure: no React, no package state. It reads `data-*` attributes and returns a
28
+ * plain object. Nothing here throws on any input.
29
+ */
30
+ /** Which of the four things the pointer was aimed at. */
31
+ type MatrxTableMenuLevel = "cell" | "row" | "column" | "selection" | "table";
32
+ interface MatrxTableMenuTarget {
33
+ /** The table instance the click landed in. */
34
+ tableId: string;
35
+ level: MatrxTableMenuLevel;
36
+ /** Present for "cell" and "row". */
37
+ rowId?: string;
38
+ /** Present for "cell" and "column". */
39
+ columnId?: string;
40
+ }
41
+ /**
42
+ * Attribute names, in one place, so the renderer and the reader cannot drift.
43
+ * `data-row-id` predates this module and keeps its name: it is already read by
44
+ * the row-drag preview and by every host that wired the row menu.
45
+ */
46
+ declare const MATRX_TABLE_ID_ATTR = "data-matrx-table-id";
47
+ declare const MATRX_ROW_ID_ATTR = "data-row-id";
48
+ declare const MATRX_CELL_ROW_ATTR = "data-matrx-cell-row";
49
+ declare const MATRX_CELL_COLUMN_ATTR = "data-matrx-table-column-id";
50
+ declare const MATRX_HEADER_COLUMN_ATTR = "data-matrx-header-column-id";
51
+ /** Marks a cell that is inside the current extended range. */
52
+ declare const MATRX_CELL_SELECTED_ATTR = "data-matrx-cell-selected";
53
+ interface MinimalElement {
54
+ closest(selector: string): MinimalElement | null;
55
+ getAttribute(name: string): string | null;
56
+ }
57
+ /**
58
+ * Read the four levels off the clicked element.
59
+ *
60
+ * Returns null when the click did not land in a canonical table at all — which
61
+ * is the signal a host needs to leave its own page-level menu alone.
62
+ */
63
+ declare function readMenuTarget(target: MinimalElement | null): MatrxTableMenuTarget | null;
64
+ /**
65
+ * The payload the table hands its host for the level that was clicked.
66
+ *
67
+ * The host builds the menu from this and never reaches back into the table.
68
+ * Every level carries the table's own count of what it is acting on, because a
69
+ * menu that says "Clear 12 cells" and clears 40 is worse than one that says
70
+ * nothing.
71
+ */
72
+ type MatrxTableMenuPayload<T = unknown> = {
73
+ level: "cell";
74
+ row: T;
75
+ rowId: string;
76
+ columnId: string;
77
+ columnLabel: string;
78
+ value: unknown;
79
+ /** The cell's value as the table displays it, for Copy. */
80
+ text: string;
81
+ controls: unknown;
82
+ } | {
83
+ level: "row";
84
+ row: T;
85
+ rowId: string;
86
+ controls: unknown;
87
+ } | {
88
+ level: "column";
89
+ columnId: string;
90
+ columnLabel: string;
91
+ /** Every rendered row's value for this column, in visual order. */
92
+ values: unknown[];
93
+ } | {
94
+ level: "selection";
95
+ rowIds: string[];
96
+ columnIds: string[];
97
+ /** The selected rectangle as an Excel/Sheets-compatible TSV block. */
98
+ tsv: string;
99
+ cellCount: number;
100
+ } | {
101
+ level: "table";
102
+ rowCount: number;
103
+ columnIds: string[];
104
+ };
105
+ /** Plain-English name for a level, for a host that labels its sections. */
106
+ declare function describeMenuLevel(payload: MatrxTableMenuPayload): string;
107
+
108
+ export { MATRX_CELL_COLUMN_ATTR, MATRX_CELL_ROW_ATTR, MATRX_CELL_SELECTED_ATTR, MATRX_HEADER_COLUMN_ATTR, MATRX_ROW_ID_ATTR, MATRX_TABLE_ID_ATTR, type MatrxTableMenuLevel, type MatrxTableMenuPayload, type MatrxTableMenuTarget, describeMenuLevel, readMenuTarget };
@@ -0,0 +1,57 @@
1
+
2
+ // src/data-table/menu-targets.ts
3
+ var MATRX_TABLE_ID_ATTR = "data-matrx-table-id";
4
+ var MATRX_ROW_ID_ATTR = "data-row-id";
5
+ var MATRX_CELL_ROW_ATTR = "data-matrx-cell-row";
6
+ var MATRX_CELL_COLUMN_ATTR = "data-matrx-table-column-id";
7
+ var MATRX_HEADER_COLUMN_ATTR = "data-matrx-header-column-id";
8
+ var MATRX_CELL_SELECTED_ATTR = "data-matrx-cell-selected";
9
+ function attr(element, name) {
10
+ if (!element) return void 0;
11
+ const found = element.closest(`[${name}]`);
12
+ const value = found?.getAttribute(name);
13
+ return value === null || value === void 0 || value === "" ? void 0 : value;
14
+ }
15
+ function readMenuTarget(target) {
16
+ const tableId = attr(target, MATRX_TABLE_ID_ATTR);
17
+ if (!tableId) return null;
18
+ const headerColumnId = attr(target, MATRX_HEADER_COLUMN_ATTR);
19
+ if (headerColumnId) return { tableId, level: "column", columnId: headerColumnId };
20
+ const cellColumnId = attr(target, MATRX_CELL_COLUMN_ATTR);
21
+ const cellRowId = attr(target, MATRX_ROW_ID_ATTR) ?? attr(target, MATRX_CELL_ROW_ATTR);
22
+ const rowId = cellRowId;
23
+ if (cellRowId && cellColumnId) {
24
+ const selected = attr(target, MATRX_CELL_SELECTED_ATTR) === "true";
25
+ if (selected) return { tableId, level: "selection", rowId: cellRowId, columnId: cellColumnId };
26
+ return { tableId, level: "cell", rowId: cellRowId, columnId: cellColumnId };
27
+ }
28
+ if (rowId) return { tableId, level: "row", rowId };
29
+ return { tableId, level: "table" };
30
+ }
31
+ function describeMenuLevel(payload) {
32
+ switch (payload.level) {
33
+ case "cell":
34
+ return payload.columnLabel;
35
+ case "row":
36
+ return "Row";
37
+ case "column":
38
+ return payload.columnLabel;
39
+ case "selection": {
40
+ const cells = payload.cellCount;
41
+ return `${cells} ${cells === 1 ? "cell" : "cells"}`;
42
+ }
43
+ case "table":
44
+ return "Table";
45
+ }
46
+ }
47
+ export {
48
+ MATRX_CELL_COLUMN_ATTR,
49
+ MATRX_CELL_ROW_ATTR,
50
+ MATRX_CELL_SELECTED_ATTR,
51
+ MATRX_HEADER_COLUMN_ATTR,
52
+ MATRX_ROW_ID_ATTR,
53
+ MATRX_TABLE_ID_ATTR,
54
+ describeMenuLevel,
55
+ readMenuTarget
56
+ };
57
+ //# sourceMappingURL=menu-targets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/data-table/menu-targets.ts"],"sourcesContent":["/**\n * @ai-matrx/design-system/data-table — WHAT WAS RIGHT-CLICKED.\n *\n * A spreadsheet's right-click menu is not one menu: it is four, and which one\n * you get is decided by where the pointer was. A cell, the row it sits in, the\n * column it sits under, and — when the click lands inside an extended range —\n * the selection. The canonical table used to expose exactly ONE of those four\n * (the row), so every surface that wanted the other three forked the table.\n *\n * This module is the pure half of the fix: it reads the four levels off the\n * DOM anchors the table already renders, and nothing more. It does not build a\n * menu, name an action, or know what a menu is — the platform's universal\n * right-click menu is an application concern and stays there. The table's job\n * is to answer, truthfully, WHICH thing the person aimed at.\n *\n * THE PRECEDENCE, and why it is this way:\n *\n * selection > cell > column > row > table\n *\n * A click inside an extended range means the range, because that is what the\n * person is looking at and what every spreadsheet acts on — taking the single\n * cell under the cursor there would silently throw away their selection. A\n * header click is the column even though the header is inside the table. A\n * click on a row but outside any cell (the checkbox gutter, the actions cell)\n * is the row. Anything else in the table is the table.\n *\n * Pure: no React, no package state. It reads `data-*` attributes and returns a\n * plain object. Nothing here throws on any input.\n */\n\n/** Which of the four things the pointer was aimed at. */\nexport type MatrxTableMenuLevel = \"cell\" | \"row\" | \"column\" | \"selection\" | \"table\";\n\nexport interface MatrxTableMenuTarget {\n /** The table instance the click landed in. */\n tableId: string;\n level: MatrxTableMenuLevel;\n /** Present for \"cell\" and \"row\". */\n rowId?: string;\n /** Present for \"cell\" and \"column\". */\n columnId?: string;\n}\n\n/**\n * Attribute names, in one place, so the renderer and the reader cannot drift.\n * `data-row-id` predates this module and keeps its name: it is already read by\n * the row-drag preview and by every host that wired the row menu.\n */\nexport const MATRX_TABLE_ID_ATTR = \"data-matrx-table-id\";\nexport const MATRX_ROW_ID_ATTR = \"data-row-id\";\nexport const MATRX_CELL_ROW_ATTR = \"data-matrx-cell-row\";\nexport const MATRX_CELL_COLUMN_ATTR = \"data-matrx-table-column-id\";\nexport const MATRX_HEADER_COLUMN_ATTR = \"data-matrx-header-column-id\";\n/** Marks a cell that is inside the current extended range. */\nexport const MATRX_CELL_SELECTED_ATTR = \"data-matrx-cell-selected\";\n\ninterface MinimalElement {\n closest(selector: string): MinimalElement | null;\n getAttribute(name: string): string | null;\n}\n\nfunction attr(element: MinimalElement | null, name: string): string | undefined {\n if (!element) return undefined;\n const found = element.closest(`[${name}]`);\n const value = found?.getAttribute(name);\n return value === null || value === undefined || value === \"\" ? undefined : value;\n}\n\n/**\n * Read the four levels off the clicked element.\n *\n * Returns null when the click did not land in a canonical table at all — which\n * is the signal a host needs to leave its own page-level menu alone.\n */\nexport function readMenuTarget(\n target: MinimalElement | null,\n): MatrxTableMenuTarget | null {\n const tableId = attr(target, MATRX_TABLE_ID_ATTR);\n if (!tableId) return null;\n\n const headerColumnId = attr(target, MATRX_HEADER_COLUMN_ATTR);\n if (headerColumnId) return { tableId, level: \"column\", columnId: headerColumnId };\n\n // A cell's row comes from the `<tr>` it is in, which every table renders —\n // the spreadsheet cursor's own row attribute is a second opinion, used only\n // when the table is windowed sideways and the row wrapper is not an ancestor.\n const cellColumnId = attr(target, MATRX_CELL_COLUMN_ATTR);\n const cellRowId = attr(target, MATRX_ROW_ID_ATTR) ?? attr(target, MATRX_CELL_ROW_ATTR);\n const rowId = cellRowId;\n\n if (cellRowId && cellColumnId) {\n // Inside an extended range the SELECTION is what the person sees and what\n // the menu must act on. A range of one cell is not a range — acting on it\n // as a selection would give a lone cell the plural verbs.\n const selected = attr(target, MATRX_CELL_SELECTED_ATTR) === \"true\";\n if (selected) return { tableId, level: \"selection\", rowId: cellRowId, columnId: cellColumnId };\n return { tableId, level: \"cell\", rowId: cellRowId, columnId: cellColumnId };\n }\n\n if (rowId) return { tableId, level: \"row\", rowId };\n return { tableId, level: \"table\" };\n}\n\n/**\n * The payload the table hands its host for the level that was clicked.\n *\n * The host builds the menu from this and never reaches back into the table.\n * Every level carries the table's own count of what it is acting on, because a\n * menu that says \"Clear 12 cells\" and clears 40 is worse than one that says\n * nothing.\n */\nexport type MatrxTableMenuPayload<T = unknown> =\n | {\n level: \"cell\";\n row: T;\n rowId: string;\n columnId: string;\n columnLabel: string;\n value: unknown;\n /** The cell's value as the table displays it, for Copy. */\n text: string;\n controls: unknown;\n }\n | { level: \"row\"; row: T; rowId: string; controls: unknown }\n | {\n level: \"column\";\n columnId: string;\n columnLabel: string;\n /** Every rendered row's value for this column, in visual order. */\n values: unknown[];\n }\n | {\n level: \"selection\";\n rowIds: string[];\n columnIds: string[];\n /** The selected rectangle as an Excel/Sheets-compatible TSV block. */\n tsv: string;\n cellCount: number;\n }\n | { level: \"table\"; rowCount: number; columnIds: string[] };\n\n/** Plain-English name for a level, for a host that labels its sections. */\nexport function describeMenuLevel(payload: MatrxTableMenuPayload): string {\n switch (payload.level) {\n case \"cell\":\n return payload.columnLabel;\n case \"row\":\n return \"Row\";\n case \"column\":\n return payload.columnLabel;\n case \"selection\": {\n const cells = payload.cellCount;\n return `${cells} ${cells === 1 ? \"cell\" : \"cells\"}`;\n }\n case \"table\":\n return \"Table\";\n }\n}\n"],"mappings":";;AAgDO,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAC5B,IAAM,yBAAyB;AAC/B,IAAM,2BAA2B;AAEjC,IAAM,2BAA2B;AAOxC,SAAS,KAAK,SAAgC,MAAkC;AAC9E,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,QAAQ,QAAQ,QAAQ,IAAI,IAAI,GAAG;AACzC,QAAM,QAAQ,OAAO,aAAa,IAAI;AACtC,SAAO,UAAU,QAAQ,UAAU,UAAa,UAAU,KAAK,SAAY;AAC7E;AAQO,SAAS,eACd,QAC6B;AAC7B,QAAM,UAAU,KAAK,QAAQ,mBAAmB;AAChD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,iBAAiB,KAAK,QAAQ,wBAAwB;AAC5D,MAAI,eAAgB,QAAO,EAAE,SAAS,OAAO,UAAU,UAAU,eAAe;AAKhF,QAAM,eAAe,KAAK,QAAQ,sBAAsB;AACxD,QAAM,YAAY,KAAK,QAAQ,iBAAiB,KAAK,KAAK,QAAQ,mBAAmB;AACrF,QAAM,QAAQ;AAEd,MAAI,aAAa,cAAc;AAI7B,UAAM,WAAW,KAAK,QAAQ,wBAAwB,MAAM;AAC5D,QAAI,SAAU,QAAO,EAAE,SAAS,OAAO,aAAa,OAAO,WAAW,UAAU,aAAa;AAC7F,WAAO,EAAE,SAAS,OAAO,QAAQ,OAAO,WAAW,UAAU,aAAa;AAAA,EAC5E;AAEA,MAAI,MAAO,QAAO,EAAE,SAAS,OAAO,OAAO,MAAM;AACjD,SAAO,EAAE,SAAS,OAAO,QAAQ;AACnC;AAyCO,SAAS,kBAAkB,SAAwC;AACxE,UAAQ,QAAQ,OAAO;AAAA,IACrB,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK,aAAa;AAChB,YAAM,QAAQ,QAAQ;AACtB,aAAO,GAAG,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;AAAA,IACnD;AAAA,IACA,KAAK;AACH,aAAO;AAAA,EACX;AACF;","names":[]}