@dxos/plugin-sheet 0.6.14-main.7bd9c89 → 0.6.14-staging.3e2eaca

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