@dxos/plugin-sheet 0.6.14-main.7bd9c89 → 0.6.14-staging.9e90729

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 (208) hide show
  1. package/dist/lib/browser/{SheetContainer-AKWROARP.mjs → SheetContainer-JBB7W52Y.mjs} +42 -52
  2. package/dist/lib/browser/SheetContainer-JBB7W52Y.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-GSV5QNLD.mjs → chunk-2ZK3YMZG.mjs} +248 -33
  4. package/dist/lib/browser/{chunk-GSV5QNLD.mjs.map → chunk-2ZK3YMZG.mjs.map} +4 -4
  5. package/dist/lib/browser/{chunk-BWN5DZWZ.mjs → chunk-3QWIMZZJ.mjs} +2 -11
  6. package/dist/lib/browser/chunk-3QWIMZZJ.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-FGMFOW6U.mjs → chunk-XXDHBYZQ.mjs} +553 -668
  8. package/dist/lib/browser/chunk-XXDHBYZQ.mjs.map +7 -0
  9. package/dist/lib/browser/{graph-M4IQ76QX.mjs → compute-graph-ZQKB6QVP.mjs} +4 -2
  10. package/dist/lib/browser/index.mjs +57 -14
  11. package/dist/lib/browser/index.mjs.map +4 -4
  12. package/dist/lib/browser/meta.json +1 -1
  13. package/dist/lib/browser/types.mjs +1 -1
  14. package/dist/lib/node/{SheetContainer-N5IQGEFL.cjs → SheetContainer-L37HUFCF.cjs} +44 -58
  15. package/dist/lib/node/SheetContainer-L37HUFCF.cjs.map +7 -0
  16. package/dist/lib/node/{chunk-53BMSUIK.cjs → chunk-7AWAC3R3.cjs} +517 -645
  17. package/dist/lib/node/chunk-7AWAC3R3.cjs.map +7 -0
  18. package/dist/lib/node/{chunk-5XPK2V4A.cjs → chunk-QNFMTK3X.cjs} +252 -28
  19. package/dist/lib/node/{chunk-5XPK2V4A.cjs.map → chunk-QNFMTK3X.cjs.map} +4 -4
  20. package/dist/lib/node/{chunk-NZARD7UP.cjs → chunk-V7E5JZBD.cjs} +5 -14
  21. package/dist/lib/node/chunk-V7E5JZBD.cjs.map +7 -0
  22. package/dist/lib/node/{graph-Q3N2X26H.cjs → compute-graph-RJB6OVW6.cjs} +21 -19
  23. package/dist/lib/node/compute-graph-RJB6OVW6.cjs.map +7 -0
  24. package/dist/lib/node/index.cjs +66 -27
  25. package/dist/lib/node/index.cjs.map +4 -4
  26. package/dist/lib/node/meta.json +1 -1
  27. package/dist/lib/node/types.cjs +6 -6
  28. package/dist/lib/node/types.cjs.map +1 -1
  29. package/dist/lib/node-esm/{SheetContainer-46PBMF2E.mjs → SheetContainer-CLKFEM35.mjs} +42 -52
  30. package/dist/lib/node-esm/SheetContainer-CLKFEM35.mjs.map +7 -0
  31. package/dist/lib/node-esm/{chunk-T3PRH7QS.mjs → chunk-3JYJEOCF.mjs} +553 -668
  32. package/dist/lib/node-esm/chunk-3JYJEOCF.mjs.map +7 -0
  33. package/dist/lib/node-esm/{chunk-5WPZCXNS.mjs → chunk-JBTORSST.mjs} +247 -33
  34. package/dist/lib/node-esm/{chunk-5WPZCXNS.mjs.map → chunk-JBTORSST.mjs.map} +4 -4
  35. package/dist/lib/node-esm/{chunk-WFDTY3IC.mjs → chunk-SPQFLYC2.mjs} +2 -11
  36. package/dist/lib/node-esm/chunk-SPQFLYC2.mjs.map +7 -0
  37. package/dist/lib/node-esm/{graph-SMPUMOV2.mjs → compute-graph-VKRG526N.mjs} +4 -2
  38. package/dist/lib/node-esm/index.mjs +57 -14
  39. package/dist/lib/node-esm/index.mjs.map +4 -4
  40. package/dist/lib/node-esm/meta.json +1 -1
  41. package/dist/lib/node-esm/types.mjs +1 -1
  42. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  43. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +3 -1
  44. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -1
  45. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -1
  46. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -1
  47. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -1
  48. package/dist/types/src/components/RangeList/RangeList.d.ts +9 -0
  49. package/dist/types/src/components/RangeList/RangeList.d.ts.map +1 -0
  50. package/dist/types/src/components/RangeList/index.d.ts +2 -0
  51. package/dist/types/src/components/RangeList/index.d.ts.map +1 -0
  52. package/dist/types/src/components/SheetContext/SheetContext.d.ts +7 -5
  53. package/dist/types/src/components/SheetContext/SheetContext.d.ts.map +1 -1
  54. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  55. package/dist/types/src/components/index.d.ts +1 -0
  56. package/dist/types/src/components/index.d.ts.map +1 -1
  57. package/dist/types/src/compute-graph/compute-graph-registry.d.ts.map +1 -0
  58. package/dist/types/src/{graph → compute-graph}/compute-graph.d.ts +1 -1
  59. package/dist/types/src/compute-graph/compute-graph.d.ts.map +1 -0
  60. package/dist/types/src/compute-graph/compute-graph.stories.d.ts.map +1 -0
  61. package/dist/types/src/compute-graph/compute-graph.test.d.ts.map +1 -0
  62. package/dist/types/src/compute-graph/compute-node.d.ts.map +1 -0
  63. package/dist/types/src/compute-graph/functions/async-function.d.ts.map +1 -0
  64. package/dist/types/src/compute-graph/functions/edge-function.d.ts.map +1 -0
  65. package/dist/types/src/compute-graph/functions/function-defs.d.ts.map +1 -0
  66. package/dist/types/src/compute-graph/functions/index.d.ts.map +1 -0
  67. package/dist/types/src/compute-graph/hyperformula.test.d.ts.map +1 -0
  68. package/dist/types/src/compute-graph/index.d.ts.map +1 -0
  69. package/dist/types/src/compute-graph/testing/index.d.ts.map +1 -0
  70. package/dist/types/src/compute-graph/testing/test-builder.d.ts.map +1 -0
  71. package/dist/types/src/compute-graph/testing/test-plugin.d.ts.map +1 -0
  72. package/dist/types/src/compute-graph/util.d.ts.map +1 -0
  73. package/dist/types/src/defs/index.d.ts +1 -1
  74. package/dist/types/src/defs/index.d.ts.map +1 -1
  75. package/dist/types/src/defs/sheet-range-types.d.ts.map +1 -1
  76. package/dist/types/src/defs/types.d.ts +6 -0
  77. package/dist/types/src/defs/types.d.ts.map +1 -1
  78. package/dist/types/src/defs/util.d.ts +2 -6
  79. package/dist/types/src/defs/util.d.ts.map +1 -1
  80. package/dist/types/src/extensions/compute.d.ts +1 -1
  81. package/dist/types/src/extensions/compute.d.ts.map +1 -1
  82. package/dist/types/src/extensions/editor/extension.d.ts +23 -3
  83. package/dist/types/src/extensions/editor/extension.d.ts.map +1 -1
  84. package/dist/types/src/index.d.ts +1 -1
  85. package/dist/types/src/index.d.ts.map +1 -1
  86. package/dist/types/src/integrations/index.d.ts +2 -0
  87. package/dist/types/src/integrations/index.d.ts.map +1 -0
  88. package/dist/types/src/integrations/thread-ranges.d.ts +8 -0
  89. package/dist/types/src/integrations/thread-ranges.d.ts.map +1 -0
  90. package/dist/types/src/model/index.d.ts +1 -1
  91. package/dist/types/src/model/index.d.ts.map +1 -1
  92. package/dist/types/src/model/sheet-model.d.ts +1 -1
  93. package/dist/types/src/model/sheet-model.d.ts.map +1 -1
  94. package/dist/types/src/{hooks → model}/useSheetModel.d.ts +1 -1
  95. package/dist/types/src/model/useSheetModel.d.ts.map +1 -0
  96. package/dist/types/src/serializer.d.ts +4 -0
  97. package/dist/types/src/serializer.d.ts.map +1 -0
  98. package/dist/types/src/testing/testing.d.ts +1 -1
  99. package/dist/types/src/testing/testing.d.ts.map +1 -1
  100. package/dist/types/src/translations.d.ts +6 -0
  101. package/dist/types/src/translations.d.ts.map +1 -1
  102. package/dist/types/src/types.d.ts +4 -30
  103. package/dist/types/src/types.d.ts.map +1 -1
  104. package/package.json +43 -50
  105. package/src/SheetPlugin.tsx +23 -10
  106. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +19 -2
  107. package/src/components/FunctionEditor/FunctionEditor.tsx +5 -5
  108. package/src/components/GridSheet/GridSheet.stories.tsx +3 -1
  109. package/src/components/GridSheet/GridSheet.tsx +114 -19
  110. package/src/components/GridSheet/SheetCellEditor.stories.tsx +1 -1
  111. package/src/components/GridSheet/util.ts +17 -7
  112. package/src/components/RangeList/RangeList.tsx +38 -0
  113. package/src/components/RangeList/index.ts +5 -0
  114. package/src/components/SheetContainer/SheetContainer.stories.tsx +1 -1
  115. package/src/components/SheetContext/SheetContext.tsx +43 -20
  116. package/src/components/Toolbar/Toolbar.tsx +34 -35
  117. package/src/components/index.ts +1 -0
  118. package/src/{graph → compute-graph}/compute-graph.stories.tsx +2 -1
  119. package/src/{graph → compute-graph}/compute-graph.ts +5 -2
  120. package/src/{graph → compute-graph}/compute-node.ts +2 -3
  121. package/src/defs/index.ts +1 -1
  122. package/src/defs/sheet-range-types.ts +1 -0
  123. package/src/defs/types.ts +6 -1
  124. package/src/defs/util.ts +3 -19
  125. package/src/extensions/compute.stories.tsx +2 -2
  126. package/src/extensions/compute.ts +2 -2
  127. package/src/extensions/editor/extension.test.ts +1 -1
  128. package/src/extensions/editor/extension.ts +48 -23
  129. package/src/index.ts +2 -2
  130. package/src/integrations/index.ts +5 -0
  131. package/src/integrations/thread-ranges.ts +101 -0
  132. package/src/model/index.ts +1 -1
  133. package/src/model/sheet-model.test.ts +1 -1
  134. package/src/model/sheet-model.ts +13 -8
  135. package/src/{hooks → model}/useSheetModel.ts +1 -1
  136. package/src/serializer.ts +27 -0
  137. package/src/testing/testing.tsx +1 -1
  138. package/src/translations.ts +6 -0
  139. package/src/types.ts +3 -1
  140. package/dist/lib/browser/SheetContainer-AKWROARP.mjs.map +0 -7
  141. package/dist/lib/browser/chunk-BWN5DZWZ.mjs.map +0 -7
  142. package/dist/lib/browser/chunk-FGMFOW6U.mjs.map +0 -7
  143. package/dist/lib/node/SheetContainer-N5IQGEFL.cjs.map +0 -7
  144. package/dist/lib/node/chunk-53BMSUIK.cjs.map +0 -7
  145. package/dist/lib/node/chunk-NZARD7UP.cjs.map +0 -7
  146. package/dist/lib/node/graph-Q3N2X26H.cjs.map +0 -7
  147. package/dist/lib/node-esm/SheetContainer-46PBMF2E.mjs.map +0 -7
  148. package/dist/lib/node-esm/chunk-T3PRH7QS.mjs.map +0 -7
  149. package/dist/lib/node-esm/chunk-WFDTY3IC.mjs.map +0 -7
  150. package/dist/types/src/graph/compute-graph-registry.d.ts.map +0 -1
  151. package/dist/types/src/graph/compute-graph.d.ts.map +0 -1
  152. package/dist/types/src/graph/compute-graph.stories.d.ts.map +0 -1
  153. package/dist/types/src/graph/compute-graph.test.d.ts.map +0 -1
  154. package/dist/types/src/graph/compute-node.d.ts.map +0 -1
  155. package/dist/types/src/graph/functions/async-function.d.ts.map +0 -1
  156. package/dist/types/src/graph/functions/edge-function.d.ts.map +0 -1
  157. package/dist/types/src/graph/functions/function-defs.d.ts.map +0 -1
  158. package/dist/types/src/graph/functions/index.d.ts.map +0 -1
  159. package/dist/types/src/graph/hyperformula.test.d.ts.map +0 -1
  160. package/dist/types/src/graph/index.d.ts.map +0 -1
  161. package/dist/types/src/graph/testing/index.d.ts.map +0 -1
  162. package/dist/types/src/graph/testing/test-builder.d.ts.map +0 -1
  163. package/dist/types/src/graph/testing/test-plugin.d.ts.map +0 -1
  164. package/dist/types/src/graph/util.d.ts.map +0 -1
  165. package/dist/types/src/hooks/hooks.stories.d.ts +0 -6
  166. package/dist/types/src/hooks/hooks.stories.d.ts.map +0 -1
  167. package/dist/types/src/hooks/index.d.ts +0 -4
  168. package/dist/types/src/hooks/index.d.ts.map +0 -1
  169. package/dist/types/src/hooks/threads.d.ts +0 -8
  170. package/dist/types/src/hooks/threads.d.ts.map +0 -1
  171. package/dist/types/src/hooks/useComputeGraph.d.ts +0 -7
  172. package/dist/types/src/hooks/useComputeGraph.d.ts.map +0 -1
  173. package/dist/types/src/hooks/useSheetModel.d.ts.map +0 -1
  174. package/dist/types/src/model/decorations.d.ts +0 -26
  175. package/dist/types/src/model/decorations.d.ts.map +0 -1
  176. package/src/hooks/hooks.stories.tsx +0 -53
  177. package/src/hooks/index.ts +0 -7
  178. package/src/hooks/threads.ts +0 -147
  179. package/src/hooks/useComputeGraph.ts +0 -28
  180. package/src/model/decorations.ts +0 -66
  181. /package/dist/lib/browser/{graph-M4IQ76QX.mjs.map → compute-graph-ZQKB6QVP.mjs.map} +0 -0
  182. /package/dist/lib/node-esm/{graph-SMPUMOV2.mjs.map → compute-graph-VKRG526N.mjs.map} +0 -0
  183. /package/dist/types/src/{graph → compute-graph}/compute-graph-registry.d.ts +0 -0
  184. /package/dist/types/src/{graph → compute-graph}/compute-graph.stories.d.ts +0 -0
  185. /package/dist/types/src/{graph → compute-graph}/compute-graph.test.d.ts +0 -0
  186. /package/dist/types/src/{graph → compute-graph}/compute-node.d.ts +0 -0
  187. /package/dist/types/src/{graph → compute-graph}/functions/async-function.d.ts +0 -0
  188. /package/dist/types/src/{graph → compute-graph}/functions/edge-function.d.ts +0 -0
  189. /package/dist/types/src/{graph → compute-graph}/functions/function-defs.d.ts +0 -0
  190. /package/dist/types/src/{graph → compute-graph}/functions/index.d.ts +0 -0
  191. /package/dist/types/src/{graph → compute-graph}/hyperformula.test.d.ts +0 -0
  192. /package/dist/types/src/{graph → compute-graph}/index.d.ts +0 -0
  193. /package/dist/types/src/{graph → compute-graph}/testing/index.d.ts +0 -0
  194. /package/dist/types/src/{graph → compute-graph}/testing/test-builder.d.ts +0 -0
  195. /package/dist/types/src/{graph → compute-graph}/testing/test-plugin.d.ts +0 -0
  196. /package/dist/types/src/{graph → compute-graph}/util.d.ts +0 -0
  197. /package/src/{graph → compute-graph}/compute-graph-registry.ts +0 -0
  198. /package/src/{graph → compute-graph}/compute-graph.test.ts +0 -0
  199. /package/src/{graph → compute-graph}/functions/async-function.ts +0 -0
  200. /package/src/{graph → compute-graph}/functions/edge-function.ts +0 -0
  201. /package/src/{graph → compute-graph}/functions/function-defs.ts +0 -0
  202. /package/src/{graph → compute-graph}/functions/index.ts +0 -0
  203. /package/src/{graph → compute-graph}/hyperformula.test.ts +0 -0
  204. /package/src/{graph → compute-graph}/index.ts +0 -0
  205. /package/src/{graph → compute-graph}/testing/index.ts +0 -0
  206. /package/src/{graph → compute-graph}/testing/test-builder.ts +0 -0
  207. /package/src/{graph → compute-graph}/testing/test-plugin.ts +0 -0
  208. /package/src/{graph → compute-graph}/util.ts +0 -0
@@ -1,15 +1,34 @@
1
1
  import {
2
- SheetType
3
- } from "./chunk-BWN5DZWZ.mjs";
2
+ DEFAULT_COLUMNS,
3
+ DEFAULT_ROWS,
4
+ MAX_COLUMNS,
5
+ MAX_ROWS,
6
+ RANGE_NOTATION,
7
+ ReadonlyException,
8
+ addressFromA1Notation,
9
+ addressFromIndex,
10
+ addressToA1Notation,
11
+ addressToIndex,
12
+ cellClassNameForRange,
13
+ createSheetName,
14
+ inRange,
15
+ initialize,
16
+ insertIndices,
17
+ isFormula,
18
+ rangeFromIndex,
19
+ rangeToA1Notation
20
+ } from "./chunk-2ZK3YMZG.mjs";
21
+ import {
22
+ Range
23
+ } from "./chunk-3QWIMZZJ.mjs";
4
24
  import {
5
25
  SHEET_PLUGIN
6
26
  } from "./chunk-D3QTX46O.mjs";
7
- import {
8
- createSheetName
9
- } from "./chunk-GSV5QNLD.mjs";
10
27
 
11
28
  // packages/plugins/plugin-sheet/src/components/ComputeGraph/ComputeGraphContextProvider.tsx
12
- import React, { createContext } from "react";
29
+ import React, { createContext, useContext } from "react";
30
+ import { raise } from "@dxos/debug";
31
+ import { useAsyncState } from "@dxos/react-hooks";
13
32
  var ComputeGraphContext = /* @__PURE__ */ createContext(void 0);
14
33
  var ComputeGraphContextProvider = ({ registry, children }) => {
15
34
  return /* @__PURE__ */ React.createElement(ComputeGraphContext.Provider, {
@@ -18,192 +37,19 @@ var ComputeGraphContextProvider = ({ registry, children }) => {
18
37
  }
19
38
  }, children);
20
39
  };
21
-
22
- // packages/plugins/plugin-sheet/src/defs/util.ts
23
- import { randomBytes } from "@dxos/crypto";
24
- import { create } from "@dxos/echo-schema";
25
-
26
- // packages/plugins/plugin-sheet/src/defs/types.ts
27
- import { invariant } from "@dxos/invariant";
28
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/defs/types.ts";
29
- var DEFAULT_ROWS = 50;
30
- var DEFAULT_COLUMNS = 26;
31
- var MAX_ROWS = 500;
32
- var MAX_COLUMNS = 26 * 2;
33
- var posEquals = (a, b) => {
34
- return a?.col === b?.col && a?.row === b?.row;
35
- };
36
- var columnLetter = (col) => {
37
- invariant(col < MAX_COLUMNS, `Invalid column: ${col}`, {
38
- F: __dxlog_file,
39
- L: 26,
40
- S: void 0,
41
- A: [
42
- "col < MAX_COLUMNS",
43
- "`Invalid column: ${col}`"
44
- ]
45
- });
46
- return (col >= 26 ? String.fromCharCode("A".charCodeAt(0) + Math.floor(col / 26) - 1) : "") + String.fromCharCode("A".charCodeAt(0) + col % 26);
47
- };
48
- var addressToA1Notation = ({ col, row }) => {
49
- return `${columnLetter(col)}${row + 1}`;
50
- };
51
- var addressFromA1Notation = (ref) => {
52
- const match = ref.match(/([A-Z]+)(\d+)/);
53
- invariant(match, `Invalid notation: ${ref}`, {
54
- F: __dxlog_file,
55
- L: 40,
56
- S: void 0,
57
- A: [
58
- "match",
59
- "`Invalid notation: ${ref}`"
60
- ]
61
- });
62
- return {
63
- row: parseInt(match[2], 10) - 1,
64
- col: match[1].split("").reduce((acc, c) => acc * 26 + c.charCodeAt(0) - "A".charCodeAt(0) + 1, 0) - 1
65
- };
66
- };
67
- var rangeToA1Notation = (range) => {
68
- return [
69
- range?.from && addressToA1Notation(range?.from),
70
- range?.to && addressToA1Notation(range?.to)
71
- ].filter(Boolean).join(":");
72
- };
73
- var inRange = (range, cell) => {
74
- if (!range) {
75
- return false;
76
- }
77
- const { from, to } = range;
78
- if (from && posEquals(from, cell) || to && posEquals(to, cell)) {
79
- return true;
80
- }
81
- if (!from || !to) {
82
- return false;
83
- }
84
- const { col: c1, row: r1 } = from;
85
- const { col: c2, row: r2 } = to;
86
- const cMin = Math.min(c1, c2);
87
- const cMax = Math.max(c1, c2);
88
- const rMin = Math.min(r1, r2);
89
- const rMax = Math.max(r1, r2);
90
- const { col, row } = cell;
91
- return col >= cMin && col <= cMax && row >= rMin && row <= rMax;
92
- };
93
-
94
- // packages/plugins/plugin-sheet/src/defs/util.ts
95
- var ApiError = class extends Error {
96
- };
97
- var ReadonlyException = class extends ApiError {
98
- };
99
- var RangeException = class extends ApiError {
100
- constructor(n) {
101
- super();
102
- }
103
- };
104
- var createIndex = (length = 8) => {
105
- const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
106
- const charactersLength = characters.length;
107
- const randomBuffer = randomBytes(length);
108
- return Array.from(randomBuffer, (byte) => characters[byte % charactersLength]).join("");
109
- };
110
- var createIndices = (length) => Array.from({
111
- length
112
- }).map(() => createIndex());
113
- var insertIndices = (indices, i, n, max) => {
114
- if (i + n > max) {
115
- throw new RangeException(i + n);
116
- }
117
- const idx = createIndices(n);
118
- indices.splice(i, 0, ...idx);
119
- };
120
- var initialize = (sheet, { rows = DEFAULT_ROWS, columns = DEFAULT_COLUMNS } = {}) => {
121
- if (!sheet.rows.length) {
122
- insertIndices(sheet.rows, 0, rows, MAX_ROWS);
123
- }
124
- if (!sheet.columns.length) {
125
- insertIndices(sheet.columns, 0, columns, MAX_COLUMNS);
126
- }
127
- };
128
- var createSheet = ({ name, cells, ...size } = {}) => {
129
- const sheet = create(SheetType, {
130
- name,
131
- cells: {},
132
- rows: [],
133
- columns: [],
134
- rowMeta: {},
135
- columnMeta: {},
136
- ranges: []
137
- });
138
- initialize(sheet, size);
139
- if (cells) {
140
- Object.entries(cells).forEach(([key, { value }]) => {
141
- const idx = addressToIndex(sheet, addressFromA1Notation(key));
142
- sheet.cells[idx] = {
143
- value
144
- };
145
- });
146
- }
147
- return sheet;
148
- };
149
- var addressToIndex = (sheet, cell) => {
150
- return `${sheet.columns[cell.col]}@${sheet.rows[cell.row]}`;
151
- };
152
- var addressFromIndex = (sheet, idx) => {
153
- const [column, row] = idx.split("@");
154
- return {
155
- col: sheet.columns.indexOf(column),
156
- row: sheet.rows.indexOf(row)
157
- };
158
- };
159
- var closest = (cursor, cells) => {
160
- let closestCell2;
161
- let closestDistance = Number.MAX_SAFE_INTEGER;
162
- for (const cell of cells) {
163
- const distance = Math.abs(cell.row - cursor.row) + Math.abs(cell.col - cursor.col);
164
- if (distance < closestDistance) {
165
- closestCell2 = cell;
166
- closestDistance = distance;
40
+ var useComputeGraph = (space) => {
41
+ const { registry } = useContext(ComputeGraphContext) ?? raise(new Error("Missing ComputeGraphContext"));
42
+ const [graph] = useAsyncState(async () => {
43
+ if (space) {
44
+ const graph2 = registry.getOrCreateGraph(space);
45
+ await graph2.open();
46
+ return graph2;
167
47
  }
168
- }
169
- return closestCell2;
170
- };
171
- var compareIndexPositions = (sheet, indexA, indexB) => {
172
- const { row: rowA, col: columnA } = addressFromIndex(sheet, indexA);
173
- const { row: rowB, col: columnB } = addressFromIndex(sheet, indexB);
174
- if (rowA !== rowB) {
175
- return rowA - rowB;
176
- } else {
177
- return columnA - columnB;
178
- }
179
- };
180
-
181
- // packages/plugins/plugin-sheet/src/defs/sheet-range-types.ts
182
- var cellClassNameForRange = ({ key, value }) => {
183
- switch (key) {
184
- case "align":
185
- switch (value) {
186
- case "start":
187
- return "text-start";
188
- case "center":
189
- return "text-center";
190
- case "end":
191
- return "text-end";
192
- default:
193
- return void 0;
194
- }
195
- case "comment":
196
- return "bg-gridComment";
197
- case "style":
198
- switch (value) {
199
- case "highlight":
200
- return "bg-gridHighlight";
201
- default:
202
- return void 0;
203
- }
204
- default:
205
- return void 0;
206
- }
48
+ }, [
49
+ space,
50
+ registry
51
+ ]);
52
+ return graph;
207
53
  };
208
54
 
209
55
  // packages/plugins/plugin-sheet/src/extensions/compute.ts
@@ -211,8 +57,8 @@ import { syntaxTree } from "@codemirror/language";
211
57
  import { RangeSetBuilder, StateEffect, StateField } from "@codemirror/state";
212
58
  import { Decoration, EditorView, ViewPlugin, WidgetType } from "@codemirror/view";
213
59
  import { debounce } from "@dxos/async";
214
- import { invariant as invariant2 } from "@dxos/invariant";
215
- import { documentId, singleValueFacet } from "@dxos/react-ui-editor/state";
60
+ import { invariant } from "@dxos/invariant";
61
+ import { documentId, singleValueFacet } from "@dxos/react-ui-editor";
216
62
  var updateAllDecorations = StateEffect.define();
217
63
  var computeGraphFacet = singleValueFacet();
218
64
 
@@ -222,7 +68,7 @@ import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
222
68
  import { ViewPlugin as ViewPlugin2, keymap } from "@codemirror/view";
223
69
  import { tags } from "@lezer/highlight";
224
70
  import { spreadsheet } from "codemirror-lang-spreadsheet";
225
- import { singleValueFacet as singleValueFacet2 } from "@dxos/react-ui-editor/state";
71
+ import { singleValueFacet as singleValueFacet2 } from "@dxos/react-ui-editor";
226
72
  import { mx } from "@dxos/react-ui-theme";
227
73
  var highlightStyles = HighlightStyle.define([
228
74
  // Function.
@@ -346,27 +192,29 @@ var sheetExtension = ({ functions = [] }) => {
346
192
  ])
347
193
  ];
348
194
  };
349
- var rangeExtension = (onInit) => {
195
+ var rangeExtension = ({ onInit, onStateChange }) => {
350
196
  let view;
351
197
  let activeRange;
352
- const provider = (range) => {
353
- if (activeRange) {
354
- view.dispatch(view.state.update({
355
- changes: {
356
- ...activeRange,
357
- insert: range.toString()
358
- },
359
- selection: {
360
- anchor: activeRange.from + range.length
361
- }
362
- }));
198
+ const notifier = {
199
+ setRange: (range) => {
200
+ if (activeRange) {
201
+ view.dispatch(view.state.update({
202
+ changes: {
203
+ ...activeRange,
204
+ insert: range.toString()
205
+ },
206
+ selection: {
207
+ anchor: activeRange.from + range.length
208
+ }
209
+ }));
210
+ }
211
+ view.focus();
363
212
  }
364
- view.focus();
365
213
  };
366
214
  return ViewPlugin2.fromClass(class {
367
215
  constructor(_view) {
368
216
  view = _view;
369
- onInit(provider);
217
+ onInit?.(notifier);
370
218
  }
371
219
  update(view2) {
372
220
  const { anchor } = view2.state.selection.ranges[0];
@@ -376,20 +224,18 @@ var rangeExtension = (onInit) => {
376
224
  visitTree(topNode, ({ type, from, to }) => {
377
225
  if (from <= anchor && to >= anchor) {
378
226
  switch (type.name) {
379
- case "Function": {
227
+ case "Function":
380
228
  activeRange = {
381
229
  from: to,
382
230
  to
383
231
  };
384
232
  break;
385
- }
386
- case "CloseParen": {
233
+ case "CloseParen":
387
234
  activeRange = {
388
235
  from,
389
236
  to: from
390
237
  };
391
238
  break;
392
- }
393
239
  case "RangeToken":
394
240
  case "CellToken":
395
241
  activeRange = {
@@ -402,11 +248,17 @@ var rangeExtension = (onInit) => {
402
248
  return false;
403
249
  });
404
250
  if (!activeRange && view2.state.doc.toString()[0] === "=") {
405
- activeRange = {
406
- from: 1,
407
- to: view2.state.doc.toString().length
408
- };
251
+ const str = view2.state.doc.sliceString(1);
252
+ if (RANGE_NOTATION.test(str)) {
253
+ activeRange = {
254
+ from: 1,
255
+ to: str.length + 1
256
+ };
257
+ }
409
258
  }
259
+ onStateChange?.({
260
+ activeRange: activeRange ? view2.state.doc.sliceString(activeRange.from, activeRange.to) : void 0
261
+ });
410
262
  }
411
263
  });
412
264
  };
@@ -422,228 +274,22 @@ var visitTree = (node, callback) => {
422
274
  return false;
423
275
  };
424
276
 
425
- // packages/plugins/plugin-sheet/src/hooks/useComputeGraph.ts
426
- import { useContext as useContext2 } from "react";
427
- import { raise } from "@dxos/debug";
428
- import { useAsyncState } from "@dxos/react-hooks";
429
-
430
- // packages/plugins/plugin-sheet/src/components/index.ts
431
- import { lazy } from "react";
432
-
433
- // packages/plugins/plugin-sheet/src/components/GridSheet/GridSheet.tsx
434
- import React3, { useCallback as useCallback2, useMemo as useMemo3, useRef } from "react";
435
- import { useAttention } from "@dxos/react-ui-attention";
436
- import { Grid as Grid2, editorKeys, GridCellEditor, closestCell } from "@dxos/react-ui-grid";
437
-
438
- // packages/plugins/plugin-sheet/src/components/GridSheet/util.ts
439
- import { useEffect, useLayoutEffect, useState } from "react";
440
- import { createDocAccessor } from "@dxos/react-client/echo";
441
- import { parseValue, cellClassesForFieldType } from "@dxos/react-ui-data";
442
- import { colToA1Notation, rowToA1Notation } from "@dxos/react-ui-grid";
443
- import { mx as mx2 } from "@dxos/react-ui-theme";
444
- var dxGridCellIndexToSheetCellAddress = (index) => {
445
- const [colStr, rowStr] = index.split(",");
446
- return {
447
- col: parseInt(colStr),
448
- row: parseInt(rowStr)
449
- };
450
- };
451
- var createDxGridColumns = (model) => {
452
- return model.sheet.columns.reduce((acc, columnId, numericIndex) => {
453
- if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {
454
- acc.grid[numericIndex] = {
455
- size: model.sheet.columnMeta[columnId].size,
456
- resizeable: true
457
- };
458
- }
459
- return acc;
460
- }, {
461
- grid: {}
462
- });
463
- };
464
- var createDxGridRows = (model) => {
465
- return model.sheet.rows.reduce((acc, rowId, numericIndex) => {
466
- if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {
467
- acc.grid[numericIndex] = {
468
- size: model.sheet.rowMeta[rowId].size,
469
- resizeable: true
470
- };
471
- }
472
- return acc;
473
- }, {
474
- grid: {}
475
- });
476
- };
477
- var projectCellProps = (model, col, row) => {
478
- const address = {
479
- col,
480
- row
481
- };
482
- const rawValue = model.getValue(address);
483
- if (rawValue === void 0 || rawValue === null) {
484
- return {
485
- value: ""
486
- };
487
- }
488
- const ranges = model.sheet.ranges?.filter(({ range }) => inRange(range, address));
489
- const type = model.getValueType(address);
490
- const classNames = ranges?.map(cellClassNameForRange).reverse();
491
- return {
492
- value: parseValue(type, rawValue),
493
- className: mx2(cellClassesForFieldType(type), classNames)
494
- };
495
- };
496
- var gridCellGetter = (model) => {
497
- const cachedGridCells = {};
498
- return (nextBounds) => {
499
- [
500
- ...Array(nextBounds.end.col - nextBounds.start.col)
501
- ].forEach((_, c0) => {
502
- return [
503
- ...Array(nextBounds.end.row - nextBounds.start.row)
504
- ].forEach((_2, r0) => {
505
- const col = nextBounds.start.col + c0;
506
- const row = nextBounds.start.row + r0;
507
- cachedGridCells[`${col},${row}`] = projectCellProps(model, col, row);
508
- });
509
- });
510
- return cachedGridCells;
511
- };
512
- };
513
- var rowLabelCell = (row) => ({
514
- value: rowToA1Notation(row),
515
- className: "text-end !pie-1",
516
- resizeHandle: "row"
517
- });
518
- var colLabelCell = (col) => ({
519
- value: colToA1Notation(col),
520
- resizeHandle: "col"
521
- });
522
- var cellGetter = (model) => {
523
- const getGridCells = gridCellGetter(model);
524
- return (nextBounds, plane) => {
525
- switch (plane) {
526
- case "grid":
527
- return getGridCells(nextBounds);
528
- case "frozenColsStart":
529
- return [
530
- ...Array(nextBounds.end.row - nextBounds.start.row)
531
- ].reduce((acc, _, r0) => {
532
- const r = nextBounds.start.row + r0;
533
- acc[`0,${r}`] = rowLabelCell(r);
534
- return acc;
535
- }, {});
536
- case "frozenRowsStart":
537
- return [
538
- ...Array(nextBounds.end.col - nextBounds.start.col)
539
- ].reduce((acc, _, c0) => {
540
- const c = nextBounds.start.col + c0;
541
- acc[`${c},0`] = colLabelCell(c);
542
- return acc;
543
- }, {});
544
- default:
545
- return {};
546
- }
547
- };
548
- };
549
- var useSheetModelDxGridProps = (dxGridRef, model) => {
550
- const [columns, setColumns] = useState(createDxGridColumns(model));
551
- const [rows, setRows] = useState(createDxGridColumns(model));
552
- useLayoutEffect(() => {
553
- const cellsAccessor = createDocAccessor(model.sheet, [
554
- "cells"
555
- ]);
556
- if (dxGridRef.current) {
557
- dxGridRef.current.getCells = cellGetter(model);
558
- }
559
- const handleCellsUpdate = () => {
560
- dxGridRef.current?.requestUpdate("initialCells");
561
- };
562
- cellsAccessor.handle.addListener("change", handleCellsUpdate);
563
- return () => cellsAccessor.handle.removeListener("change", handleCellsUpdate);
564
- }, [
565
- model
566
- ]);
567
- useEffect(() => {
568
- const columnMetaAccessor = createDocAccessor(model.sheet, [
569
- "columnMeta"
570
- ]);
571
- const rowMetaAccessor = createDocAccessor(model.sheet, [
572
- "rowMeta"
573
- ]);
574
- const handleColumnMetaUpdate = () => {
575
- setColumns(createDxGridColumns(model));
576
- };
577
- const handleRowMetaUpdate = () => {
578
- setRows(createDxGridRows(model));
579
- };
580
- columnMetaAccessor.handle.addListener("change", handleColumnMetaUpdate);
581
- rowMetaAccessor.handle.addListener("change", handleRowMetaUpdate);
582
- return () => {
583
- columnMetaAccessor.handle.removeListener("change", handleColumnMetaUpdate);
584
- rowMetaAccessor.handle.removeListener("change", handleRowMetaUpdate);
585
- };
586
- }, [
587
- model
588
- ]);
589
- return {
590
- columns,
591
- rows
592
- };
593
- };
594
-
595
- // packages/plugins/plugin-sheet/src/hooks/useSheetModel.ts
596
- import { useEffect as useEffect2, useState as useState2 } from "react";
597
-
598
- // packages/plugins/plugin-sheet/src/model/decorations.ts
599
- import { create as create2 } from "@dxos/echo-schema";
600
- var createDecorations = () => {
601
- const { decorations } = create2({
602
- decorations: {}
603
- });
604
- const addDecoration = (cellIndex, decorator) => {
605
- decorations[cellIndex] = [
606
- ...decorations[cellIndex] || [],
607
- decorator
608
- ];
609
- };
610
- const removeDecoration = (cellIndex, type) => {
611
- if (type) {
612
- decorations[cellIndex] = (decorations[cellIndex] || []).filter((d) => d.type !== type);
613
- } else {
614
- delete decorations[cellIndex];
615
- }
616
- };
617
- const getDecorationsForCell = (cellIndex) => {
618
- return decorations[cellIndex];
619
- };
620
- const getAllDecorations = () => {
621
- const result = [];
622
- for (const decoratorArray of Object.values(decorations)) {
623
- for (const decorator of decoratorArray) {
624
- result.push(decorator);
625
- }
626
- }
627
- return result;
628
- };
629
- return {
630
- addDecoration,
631
- removeDecoration,
632
- getDecorationsForCell,
633
- getAllDecorations
634
- };
635
- };
277
+ // packages/plugins/plugin-sheet/src/components/SheetContext/SheetContext.tsx
278
+ import React2, { createContext as createContext2, useCallback, useContext as useContext2, useState as useState2 } from "react";
279
+ import { invariant as invariant3 } from "@dxos/invariant";
280
+ import { fullyQualifiedId } from "@dxos/react-client/echo";
281
+ import { Grid, useGridContext } from "@dxos/react-ui-grid";
636
282
 
637
283
  // packages/plugins/plugin-sheet/src/model/sheet-model.ts
638
284
  import { Event } from "@dxos/async";
639
285
  import { Resource } from "@dxos/context";
640
286
  import { getTypename } from "@dxos/echo-schema";
641
- import { invariant as invariant3 } from "@dxos/invariant";
287
+ import { invariant as invariant2 } from "@dxos/invariant";
642
288
  import { PublicKey } from "@dxos/keys";
643
289
  import { log } from "@dxos/log";
644
290
  import { FieldValueType } from "@dxos/schema";
645
291
  import { DetailedCellError, ExportedCellChange } from "#hyperformula";
646
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/model/sheet-model.ts";
292
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/model/sheet-model.ts";
647
293
  var typeMap = {
648
294
  BOOLEAN: FieldValueType.Boolean,
649
295
  NUMBER_RAW: FieldValueType.Number,
@@ -700,8 +346,8 @@ var SheetModel = class extends Resource {
700
346
  log("initialize", {
701
347
  id: this.id
702
348
  }, {
703
- F: __dxlog_file2,
704
- L: 106,
349
+ F: __dxlog_file,
350
+ L: 111,
705
351
  S: this,
706
352
  C: (f, a) => f(...a)
707
353
  });
@@ -721,9 +367,9 @@ var SheetModel = class extends Resource {
721
367
  * @deprecated
722
368
  */
723
369
  reset() {
724
- invariant3(this._node, void 0, {
725
- F: __dxlog_file2,
726
- L: 126,
370
+ invariant2(this._node, void 0, {
371
+ F: __dxlog_file,
372
+ L: 131,
727
373
  S: this,
728
374
  A: [
729
375
  "this._node",
@@ -732,9 +378,9 @@ var SheetModel = class extends Resource {
732
378
  });
733
379
  this._node.graph.hf.clearSheet(this._node.sheetId);
734
380
  Object.entries(this._sheet.cells).forEach(([key, { value }]) => {
735
- invariant3(this._node, void 0, {
736
- F: __dxlog_file2,
737
- L: 129,
381
+ invariant2(this._node, void 0, {
382
+ F: __dxlog_file,
383
+ L: 134,
738
384
  S: this,
739
385
  A: [
740
386
  "this._node",
@@ -742,7 +388,7 @@ var SheetModel = class extends Resource {
742
388
  ]
743
389
  });
744
390
  const { col, row } = addressFromIndex(this._sheet, key);
745
- if (typeof value === "string" && value.charAt(0) === "=") {
391
+ if (isFormula(value)) {
746
392
  value = this._graph.mapFormulaToNative(this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value)));
747
393
  }
748
394
  this._node.graph.hf.setCellContents({
@@ -778,9 +424,9 @@ var SheetModel = class extends Resource {
778
424
  * Clear range of values.
779
425
  */
780
426
  clear(range) {
781
- invariant3(this._node, void 0, {
782
- F: __dxlog_file2,
783
- L: 171,
427
+ invariant2(this._node, void 0, {
428
+ F: __dxlog_file,
429
+ L: 176,
784
430
  S: this,
785
431
  A: [
786
432
  "this._node",
@@ -796,9 +442,9 @@ var SheetModel = class extends Resource {
796
442
  });
797
443
  }
798
444
  cut(range) {
799
- invariant3(this._node, void 0, {
800
- F: __dxlog_file2,
801
- L: 182,
445
+ invariant2(this._node, void 0, {
446
+ F: __dxlog_file,
447
+ L: 187,
802
448
  S: this,
803
449
  A: [
804
450
  "this._node",
@@ -812,9 +458,9 @@ var SheetModel = class extends Resource {
812
458
  });
813
459
  }
814
460
  copy(range) {
815
- invariant3(this._node, void 0, {
816
- F: __dxlog_file2,
817
- L: 191,
461
+ invariant2(this._node, void 0, {
462
+ F: __dxlog_file,
463
+ L: 196,
818
464
  S: this,
819
465
  A: [
820
466
  "this._node",
@@ -824,9 +470,9 @@ var SheetModel = class extends Resource {
824
470
  this._node.graph.hf.copy(toModelRange(this._node.sheetId, range));
825
471
  }
826
472
  paste(cell) {
827
- invariant3(this._node, void 0, {
828
- F: __dxlog_file2,
829
- L: 196,
473
+ invariant2(this._node, void 0, {
474
+ F: __dxlog_file,
475
+ L: 201,
830
476
  S: this,
831
477
  A: [
832
478
  "this._node",
@@ -851,9 +497,9 @@ var SheetModel = class extends Resource {
851
497
  }
852
498
  // TODO(burdon): Display undo/redo state.
853
499
  undo() {
854
- invariant3(this._node, void 0, {
855
- F: __dxlog_file2,
856
- L: 211,
500
+ invariant2(this._node, void 0, {
501
+ F: __dxlog_file,
502
+ L: 216,
857
503
  S: this,
858
504
  A: [
859
505
  "this._node",
@@ -865,9 +511,9 @@ var SheetModel = class extends Resource {
865
511
  }
866
512
  }
867
513
  redo() {
868
- invariant3(this._node, void 0, {
869
- F: __dxlog_file2,
870
- L: 219,
514
+ invariant2(this._node, void 0, {
515
+ F: __dxlog_file,
516
+ L: 224,
871
517
  S: this,
872
518
  A: [
873
519
  "this._node",
@@ -893,7 +539,7 @@ var SheetModel = class extends Resource {
893
539
  if (value == null) {
894
540
  return void 0;
895
541
  }
896
- if (typeof value === "string" && value.charAt(0) === "=") {
542
+ if (isFormula(value)) {
897
543
  return this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value));
898
544
  } else {
899
545
  return String(value);
@@ -909,9 +555,9 @@ var SheetModel = class extends Resource {
909
555
  * Gets the regular or computed value from the engine.
910
556
  */
911
557
  getValue(cell) {
912
- invariant3(this._node, void 0, {
913
- F: __dxlog_file2,
914
- L: 262,
558
+ invariant2(this._node, void 0, {
559
+ F: __dxlog_file,
560
+ L: 267,
915
561
  S: this,
916
562
  A: [
917
563
  "this._node",
@@ -928,9 +574,9 @@ var SheetModel = class extends Resource {
928
574
  * Get value type.
929
575
  */
930
576
  getValueType(cell) {
931
- invariant3(this._node, void 0, {
932
- F: __dxlog_file2,
933
- L: 275,
577
+ invariant2(this._node, void 0, {
578
+ F: __dxlog_file,
579
+ L: 280,
934
580
  S: this,
935
581
  A: [
936
582
  "this._node",
@@ -945,9 +591,9 @@ var SheetModel = class extends Resource {
945
591
  * Sets the value, updating the sheet and engine.
946
592
  */
947
593
  setValue(cell, value) {
948
- invariant3(this._node, void 0, {
949
- F: __dxlog_file2,
950
- L: 285,
594
+ invariant2(this._node, void 0, {
595
+ F: __dxlog_file,
596
+ L: 290,
951
597
  S: this,
952
598
  A: [
953
599
  "this._node",
@@ -975,14 +621,14 @@ var SheetModel = class extends Resource {
975
621
  col: cell.col
976
622
  }, [
977
623
  [
978
- typeof value === "string" && value.charAt(0) === "=" ? this._graph.mapFormulaToNative(value) : value
624
+ isFormula(value) ? this._graph.mapFormulaToNative(value) : value
979
625
  ]
980
626
  ]);
981
627
  const idx = addressToIndex(this._sheet, cell);
982
628
  if (value === void 0 || value === null) {
983
629
  delete this._sheet.cells[idx];
984
630
  } else {
985
- if (typeof value === "string" && value.charAt(0) === "=") {
631
+ if (isFormula(value)) {
986
632
  value = this._graph.mapFunctionBindingToId(this.mapFormulaRefsToIndices(value));
987
633
  }
988
634
  this._sheet.cells[idx] = {
@@ -1042,12 +688,12 @@ var SheetModel = class extends Resource {
1042
688
  * Map from A1 notation to indices.
1043
689
  */
1044
690
  mapFormulaRefsToIndices(formula) {
1045
- invariant3(formula.charAt(0) === "=", void 0, {
1046
- F: __dxlog_file2,
1047
- L: 374,
691
+ invariant2(isFormula(formula), void 0, {
692
+ F: __dxlog_file,
693
+ L: 379,
1048
694
  S: this,
1049
695
  A: [
1050
- "formula.charAt(0) === '='",
696
+ "isFormula(formula)",
1051
697
  ""
1052
698
  ]
1053
699
  });
@@ -1059,12 +705,12 @@ var SheetModel = class extends Resource {
1059
705
  * Map from indices to A1 notation.
1060
706
  */
1061
707
  mapFormulaIndicesToRefs(formula) {
1062
- invariant3(formula.charAt(0) === "=", void 0, {
1063
- F: __dxlog_file2,
1064
- L: 384,
708
+ invariant2(isFormula(formula), void 0, {
709
+ F: __dxlog_file,
710
+ L: 389,
1065
711
  S: this,
1066
712
  A: [
1067
- "formula.charAt(0) === '='",
713
+ "isFormula(formula)",
1068
714
  ""
1069
715
  ]
1070
716
  });
@@ -1085,9 +731,9 @@ var SheetModel = class extends Resource {
1085
731
  return new Date(year, month - 1, day, hours, minutes, seconds);
1086
732
  }
1087
733
  toDateTime(num) {
1088
- invariant3(this._node, void 0, {
1089
- F: __dxlog_file2,
1090
- L: 405,
734
+ invariant2(this._node, void 0, {
735
+ F: __dxlog_file,
736
+ L: 410,
1091
737
  S: this,
1092
738
  A: [
1093
739
  "this._node",
@@ -1097,9 +743,9 @@ var SheetModel = class extends Resource {
1097
743
  return this._node.graph.hf.numberToDateTime(num);
1098
744
  }
1099
745
  toDate(num) {
1100
- invariant3(this._node, void 0, {
1101
- F: __dxlog_file2,
1102
- L: 410,
746
+ invariant2(this._node, void 0, {
747
+ F: __dxlog_file,
748
+ L: 415,
1103
749
  S: this,
1104
750
  A: [
1105
751
  "this._node",
@@ -1109,9 +755,9 @@ var SheetModel = class extends Resource {
1109
755
  return this._node.graph.hf.numberToDate(num);
1110
756
  }
1111
757
  toTime(num) {
1112
- invariant3(this._node, void 0, {
1113
- F: __dxlog_file2,
1114
- L: 415,
758
+ invariant2(this._node, void 0, {
759
+ F: __dxlog_file,
760
+ L: 420,
1115
761
  S: this,
1116
762
  A: [
1117
763
  "this._node",
@@ -1122,10 +768,11 @@ var SheetModel = class extends Resource {
1122
768
  }
1123
769
  };
1124
770
 
1125
- // packages/plugins/plugin-sheet/src/hooks/useSheetModel.ts
771
+ // packages/plugins/plugin-sheet/src/model/useSheetModel.ts
772
+ import { useEffect, useState } from "react";
1126
773
  var useSheetModel = (graph, sheet, { readonly } = {}) => {
1127
- const [model, setModel] = useState2();
1128
- useEffect2(() => {
774
+ const [model, setModel] = useState();
775
+ useEffect(() => {
1129
776
  if (!graph || !sheet) {
1130
777
  return;
1131
778
  }
@@ -1149,182 +796,377 @@ var useSheetModel = (graph, sheet, { readonly } = {}) => {
1149
796
  return model;
1150
797
  };
1151
798
 
1152
- // packages/plugins/plugin-sheet/src/hooks/threads.ts
1153
- import { effect } from "@preact/signals-core";
1154
- import { useCallback, useEffect as useEffect3, useMemo } from "react";
799
+ // packages/plugins/plugin-sheet/src/components/SheetContext/SheetContext.tsx
800
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/SheetContext/SheetContext.tsx";
801
+ var SheetContext = /* @__PURE__ */ createContext2(void 0);
802
+ var useSheetContext = () => {
803
+ const context = useContext2(SheetContext);
804
+ invariant3(context, void 0, {
805
+ F: __dxlog_file2,
806
+ L: 52,
807
+ S: void 0,
808
+ A: [
809
+ "context",
810
+ ""
811
+ ]
812
+ });
813
+ return context;
814
+ };
815
+ var SheetProviderImpl = ({ model, onInfo, children, __gridScope }) => {
816
+ const { id, editing, setEditing } = useGridContext("SheetProvider", __gridScope);
817
+ const [cursor, setCursorInternal] = useState2();
818
+ const [range, setRangeInternal] = useState2();
819
+ const [cursorFallbackRange, setCursorFallbackRange] = useState2();
820
+ const [activeRefs, setActiveRefs] = useState2("");
821
+ const setCursor = useCallback((nextCursor) => {
822
+ setCursorInternal(nextCursor);
823
+ setCursorFallbackRange(range?.to ? range : nextCursor ? {
824
+ from: nextCursor,
825
+ to: nextCursor
826
+ } : void 0);
827
+ }, [
828
+ range
829
+ ]);
830
+ const setRange = useCallback((nextRange) => {
831
+ setRangeInternal(nextRange);
832
+ setCursorFallbackRange(nextRange?.to ? nextRange : cursor ? {
833
+ from: cursor,
834
+ to: cursor
835
+ } : void 0);
836
+ }, [
837
+ cursor
838
+ ]);
839
+ return /* @__PURE__ */ React2.createElement(SheetContext.Provider, {
840
+ value: {
841
+ id,
842
+ model,
843
+ editing,
844
+ setEditing,
845
+ cursor,
846
+ setCursor,
847
+ range,
848
+ setRange,
849
+ cursorFallbackRange,
850
+ activeRefs,
851
+ setActiveRefs,
852
+ // TODO(burdon): Change to event.
853
+ onInfo
854
+ }
855
+ }, children);
856
+ };
857
+ var SheetProvider = ({ children, graph, sheet, readonly, onInfo }) => {
858
+ const model = useSheetModel(graph, sheet, {
859
+ readonly
860
+ });
861
+ return !model ? null : /* @__PURE__ */ React2.createElement(Grid.Root, {
862
+ id: fullyQualifiedId(sheet)
863
+ }, /* @__PURE__ */ React2.createElement(SheetProviderImpl, {
864
+ model,
865
+ onInfo
866
+ }, children));
867
+ };
868
+
869
+ // packages/plugins/plugin-sheet/src/components/GridSheet/GridSheet.tsx
870
+ import React4, { useCallback as useCallback3, useMemo as useMemo2, useRef, useState as useState4 } from "react";
871
+ import { DropdownMenu, Icon, useTranslation } from "@dxos/react-ui";
872
+ import { useAttention } from "@dxos/react-ui-attention";
873
+ import { closestCell, editorKeys, Grid as Grid2, GridCellEditor } from "@dxos/react-ui-grid";
874
+
875
+ // packages/plugins/plugin-sheet/src/components/GridSheet/util.ts
876
+ import { useEffect as useEffect3, useLayoutEffect, useState as useState3 } from "react";
877
+ import { createDocAccessor, fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
878
+ import { parseValue, cellClassesForFieldType } from "@dxos/react-ui-data";
879
+ import { colToA1Notation, rowToA1Notation, commentedClassName } from "@dxos/react-ui-grid";
880
+ import { mx as mx2 } from "@dxos/react-ui-theme";
881
+
882
+ // packages/plugins/plugin-sheet/src/integrations/thread-ranges.ts
883
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo } from "react";
1155
884
  import { LayoutAction, useIntentDispatcher, useIntentResolver } from "@dxos/app-framework";
1156
885
  import { debounce as debounce2 } from "@dxos/async";
1157
- import { fullyQualifiedId } from "@dxos/react-client/echo";
1158
- var useUpdateFocusedCellOnThreadSelection = (model, grid) => {
1159
- const handleScrollIntoView = useCallback(({ action, data }) => {
886
+ import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
887
+
888
+ // packages/plugins/plugin-sheet/src/components/index.ts
889
+ import { lazy } from "react";
890
+
891
+ // packages/plugins/plugin-sheet/src/components/RangeList/RangeList.tsx
892
+ import React3 from "react";
893
+ import { S } from "@dxos/echo-schema";
894
+ import { List } from "@dxos/react-ui-list";
895
+ import { ghostHover } from "@dxos/react-ui-theme";
896
+ var RangeList = ({ sheet, onSelect, onDelete }) => {
897
+ return /* @__PURE__ */ React3.createElement("div", {
898
+ className: "flex flex-col"
899
+ }, /* @__PURE__ */ React3.createElement(List.Root, {
900
+ items: sheet.ranges,
901
+ isItem: S.is(Range)
902
+ }, ({ items }) => items.map((item, i) => /* @__PURE__ */ React3.createElement(List.Item, {
903
+ key: i,
904
+ item,
905
+ classNames: [
906
+ "p-2",
907
+ ghostHover
908
+ ]
909
+ }, /* @__PURE__ */ React3.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React3.createElement(List.ItemTitle, {
910
+ onClick: () => onSelect?.(item)
911
+ }, rangeToA1Notation(rangeFromIndex(sheet, item.range))), onDelete && /* @__PURE__ */ React3.createElement(List.ItemDeleteButton, {
912
+ onClick: () => onDelete(item)
913
+ })))));
914
+ };
915
+
916
+ // packages/plugins/plugin-sheet/src/components/index.ts
917
+ var SheetContainer = lazy(() => import("./SheetContainer-JBB7W52Y.mjs"));
918
+
919
+ // packages/plugins/plugin-sheet/src/integrations/thread-ranges.ts
920
+ var completeCellRangeToThreadCursor = (range) => {
921
+ return `${range.from.col},${range.from.row},${range.to.col},${range.to.row}`;
922
+ };
923
+ var parseThreadAnchorAsCellRange = (cursor) => {
924
+ const coords = cursor.split(",");
925
+ if (coords.length !== 4) {
926
+ return null;
927
+ } else {
928
+ const [fromCol, fromRow, toCol, toRow] = coords;
929
+ return {
930
+ from: {
931
+ col: parseInt(fromCol),
932
+ row: parseInt(fromRow)
933
+ },
934
+ to: {
935
+ col: parseInt(toCol),
936
+ row: parseInt(toRow)
937
+ }
938
+ };
939
+ }
940
+ };
941
+ var useUpdateFocusedCellOnThreadSelection = (grid) => {
942
+ const { model, setActiveRefs } = useSheetContext();
943
+ const handleScrollIntoView = useCallback2(({ action, data }) => {
1160
944
  switch (action) {
1161
945
  case LayoutAction.SCROLL_INTO_VIEW: {
1162
- if (!data?.id || data?.cursor === void 0 || data?.id !== fullyQualifiedId(model.sheet)) {
946
+ if (!data?.id || data?.cursor === void 0 || data?.id !== fullyQualifiedId2(model.sheet)) {
1163
947
  return;
1164
948
  }
1165
- const cellAddress = addressFromIndex(model.sheet, data.cursor);
1166
- grid.current?.setFocus({
1167
- ...cellAddress,
949
+ setActiveRefs(data.thread);
950
+ const range = parseThreadAnchorAsCellRange(data.cursor);
951
+ range && grid.current?.setFocus({
952
+ ...range.to,
1168
953
  plane: "grid"
1169
954
  }, true);
1170
955
  }
1171
956
  }
1172
957
  }, [
1173
- model.sheet
958
+ model.sheet,
959
+ setActiveRefs
1174
960
  ]);
1175
961
  useIntentResolver(SHEET_PLUGIN, handleScrollIntoView);
1176
962
  };
1177
- var useSelectThreadOnCellFocus = (model, cursor) => {
963
+ var useSelectThreadOnCellFocus = () => {
964
+ const { model, cursor } = useSheetContext();
1178
965
  const dispatch = useIntentDispatcher();
1179
- const activeThreads = useMemo(() => model.sheet.threads?.filter((thread) => !!thread && thread.status === "active") ?? [], [
966
+ const threads = useMemo(() => model.sheet.threads?.filter((thread) => !!thread) ?? [], [
1180
967
  // TODO(thure): Surely we can find a better dependency for this…
1181
968
  JSON.stringify(model.sheet.threads)
1182
969
  ]);
1183
- const activeThreadAddresses = useMemo(() => activeThreads.map((thread) => thread.anchor).filter((anchor) => anchor !== void 0).map((anchor) => addressFromIndex(model.sheet, anchor)), [
1184
- activeThreads,
1185
- model.sheet
1186
- ]);
1187
- const selectClosestThread = useCallback((cellAddress) => {
1188
- if (!cellAddress || !activeThreads) {
970
+ const selectClosestThread = useCallback2((cellAddress) => {
971
+ if (!cellAddress || !threads) {
1189
972
  return;
1190
973
  }
1191
- const closestThreadAnchor = closest(cellAddress, activeThreadAddresses);
1192
- if (closestThreadAnchor) {
1193
- const closestThread = activeThreads.find((thread) => thread && thread.anchor === addressToIndex(model.sheet, closestThreadAnchor));
1194
- if (closestThread) {
1195
- void dispatch([
1196
- {
1197
- action: "dxos.org/plugin/thread/action/select",
1198
- data: {
1199
- current: fullyQualifiedId(closestThread)
1200
- }
1201
- }
1202
- ]);
974
+ const closestThread = threads?.find(({ anchor }) => {
975
+ if (anchor) {
976
+ const range = parseThreadAnchorAsCellRange(anchor);
977
+ return range ? inRange(range, cellAddress) : false;
978
+ } else {
979
+ return false;
1203
980
  }
981
+ });
982
+ if (closestThread) {
983
+ void dispatch([
984
+ {
985
+ action: "dxos.org/plugin/thread/action/select",
986
+ data: {
987
+ current: fullyQualifiedId2(closestThread)
988
+ }
989
+ }
990
+ ]);
1204
991
  }
1205
992
  }, [
1206
993
  dispatch,
1207
- activeThreads,
1208
- activeThreadAddresses,
1209
- model.sheet
994
+ threads
1210
995
  ]);
1211
996
  const debounced = useMemo(() => {
1212
997
  return debounce2((cellCoords) => requestAnimationFrame(() => selectClosestThread(cellCoords)), 50);
1213
998
  }, [
1214
999
  selectClosestThread
1215
1000
  ]);
1216
- useEffect3(() => {
1001
+ useEffect2(() => {
1217
1002
  if (!cursor) {
1218
1003
  return;
1219
1004
  }
1220
1005
  debounced(cursor);
1221
1006
  }, [
1222
1007
  cursor,
1223
- selectClosestThread
1008
+ debounced
1224
1009
  ]);
1225
1010
  };
1226
- var createThreadDecoration = (cellIndex, threadId, sheetId) => {
1011
+
1012
+ // packages/plugins/plugin-sheet/src/components/GridSheet/util.ts
1013
+ var dxGridCellIndexToSheetCellAddress = (index) => {
1014
+ const [colStr, rowStr] = index.split(",");
1227
1015
  return {
1228
- type: "comment",
1229
- classNames: [
1230
- "bg-greenFill"
1231
- ],
1232
- cellIndex
1016
+ col: parseInt(colStr),
1017
+ row: parseInt(rowStr)
1233
1018
  };
1234
1019
  };
1235
- var useThreadDecorations = (model, decorations) => {
1236
- const sheet = useMemo(() => model.sheet, [
1237
- model.sheet
1238
- ]);
1239
- const sheetId = useMemo(() => fullyQualifiedId(sheet), [
1240
- sheet
1241
- ]);
1242
- useEffect3(() => {
1243
- const unsubscribe = effect(() => {
1244
- const activeThreadAnchors = /* @__PURE__ */ new Set();
1245
- if (!sheet.threads) {
1246
- return;
1247
- }
1248
- for (const thread of sheet.threads) {
1249
- if (!thread || thread.anchor === void 0 || thread.status === "resolved") {
1250
- continue;
1251
- }
1252
- activeThreadAnchors.add(thread.anchor);
1253
- const index = thread.anchor;
1254
- const existingDecorations = decorations.getDecorationsForCell(index);
1255
- if (!existingDecorations || !existingDecorations.some((d) => d.type === "comment")) {
1256
- decorations.addDecoration(index, createThreadDecoration(index, thread.id, sheetId));
1257
- }
1258
- }
1259
- for (const decoration of decorations.getAllDecorations()) {
1260
- if (decoration.type !== "comment") {
1261
- continue;
1262
- }
1263
- if (!activeThreadAnchors.has(decoration.cellIndex)) {
1264
- decorations.removeDecoration(decoration.cellIndex, "comment");
1265
- }
1266
- }
1267
- });
1268
- return () => unsubscribe();
1020
+ var createDxGridColumns = (model) => {
1021
+ return model.sheet.columns.reduce((acc, columnId, numericIndex) => {
1022
+ if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {
1023
+ acc.grid[numericIndex] = {
1024
+ size: model.sheet.columnMeta[columnId].size,
1025
+ resizeable: true
1026
+ };
1027
+ }
1028
+ return acc;
1029
+ }, {
1030
+ grid: {}
1269
1031
  });
1270
1032
  };
1271
-
1272
- // packages/plugins/plugin-sheet/src/components/SheetContext/SheetContext.tsx
1273
- import React2, { createContext as createContext2, useContext, useMemo as useMemo2, useState as useState3 } from "react";
1274
- import { invariant as invariant4 } from "@dxos/invariant";
1275
- import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
1276
- import { Grid, useGridContext } from "@dxos/react-ui-grid";
1277
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/SheetContext/SheetContext.tsx";
1278
- var SheetContext = /* @__PURE__ */ createContext2(void 0);
1279
- var useSheetContext = () => {
1280
- const context = useContext(SheetContext);
1281
- invariant4(context, void 0, {
1282
- F: __dxlog_file3,
1283
- L: 45,
1284
- S: void 0,
1285
- A: [
1286
- "context",
1287
- ""
1288
- ]
1033
+ var createDxGridRows = (model) => {
1034
+ return model.sheet.rows.reduce((acc, rowId, numericIndex) => {
1035
+ if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {
1036
+ acc.grid[numericIndex] = {
1037
+ size: model.sheet.rowMeta[rowId].size,
1038
+ resizeable: true
1039
+ };
1040
+ }
1041
+ return acc;
1042
+ }, {
1043
+ grid: {}
1289
1044
  });
1290
- return context;
1291
1045
  };
1292
- var SheetProviderImpl = ({ model, onInfo, children, __gridScope }) => {
1293
- const { id, editing, setEditing } = useGridContext("SheetProvider", __gridScope);
1294
- const decorations = useMemo2(() => createDecorations(), []);
1295
- const [cursor, setCursor] = useState3();
1296
- const [range, setRange] = useState3();
1297
- useSelectThreadOnCellFocus(model, cursor);
1298
- useThreadDecorations(model, decorations);
1299
- return /* @__PURE__ */ React2.createElement(SheetContext.Provider, {
1300
- value: {
1301
- id,
1302
- model,
1303
- editing,
1304
- setEditing,
1305
- cursor,
1306
- setCursor,
1307
- range,
1308
- setRange,
1309
- // TODO(burdon): Change to event.
1310
- onInfo,
1311
- decorations
1046
+ var projectCellProps = (model, col, row) => {
1047
+ const address = {
1048
+ col,
1049
+ row
1050
+ };
1051
+ const rawValue = model.getValue(address);
1052
+ const ranges = model.sheet.ranges?.filter(({ range }) => inRange(rangeFromIndex(model.sheet, range), address));
1053
+ const threadRefs = model.sheet.threads?.filter((thread) => {
1054
+ const range = thread?.anchor && parseThreadAnchorAsCellRange(thread.anchor);
1055
+ return thread && range ? inRange(range, address) : false;
1056
+ }).map((thread) => fullyQualifiedId3(thread)).join(" ");
1057
+ const type = model.getValueType(address);
1058
+ const classNames = ranges?.map(cellClassNameForRange).reverse();
1059
+ return {
1060
+ value: parseValue(type, rawValue),
1061
+ className: mx2(cellClassesForFieldType(type), threadRefs && commentedClassName, classNames),
1062
+ dataRefs: threadRefs
1063
+ };
1064
+ };
1065
+ var gridCellGetter = (model) => {
1066
+ const cachedGridCells = {};
1067
+ return (nextBounds) => {
1068
+ [
1069
+ ...Array(nextBounds.end.col - nextBounds.start.col)
1070
+ ].forEach((_, c0) => {
1071
+ return [
1072
+ ...Array(nextBounds.end.row - nextBounds.start.row)
1073
+ ].forEach((_2, r0) => {
1074
+ const col = nextBounds.start.col + c0;
1075
+ const row = nextBounds.start.row + r0;
1076
+ cachedGridCells[`${col},${row}`] = projectCellProps(model, col, row);
1077
+ });
1078
+ });
1079
+ return cachedGridCells;
1080
+ };
1081
+ };
1082
+ var rowLabelCell = (row) => ({
1083
+ value: rowToA1Notation(row),
1084
+ className: "text-end !pie-1",
1085
+ resizeHandle: "row"
1086
+ });
1087
+ var colLabelCell = (col) => ({
1088
+ value: colToA1Notation(col),
1089
+ resizeHandle: "col"
1090
+ });
1091
+ var cellGetter = (model) => {
1092
+ const getGridCells = gridCellGetter(model);
1093
+ return (nextBounds, plane) => {
1094
+ switch (plane) {
1095
+ case "grid":
1096
+ return getGridCells(nextBounds);
1097
+ case "frozenColsStart":
1098
+ return [
1099
+ ...Array(nextBounds.end.row - nextBounds.start.row)
1100
+ ].reduce((acc, _, r0) => {
1101
+ const r = nextBounds.start.row + r0;
1102
+ acc[`0,${r}`] = rowLabelCell(r);
1103
+ return acc;
1104
+ }, {});
1105
+ case "frozenRowsStart":
1106
+ return [
1107
+ ...Array(nextBounds.end.col - nextBounds.start.col)
1108
+ ].reduce((acc, _, c0) => {
1109
+ const c = nextBounds.start.col + c0;
1110
+ acc[`${c},0`] = colLabelCell(c);
1111
+ return acc;
1112
+ }, {});
1113
+ default:
1114
+ return {};
1312
1115
  }
1313
- }, children);
1116
+ };
1314
1117
  };
1315
- var SheetProvider = ({ children, graph, sheet, readonly, onInfo }) => {
1316
- const model = useSheetModel(graph, sheet, {
1317
- readonly
1318
- });
1319
- return !model ? null : /* @__PURE__ */ React2.createElement(Grid.Root, {
1320
- id: fullyQualifiedId2(sheet)
1321
- }, /* @__PURE__ */ React2.createElement(SheetProviderImpl, {
1322
- model,
1323
- onInfo
1324
- }, children));
1118
+ var useSheetModelDxGridProps = (dxGridRef, model) => {
1119
+ const [columns, setColumns] = useState3(createDxGridColumns(model));
1120
+ const [rows, setRows] = useState3(createDxGridColumns(model));
1121
+ useLayoutEffect(() => {
1122
+ const cellsAccessor = createDocAccessor(model.sheet, [
1123
+ "cells"
1124
+ ]);
1125
+ if (dxGridRef.current) {
1126
+ dxGridRef.current.getCells = cellGetter(model);
1127
+ }
1128
+ const handleCellsUpdate = () => {
1129
+ dxGridRef.current?.requestUpdate("initialCells");
1130
+ };
1131
+ cellsAccessor.handle.addListener("change", handleCellsUpdate);
1132
+ return () => cellsAccessor.handle.removeListener("change", handleCellsUpdate);
1133
+ }, [
1134
+ model
1135
+ ]);
1136
+ useEffect3(() => {
1137
+ const columnMetaAccessor = createDocAccessor(model.sheet, [
1138
+ "columnMeta"
1139
+ ]);
1140
+ const rowMetaAccessor = createDocAccessor(model.sheet, [
1141
+ "rowMeta"
1142
+ ]);
1143
+ const handleColumnMetaUpdate = () => {
1144
+ setColumns(createDxGridColumns(model));
1145
+ };
1146
+ const handleRowMetaUpdate = () => {
1147
+ setRows(createDxGridRows(model));
1148
+ };
1149
+ columnMetaAccessor.handle.addListener("change", handleColumnMetaUpdate);
1150
+ rowMetaAccessor.handle.addListener("change", handleRowMetaUpdate);
1151
+ return () => {
1152
+ columnMetaAccessor.handle.removeListener("change", handleColumnMetaUpdate);
1153
+ rowMetaAccessor.handle.removeListener("change", handleRowMetaUpdate);
1154
+ };
1155
+ }, [
1156
+ model
1157
+ ]);
1158
+ return {
1159
+ columns,
1160
+ rows
1161
+ };
1325
1162
  };
1326
1163
 
1327
1164
  // packages/plugins/plugin-sheet/src/components/GridSheet/GridSheet.tsx
1165
+ var inertPosition = {
1166
+ plane: "grid",
1167
+ col: 0,
1168
+ row: 0
1169
+ };
1328
1170
  var initialCells = {
1329
1171
  grid: {},
1330
1172
  frozenColsStart: [
@@ -1365,11 +1207,12 @@ var sheetColDefault = {
1365
1207
  }
1366
1208
  };
1367
1209
  var GridSheet = () => {
1368
- const { id, model, editing, setEditing, setCursor, setRange, range, cursor } = useSheetContext();
1210
+ const { t } = useTranslation(SHEET_PLUGIN);
1211
+ const { id, model, editing, setEditing, setCursor, setRange, cursor, cursorFallbackRange, activeRefs } = useSheetContext();
1369
1212
  const dxGrid = useRef(null);
1370
- const rangeNotifier = useRef();
1213
+ const rangeController = useRef();
1371
1214
  const { hasAttention } = useAttention(id);
1372
- const handleFocus = useCallback2((event) => {
1215
+ const handleFocus = useCallback3((event) => {
1373
1216
  if (!editing) {
1374
1217
  const cell = closestCell(event.target);
1375
1218
  if (cell && cell.plane === "grid") {
@@ -1382,7 +1225,7 @@ var GridSheet = () => {
1382
1225
  }, [
1383
1226
  editing
1384
1227
  ]);
1385
- const handleClose = useCallback2((value, { key, shift }) => {
1228
+ const handleClose = useCallback3((value, { key, shift }) => {
1386
1229
  if (value !== void 0) {
1387
1230
  model.setValue(dxGridCellIndexToSheetCellAddress(editing.index), value);
1388
1231
  }
@@ -1403,10 +1246,18 @@ var GridSheet = () => {
1403
1246
  dxGrid.current?.refocus(axis, delta);
1404
1247
  }, [
1405
1248
  model,
1406
- editing,
1407
- setEditing
1249
+ editing
1250
+ ]);
1251
+ const handleBlur = useCallback3((value) => {
1252
+ if (value !== void 0) {
1253
+ model.setValue(dxGridCellIndexToSheetCellAddress(editing.index), value);
1254
+ }
1255
+ setEditing(null);
1256
+ }, [
1257
+ model,
1258
+ editing
1408
1259
  ]);
1409
- const handleAxisResize = useCallback2(({ axis, size, index: numericIndex }) => {
1260
+ const handleAxisResize = useCallback3(({ axis, size, index: numericIndex }) => {
1410
1261
  if (axis === "row") {
1411
1262
  const rowId = model.sheet.rows[parseInt(numericIndex)];
1412
1263
  model.sheet.rowMeta[rowId] ??= {};
@@ -1419,39 +1270,35 @@ var GridSheet = () => {
1419
1270
  }, [
1420
1271
  model
1421
1272
  ]);
1422
- const handleSelect = useCallback2(({ minCol, maxCol, minRow, maxRow }) => {
1423
- const range2 = {
1273
+ const handleSelect = useCallback3(({ minCol, maxCol, minRow, maxRow }) => {
1274
+ const range = {
1424
1275
  from: {
1425
1276
  col: minCol,
1426
1277
  row: minRow
1427
1278
  }
1428
1279
  };
1429
1280
  if (minCol !== maxCol || minRow !== maxRow) {
1430
- range2.to = {
1281
+ range.to = {
1431
1282
  col: maxCol,
1432
1283
  row: maxRow
1433
1284
  };
1434
1285
  }
1435
1286
  if (editing) {
1436
- rangeNotifier.current?.(rangeToA1Notation(range2));
1287
+ rangeController.current?.setRange(rangeToA1Notation(range));
1437
1288
  } else {
1438
- setRange(range2.to ? range2 : void 0);
1289
+ setRange(range.to ? range : void 0);
1439
1290
  }
1440
1291
  }, [
1441
1292
  editing
1442
1293
  ]);
1443
- const handleWheel = useCallback2((event) => {
1294
+ const handleWheel = useCallback3((event) => {
1444
1295
  if (!hasAttention) {
1445
1296
  event.stopPropagation();
1446
1297
  }
1447
1298
  }, [
1448
1299
  hasAttention
1449
1300
  ]);
1450
- const handleKeyDown = useCallback2((event) => {
1451
- const cursorFallbackRange = range ?? cursor ? {
1452
- from: cursor,
1453
- to: cursor
1454
- } : null;
1301
+ const handleKeyDown = useCallback3((event) => {
1455
1302
  switch (event.key) {
1456
1303
  case "Backspace":
1457
1304
  case "Delete":
@@ -1482,12 +1329,36 @@ var GridSheet = () => {
1482
1329
  }
1483
1330
  }
1484
1331
  }, [
1485
- range,
1332
+ cursorFallbackRange,
1486
1333
  model,
1487
1334
  cursor
1488
1335
  ]);
1336
+ const contextMenuAnchorRef = useRef(null);
1337
+ const [contextMenuOpen, setContextMenuOpen] = useState4(null);
1338
+ const contextMenuAxis = contextMenuOpen?.plane.startsWith("frozenRows") ? "col" : "row";
1339
+ const handleContextMenu = useCallback3((event) => {
1340
+ const cell = closestCell(event.target);
1341
+ if (cell && cell.plane.startsWith("frozen")) {
1342
+ event.preventDefault();
1343
+ contextMenuAnchorRef.current = event.target;
1344
+ setContextMenuOpen(cell);
1345
+ }
1346
+ }, []);
1347
+ const handleAxisMenuAction = useCallback3((operation) => {
1348
+ switch (operation) {
1349
+ case "add-before":
1350
+ case "add-after":
1351
+ model[contextMenuAxis === "col" ? "insertColumns" : "insertRows"](contextMenuOpen[contextMenuAxis] + (operation === "add-before" ? 0 : 1), 1);
1352
+ break;
1353
+ case "remove":
1354
+ }
1355
+ }, [
1356
+ contextMenuAxis,
1357
+ contextMenuOpen,
1358
+ model
1359
+ ]);
1489
1360
  const { columns, rows } = useSheetModelDxGridProps(dxGrid, model);
1490
- const extension = useMemo3(() => [
1361
+ const extension = useMemo2(() => [
1491
1362
  editorKeys({
1492
1363
  onClose: handleClose,
1493
1364
  ...editing?.initialContent && {
@@ -1497,23 +1368,32 @@ var GridSheet = () => {
1497
1368
  sheetExtension({
1498
1369
  functions: model.graph.getFunctions()
1499
1370
  }),
1500
- rangeExtension((fn) => rangeNotifier.current = fn)
1371
+ rangeExtension({
1372
+ onInit: (fn) => rangeController.current = fn,
1373
+ onStateChange: (state) => {
1374
+ if (dxGrid.current) {
1375
+ dxGrid.current.mode = typeof state.activeRange === "undefined" ? "edit" : "edit-select";
1376
+ }
1377
+ }
1378
+ })
1501
1379
  ], [
1502
1380
  model,
1503
1381
  handleClose,
1504
1382
  editing
1505
1383
  ]);
1506
- const getCellContent = useCallback2((index) => {
1384
+ const getCellContent = useCallback3((index) => {
1507
1385
  const cell = dxGridCellIndexToSheetCellAddress(index);
1508
1386
  return model.getCellText(cell);
1509
1387
  }, [
1510
1388
  model
1511
1389
  ]);
1512
- useUpdateFocusedCellOnThreadSelection(model, dxGrid);
1513
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(GridCellEditor, {
1390
+ useUpdateFocusedCellOnThreadSelection(dxGrid);
1391
+ useSelectThreadOnCellFocus();
1392
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(GridCellEditor, {
1514
1393
  getCellContent,
1515
- extension
1516
- }), /* @__PURE__ */ React3.createElement(Grid2.Content, {
1394
+ extension,
1395
+ onBlur: handleBlur
1396
+ }), /* @__PURE__ */ React4.createElement(Grid2.Content, {
1517
1397
  initialCells,
1518
1398
  limitColumns: DEFAULT_COLUMNS,
1519
1399
  limitRows: DEFAULT_ROWS,
@@ -1527,44 +1407,49 @@ var GridSheet = () => {
1527
1407
  onFocus: handleFocus,
1528
1408
  onWheelCapture: handleWheel,
1529
1409
  onKeyDown: handleKeyDown,
1410
+ onContextMenu: handleContextMenu,
1530
1411
  overscroll: "inline",
1531
1412
  className: "[--dx-grid-base:var(--surface-bg)]",
1413
+ activeRefs,
1532
1414
  ref: dxGrid
1533
- }));
1534
- };
1535
-
1536
- // packages/plugins/plugin-sheet/src/components/index.ts
1537
- var SheetContainer = lazy(() => import("./SheetContainer-AKWROARP.mjs"));
1538
-
1539
- // packages/plugins/plugin-sheet/src/hooks/useComputeGraph.ts
1540
- var useComputeGraph = (space) => {
1541
- const { registry } = useContext2(ComputeGraphContext) ?? raise(new Error("Missing ComputeGraphContext"));
1542
- const [graph] = useAsyncState(async () => {
1543
- if (space) {
1544
- const graph2 = registry.getOrCreateGraph(space);
1545
- await graph2.open();
1546
- return graph2;
1547
- }
1548
- }, [
1549
- space,
1550
- registry
1551
- ]);
1552
- return graph;
1415
+ }), /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
1416
+ modal: false,
1417
+ open: !!contextMenuOpen,
1418
+ onOpenChange: (nextOpen) => setContextMenuOpen(nextOpen ? inertPosition : null)
1419
+ }, /* @__PURE__ */ React4.createElement(DropdownMenu.VirtualTrigger, {
1420
+ virtualRef: contextMenuAnchorRef
1421
+ }), /* @__PURE__ */ React4.createElement(DropdownMenu.Content, {
1422
+ side: contextMenuAxis === "col" ? "bottom" : "right",
1423
+ sideOffset: 4,
1424
+ collisionPadding: 8
1425
+ }, /* @__PURE__ */ React4.createElement(DropdownMenu.Viewport, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
1426
+ onClick: () => handleAxisMenuAction("add-before")
1427
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1428
+ size: 5,
1429
+ icon: contextMenuAxis === "col" ? "ph--columns-plus-left--regular" : "ph--rows-plus-top--regular"
1430
+ }), /* @__PURE__ */ React4.createElement("span", null, t(`add ${contextMenuAxis} before label`))), /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
1431
+ onClick: () => handleAxisMenuAction("add-after")
1432
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1433
+ size: 5,
1434
+ icon: contextMenuAxis === "col" ? "ph--columns-plus-right--regular" : "ph--rows-plus-bottom--regular"
1435
+ }), /* @__PURE__ */ React4.createElement("span", null, t(`add ${contextMenuAxis} after label`))), /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
1436
+ disabled: true,
1437
+ onClick: () => handleAxisMenuAction("remove")
1438
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1439
+ size: 5,
1440
+ icon: "ph--backspace--regular"
1441
+ }), /* @__PURE__ */ React4.createElement("span", null, t(`delete ${contextMenuAxis} label`)))), /* @__PURE__ */ React4.createElement(DropdownMenu.Arrow, null))));
1553
1442
  };
1554
1443
 
1555
1444
  export {
1556
1445
  ComputeGraphContextProvider,
1557
- addressToA1Notation,
1558
- rangeToA1Notation,
1559
- inRange,
1560
- createSheet,
1561
- addressToIndex,
1562
- compareIndexPositions,
1563
- computeGraphFacet,
1564
1446
  useComputeGraph,
1447
+ completeCellRangeToThreadCursor,
1448
+ computeGraphFacet,
1565
1449
  useSheetContext,
1566
1450
  SheetProvider,
1567
1451
  GridSheet,
1452
+ RangeList,
1568
1453
  SheetContainer
1569
1454
  };
1570
- //# sourceMappingURL=chunk-FGMFOW6U.mjs.map
1455
+ //# sourceMappingURL=chunk-XXDHBYZQ.mjs.map