@dxos/plugin-sheet 0.6.14-main.7bd9c89 → 0.6.14-staging.54a8bab

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 (231) hide show
  1. package/dist/lib/browser/{SheetContainer-AKWROARP.mjs → SheetContainer-JZEKRM4Z.mjs} +83 -76
  2. package/dist/lib/browser/SheetContainer-JZEKRM4Z.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-BWN5DZWZ.mjs → chunk-BVUN7SHF.mjs} +6 -13
  4. package/dist/lib/browser/chunk-BVUN7SHF.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-FGMFOW6U.mjs → chunk-G2FUL6PK.mjs} +791 -690
  6. package/dist/lib/browser/chunk-G2FUL6PK.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-D3QTX46O.mjs → chunk-RABELMEQ.mjs} +3 -2
  8. package/dist/lib/browser/{chunk-D3QTX46O.mjs.map → chunk-RABELMEQ.mjs.map} +3 -3
  9. package/dist/lib/browser/{chunk-GSV5QNLD.mjs → chunk-VMSX6Z4X.mjs} +297 -44
  10. package/dist/lib/browser/chunk-VMSX6Z4X.mjs.map +7 -0
  11. package/dist/lib/browser/{graph-M4IQ76QX.mjs → compute-graph-GGWUX644.mjs} +4 -2
  12. package/dist/lib/browser/index.mjs +91 -21
  13. package/dist/lib/browser/index.mjs.map +4 -4
  14. package/dist/lib/browser/meta.json +1 -1
  15. package/dist/lib/browser/meta.mjs +1 -1
  16. package/dist/lib/browser/types.mjs +2 -2
  17. package/dist/lib/node/{SheetContainer-N5IQGEFL.cjs → SheetContainer-PJE74VO4.cjs} +81 -81
  18. package/dist/lib/node/SheetContainer-PJE74VO4.cjs.map +7 -0
  19. package/dist/lib/node/{chunk-QIFIGEKV.cjs → chunk-2ZVZI2KJ.cjs} +6 -5
  20. package/dist/lib/node/{chunk-QIFIGEKV.cjs.map → chunk-2ZVZI2KJ.cjs.map} +3 -3
  21. package/dist/lib/node/{chunk-NZARD7UP.cjs → chunk-AWKOWDMI.cjs} +10 -17
  22. package/dist/lib/node/chunk-AWKOWDMI.cjs.map +7 -0
  23. package/dist/lib/node/{chunk-5XPK2V4A.cjs → chunk-O7XR4R7Y.cjs} +306 -42
  24. package/dist/lib/node/chunk-O7XR4R7Y.cjs.map +7 -0
  25. package/dist/lib/node/{chunk-53BMSUIK.cjs → chunk-STZ7S7RF.cjs} +755 -668
  26. package/dist/lib/node/chunk-STZ7S7RF.cjs.map +7 -0
  27. package/dist/lib/node/{graph-Q3N2X26H.cjs → compute-graph-KGWA2QLE.cjs} +21 -19
  28. package/dist/lib/node/compute-graph-KGWA2QLE.cjs.map +7 -0
  29. package/dist/lib/node/index.cjs +109 -42
  30. package/dist/lib/node/index.cjs.map +4 -4
  31. package/dist/lib/node/meta.cjs +3 -3
  32. package/dist/lib/node/meta.cjs.map +1 -1
  33. package/dist/lib/node/meta.json +1 -1
  34. package/dist/lib/node/types.cjs +7 -7
  35. package/dist/lib/node/types.cjs.map +1 -1
  36. package/dist/lib/node-esm/{SheetContainer-46PBMF2E.mjs → SheetContainer-R73XEXHU.mjs} +83 -76
  37. package/dist/lib/node-esm/SheetContainer-R73XEXHU.mjs.map +7 -0
  38. package/dist/lib/node-esm/{chunk-VCYJWE3O.mjs → chunk-BM2Q3FFC.mjs} +3 -2
  39. package/dist/lib/node-esm/{chunk-VCYJWE3O.mjs.map → chunk-BM2Q3FFC.mjs.map} +3 -3
  40. package/dist/lib/node-esm/{chunk-5WPZCXNS.mjs → chunk-CR4K75EL.mjs} +296 -44
  41. package/dist/lib/node-esm/chunk-CR4K75EL.mjs.map +7 -0
  42. package/dist/lib/node-esm/{chunk-WFDTY3IC.mjs → chunk-UIBWRHW7.mjs} +6 -13
  43. package/dist/lib/node-esm/chunk-UIBWRHW7.mjs.map +7 -0
  44. package/dist/lib/node-esm/{chunk-T3PRH7QS.mjs → chunk-V5N3Y2O5.mjs} +791 -690
  45. package/dist/lib/node-esm/chunk-V5N3Y2O5.mjs.map +7 -0
  46. package/dist/lib/node-esm/{graph-SMPUMOV2.mjs → compute-graph-2SCZT7N5.mjs} +4 -2
  47. package/dist/lib/node-esm/index.mjs +91 -21
  48. package/dist/lib/node-esm/index.mjs.map +4 -4
  49. package/dist/lib/node-esm/meta.json +1 -1
  50. package/dist/lib/node-esm/meta.mjs +1 -1
  51. package/dist/lib/node-esm/types.mjs +2 -2
  52. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  53. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +3 -1
  54. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -1
  55. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -1
  56. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -1
  57. package/dist/types/src/components/GridSheet/util.d.ts +1 -2
  58. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -1
  59. package/dist/types/src/components/RangeList/RangeList.d.ts +7 -0
  60. package/dist/types/src/components/RangeList/RangeList.d.ts.map +1 -0
  61. package/dist/types/src/components/RangeList/index.d.ts +2 -0
  62. package/dist/types/src/components/RangeList/index.d.ts.map +1 -0
  63. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts +6 -3
  64. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts.map +1 -1
  65. package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts.map +1 -1
  66. package/dist/types/src/components/SheetContext/SheetContext.d.ts +7 -5
  67. package/dist/types/src/components/SheetContext/SheetContext.d.ts.map +1 -1
  68. package/dist/types/src/components/Toolbar/Toolbar.d.ts +6 -3
  69. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  70. package/dist/types/src/components/index.d.ts +5 -2
  71. package/dist/types/src/components/index.d.ts.map +1 -1
  72. package/dist/types/src/compute-graph/compute-graph-registry.d.ts.map +1 -0
  73. package/dist/types/src/{graph → compute-graph}/compute-graph.d.ts +3 -3
  74. package/dist/types/src/compute-graph/compute-graph.d.ts.map +1 -0
  75. package/dist/types/src/compute-graph/compute-graph.stories.d.ts.map +1 -0
  76. package/dist/types/src/compute-graph/compute-graph.test.d.ts.map +1 -0
  77. package/dist/types/src/compute-graph/compute-node.d.ts.map +1 -0
  78. package/dist/types/src/compute-graph/functions/async-function.d.ts.map +1 -0
  79. package/dist/types/src/compute-graph/functions/edge-function.d.ts.map +1 -0
  80. package/dist/types/src/compute-graph/functions/function-defs.d.ts.map +1 -0
  81. package/dist/types/src/compute-graph/functions/index.d.ts.map +1 -0
  82. package/dist/types/src/compute-graph/hyperformula.test.d.ts.map +1 -0
  83. package/dist/types/src/compute-graph/index.d.ts.map +1 -0
  84. package/dist/types/src/compute-graph/testing/index.d.ts.map +1 -0
  85. package/dist/types/src/compute-graph/testing/test-builder.d.ts.map +1 -0
  86. package/dist/types/src/compute-graph/testing/test-plugin.d.ts.map +1 -0
  87. package/dist/types/src/compute-graph/util.d.ts.map +1 -0
  88. package/dist/types/src/defs/index.d.ts +1 -1
  89. package/dist/types/src/defs/index.d.ts.map +1 -1
  90. package/dist/types/src/defs/sheet-range-types.d.ts +2 -2
  91. package/dist/types/src/defs/sheet-range-types.d.ts.map +1 -1
  92. package/dist/types/src/defs/types.d.ts +6 -0
  93. package/dist/types/src/defs/types.d.ts.map +1 -1
  94. package/dist/types/src/defs/util.d.ts +3 -7
  95. package/dist/types/src/defs/util.d.ts.map +1 -1
  96. package/dist/types/src/extensions/compute.d.ts +1 -1
  97. package/dist/types/src/extensions/compute.d.ts.map +1 -1
  98. package/dist/types/src/extensions/editor/extension.d.ts +23 -3
  99. package/dist/types/src/extensions/editor/extension.d.ts.map +1 -1
  100. package/dist/types/src/index.d.ts +1 -1
  101. package/dist/types/src/index.d.ts.map +1 -1
  102. package/dist/types/src/integrations/index.d.ts +2 -0
  103. package/dist/types/src/integrations/index.d.ts.map +1 -0
  104. package/dist/types/src/integrations/thread-ranges.d.ts +7 -0
  105. package/dist/types/src/integrations/thread-ranges.d.ts.map +1 -0
  106. package/dist/types/src/meta.d.ts +1 -0
  107. package/dist/types/src/meta.d.ts.map +1 -1
  108. package/dist/types/src/model/index.d.ts +1 -1
  109. package/dist/types/src/model/index.d.ts.map +1 -1
  110. package/dist/types/src/model/sheet-model.d.ts +13 -6
  111. package/dist/types/src/model/sheet-model.d.ts.map +1 -1
  112. package/dist/types/src/{hooks → model}/useSheetModel.d.ts +1 -1
  113. package/dist/types/src/model/useSheetModel.d.ts.map +1 -0
  114. package/dist/types/src/serializer.d.ts +4 -0
  115. package/dist/types/src/serializer.d.ts.map +1 -0
  116. package/dist/types/src/testing/testing.d.ts +1 -1
  117. package/dist/types/src/testing/testing.d.ts.map +1 -1
  118. package/dist/types/src/translations.d.ts +18 -3
  119. package/dist/types/src/translations.d.ts.map +1 -1
  120. package/dist/types/src/types.d.ts +37 -33
  121. package/dist/types/src/types.d.ts.map +1 -1
  122. package/package.json +43 -50
  123. package/src/SheetPlugin.tsx +45 -12
  124. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +19 -2
  125. package/src/components/FunctionEditor/FunctionEditor.tsx +5 -5
  126. package/src/components/GridSheet/GridSheet.stories.tsx +3 -1
  127. package/src/components/GridSheet/GridSheet.tsx +181 -24
  128. package/src/components/GridSheet/SheetCellEditor.stories.tsx +1 -1
  129. package/src/components/GridSheet/util.ts +34 -18
  130. package/src/components/RangeList/RangeList.tsx +53 -0
  131. package/src/components/RangeList/index.ts +5 -0
  132. package/src/components/SheetContainer/SheetContainer.stories.tsx +5 -3
  133. package/src/components/SheetContainer/SheetContainer.tsx +10 -4
  134. package/src/components/SheetContext/SheetContext.tsx +43 -20
  135. package/src/components/Toolbar/Toolbar.tsx +98 -74
  136. package/src/components/index.ts +1 -0
  137. package/src/{graph → compute-graph}/compute-graph.stories.tsx +2 -1
  138. package/src/{graph → compute-graph}/compute-graph.ts +27 -9
  139. package/src/{graph → compute-graph}/compute-node.ts +2 -3
  140. package/src/{graph → compute-graph}/functions/async-function.ts +1 -0
  141. package/src/{graph → compute-graph}/functions/edge-function.ts +5 -3
  142. package/src/defs/index.ts +1 -1
  143. package/src/defs/sheet-range-types.ts +9 -6
  144. package/src/defs/types.ts +6 -1
  145. package/src/defs/util.ts +4 -19
  146. package/src/extensions/compute.stories.tsx +2 -2
  147. package/src/extensions/compute.ts +2 -2
  148. package/src/extensions/editor/extension.test.ts +1 -1
  149. package/src/extensions/editor/extension.ts +48 -23
  150. package/src/index.ts +2 -2
  151. package/src/integrations/index.ts +5 -0
  152. package/src/integrations/thread-ranges.ts +101 -0
  153. package/src/meta.ts +1 -0
  154. package/src/model/index.ts +1 -1
  155. package/src/model/sheet-model.test.ts +6 -4
  156. package/src/model/sheet-model.ts +103 -26
  157. package/src/{hooks → model}/useSheetModel.ts +1 -1
  158. package/src/serializer.ts +27 -0
  159. package/src/testing/testing.tsx +1 -1
  160. package/src/translations.ts +18 -3
  161. package/src/types.ts +24 -2
  162. package/dist/lib/browser/SheetContainer-AKWROARP.mjs.map +0 -7
  163. package/dist/lib/browser/chunk-BWN5DZWZ.mjs.map +0 -7
  164. package/dist/lib/browser/chunk-FGMFOW6U.mjs.map +0 -7
  165. package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +0 -7
  166. package/dist/lib/node/SheetContainer-N5IQGEFL.cjs.map +0 -7
  167. package/dist/lib/node/chunk-53BMSUIK.cjs.map +0 -7
  168. package/dist/lib/node/chunk-5XPK2V4A.cjs.map +0 -7
  169. package/dist/lib/node/chunk-NZARD7UP.cjs.map +0 -7
  170. package/dist/lib/node/graph-Q3N2X26H.cjs.map +0 -7
  171. package/dist/lib/node-esm/SheetContainer-46PBMF2E.mjs.map +0 -7
  172. package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +0 -7
  173. package/dist/lib/node-esm/chunk-T3PRH7QS.mjs.map +0 -7
  174. package/dist/lib/node-esm/chunk-WFDTY3IC.mjs.map +0 -7
  175. package/dist/types/src/graph/compute-graph-registry.d.ts.map +0 -1
  176. package/dist/types/src/graph/compute-graph.d.ts.map +0 -1
  177. package/dist/types/src/graph/compute-graph.stories.d.ts.map +0 -1
  178. package/dist/types/src/graph/compute-graph.test.d.ts.map +0 -1
  179. package/dist/types/src/graph/compute-node.d.ts.map +0 -1
  180. package/dist/types/src/graph/functions/async-function.d.ts.map +0 -1
  181. package/dist/types/src/graph/functions/edge-function.d.ts.map +0 -1
  182. package/dist/types/src/graph/functions/function-defs.d.ts.map +0 -1
  183. package/dist/types/src/graph/functions/index.d.ts.map +0 -1
  184. package/dist/types/src/graph/hyperformula.test.d.ts.map +0 -1
  185. package/dist/types/src/graph/index.d.ts.map +0 -1
  186. package/dist/types/src/graph/testing/index.d.ts.map +0 -1
  187. package/dist/types/src/graph/testing/test-builder.d.ts.map +0 -1
  188. package/dist/types/src/graph/testing/test-plugin.d.ts.map +0 -1
  189. package/dist/types/src/graph/util.d.ts.map +0 -1
  190. package/dist/types/src/hooks/hooks.stories.d.ts +0 -6
  191. package/dist/types/src/hooks/hooks.stories.d.ts.map +0 -1
  192. package/dist/types/src/hooks/index.d.ts +0 -4
  193. package/dist/types/src/hooks/index.d.ts.map +0 -1
  194. package/dist/types/src/hooks/threads.d.ts +0 -8
  195. package/dist/types/src/hooks/threads.d.ts.map +0 -1
  196. package/dist/types/src/hooks/useComputeGraph.d.ts +0 -7
  197. package/dist/types/src/hooks/useComputeGraph.d.ts.map +0 -1
  198. package/dist/types/src/hooks/useSheetModel.d.ts.map +0 -1
  199. package/dist/types/src/model/decorations.d.ts +0 -26
  200. package/dist/types/src/model/decorations.d.ts.map +0 -1
  201. package/src/hooks/hooks.stories.tsx +0 -53
  202. package/src/hooks/index.ts +0 -7
  203. package/src/hooks/threads.ts +0 -147
  204. package/src/hooks/useComputeGraph.ts +0 -28
  205. package/src/model/decorations.ts +0 -66
  206. /package/dist/lib/browser/{graph-M4IQ76QX.mjs.map → compute-graph-GGWUX644.mjs.map} +0 -0
  207. /package/dist/lib/node-esm/{graph-SMPUMOV2.mjs.map → compute-graph-2SCZT7N5.mjs.map} +0 -0
  208. /package/dist/types/src/{graph → compute-graph}/compute-graph-registry.d.ts +0 -0
  209. /package/dist/types/src/{graph → compute-graph}/compute-graph.stories.d.ts +0 -0
  210. /package/dist/types/src/{graph → compute-graph}/compute-graph.test.d.ts +0 -0
  211. /package/dist/types/src/{graph → compute-graph}/compute-node.d.ts +0 -0
  212. /package/dist/types/src/{graph → compute-graph}/functions/async-function.d.ts +0 -0
  213. /package/dist/types/src/{graph → compute-graph}/functions/edge-function.d.ts +0 -0
  214. /package/dist/types/src/{graph → compute-graph}/functions/function-defs.d.ts +0 -0
  215. /package/dist/types/src/{graph → compute-graph}/functions/index.d.ts +0 -0
  216. /package/dist/types/src/{graph → compute-graph}/hyperformula.test.d.ts +0 -0
  217. /package/dist/types/src/{graph → compute-graph}/index.d.ts +0 -0
  218. /package/dist/types/src/{graph → compute-graph}/testing/index.d.ts +0 -0
  219. /package/dist/types/src/{graph → compute-graph}/testing/test-builder.d.ts +0 -0
  220. /package/dist/types/src/{graph → compute-graph}/testing/test-plugin.d.ts +0 -0
  221. /package/dist/types/src/{graph → compute-graph}/util.d.ts +0 -0
  222. /package/src/{graph → compute-graph}/compute-graph-registry.ts +0 -0
  223. /package/src/{graph → compute-graph}/compute-graph.test.ts +0 -0
  224. /package/src/{graph → compute-graph}/functions/function-defs.ts +0 -0
  225. /package/src/{graph → compute-graph}/functions/index.ts +0 -0
  226. /package/src/{graph → compute-graph}/hyperformula.test.ts +0 -0
  227. /package/src/{graph → compute-graph}/index.ts +0 -0
  228. /package/src/{graph → compute-graph}/testing/index.ts +0 -0
  229. /package/src/{graph → compute-graph}/testing/test-builder.ts +0 -0
  230. /package/src/{graph → compute-graph}/testing/test-plugin.ts +0 -0
  231. /package/src/{graph → compute-graph}/util.ts +0 -0
@@ -1,15 +1,35 @@
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-VMSX6Z4X.mjs";
4
21
  import {
5
- SHEET_PLUGIN
6
- } from "./chunk-D3QTX46O.mjs";
22
+ Range,
23
+ SheetAction
24
+ } from "./chunk-BVUN7SHF.mjs";
7
25
  import {
8
- createSheetName
9
- } from "./chunk-GSV5QNLD.mjs";
26
+ SHEET_PLUGIN
27
+ } from "./chunk-RABELMEQ.mjs";
10
28
 
11
29
  // packages/plugins/plugin-sheet/src/components/ComputeGraph/ComputeGraphContextProvider.tsx
12
- import React, { createContext } from "react";
30
+ import React, { createContext, useContext } from "react";
31
+ import { raise } from "@dxos/debug";
32
+ import { useAsyncState } from "@dxos/react-hooks";
13
33
  var ComputeGraphContext = /* @__PURE__ */ createContext(void 0);
14
34
  var ComputeGraphContextProvider = ({ registry, children }) => {
15
35
  return /* @__PURE__ */ React.createElement(ComputeGraphContext.Provider, {
@@ -18,192 +38,19 @@ var ComputeGraphContextProvider = ({ registry, children }) => {
18
38
  }
19
39
  }, children);
20
40
  };
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;
41
+ var useComputeGraph = (space) => {
42
+ const { registry } = useContext(ComputeGraphContext) ?? raise(new Error("Missing ComputeGraphContext"));
43
+ const [graph] = useAsyncState(async () => {
44
+ if (space) {
45
+ const graph2 = registry.getOrCreateGraph(space);
46
+ await graph2.open();
47
+ return graph2;
167
48
  }
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
- }
49
+ }, [
50
+ space,
51
+ registry
52
+ ]);
53
+ return graph;
207
54
  };
208
55
 
209
56
  // packages/plugins/plugin-sheet/src/extensions/compute.ts
@@ -211,8 +58,8 @@ import { syntaxTree } from "@codemirror/language";
211
58
  import { RangeSetBuilder, StateEffect, StateField } from "@codemirror/state";
212
59
  import { Decoration, EditorView, ViewPlugin, WidgetType } from "@codemirror/view";
213
60
  import { debounce } from "@dxos/async";
214
- import { invariant as invariant2 } from "@dxos/invariant";
215
- import { documentId, singleValueFacet } from "@dxos/react-ui-editor/state";
61
+ import { invariant } from "@dxos/invariant";
62
+ import { documentId, singleValueFacet } from "@dxos/react-ui-editor";
216
63
  var updateAllDecorations = StateEffect.define();
217
64
  var computeGraphFacet = singleValueFacet();
218
65
 
@@ -222,7 +69,7 @@ import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
222
69
  import { ViewPlugin as ViewPlugin2, keymap } from "@codemirror/view";
223
70
  import { tags } from "@lezer/highlight";
224
71
  import { spreadsheet } from "codemirror-lang-spreadsheet";
225
- import { singleValueFacet as singleValueFacet2 } from "@dxos/react-ui-editor/state";
72
+ import { singleValueFacet as singleValueFacet2 } from "@dxos/react-ui-editor";
226
73
  import { mx } from "@dxos/react-ui-theme";
227
74
  var highlightStyles = HighlightStyle.define([
228
75
  // Function.
@@ -346,27 +193,29 @@ var sheetExtension = ({ functions = [] }) => {
346
193
  ])
347
194
  ];
348
195
  };
349
- var rangeExtension = (onInit) => {
196
+ var rangeExtension = ({ onInit, onStateChange }) => {
350
197
  let view;
351
198
  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
- }));
199
+ const notifier = {
200
+ setRange: (range) => {
201
+ if (activeRange) {
202
+ view.dispatch(view.state.update({
203
+ changes: {
204
+ ...activeRange,
205
+ insert: range.toString()
206
+ },
207
+ selection: {
208
+ anchor: activeRange.from + range.length
209
+ }
210
+ }));
211
+ }
212
+ view.focus();
363
213
  }
364
- view.focus();
365
214
  };
366
215
  return ViewPlugin2.fromClass(class {
367
216
  constructor(_view) {
368
217
  view = _view;
369
- onInit(provider);
218
+ onInit?.(notifier);
370
219
  }
371
220
  update(view2) {
372
221
  const { anchor } = view2.state.selection.ranges[0];
@@ -376,20 +225,18 @@ var rangeExtension = (onInit) => {
376
225
  visitTree(topNode, ({ type, from, to }) => {
377
226
  if (from <= anchor && to >= anchor) {
378
227
  switch (type.name) {
379
- case "Function": {
228
+ case "Function":
380
229
  activeRange = {
381
230
  from: to,
382
231
  to
383
232
  };
384
233
  break;
385
- }
386
- case "CloseParen": {
234
+ case "CloseParen":
387
235
  activeRange = {
388
236
  from,
389
237
  to: from
390
238
  };
391
239
  break;
392
- }
393
240
  case "RangeToken":
394
241
  case "CellToken":
395
242
  activeRange = {
@@ -402,11 +249,17 @@ var rangeExtension = (onInit) => {
402
249
  return false;
403
250
  });
404
251
  if (!activeRange && view2.state.doc.toString()[0] === "=") {
405
- activeRange = {
406
- from: 1,
407
- to: view2.state.doc.toString().length
408
- };
252
+ const str = view2.state.doc.sliceString(1);
253
+ if (RANGE_NOTATION.test(str)) {
254
+ activeRange = {
255
+ from: 1,
256
+ to: str.length + 1
257
+ };
258
+ }
409
259
  }
260
+ onStateChange?.({
261
+ activeRange: activeRange ? view2.state.doc.sliceString(activeRange.from, activeRange.to) : void 0
262
+ });
410
263
  }
411
264
  });
412
265
  };
@@ -422,236 +275,48 @@ var visitTree = (node, callback) => {
422
275
  return false;
423
276
  };
424
277
 
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
- };
278
+ // packages/plugins/plugin-sheet/src/components/SheetContext/SheetContext.tsx
279
+ import React2, { createContext as createContext2, useCallback, useContext as useContext2, useState as useState2 } from "react";
280
+ import { invariant as invariant3 } from "@dxos/invariant";
281
+ import { fullyQualifiedId } from "@dxos/react-client/echo";
282
+ import { Grid, useGridContext } from "@dxos/react-ui-grid";
636
283
 
637
284
  // packages/plugins/plugin-sheet/src/model/sheet-model.ts
638
285
  import { Event } from "@dxos/async";
639
286
  import { Resource } from "@dxos/context";
640
- import { getTypename } from "@dxos/echo-schema";
641
- import { invariant as invariant3 } from "@dxos/invariant";
287
+ import { getTypename, FormatEnum, TypeEnum } from "@dxos/echo-schema";
288
+ import { invariant as invariant2 } from "@dxos/invariant";
642
289
  import { PublicKey } from "@dxos/keys";
643
290
  import { log } from "@dxos/log";
644
- 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
- BOOLEAN: FieldValueType.Boolean,
649
- NUMBER_RAW: FieldValueType.Number,
650
- NUMBER_PERCENT: FieldValueType.Percent,
651
- NUMBER_CURRENCY: FieldValueType.Currency,
652
- NUMBER_DATETIME: FieldValueType.DateTime,
653
- NUMBER_DATE: FieldValueType.Date,
654
- NUMBER_TIME: FieldValueType.Time
294
+ BOOLEAN: {
295
+ type: TypeEnum.Boolean
296
+ },
297
+ NUMBER_RAW: {
298
+ type: TypeEnum.Number
299
+ },
300
+ NUMBER_PERCENT: {
301
+ type: TypeEnum.Number,
302
+ format: FormatEnum.Percent
303
+ },
304
+ NUMBER_CURRENCY: {
305
+ type: TypeEnum.Number,
306
+ format: FormatEnum.Currency
307
+ },
308
+ NUMBER_DATETIME: {
309
+ type: TypeEnum.String,
310
+ format: FormatEnum.DateTime
311
+ },
312
+ NUMBER_DATE: {
313
+ type: TypeEnum.String,
314
+ format: FormatEnum.Date
315
+ },
316
+ NUMBER_TIME: {
317
+ type: TypeEnum.String,
318
+ format: FormatEnum.Time
319
+ }
655
320
  };
656
321
  var getTopLeft = (range) => {
657
322
  const to = range.to ?? range.from;
@@ -700,12 +365,17 @@ var SheetModel = class extends Resource {
700
365
  log("initialize", {
701
366
  id: this.id
702
367
  }, {
703
- F: __dxlog_file2,
704
- L: 106,
368
+ F: __dxlog_file,
369
+ L: 113,
705
370
  S: this,
706
371
  C: (f, a) => f(...a)
707
372
  });
708
373
  initialize(this._sheet);
374
+ this._graph.update.on((event) => {
375
+ if (event.type === "functionsUpdated") {
376
+ this.reset();
377
+ }
378
+ });
709
379
  this._node = this._graph.getOrCreateNode(createSheetName({
710
380
  type: getTypename(this._sheet),
711
381
  id: this._sheet.id
@@ -721,9 +391,9 @@ var SheetModel = class extends Resource {
721
391
  * @deprecated
722
392
  */
723
393
  reset() {
724
- invariant3(this._node, void 0, {
725
- F: __dxlog_file2,
726
- L: 126,
394
+ invariant2(this._node, void 0, {
395
+ F: __dxlog_file,
396
+ L: 139,
727
397
  S: this,
728
398
  A: [
729
399
  "this._node",
@@ -732,9 +402,9 @@ var SheetModel = class extends Resource {
732
402
  });
733
403
  this._node.graph.hf.clearSheet(this._node.sheetId);
734
404
  Object.entries(this._sheet.cells).forEach(([key, { value }]) => {
735
- invariant3(this._node, void 0, {
736
- F: __dxlog_file2,
737
- L: 129,
405
+ invariant2(this._node, void 0, {
406
+ F: __dxlog_file,
407
+ L: 142,
738
408
  S: this,
739
409
  A: [
740
410
  "this._node",
@@ -742,8 +412,13 @@ var SheetModel = class extends Resource {
742
412
  ]
743
413
  });
744
414
  const { col, row } = addressFromIndex(this._sheet, key);
745
- if (typeof value === "string" && value.charAt(0) === "=") {
746
- value = this._graph.mapFormulaToNative(this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value)));
415
+ if (isFormula(value)) {
416
+ const binding = this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value));
417
+ if (binding) {
418
+ value = this._graph.mapFormulaToNative(binding);
419
+ } else {
420
+ value = "";
421
+ }
747
422
  }
748
423
  this._node.graph.hf.setCellContents({
749
424
  sheet: this._node.sheetId,
@@ -763,11 +438,79 @@ var SheetModel = class extends Resource {
763
438
  this._node?.graph.hf.rebuildAndRecalculate();
764
439
  }
765
440
  insertRows(i, n = 1) {
766
- insertIndices(this._sheet.rows, i, n, MAX_ROWS);
441
+ const idx = insertIndices(this._sheet.rows, i, n, MAX_ROWS);
767
442
  this.reset();
443
+ return idx;
768
444
  }
769
445
  insertColumns(i, n = 1) {
770
- insertIndices(this._sheet.columns, i, n, MAX_COLUMNS);
446
+ const idx = insertIndices(this._sheet.columns, i, n, MAX_COLUMNS);
447
+ this.reset();
448
+ return idx;
449
+ }
450
+ dropRow(rowIndex) {
451
+ const range = {
452
+ from: addressFromIndex(this._sheet, `${this._sheet.columns[0]}@${rowIndex}`),
453
+ to: addressFromIndex(this._sheet, `${this._sheet.columns[this._sheet.columns.length - 1]}@${rowIndex}`)
454
+ };
455
+ const values = this.getCellValues(range).flat();
456
+ const index = this._sheet.rows.indexOf(rowIndex);
457
+ this.clear(range);
458
+ this._sheet.rows.splice(index, 1);
459
+ delete this._sheet.rowMeta[rowIndex];
460
+ this.reset();
461
+ return {
462
+ axis: "row",
463
+ index,
464
+ axisIndex: rowIndex,
465
+ axisMeta: this._sheet.rowMeta[rowIndex],
466
+ values
467
+ };
468
+ }
469
+ dropColumn(colIndex) {
470
+ const range = {
471
+ from: addressFromIndex(this._sheet, `${colIndex}@${this._sheet.rows[0]}`),
472
+ to: addressFromIndex(this._sheet, `${colIndex}@${this._sheet.rows[this._sheet.rows.length - 1]}`)
473
+ };
474
+ const values = this.getCellValues(range).flat();
475
+ const index = this._sheet.columns.indexOf(colIndex);
476
+ this.clear(range);
477
+ this._sheet.columns.splice(index, 1);
478
+ delete this._sheet.columnMeta[colIndex];
479
+ this.reset();
480
+ return {
481
+ axis: "col",
482
+ index,
483
+ axisIndex: colIndex,
484
+ axisMeta: this._sheet.rowMeta[colIndex],
485
+ values
486
+ };
487
+ }
488
+ restoreRow({ index, axisIndex, axisMeta, values }) {
489
+ this._sheet.rows.splice(index, 0, axisIndex);
490
+ values.forEach((value, col) => {
491
+ if (value) {
492
+ this._sheet.cells[`${this._sheet.columns[col]}@${axisIndex}`] = {
493
+ value
494
+ };
495
+ }
496
+ });
497
+ if (axisMeta) {
498
+ this._sheet.rowMeta[axisIndex] = axisMeta;
499
+ }
500
+ this.reset();
501
+ }
502
+ restoreColumn({ index, axisIndex, axisMeta, values }) {
503
+ this._sheet.columns.splice(index, 0, axisIndex);
504
+ values.forEach((value, row) => {
505
+ if (value) {
506
+ this._sheet.cells[`${axisIndex}@${this._sheet.rows[row]}`] = {
507
+ value
508
+ };
509
+ }
510
+ });
511
+ if (axisMeta) {
512
+ this._sheet.columnMeta[axisIndex] = axisMeta;
513
+ }
771
514
  this.reset();
772
515
  }
773
516
  //
@@ -778,9 +521,9 @@ var SheetModel = class extends Resource {
778
521
  * Clear range of values.
779
522
  */
780
523
  clear(range) {
781
- invariant3(this._node, void 0, {
782
- F: __dxlog_file2,
783
- L: 171,
524
+ invariant2(this._node, void 0, {
525
+ F: __dxlog_file,
526
+ L: 245,
784
527
  S: this,
785
528
  A: [
786
529
  "this._node",
@@ -796,9 +539,9 @@ var SheetModel = class extends Resource {
796
539
  });
797
540
  }
798
541
  cut(range) {
799
- invariant3(this._node, void 0, {
800
- F: __dxlog_file2,
801
- L: 182,
542
+ invariant2(this._node, void 0, {
543
+ F: __dxlog_file,
544
+ L: 256,
802
545
  S: this,
803
546
  A: [
804
547
  "this._node",
@@ -812,9 +555,9 @@ var SheetModel = class extends Resource {
812
555
  });
813
556
  }
814
557
  copy(range) {
815
- invariant3(this._node, void 0, {
816
- F: __dxlog_file2,
817
- L: 191,
558
+ invariant2(this._node, void 0, {
559
+ F: __dxlog_file,
560
+ L: 265,
818
561
  S: this,
819
562
  A: [
820
563
  "this._node",
@@ -824,9 +567,9 @@ var SheetModel = class extends Resource {
824
567
  this._node.graph.hf.copy(toModelRange(this._node.sheetId, range));
825
568
  }
826
569
  paste(cell) {
827
- invariant3(this._node, void 0, {
828
- F: __dxlog_file2,
829
- L: 196,
570
+ invariant2(this._node, void 0, {
571
+ F: __dxlog_file,
572
+ L: 270,
830
573
  S: this,
831
574
  A: [
832
575
  "this._node",
@@ -851,9 +594,9 @@ var SheetModel = class extends Resource {
851
594
  }
852
595
  // TODO(burdon): Display undo/redo state.
853
596
  undo() {
854
- invariant3(this._node, void 0, {
855
- F: __dxlog_file2,
856
- L: 211,
597
+ invariant2(this._node, void 0, {
598
+ F: __dxlog_file,
599
+ L: 285,
857
600
  S: this,
858
601
  A: [
859
602
  "this._node",
@@ -865,9 +608,9 @@ var SheetModel = class extends Resource {
865
608
  }
866
609
  }
867
610
  redo() {
868
- invariant3(this._node, void 0, {
869
- F: __dxlog_file2,
870
- L: 219,
611
+ invariant2(this._node, void 0, {
612
+ F: __dxlog_file,
613
+ L: 293,
871
614
  S: this,
872
615
  A: [
873
616
  "this._node",
@@ -893,7 +636,7 @@ var SheetModel = class extends Resource {
893
636
  if (value == null) {
894
637
  return void 0;
895
638
  }
896
- if (typeof value === "string" && value.charAt(0) === "=") {
639
+ if (isFormula(value)) {
897
640
  return this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value));
898
641
  } else {
899
642
  return String(value);
@@ -909,17 +652,27 @@ var SheetModel = class extends Resource {
909
652
  * Gets the regular or computed value from the engine.
910
653
  */
911
654
  getValue(cell) {
912
- invariant3(this._node, void 0, {
913
- F: __dxlog_file2,
914
- L: 262,
655
+ invariant2(this._node, void 0, {
656
+ F: __dxlog_file,
657
+ L: 336,
915
658
  S: this,
916
659
  A: [
917
660
  "this._node",
918
661
  ""
919
662
  ]
920
663
  });
921
- const value = this._node.graph.hf.getCellValue(toSimpleCellAddress(this._node.sheetId, cell));
664
+ const address = toSimpleCellAddress(this._node.sheetId, cell);
665
+ const value = this._node.graph.hf.getCellValue(address);
922
666
  if (value instanceof DetailedCellError) {
667
+ log.info("cell error", {
668
+ cell,
669
+ error: value
670
+ }, {
671
+ F: __dxlog_file,
672
+ L: 341,
673
+ S: this,
674
+ C: (f, a) => f(...a)
675
+ });
923
676
  return value.toString();
924
677
  }
925
678
  return value;
@@ -927,10 +680,10 @@ var SheetModel = class extends Resource {
927
680
  /**
928
681
  * Get value type.
929
682
  */
930
- getValueType(cell) {
931
- invariant3(this._node, void 0, {
932
- F: __dxlog_file2,
933
- L: 275,
683
+ getValueDescription(cell) {
684
+ invariant2(this._node, void 0, {
685
+ F: __dxlog_file,
686
+ L: 352,
934
687
  S: this,
935
688
  A: [
936
689
  "this._node",
@@ -945,9 +698,9 @@ var SheetModel = class extends Resource {
945
698
  * Sets the value, updating the sheet and engine.
946
699
  */
947
700
  setValue(cell, value) {
948
- invariant3(this._node, void 0, {
949
- F: __dxlog_file2,
950
- L: 285,
701
+ invariant2(this._node, void 0, {
702
+ F: __dxlog_file,
703
+ L: 362,
951
704
  S: this,
952
705
  A: [
953
706
  "this._node",
@@ -975,14 +728,14 @@ var SheetModel = class extends Resource {
975
728
  col: cell.col
976
729
  }, [
977
730
  [
978
- typeof value === "string" && value.charAt(0) === "=" ? this._graph.mapFormulaToNative(value) : value
731
+ isFormula(value) ? this._graph.mapFormulaToNative(value) : value
979
732
  ]
980
733
  ]);
981
734
  const idx = addressToIndex(this._sheet, cell);
982
735
  if (value === void 0 || value === null) {
983
736
  delete this._sheet.cells[idx];
984
737
  } else {
985
- if (typeof value === "string" && value.charAt(0) === "=") {
738
+ if (isFormula(value)) {
986
739
  value = this._graph.mapFunctionBindingToId(this.mapFormulaRefsToIndices(value));
987
740
  }
988
741
  this._sheet.cells[idx] = {
@@ -1042,12 +795,12 @@ var SheetModel = class extends Resource {
1042
795
  * Map from A1 notation to indices.
1043
796
  */
1044
797
  mapFormulaRefsToIndices(formula) {
1045
- invariant3(formula.charAt(0) === "=", void 0, {
1046
- F: __dxlog_file2,
1047
- L: 374,
798
+ invariant2(isFormula(formula), void 0, {
799
+ F: __dxlog_file,
800
+ L: 451,
1048
801
  S: this,
1049
802
  A: [
1050
- "formula.charAt(0) === '='",
803
+ "isFormula(formula)",
1051
804
  ""
1052
805
  ]
1053
806
  });
@@ -1059,12 +812,12 @@ var SheetModel = class extends Resource {
1059
812
  * Map from indices to A1 notation.
1060
813
  */
1061
814
  mapFormulaIndicesToRefs(formula) {
1062
- invariant3(formula.charAt(0) === "=", void 0, {
1063
- F: __dxlog_file2,
1064
- L: 384,
815
+ invariant2(isFormula(formula), void 0, {
816
+ F: __dxlog_file,
817
+ L: 461,
1065
818
  S: this,
1066
819
  A: [
1067
- "formula.charAt(0) === '='",
820
+ "isFormula(formula)",
1068
821
  ""
1069
822
  ]
1070
823
  });
@@ -1085,9 +838,9 @@ var SheetModel = class extends Resource {
1085
838
  return new Date(year, month - 1, day, hours, minutes, seconds);
1086
839
  }
1087
840
  toDateTime(num) {
1088
- invariant3(this._node, void 0, {
1089
- F: __dxlog_file2,
1090
- L: 405,
841
+ invariant2(this._node, void 0, {
842
+ F: __dxlog_file,
843
+ L: 482,
1091
844
  S: this,
1092
845
  A: [
1093
846
  "this._node",
@@ -1097,9 +850,9 @@ var SheetModel = class extends Resource {
1097
850
  return this._node.graph.hf.numberToDateTime(num);
1098
851
  }
1099
852
  toDate(num) {
1100
- invariant3(this._node, void 0, {
1101
- F: __dxlog_file2,
1102
- L: 410,
853
+ invariant2(this._node, void 0, {
854
+ F: __dxlog_file,
855
+ L: 487,
1103
856
  S: this,
1104
857
  A: [
1105
858
  "this._node",
@@ -1109,9 +862,9 @@ var SheetModel = class extends Resource {
1109
862
  return this._node.graph.hf.numberToDate(num);
1110
863
  }
1111
864
  toTime(num) {
1112
- invariant3(this._node, void 0, {
1113
- F: __dxlog_file2,
1114
- L: 415,
865
+ invariant2(this._node, void 0, {
866
+ F: __dxlog_file,
867
+ L: 492,
1115
868
  S: this,
1116
869
  A: [
1117
870
  "this._node",
@@ -1122,10 +875,11 @@ var SheetModel = class extends Resource {
1122
875
  }
1123
876
  };
1124
877
 
1125
- // packages/plugins/plugin-sheet/src/hooks/useSheetModel.ts
878
+ // packages/plugins/plugin-sheet/src/model/useSheetModel.ts
879
+ import { useEffect, useState } from "react";
1126
880
  var useSheetModel = (graph, sheet, { readonly } = {}) => {
1127
- const [model, setModel] = useState2();
1128
- useEffect2(() => {
881
+ const [model, setModel] = useState();
882
+ useEffect(() => {
1129
883
  if (!graph || !sheet) {
1130
884
  return;
1131
885
  }
@@ -1149,182 +903,407 @@ var useSheetModel = (graph, sheet, { readonly } = {}) => {
1149
903
  return model;
1150
904
  };
1151
905
 
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";
906
+ // packages/plugins/plugin-sheet/src/components/SheetContext/SheetContext.tsx
907
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/SheetContext/SheetContext.tsx";
908
+ var SheetContext = /* @__PURE__ */ createContext2(void 0);
909
+ var useSheetContext = () => {
910
+ const context = useContext2(SheetContext);
911
+ invariant3(context, void 0, {
912
+ F: __dxlog_file2,
913
+ L: 52,
914
+ S: void 0,
915
+ A: [
916
+ "context",
917
+ ""
918
+ ]
919
+ });
920
+ return context;
921
+ };
922
+ var SheetProviderImpl = ({ model, onInfo, children, __gridScope }) => {
923
+ const { id, editing, setEditing } = useGridContext("SheetProvider", __gridScope);
924
+ const [cursor, setCursorInternal] = useState2();
925
+ const [range, setRangeInternal] = useState2();
926
+ const [cursorFallbackRange, setCursorFallbackRange] = useState2();
927
+ const [activeRefs, setActiveRefs] = useState2("");
928
+ const setCursor = useCallback((nextCursor) => {
929
+ setCursorInternal(nextCursor);
930
+ setCursorFallbackRange(range?.to ? range : nextCursor ? {
931
+ from: nextCursor,
932
+ to: nextCursor
933
+ } : void 0);
934
+ }, [
935
+ range
936
+ ]);
937
+ const setRange = useCallback((nextRange) => {
938
+ setRangeInternal(nextRange);
939
+ setCursorFallbackRange(nextRange?.to ? nextRange : cursor ? {
940
+ from: cursor,
941
+ to: cursor
942
+ } : void 0);
943
+ }, [
944
+ cursor
945
+ ]);
946
+ return /* @__PURE__ */ React2.createElement(SheetContext.Provider, {
947
+ value: {
948
+ id,
949
+ model,
950
+ editing,
951
+ setEditing,
952
+ cursor,
953
+ setCursor,
954
+ range,
955
+ setRange,
956
+ cursorFallbackRange,
957
+ activeRefs,
958
+ setActiveRefs,
959
+ // TODO(burdon): Change to event.
960
+ onInfo
961
+ }
962
+ }, children);
963
+ };
964
+ var SheetProvider = ({ children, graph, sheet, readonly, onInfo }) => {
965
+ const model = useSheetModel(graph, sheet, {
966
+ readonly
967
+ });
968
+ return !model ? null : /* @__PURE__ */ React2.createElement(Grid.Root, {
969
+ id: fullyQualifiedId(sheet)
970
+ }, /* @__PURE__ */ React2.createElement(SheetProviderImpl, {
971
+ model,
972
+ onInfo
973
+ }, children));
974
+ };
975
+
976
+ // packages/plugins/plugin-sheet/src/components/GridSheet/GridSheet.tsx
977
+ import React4, { useCallback as useCallback4, useMemo as useMemo2, useRef, useState as useState4 } from "react";
978
+ import { useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
979
+ import { DropdownMenu, Icon, useTranslation as useTranslation2 } from "@dxos/react-ui";
980
+ import { useAttention } from "@dxos/react-ui-attention";
981
+ import { closestCell, editorKeys, Grid as Grid2, GridCellEditor } from "@dxos/react-ui-grid";
982
+
983
+ // packages/plugins/plugin-sheet/src/components/GridSheet/util.ts
984
+ import { useEffect as useEffect3, useState as useState3 } from "react";
985
+ import { createDocAccessor, fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
986
+ import { parseValue, cellClassesForFieldType } from "@dxos/react-ui-data";
987
+ import { colToA1Notation, rowToA1Notation, commentedClassName } from "@dxos/react-ui-grid";
988
+ import { mx as mx2 } from "@dxos/react-ui-theme";
989
+
990
+ // packages/plugins/plugin-sheet/src/integrations/thread-ranges.ts
991
+ import { useCallback as useCallback3, useEffect as useEffect2, useMemo } from "react";
1155
992
  import { LayoutAction, useIntentDispatcher, useIntentResolver } from "@dxos/app-framework";
1156
993
  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 }) => {
994
+ import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
995
+
996
+ // packages/plugins/plugin-sheet/src/components/index.ts
997
+ import { lazy } from "react";
998
+
999
+ // packages/plugins/plugin-sheet/src/components/RangeList/RangeList.tsx
1000
+ import React3, { useCallback as useCallback2 } from "react";
1001
+ import { S } from "@dxos/echo-schema";
1002
+ import { useTranslation } from "@dxos/react-ui";
1003
+ import { List } from "@dxos/react-ui-list";
1004
+ import { ghostHover } from "@dxos/react-ui-theme";
1005
+ var RangeList = ({ sheet }) => {
1006
+ const { t } = useTranslation(SHEET_PLUGIN);
1007
+ const handleSelectRange = (range) => {
1008
+ };
1009
+ const handleDeleteRange = useCallback2((range) => {
1010
+ const index = sheet.ranges.findIndex((sheetRange) => sheetRange === range);
1011
+ sheet.ranges.splice(index, 1);
1012
+ }, [
1013
+ sheet
1014
+ ]);
1015
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("h2", {
1016
+ className: "p-2 text-sm font-semibold"
1017
+ }, t("range list heading")), /* @__PURE__ */ React3.createElement(List.Root, {
1018
+ items: sheet.ranges,
1019
+ isItem: S.is(Range)
1020
+ }, ({ items: ranges }) => ranges.map((range, i) => /* @__PURE__ */ React3.createElement(List.Item, {
1021
+ key: i,
1022
+ item: range,
1023
+ classNames: [
1024
+ "p-2",
1025
+ ghostHover
1026
+ ]
1027
+ }, /* @__PURE__ */ React3.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React3.createElement(List.ItemTitle, {
1028
+ onClick: () => handleSelectRange(range)
1029
+ }, t("range title", {
1030
+ position: rangeToA1Notation(rangeFromIndex(sheet, range.range)),
1031
+ key: t(`range key ${range.key} label`),
1032
+ value: t(`range value ${range.value} label`)
1033
+ })), /* @__PURE__ */ React3.createElement(List.ItemDeleteButton, {
1034
+ onClick: () => handleDeleteRange(range)
1035
+ })))));
1036
+ };
1037
+
1038
+ // packages/plugins/plugin-sheet/src/components/index.ts
1039
+ var SheetContainer = lazy(() => import("./SheetContainer-JZEKRM4Z.mjs"));
1040
+
1041
+ // packages/plugins/plugin-sheet/src/integrations/thread-ranges.ts
1042
+ var completeCellRangeToThreadCursor = (range) => {
1043
+ return `${range.from.col},${range.from.row},${range.to.col},${range.to.row}`;
1044
+ };
1045
+ var parseThreadAnchorAsCellRange = (cursor) => {
1046
+ const coords = cursor.split(",");
1047
+ if (coords.length !== 4) {
1048
+ return null;
1049
+ } else {
1050
+ const [fromCol, fromRow, toCol, toRow] = coords;
1051
+ return {
1052
+ from: {
1053
+ col: parseInt(fromCol),
1054
+ row: parseInt(fromRow)
1055
+ },
1056
+ to: {
1057
+ col: parseInt(toCol),
1058
+ row: parseInt(toRow)
1059
+ }
1060
+ };
1061
+ }
1062
+ };
1063
+ var useUpdateFocusedCellOnThreadSelection = (grid) => {
1064
+ const { model, setActiveRefs } = useSheetContext();
1065
+ const handleScrollIntoView = useCallback3(({ action, data }) => {
1160
1066
  switch (action) {
1161
1067
  case LayoutAction.SCROLL_INTO_VIEW: {
1162
- if (!data?.id || data?.cursor === void 0 || data?.id !== fullyQualifiedId(model.sheet)) {
1068
+ if (!data?.id || data?.cursor === void 0 || data?.id !== fullyQualifiedId2(model.sheet)) {
1163
1069
  return;
1164
1070
  }
1165
- const cellAddress = addressFromIndex(model.sheet, data.cursor);
1166
- grid.current?.setFocus({
1167
- ...cellAddress,
1071
+ setActiveRefs(data.thread);
1072
+ const range = parseThreadAnchorAsCellRange(data.cursor);
1073
+ range && grid?.setFocus({
1074
+ ...range.to,
1168
1075
  plane: "grid"
1169
1076
  }, true);
1170
1077
  }
1171
1078
  }
1172
1079
  }, [
1173
- model.sheet
1080
+ model.sheet,
1081
+ setActiveRefs
1174
1082
  ]);
1175
1083
  useIntentResolver(SHEET_PLUGIN, handleScrollIntoView);
1176
1084
  };
1177
- var useSelectThreadOnCellFocus = (model, cursor) => {
1085
+ var useSelectThreadOnCellFocus = () => {
1086
+ const { model, cursor } = useSheetContext();
1178
1087
  const dispatch = useIntentDispatcher();
1179
- const activeThreads = useMemo(() => model.sheet.threads?.filter((thread) => !!thread && thread.status === "active") ?? [], [
1088
+ const threads = useMemo(() => model.sheet.threads?.filter((thread) => !!thread) ?? [], [
1180
1089
  // TODO(thure): Surely we can find a better dependency for this…
1181
1090
  JSON.stringify(model.sheet.threads)
1182
1091
  ]);
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) {
1092
+ const selectClosestThread = useCallback3((cellAddress) => {
1093
+ if (!cellAddress || !threads) {
1189
1094
  return;
1190
1095
  }
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
- ]);
1096
+ const closestThread = threads?.find(({ anchor }) => {
1097
+ if (anchor) {
1098
+ const range = parseThreadAnchorAsCellRange(anchor);
1099
+ return range ? inRange(range, cellAddress) : false;
1100
+ } else {
1101
+ return false;
1203
1102
  }
1103
+ });
1104
+ if (closestThread) {
1105
+ void dispatch([
1106
+ {
1107
+ action: "dxos.org/plugin/thread/action/select",
1108
+ data: {
1109
+ current: fullyQualifiedId2(closestThread)
1110
+ }
1111
+ }
1112
+ ]);
1204
1113
  }
1205
1114
  }, [
1206
1115
  dispatch,
1207
- activeThreads,
1208
- activeThreadAddresses,
1209
- model.sheet
1116
+ threads
1210
1117
  ]);
1211
1118
  const debounced = useMemo(() => {
1212
1119
  return debounce2((cellCoords) => requestAnimationFrame(() => selectClosestThread(cellCoords)), 50);
1213
1120
  }, [
1214
1121
  selectClosestThread
1215
1122
  ]);
1216
- useEffect3(() => {
1123
+ useEffect2(() => {
1217
1124
  if (!cursor) {
1218
1125
  return;
1219
1126
  }
1220
1127
  debounced(cursor);
1221
1128
  }, [
1222
1129
  cursor,
1223
- selectClosestThread
1130
+ debounced
1224
1131
  ]);
1225
1132
  };
1226
- var createThreadDecoration = (cellIndex, threadId, sheetId) => {
1133
+
1134
+ // packages/plugins/plugin-sheet/src/components/GridSheet/util.ts
1135
+ var dxGridCellIndexToSheetCellAddress = (index) => {
1136
+ const [colStr, rowStr] = index.split(",");
1227
1137
  return {
1228
- type: "comment",
1229
- classNames: [
1230
- "bg-greenFill"
1231
- ],
1232
- cellIndex
1138
+ col: parseInt(colStr),
1139
+ row: parseInt(rowStr)
1233
1140
  };
1234
1141
  };
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();
1142
+ var createDxGridColumns = (model) => {
1143
+ return model.sheet.columns.reduce((acc, columnId, numericIndex) => {
1144
+ if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {
1145
+ acc.grid[numericIndex] = {
1146
+ size: model.sheet.columnMeta[columnId].size,
1147
+ resizeable: true
1148
+ };
1149
+ }
1150
+ return acc;
1151
+ }, {
1152
+ grid: {}
1269
1153
  });
1270
1154
  };
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
- ]
1155
+ var createDxGridRows = (model) => {
1156
+ return model.sheet.rows.reduce((acc, rowId, numericIndex) => {
1157
+ if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {
1158
+ acc.grid[numericIndex] = {
1159
+ size: model.sheet.rowMeta[rowId].size,
1160
+ resizeable: true
1161
+ };
1162
+ }
1163
+ return acc;
1164
+ }, {
1165
+ grid: {}
1289
1166
  });
1290
- return context;
1291
1167
  };
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
1168
+ var projectCellProps = (model, col, row) => {
1169
+ const address = {
1170
+ col,
1171
+ row
1172
+ };
1173
+ const rawValue = model.getValue(address);
1174
+ const ranges = model.sheet.ranges?.filter(({ range }) => inRange(rangeFromIndex(model.sheet, range), address));
1175
+ const threadRefs = model.sheet.threads?.filter((thread) => {
1176
+ const range = thread?.anchor && parseThreadAnchorAsCellRange(thread.anchor);
1177
+ return thread && range ? inRange(range, address) : false;
1178
+ }).map((thread) => fullyQualifiedId3(thread)).join(" ");
1179
+ const description = model.getValueDescription(address);
1180
+ const type = description?.type;
1181
+ const format = description?.format;
1182
+ const classNames = ranges?.map(cellClassNameForRange).reverse();
1183
+ return {
1184
+ value: parseValue({
1185
+ type,
1186
+ format,
1187
+ value: rawValue
1188
+ }),
1189
+ className: mx2(cellClassesForFieldType({
1190
+ type,
1191
+ format
1192
+ }), threadRefs && commentedClassName, classNames),
1193
+ dataRefs: threadRefs
1194
+ };
1195
+ };
1196
+ var gridCellGetter = (model) => {
1197
+ const cachedGridCells = {};
1198
+ return (nextBounds) => {
1199
+ [
1200
+ ...Array(nextBounds.end.col - nextBounds.start.col)
1201
+ ].forEach((_, c0) => {
1202
+ return [
1203
+ ...Array(nextBounds.end.row - nextBounds.start.row)
1204
+ ].forEach((_2, r0) => {
1205
+ const col = nextBounds.start.col + c0;
1206
+ const row = nextBounds.start.row + r0;
1207
+ cachedGridCells[`${col},${row}`] = projectCellProps(model, col, row);
1208
+ });
1209
+ });
1210
+ return cachedGridCells;
1211
+ };
1212
+ };
1213
+ var rowLabelCell = (row) => ({
1214
+ value: rowToA1Notation(row),
1215
+ className: "text-end !pie-1",
1216
+ resizeHandle: "row"
1217
+ });
1218
+ var colLabelCell = (col) => ({
1219
+ value: colToA1Notation(col),
1220
+ resizeHandle: "col"
1221
+ });
1222
+ var cellGetter = (model) => {
1223
+ const getGridCells = gridCellGetter(model);
1224
+ return (nextBounds, plane) => {
1225
+ switch (plane) {
1226
+ case "grid":
1227
+ return getGridCells(nextBounds);
1228
+ case "frozenColsStart":
1229
+ return [
1230
+ ...Array(nextBounds.end.row - nextBounds.start.row)
1231
+ ].reduce((acc, _, r0) => {
1232
+ const r = nextBounds.start.row + r0;
1233
+ acc[`0,${r}`] = rowLabelCell(r);
1234
+ return acc;
1235
+ }, {});
1236
+ case "frozenRowsStart":
1237
+ return [
1238
+ ...Array(nextBounds.end.col - nextBounds.start.col)
1239
+ ].reduce((acc, _, c0) => {
1240
+ const c = nextBounds.start.col + c0;
1241
+ acc[`${c},0`] = colLabelCell(c);
1242
+ return acc;
1243
+ }, {});
1244
+ default:
1245
+ return {};
1312
1246
  }
1313
- }, children);
1247
+ };
1314
1248
  };
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, {
1249
+ var useSheetModelDxGridProps = (dxGrid, model) => {
1250
+ const [columns, setColumns] = useState3(createDxGridColumns(model));
1251
+ const [rows, setRows] = useState3(createDxGridColumns(model));
1252
+ useEffect3(() => {
1253
+ const cellsAccessor = createDocAccessor(model.sheet, [
1254
+ "cells"
1255
+ ]);
1256
+ if (dxGrid) {
1257
+ dxGrid.getCells = cellGetter(model);
1258
+ }
1259
+ const handleCellsUpdate = () => {
1260
+ dxGrid?.requestUpdate("initialCells");
1261
+ };
1262
+ cellsAccessor.handle.addListener("change", handleCellsUpdate);
1263
+ const unsubscribe = model.graph.update.on(handleCellsUpdate);
1264
+ return () => {
1265
+ cellsAccessor.handle.removeListener("change", handleCellsUpdate);
1266
+ unsubscribe();
1267
+ };
1268
+ }, [
1322
1269
  model,
1323
- onInfo
1324
- }, children));
1270
+ dxGrid
1271
+ ]);
1272
+ useEffect3(() => {
1273
+ const columnMetaAccessor = createDocAccessor(model.sheet, [
1274
+ "columnMeta"
1275
+ ]);
1276
+ const rowMetaAccessor = createDocAccessor(model.sheet, [
1277
+ "rowMeta"
1278
+ ]);
1279
+ const handleColumnMetaUpdate = () => {
1280
+ setColumns(createDxGridColumns(model));
1281
+ };
1282
+ const handleRowMetaUpdate = () => {
1283
+ setRows(createDxGridRows(model));
1284
+ };
1285
+ columnMetaAccessor.handle.addListener("change", handleColumnMetaUpdate);
1286
+ rowMetaAccessor.handle.addListener("change", handleRowMetaUpdate);
1287
+ return () => {
1288
+ columnMetaAccessor.handle.removeListener("change", handleColumnMetaUpdate);
1289
+ rowMetaAccessor.handle.removeListener("change", handleRowMetaUpdate);
1290
+ };
1291
+ }, [
1292
+ model,
1293
+ dxGrid
1294
+ ]);
1295
+ return {
1296
+ columns,
1297
+ rows
1298
+ };
1325
1299
  };
1326
1300
 
1327
1301
  // packages/plugins/plugin-sheet/src/components/GridSheet/GridSheet.tsx
1302
+ var inertPosition = {
1303
+ plane: "grid",
1304
+ col: 0,
1305
+ row: 0
1306
+ };
1328
1307
  var initialCells = {
1329
1308
  grid: {},
1330
1309
  frozenColsStart: [
@@ -1365,24 +1344,34 @@ var sheetColDefault = {
1365
1344
  }
1366
1345
  };
1367
1346
  var GridSheet = () => {
1368
- const { id, model, editing, setEditing, setCursor, setRange, range, cursor } = useSheetContext();
1369
- const dxGrid = useRef(null);
1370
- const rangeNotifier = useRef();
1347
+ const { t } = useTranslation2(SHEET_PLUGIN);
1348
+ const { id, model, editing, setEditing, setCursor, setRange, cursor, cursorFallbackRange, activeRefs } = useSheetContext();
1349
+ const [dxGrid, setDxGrid] = useState4(null);
1350
+ const [extraplanarFocus, setExtraplanarFocus] = useState4(null);
1351
+ const dispatch = useIntentDispatcher2();
1352
+ const rangeController = useRef();
1371
1353
  const { hasAttention } = useAttention(id);
1372
- const handleFocus = useCallback2((event) => {
1354
+ const handleFocus = useCallback4((event) => {
1373
1355
  if (!editing) {
1374
1356
  const cell = closestCell(event.target);
1375
- if (cell && cell.plane === "grid") {
1376
- setCursor({
1377
- col: cell.col,
1378
- row: cell.row
1379
- });
1357
+ if (cell) {
1358
+ if (cell.plane === "grid") {
1359
+ setCursor({
1360
+ col: cell.col,
1361
+ row: cell.row
1362
+ });
1363
+ setExtraplanarFocus(null);
1364
+ } else {
1365
+ setExtraplanarFocus(cell);
1366
+ }
1367
+ } else {
1368
+ setExtraplanarFocus(null);
1380
1369
  }
1381
1370
  }
1382
1371
  }, [
1383
1372
  editing
1384
1373
  ]);
1385
- const handleClose = useCallback2((value, { key, shift }) => {
1374
+ const handleClose = useCallback4((value, { key, shift }) => {
1386
1375
  if (value !== void 0) {
1387
1376
  model.setValue(dxGridCellIndexToSheetCellAddress(editing.index), value);
1388
1377
  }
@@ -1400,13 +1389,22 @@ var GridSheet = () => {
1400
1389
  "ArrowUp",
1401
1390
  "ArrowLeft"
1402
1391
  ].includes(key) ? -1 : 1 : shift ? -1 : 1;
1403
- dxGrid.current?.refocus(axis, delta);
1392
+ dxGrid?.refocus(axis, delta);
1404
1393
  }, [
1405
1394
  model,
1406
1395
  editing,
1407
- setEditing
1396
+ dxGrid
1397
+ ]);
1398
+ const handleBlur = useCallback4((value) => {
1399
+ if (value !== void 0) {
1400
+ model.setValue(dxGridCellIndexToSheetCellAddress(editing.index), value);
1401
+ }
1402
+ setEditing(null);
1403
+ }, [
1404
+ model,
1405
+ editing
1408
1406
  ]);
1409
- const handleAxisResize = useCallback2(({ axis, size, index: numericIndex }) => {
1407
+ const handleAxisResize = useCallback4(({ axis, size, index: numericIndex }) => {
1410
1408
  if (axis === "row") {
1411
1409
  const rowId = model.sheet.rows[parseInt(numericIndex)];
1412
1410
  model.sheet.rowMeta[rowId] ??= {};
@@ -1419,44 +1417,91 @@ var GridSheet = () => {
1419
1417
  }, [
1420
1418
  model
1421
1419
  ]);
1422
- const handleSelect = useCallback2(({ minCol, maxCol, minRow, maxRow }) => {
1423
- const range2 = {
1420
+ const handleSelect = useCallback4(({ minCol, maxCol, minRow, maxRow }) => {
1421
+ const range = {
1424
1422
  from: {
1425
1423
  col: minCol,
1426
1424
  row: minRow
1427
1425
  }
1428
1426
  };
1429
1427
  if (minCol !== maxCol || minRow !== maxRow) {
1430
- range2.to = {
1428
+ range.to = {
1431
1429
  col: maxCol,
1432
1430
  row: maxRow
1433
1431
  };
1434
1432
  }
1435
1433
  if (editing) {
1436
- rangeNotifier.current?.(rangeToA1Notation(range2));
1434
+ rangeController.current?.setRange(rangeToA1Notation(range));
1437
1435
  } else {
1438
- setRange(range2.to ? range2 : void 0);
1436
+ setRange(range.to ? range : void 0);
1439
1437
  }
1440
1438
  }, [
1441
1439
  editing
1442
1440
  ]);
1443
- const handleWheel = useCallback2((event) => {
1441
+ const handleWheel = useCallback4((event) => {
1444
1442
  if (!hasAttention) {
1445
1443
  event.stopPropagation();
1446
1444
  }
1447
1445
  }, [
1448
1446
  hasAttention
1449
1447
  ]);
1450
- const handleKeyDown = useCallback2((event) => {
1451
- const cursorFallbackRange = range ?? cursor ? {
1452
- from: cursor,
1453
- to: cursor
1454
- } : null;
1448
+ const selectEntireAxis = useCallback4((pos) => {
1449
+ switch (pos.plane) {
1450
+ case "frozenRowsStart":
1451
+ return dxGrid?.setSelection({
1452
+ start: {
1453
+ col: pos.col,
1454
+ row: 0,
1455
+ plane: "grid"
1456
+ },
1457
+ end: {
1458
+ col: pos.col,
1459
+ row: model.sheet.rows.length - 1,
1460
+ plane: "grid"
1461
+ }
1462
+ });
1463
+ case "frozenColsStart":
1464
+ return dxGrid?.setSelection({
1465
+ start: {
1466
+ row: pos.row,
1467
+ col: 0,
1468
+ plane: "grid"
1469
+ },
1470
+ end: {
1471
+ row: pos.row,
1472
+ col: model.sheet.columns.length - 1,
1473
+ plane: "grid"
1474
+ }
1475
+ });
1476
+ }
1477
+ }, [
1478
+ dxGrid,
1479
+ model.sheet
1480
+ ]);
1481
+ const handleClick = useCallback4((event) => {
1482
+ const cell = closestCell(event.target);
1483
+ if (cell) {
1484
+ selectEntireAxis(cell);
1485
+ }
1486
+ }, [
1487
+ selectEntireAxis
1488
+ ]);
1489
+ const handleKeyDown = useCallback4((event) => {
1455
1490
  switch (event.key) {
1456
1491
  case "Backspace":
1457
1492
  case "Delete":
1458
1493
  event.preventDefault();
1459
1494
  return cursorFallbackRange && model.clear(cursorFallbackRange);
1495
+ case "Enter":
1496
+ case "Space":
1497
+ if (dxGrid && extraplanarFocus) {
1498
+ switch (extraplanarFocus.plane) {
1499
+ case "frozenRowsStart":
1500
+ case "frozenColsStart":
1501
+ event.preventDefault();
1502
+ return selectEntireAxis(extraplanarFocus);
1503
+ }
1504
+ }
1460
1505
  }
1461
1506
  if (event.metaKey || event.ctrlKey) {
1462
1507
  switch (event.key) {
@@ -1482,12 +1527,54 @@ var GridSheet = () => {
1482
1527
  }
1483
1528
  }
1484
1529
  }, [
1485
- range,
1530
+ cursorFallbackRange,
1486
1531
  model,
1487
- cursor
1532
+ cursor,
1533
+ extraplanarFocus,
1534
+ selectEntireAxis
1535
+ ]);
1536
+ const contextMenuAnchorRef = useRef(null);
1537
+ const [contextMenuOpen, setContextMenuOpen] = useState4(null);
1538
+ const contextMenuAxis = contextMenuOpen?.plane.startsWith("frozenRows") ? "col" : "row";
1539
+ const handleContextMenu = useCallback4((event) => {
1540
+ const cell = closestCell(event.target);
1541
+ if (cell && cell.plane.startsWith("frozen")) {
1542
+ event.preventDefault();
1543
+ contextMenuAnchorRef.current = event.target;
1544
+ setContextMenuOpen(cell);
1545
+ }
1546
+ }, []);
1547
+ const handleAxisMenuAction = useCallback4((operation) => {
1548
+ switch (operation) {
1549
+ case "insert-before":
1550
+ case "insert-after":
1551
+ return dispatch({
1552
+ action: SheetAction.INSERT_AXIS,
1553
+ data: {
1554
+ model,
1555
+ axis: contextMenuAxis,
1556
+ index: contextMenuOpen[contextMenuAxis] + (operation === "insert-before" ? 0 : 1)
1557
+ }
1558
+ });
1559
+ break;
1560
+ case "drop":
1561
+ return dispatch({
1562
+ action: SheetAction.DROP_AXIS,
1563
+ data: {
1564
+ model,
1565
+ axis: contextMenuAxis,
1566
+ axisIndex: model.sheet[contextMenuAxis === "row" ? "rows" : "columns"][contextMenuOpen[contextMenuAxis]]
1567
+ }
1568
+ });
1569
+ }
1570
+ }, [
1571
+ contextMenuAxis,
1572
+ contextMenuOpen,
1573
+ model,
1574
+ dispatch
1488
1575
  ]);
1489
1576
  const { columns, rows } = useSheetModelDxGridProps(dxGrid, model);
1490
- const extension = useMemo3(() => [
1577
+ const extension = useMemo2(() => [
1491
1578
  editorKeys({
1492
1579
  onClose: handleClose,
1493
1580
  ...editing?.initialContent && {
@@ -1497,23 +1584,32 @@ var GridSheet = () => {
1497
1584
  sheetExtension({
1498
1585
  functions: model.graph.getFunctions()
1499
1586
  }),
1500
- rangeExtension((fn) => rangeNotifier.current = fn)
1587
+ rangeExtension({
1588
+ onInit: (fn) => rangeController.current = fn,
1589
+ onStateChange: (state) => {
1590
+ if (dxGrid) {
1591
+ dxGrid.mode = typeof state.activeRange === "undefined" ? "edit" : "edit-select";
1592
+ }
1593
+ }
1594
+ })
1501
1595
  ], [
1502
1596
  model,
1503
1597
  handleClose,
1504
1598
  editing
1505
1599
  ]);
1506
- const getCellContent = useCallback2((index) => {
1600
+ const getCellContent = useCallback4((index) => {
1507
1601
  const cell = dxGridCellIndexToSheetCellAddress(index);
1508
1602
  return model.getCellText(cell);
1509
1603
  }, [
1510
1604
  model
1511
1605
  ]);
1512
- useUpdateFocusedCellOnThreadSelection(model, dxGrid);
1513
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(GridCellEditor, {
1606
+ useUpdateFocusedCellOnThreadSelection(dxGrid);
1607
+ useSelectThreadOnCellFocus();
1608
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(GridCellEditor, {
1514
1609
  getCellContent,
1515
- extension
1516
- }), /* @__PURE__ */ React3.createElement(Grid2.Content, {
1610
+ extension,
1611
+ onBlur: handleBlur
1612
+ }), /* @__PURE__ */ React4.createElement(Grid2.Content, {
1517
1613
  initialCells,
1518
1614
  limitColumns: DEFAULT_COLUMNS,
1519
1615
  limitRows: DEFAULT_ROWS,
@@ -1527,44 +1623,49 @@ var GridSheet = () => {
1527
1623
  onFocus: handleFocus,
1528
1624
  onWheelCapture: handleWheel,
1529
1625
  onKeyDown: handleKeyDown,
1626
+ onContextMenu: handleContextMenu,
1627
+ onClick: handleClick,
1530
1628
  overscroll: "inline",
1531
1629
  className: "[--dx-grid-base:var(--surface-bg)]",
1532
- 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;
1630
+ activeRefs,
1631
+ ref: setDxGrid
1632
+ }), /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
1633
+ modal: false,
1634
+ open: !!contextMenuOpen,
1635
+ onOpenChange: (nextOpen) => setContextMenuOpen(nextOpen ? inertPosition : null)
1636
+ }, /* @__PURE__ */ React4.createElement(DropdownMenu.VirtualTrigger, {
1637
+ virtualRef: contextMenuAnchorRef
1638
+ }), /* @__PURE__ */ React4.createElement(DropdownMenu.Content, {
1639
+ side: contextMenuAxis === "col" ? "bottom" : "right",
1640
+ sideOffset: 4,
1641
+ collisionPadding: 8
1642
+ }, /* @__PURE__ */ React4.createElement(DropdownMenu.Viewport, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
1643
+ onClick: () => handleAxisMenuAction("insert-before")
1644
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1645
+ size: 5,
1646
+ icon: contextMenuAxis === "col" ? "ph--columns-plus-left--regular" : "ph--rows-plus-top--regular"
1647
+ }), /* @__PURE__ */ React4.createElement("span", null, t(`add ${contextMenuAxis} before label`))), /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
1648
+ onClick: () => handleAxisMenuAction("insert-after")
1649
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1650
+ size: 5,
1651
+ icon: contextMenuAxis === "col" ? "ph--columns-plus-right--regular" : "ph--rows-plus-bottom--regular"
1652
+ }), /* @__PURE__ */ React4.createElement("span", null, t(`add ${contextMenuAxis} after label`))), /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
1653
+ onClick: () => handleAxisMenuAction("drop")
1654
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1655
+ size: 5,
1656
+ icon: "ph--backspace--regular"
1657
+ }), /* @__PURE__ */ React4.createElement("span", null, t(`delete ${contextMenuAxis} label`)))), /* @__PURE__ */ React4.createElement(DropdownMenu.Arrow, null))));
1553
1658
  };
1554
1659
 
1555
1660
  export {
1556
1661
  ComputeGraphContextProvider,
1557
- addressToA1Notation,
1558
- rangeToA1Notation,
1559
- inRange,
1560
- createSheet,
1561
- addressToIndex,
1562
- compareIndexPositions,
1563
- computeGraphFacet,
1564
1662
  useComputeGraph,
1663
+ completeCellRangeToThreadCursor,
1664
+ computeGraphFacet,
1565
1665
  useSheetContext,
1566
1666
  SheetProvider,
1567
1667
  GridSheet,
1668
+ RangeList,
1568
1669
  SheetContainer
1569
1670
  };
1570
- //# sourceMappingURL=chunk-FGMFOW6U.mjs.map
1671
+ //# sourceMappingURL=chunk-G2FUL6PK.mjs.map