@dxos/plugin-sheet 0.6.12-main.15a606f → 0.6.12-main.2d19bf1

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 (266) hide show
  1. package/dist/lib/browser/SheetContainer-NDNIS44E.mjs +265 -0
  2. package/dist/lib/browser/SheetContainer-NDNIS44E.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-AQSGDA4X.mjs +1614 -0
  4. package/dist/lib/browser/chunk-AQSGDA4X.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-QILRZNE5.mjs → chunk-D3QTX46O.mjs} +4 -5
  6. package/dist/lib/browser/chunk-D3QTX46O.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-T3NJFTD4.mjs → chunk-GKI67SEF.mjs} +20 -26
  8. package/dist/lib/browser/chunk-GKI67SEF.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-6ZMQVB4Z.mjs → chunk-GSV5QNLD.mjs} +220 -177
  10. package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +7 -0
  11. package/dist/lib/browser/graph-M4IQ76QX.mjs +33 -0
  12. package/dist/lib/browser/index.mjs +41 -22
  13. package/dist/lib/browser/index.mjs.map +3 -3
  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 +4 -8
  17. package/dist/lib/node/SheetContainer-YSQGJD7K.cjs +276 -0
  18. package/dist/lib/node/SheetContainer-YSQGJD7K.cjs.map +7 -0
  19. package/dist/lib/node/{chunk-DD6FIXWC.cjs → chunk-5XPK2V4A.cjs} +222 -175
  20. package/dist/lib/node/chunk-5XPK2V4A.cjs.map +7 -0
  21. package/dist/lib/node/chunk-6F43RV45.cjs +1610 -0
  22. package/dist/lib/node/chunk-6F43RV45.cjs.map +7 -0
  23. package/dist/lib/node/{chunk-Q3HBHPRL.cjs → chunk-ER3PM7GD.cjs} +26 -34
  24. package/dist/lib/node/chunk-ER3PM7GD.cjs.map +7 -0
  25. package/dist/lib/node/{chunk-BNARJ5GM.cjs → chunk-QIFIGEKV.cjs} +6 -7
  26. package/dist/lib/node/chunk-QIFIGEKV.cjs.map +7 -0
  27. package/dist/lib/node/graph-Q3N2X26H.cjs +55 -0
  28. package/dist/lib/node/graph-Q3N2X26H.cjs.map +7 -0
  29. package/dist/lib/node/index.cjs +61 -44
  30. package/dist/lib/node/index.cjs.map +3 -3
  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 +8 -12
  35. package/dist/lib/node/types.cjs.map +2 -2
  36. package/dist/lib/node-esm/SheetContainer-M7WRMZDU.mjs +266 -0
  37. package/dist/lib/node-esm/SheetContainer-M7WRMZDU.mjs.map +7 -0
  38. package/dist/lib/node-esm/{chunk-D6KU5MI7.mjs → chunk-5WPZCXNS.mjs} +220 -177
  39. package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +7 -0
  40. package/dist/lib/node-esm/chunk-ELTFPX5B.mjs +1615 -0
  41. package/dist/lib/node-esm/chunk-ELTFPX5B.mjs.map +7 -0
  42. package/dist/lib/node-esm/{chunk-IU2L277A.mjs → chunk-VCYJWE3O.mjs} +4 -5
  43. package/dist/lib/node-esm/chunk-VCYJWE3O.mjs.map +7 -0
  44. package/dist/lib/node-esm/{chunk-BMNA27EX.mjs → chunk-ZVLLQ2PJ.mjs} +20 -26
  45. package/dist/lib/node-esm/chunk-ZVLLQ2PJ.mjs.map +7 -0
  46. package/dist/lib/node-esm/graph-SMPUMOV2.mjs +34 -0
  47. package/dist/lib/node-esm/index.mjs +41 -22
  48. package/dist/lib/node-esm/index.mjs.map +3 -3
  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 +4 -8
  52. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  53. package/dist/types/src/components/FunctionEditor/FunctionEditor.d.ts +3 -0
  54. package/dist/types/src/components/FunctionEditor/FunctionEditor.d.ts.map +1 -0
  55. package/dist/types/src/components/FunctionEditor/index.d.ts +2 -0
  56. package/dist/types/src/components/FunctionEditor/index.d.ts.map +1 -0
  57. package/dist/types/src/components/GridSheet/GridSheet.d.ts +1 -8
  58. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -1
  59. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +1 -1
  60. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -1
  61. package/dist/types/src/components/{CellEditor/CellEditor.stories.d.ts → GridSheet/SheetCellEditor.stories.d.ts} +2 -2
  62. package/dist/types/src/components/GridSheet/SheetCellEditor.stories.d.ts.map +1 -0
  63. package/dist/types/src/components/GridSheet/index.d.ts +2 -0
  64. package/dist/types/src/components/GridSheet/index.d.ts.map +1 -0
  65. package/dist/types/src/components/GridSheet/util.d.ts +13 -3
  66. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -1
  67. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts +6 -0
  68. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts.map +1 -0
  69. package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts +11 -0
  70. package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts.map +1 -0
  71. package/dist/types/src/components/SheetContainer/index.d.ts +3 -0
  72. package/dist/types/src/components/SheetContainer/index.d.ts.map +1 -0
  73. package/dist/types/src/components/SheetContext/SheetContext.d.ts +27 -0
  74. package/dist/types/src/components/SheetContext/SheetContext.d.ts.map +1 -0
  75. package/dist/types/src/components/SheetContext/index.d.ts +2 -0
  76. package/dist/types/src/components/SheetContext/index.d.ts.map +1 -0
  77. package/dist/types/src/components/Toolbar/Toolbar.d.ts +31 -17
  78. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  79. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +1 -1
  80. package/dist/types/src/components/index.d.ts +3 -2
  81. package/dist/types/src/components/index.d.ts.map +1 -1
  82. package/dist/types/src/defs/types.d.ts.map +1 -1
  83. package/dist/types/src/defs/util.d.ts +1 -1
  84. package/dist/types/src/defs/util.d.ts.map +1 -1
  85. package/dist/types/src/extensions/compute.d.ts +3 -2
  86. package/dist/types/src/extensions/compute.d.ts.map +1 -1
  87. package/dist/types/src/extensions/compute.stories.d.ts.map +1 -1
  88. package/dist/types/src/extensions/editor/extension.d.ts.map +1 -0
  89. package/dist/types/src/extensions/editor/extension.test.d.ts.map +1 -0
  90. package/dist/types/src/extensions/editor/index.d.ts +2 -0
  91. package/dist/types/src/extensions/editor/index.d.ts.map +1 -0
  92. package/dist/types/src/extensions/index.d.ts +1 -0
  93. package/dist/types/src/extensions/index.d.ts.map +1 -1
  94. package/dist/types/src/graph/compute-graph-registry.d.ts +34 -0
  95. package/dist/types/src/graph/compute-graph-registry.d.ts.map +1 -0
  96. package/dist/types/src/graph/compute-graph.d.ts +17 -34
  97. package/dist/types/src/graph/compute-graph.d.ts.map +1 -1
  98. package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -1
  99. package/dist/types/src/graph/compute-graph.test.d.ts +2 -0
  100. package/dist/types/src/graph/compute-graph.test.d.ts.map +1 -0
  101. package/dist/types/src/graph/compute-node.d.ts +9 -2
  102. package/dist/types/src/graph/compute-node.d.ts.map +1 -1
  103. package/dist/types/src/graph/{async-function.d.ts → functions/async-function.d.ts} +13 -4
  104. package/dist/types/src/graph/functions/async-function.d.ts.map +1 -0
  105. package/dist/types/src/graph/functions/edge-function.d.ts +21 -0
  106. package/dist/types/src/graph/functions/edge-function.d.ts.map +1 -0
  107. package/dist/types/src/graph/functions/function-defs.d.ts.map +1 -0
  108. package/dist/types/src/graph/functions/index.d.ts +4 -0
  109. package/dist/types/src/graph/functions/index.d.ts.map +1 -0
  110. package/dist/types/src/graph/index.d.ts +2 -1
  111. package/dist/types/src/graph/index.d.ts.map +1 -1
  112. package/dist/types/src/graph/testing/index.d.ts +3 -0
  113. package/dist/types/src/graph/testing/index.d.ts.map +1 -0
  114. package/dist/types/src/graph/testing/test-builder.d.ts +15 -0
  115. package/dist/types/src/graph/testing/test-builder.d.ts.map +1 -0
  116. package/dist/types/src/graph/testing/test-plugin.d.ts +36 -0
  117. package/dist/types/src/graph/testing/test-plugin.d.ts.map +1 -0
  118. package/dist/types/src/hooks/index.d.ts +1 -0
  119. package/dist/types/src/hooks/index.d.ts.map +1 -1
  120. package/dist/types/src/hooks/threads.d.ts +8 -0
  121. package/dist/types/src/hooks/threads.d.ts.map +1 -0
  122. package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -1
  123. package/dist/types/src/hooks/useSheetModel.d.ts +2 -2
  124. package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -1
  125. package/dist/types/src/meta.d.ts +3 -6
  126. package/dist/types/src/meta.d.ts.map +1 -1
  127. package/dist/types/src/{components/Sheet → model}/decorations.d.ts +1 -0
  128. package/dist/types/src/model/decorations.d.ts.map +1 -0
  129. package/dist/types/src/model/formatting-model.d.ts +3 -0
  130. package/dist/types/src/model/formatting-model.d.ts.map +1 -1
  131. package/dist/types/src/model/index.d.ts +1 -0
  132. package/dist/types/src/model/index.d.ts.map +1 -1
  133. package/dist/types/src/model/sheet-model.d.ts +6 -5
  134. package/dist/types/src/model/sheet-model.d.ts.map +1 -1
  135. package/dist/types/src/model/sheet-model.test.d.ts +2 -0
  136. package/dist/types/src/model/sheet-model.test.d.ts.map +1 -0
  137. package/dist/types/src/testing/testing.d.ts +4 -5
  138. package/dist/types/src/testing/testing.d.ts.map +1 -1
  139. package/dist/types/src/types.d.ts +17 -31
  140. package/dist/types/src/types.d.ts.map +1 -1
  141. package/package.json +42 -41
  142. package/src/SheetPlugin.tsx +22 -17
  143. package/src/components/FunctionEditor/FunctionEditor.tsx +45 -0
  144. package/src/components/FunctionEditor/index.ts +5 -0
  145. package/src/components/GridSheet/GridSheet.stories.tsx +11 -5
  146. package/src/components/GridSheet/GridSheet.tsx +78 -70
  147. package/src/components/{CellEditor/CellEditor.stories.tsx → GridSheet/SheetCellEditor.stories.tsx} +4 -5
  148. package/src/components/{Sheet → GridSheet}/index.ts +1 -1
  149. package/src/components/GridSheet/util.ts +94 -39
  150. package/src/components/SheetContainer/SheetContainer.stories.tsx +40 -0
  151. package/src/components/SheetContainer/SheetContainer.tsx +52 -0
  152. package/src/components/SheetContainer/index.ts +7 -0
  153. package/src/components/{Sheet/sheet-context.tsx → SheetContext/SheetContext.tsx} +48 -28
  154. package/src/components/SheetContext/index.ts +5 -0
  155. package/src/components/Toolbar/Toolbar.tsx +127 -86
  156. package/src/components/index.ts +2 -1
  157. package/src/defs/types.ts +1 -0
  158. package/src/defs/util.ts +20 -4
  159. package/src/extensions/compute.stories.tsx +23 -23
  160. package/src/extensions/compute.ts +91 -42
  161. package/src/{components/CellEditor → extensions/editor}/extension.test.ts +0 -1
  162. package/src/{components/CellEditor → extensions/editor}/extension.ts +4 -3
  163. package/src/{components/CellEditor → extensions/editor}/index.ts +0 -1
  164. package/src/extensions/index.ts +1 -0
  165. package/src/graph/compute-graph-registry.ts +90 -0
  166. package/src/graph/compute-graph.stories.tsx +4 -3
  167. package/src/graph/compute-graph.test.ts +87 -0
  168. package/src/graph/compute-graph.ts +73 -121
  169. package/src/graph/compute-node.ts +17 -5
  170. package/src/graph/{async-function.ts → functions/async-function.ts} +23 -15
  171. package/src/graph/{edge-function.ts → functions/edge-function.ts} +14 -13
  172. package/src/graph/functions/index.ts +7 -0
  173. package/src/graph/hyperformula.test.ts +1 -2
  174. package/src/graph/index.ts +2 -1
  175. package/src/graph/testing/index.ts +6 -0
  176. package/src/graph/testing/test-builder.ts +54 -0
  177. package/src/graph/{custom-function.ts → testing/test-plugin.ts} +43 -9
  178. package/src/hooks/hooks.stories.tsx +3 -3
  179. package/src/hooks/index.ts +1 -0
  180. package/src/{components/Sheet/threads.tsx → hooks/threads.ts} +26 -84
  181. package/src/hooks/useComputeGraph.ts +9 -1
  182. package/src/hooks/useSheetModel.ts +4 -7
  183. package/src/{meta.tsx → meta.ts} +3 -3
  184. package/src/{components/Sheet → model}/decorations.ts +2 -0
  185. package/src/model/formatting-model.ts +12 -9
  186. package/src/model/index.ts +1 -0
  187. package/src/model/sheet-model.test.ts +57 -0
  188. package/src/model/sheet-model.ts +60 -41
  189. package/src/testing/testing.tsx +17 -15
  190. package/src/types.ts +12 -38
  191. package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs +0 -261
  192. package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs.map +0 -7
  193. package/dist/lib/browser/chunk-6ZMQVB4Z.mjs.map +0 -7
  194. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +0 -7
  195. package/dist/lib/browser/chunk-T3NJFTD4.mjs.map +0 -7
  196. package/dist/lib/browser/chunk-U2JHW3L6.mjs +0 -2552
  197. package/dist/lib/browser/chunk-U2JHW3L6.mjs.map +0 -7
  198. package/dist/lib/browser/graph-T27BOBOV.mjs +0 -21
  199. package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs +0 -279
  200. package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs.map +0 -7
  201. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +0 -7
  202. package/dist/lib/node/chunk-DD6FIXWC.cjs.map +0 -7
  203. package/dist/lib/node/chunk-OTTD7FBK.cjs +0 -2536
  204. package/dist/lib/node/chunk-OTTD7FBK.cjs.map +0 -7
  205. package/dist/lib/node/chunk-Q3HBHPRL.cjs.map +0 -7
  206. package/dist/lib/node/graph-SPKGX7W4.cjs +0 -43
  207. package/dist/lib/node/graph-SPKGX7W4.cjs.map +0 -7
  208. package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs +0 -262
  209. package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs.map +0 -7
  210. package/dist/lib/node-esm/chunk-7HVSOTGA.mjs +0 -2553
  211. package/dist/lib/node-esm/chunk-7HVSOTGA.mjs.map +0 -7
  212. package/dist/lib/node-esm/chunk-BMNA27EX.mjs.map +0 -7
  213. package/dist/lib/node-esm/chunk-D6KU5MI7.mjs.map +0 -7
  214. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +0 -7
  215. package/dist/lib/node-esm/graph-U67IO4UC.mjs +0 -22
  216. package/dist/types/src/components/CellEditor/CellEditor.d.ts +0 -34
  217. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +0 -1
  218. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +0 -1
  219. package/dist/types/src/components/CellEditor/extension.d.ts.map +0 -1
  220. package/dist/types/src/components/CellEditor/extension.test.d.ts.map +0 -1
  221. package/dist/types/src/components/CellEditor/index.d.ts +0 -3
  222. package/dist/types/src/components/CellEditor/index.d.ts.map +0 -1
  223. package/dist/types/src/components/Sheet/Sheet.d.ts +0 -55
  224. package/dist/types/src/components/Sheet/Sheet.d.ts.map +0 -1
  225. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +0 -53
  226. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +0 -1
  227. package/dist/types/src/components/Sheet/decorations.d.ts.map +0 -1
  228. package/dist/types/src/components/Sheet/grid.d.ts +0 -52
  229. package/dist/types/src/components/Sheet/grid.d.ts.map +0 -1
  230. package/dist/types/src/components/Sheet/index.d.ts +0 -2
  231. package/dist/types/src/components/Sheet/index.d.ts.map +0 -1
  232. package/dist/types/src/components/Sheet/nav.d.ts +0 -29
  233. package/dist/types/src/components/Sheet/nav.d.ts.map +0 -1
  234. package/dist/types/src/components/Sheet/sheet-context.d.ts +0 -26
  235. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +0 -1
  236. package/dist/types/src/components/Sheet/threads.d.ts +0 -2
  237. package/dist/types/src/components/Sheet/threads.d.ts.map +0 -1
  238. package/dist/types/src/components/Sheet/util.d.ts +0 -18
  239. package/dist/types/src/components/Sheet/util.d.ts.map +0 -1
  240. package/dist/types/src/components/SheetContainer.d.ts +0 -8
  241. package/dist/types/src/components/SheetContainer.d.ts.map +0 -1
  242. package/dist/types/src/components/Toolbar/common.d.ts +0 -20
  243. package/dist/types/src/components/Toolbar/common.d.ts.map +0 -1
  244. package/dist/types/src/graph/async-function.d.ts.map +0 -1
  245. package/dist/types/src/graph/compute-graph.browser.test.d.ts +0 -2
  246. package/dist/types/src/graph/compute-graph.browser.test.d.ts.map +0 -1
  247. package/dist/types/src/graph/custom-function.d.ts +0 -21
  248. package/dist/types/src/graph/custom-function.d.ts.map +0 -1
  249. package/dist/types/src/graph/edge-function.d.ts +0 -20
  250. package/dist/types/src/graph/edge-function.d.ts.map +0 -1
  251. package/dist/types/src/graph/function-defs.d.ts.map +0 -1
  252. package/src/components/CellEditor/CellEditor.tsx +0 -163
  253. package/src/components/Sheet/Sheet.stories.tsx +0 -250
  254. package/src/components/Sheet/Sheet.tsx +0 -1199
  255. package/src/components/Sheet/grid.ts +0 -191
  256. package/src/components/Sheet/nav.ts +0 -157
  257. package/src/components/Sheet/util.ts +0 -56
  258. package/src/components/SheetContainer.tsx +0 -88
  259. package/src/components/Toolbar/common.tsx +0 -72
  260. package/src/graph/compute-graph.browser.test.ts +0 -104
  261. /package/dist/lib/browser/{graph-T27BOBOV.mjs.map → graph-M4IQ76QX.mjs.map} +0 -0
  262. /package/dist/lib/node-esm/{graph-U67IO4UC.mjs.map → graph-SMPUMOV2.mjs.map} +0 -0
  263. /package/dist/types/src/{components/CellEditor → extensions/editor}/extension.d.ts +0 -0
  264. /package/dist/types/src/{components/CellEditor → extensions/editor}/extension.test.d.ts +0 -0
  265. /package/dist/types/src/graph/{function-defs.d.ts → functions/function-defs.d.ts} +0 -0
  266. /package/src/graph/{function-defs.ts → functions/function-defs.ts} +0 -0
@@ -8,14 +8,30 @@ import { type ProcedureAst } from 'hyperformula/typings/parser';
8
8
  import { getDeep } from '@dxos/util';
9
9
 
10
10
  import { FunctionArgumentType } from '#hyperformula';
11
- import { type AsyncFunction, FunctionPluginAsync } from './async-function';
12
- import { parseNumberString } from './util';
11
+ import { type ComputeGraphPlugin } from '../compute-graph-registry';
12
+ import { type AsyncFunction, AsyncFunctionPlugin } from '../functions';
13
+ import { parseNumberString } from '../util';
13
14
 
14
15
  /**
16
+ * Testing functions run locally (not run via EDGE).
15
17
  * https://hyperformula.handsontable.com/guide/custom-functions.html#add-a-simple-custom-function
16
18
  */
17
- export class CustomPlugin extends FunctionPluginAsync {
19
+ export class TestPlugin extends AsyncFunctionPlugin {
20
+ /**
21
+ * Simple local function returns input value.
22
+ */
18
23
  test(ast: ProcedureAst, state: InterpreterState) {
24
+ const handler: AsyncFunction = async (_value) => {
25
+ return _value;
26
+ };
27
+
28
+ return this.runAsyncFunction(ast, state, handler);
29
+ }
30
+
31
+ /**
32
+ * Simple local function returns random number.
33
+ */
34
+ random(ast: ProcedureAst, state: InterpreterState) {
19
35
  const handler: AsyncFunction = async () => {
20
36
  return Math.random();
21
37
  };
@@ -23,6 +39,9 @@ export class CustomPlugin extends FunctionPluginAsync {
23
39
  return this.runAsyncFunction(ast, state, handler);
24
40
  }
25
41
 
42
+ /**
43
+ * Async HTTP function.
44
+ */
26
45
  crypto(ast: ProcedureAst, state: InterpreterState) {
27
46
  const handler: AsyncFunction = async (_currency) => {
28
47
  const currency = (_currency || 'USD').toUpperCase();
@@ -40,9 +59,15 @@ export class CustomPlugin extends FunctionPluginAsync {
40
59
  }
41
60
  }
42
61
 
43
- CustomPlugin.implementedFunctions = {
62
+ TestPlugin.implementedFunctions = {
44
63
  TEST: {
45
64
  method: 'test',
65
+ parameters: [{ argumentType: FunctionArgumentType.NUMBER, optionalArg: false }],
66
+ isVolatile: true,
67
+ },
68
+
69
+ RANDOM: {
70
+ method: 'random',
46
71
  parameters: [],
47
72
  isVolatile: true,
48
73
  },
@@ -54,13 +79,22 @@ CustomPlugin.implementedFunctions = {
54
79
  },
55
80
  };
56
81
 
57
- export const CustomPluginTranslations = {
82
+ export const TestPluginTranslations = {
58
83
  enGB: {
59
- TEST: 'TEST',
60
- CRYPTO: 'CRYPTO',
84
+ TEST: 'Returns input value',
85
+ RANDOM: 'Random number',
86
+ CRYPTO: 'Crypto token value',
61
87
  },
62
88
  enUS: {
63
- TEST: 'TEST',
64
- CRYPTO: 'CRYPTO',
89
+ TEST: 'Returns input value',
90
+ RANDOM: 'Random number',
91
+ CRYPTO: 'Crypto token value',
65
92
  },
66
93
  };
94
+
95
+ export const testFunctionPlugins: ComputeGraphPlugin[] = [
96
+ {
97
+ plugin: TestPlugin,
98
+ translations: TestPluginTranslations,
99
+ },
100
+ ];
@@ -14,14 +14,14 @@ import { withTheme } from '@dxos/storybook-utils';
14
14
  import { ComputeGraphContextProvider } from '../components';
15
15
  import { createSheet } from '../defs';
16
16
  import { useComputeGraph, useSheetModel } from '../hooks';
17
- import { withGraphDecorator } from '../testing';
17
+ import { withComputeGraphDecorator } from '../testing';
18
18
  import { SheetType } from '../types';
19
19
 
20
20
  const Story = () => {
21
21
  const space = useSpace();
22
22
  const graph = useComputeGraph(space);
23
23
  const [sheet, setSheet] = useState<SheetType>();
24
- const model = useSheetModel(space, sheet);
24
+ const model = useSheetModel(graph, sheet);
25
25
  useEffect(() => {
26
26
  if (space) {
27
27
  const sheet = space.db.add(createSheet());
@@ -41,7 +41,7 @@ export default {
41
41
  component: ComputeGraphContextProvider,
42
42
  decorators: [
43
43
  withClientProvider({ types: [SheetType], createIdentity: true, createSpace: true }),
44
- withGraphDecorator,
44
+ withComputeGraphDecorator(),
45
45
  withTheme,
46
46
  ],
47
47
  render: (args: any) => <Story {...args} />,
@@ -5,3 +5,4 @@
5
5
  export * from './useComputeGraph';
6
6
  export * from './useFormattingModel';
7
7
  export * from './useSheetModel';
8
+ export * from './threads';
@@ -3,82 +3,21 @@
3
3
  //
4
4
 
5
5
  import { effect } from '@preact/signals-core';
6
- import React, { type PropsWithChildren, useCallback, useEffect, useMemo } from 'react';
6
+ import { type MutableRefObject, useCallback, useEffect, useMemo } from 'react';
7
7
 
8
8
  import { type IntentResolver, LayoutAction, useIntentDispatcher, useIntentResolver } from '@dxos/app-framework';
9
9
  import { debounce } from '@dxos/async';
10
10
  import { fullyQualifiedId } from '@dxos/react-client/echo';
11
- import { Icon, useTranslation } from '@dxos/react-ui';
11
+ import { type DxGridElement, type DxGridPosition } from '@dxos/react-ui-grid';
12
12
 
13
- import { type Decoration } from './decorations';
14
- import { useSheetContext } from './sheet-context';
15
- import { addressFromIndex, addressToIndex, type CellAddress, closest } from '../../defs';
16
- import { SHEET_PLUGIN } from '../../meta';
17
-
18
- // TODO(burdon): Move into folder; split hooks.
19
-
20
- const CommentIndicator = () => {
21
- return (
22
- <div
23
- role='none'
24
- className='absolute top-0 right-0 w-0 h-0 border-t-8 border-l-8 border-t-cmCommentSurface border-l-transparent'
25
- />
26
- );
27
- };
28
-
29
- const ThreadedCellWrapper = ({ children }: PropsWithChildren) => {
30
- const dispatch = useIntentDispatcher();
31
- const [isHovered, setIsHovered] = React.useState(false);
32
- const { t } = useTranslation(SHEET_PLUGIN);
33
-
34
- const handleClick = React.useCallback(
35
- (_event: React.MouseEvent) => {
36
- void dispatch({ action: LayoutAction.SET_LAYOUT, data: { element: 'complementary', state: true } });
37
- },
38
- [dispatch],
39
- );
40
-
41
- return (
42
- <div
43
- role='none'
44
- className='relative h-full is-full'
45
- onMouseEnter={() => {
46
- setIsHovered(true);
47
- }}
48
- onMouseLeave={() => {
49
- setIsHovered(false);
50
- }}
51
- >
52
- <CommentIndicator />
53
- {isHovered && (
54
- <div className='absolute inset-0 flex items-center justify-end pr-1'>
55
- <button
56
- className='ch-button text-xs min-bs-0 p-1'
57
- onClick={handleClick}
58
- aria-label={t('open comment for sheet cell')}
59
- >
60
- <Icon icon='ph--chat--regular' aria-hidden={true} />
61
- </button>
62
- </div>
63
- )}
64
- {children}
65
- </div>
66
- );
67
- };
68
-
69
- const createThreadDecoration = (cellIndex: string, threadId: string, sheetId: string): Decoration => {
70
- return {
71
- type: 'comment',
72
- cellIndex,
73
- decorate: (props) => <ThreadedCellWrapper {...props} />,
74
- };
75
- };
76
-
77
- // TODO(burdon): Factor out hooks.
78
-
79
- const useUpdateCursorOnThreadSelection = () => {
80
- const { setCursor, model } = useSheetContext();
13
+ import { addressFromIndex, addressToIndex, type CellAddress, closest } from '../defs';
14
+ import { SHEET_PLUGIN } from '../meta';
15
+ import { type SheetModel, type Decoration, type Decorations } from '../model';
81
16
 
17
+ export const useUpdateFocusedCellOnThreadSelection = (
18
+ model: SheetModel,
19
+ grid: MutableRefObject<DxGridElement | null>,
20
+ ) => {
82
21
  const handleScrollIntoView: IntentResolver = useCallback(
83
22
  ({ action, data }) => {
84
23
  switch (action) {
@@ -89,18 +28,17 @@ const useUpdateCursorOnThreadSelection = () => {
89
28
 
90
29
  // TODO(Zan): Everywhere we refer to the cursor in a thread context should change to `anchor`.
91
30
  const cellAddress = addressFromIndex(model.sheet, data.cursor);
92
- setCursor(cellAddress);
31
+ grid.current?.setFocus({ ...cellAddress, plane: 'grid' }, true);
93
32
  }
94
33
  }
95
34
  },
96
- [model.sheet, setCursor],
35
+ [model.sheet],
97
36
  );
98
37
 
99
38
  useIntentResolver(SHEET_PLUGIN, handleScrollIntoView);
100
39
  };
101
40
 
102
- const useSelectThreadOnCursorChange = () => {
103
- const { cursor, model } = useSheetContext();
41
+ export const useSelectThreadOnCellFocus = (model: SheetModel, cursor?: CellAddress) => {
104
42
  const dispatch = useIntentDispatcher();
105
43
 
106
44
  const activeThreads = useMemo(
@@ -108,7 +46,10 @@ const useSelectThreadOnCursorChange = () => {
108
46
  model.sheet.threads?.filter(
109
47
  (thread): thread is NonNullable<typeof thread> => !!thread && thread.status === 'active',
110
48
  ) ?? [],
111
- [JSON.stringify(model.sheet.threads)],
49
+ [
50
+ // TODO(thure): Surely we can find a better dependency for this…
51
+ JSON.stringify(model.sheet.threads),
52
+ ],
112
53
  );
113
54
 
114
55
  const activeThreadAddresses = useMemo(
@@ -143,7 +84,7 @@ const useSelectThreadOnCursorChange = () => {
143
84
  );
144
85
 
145
86
  const debounced = useMemo(() => {
146
- return debounce((cursor: CellAddress) => requestAnimationFrame(() => selectClosestThread(cursor)), 50);
87
+ return debounce((cellCoords: DxGridPosition) => requestAnimationFrame(() => selectClosestThread(cellCoords)), 50);
147
88
  }, [selectClosestThread]);
148
89
 
149
90
  useEffect(() => {
@@ -154,8 +95,15 @@ const useSelectThreadOnCursorChange = () => {
154
95
  }, [cursor, selectClosestThread]);
155
96
  };
156
97
 
157
- const useThreadDecorations = () => {
158
- const { decorations, model } = useSheetContext();
98
+ const createThreadDecoration = (cellIndex: string, threadId: string, sheetId: string): Decoration => {
99
+ return {
100
+ type: 'comment',
101
+ classNames: ['bg-greenFill'],
102
+ cellIndex,
103
+ };
104
+ };
105
+
106
+ export const useThreadDecorations = (model: SheetModel, decorations: Decorations) => {
159
107
  const sheet = useMemo(() => model.sheet, [model.sheet]);
160
108
  const sheetId = useMemo(() => fullyQualifiedId(sheet), [sheet]);
161
109
 
@@ -197,9 +145,3 @@ const useThreadDecorations = () => {
197
145
  return () => unsubscribe();
198
146
  });
199
147
  };
200
-
201
- export const useThreads = () => {
202
- useUpdateCursorOnThreadSelection();
203
- useSelectThreadOnCursorChange();
204
- useThreadDecorations();
205
- };
@@ -16,5 +16,13 @@ import { type ComputeGraph } from '../graph';
16
16
  */
17
17
  export const useComputeGraph = (space?: Space): ComputeGraph | undefined => {
18
18
  const { registry } = useContext(ComputeGraphContext) ?? raise(new Error('Missing ComputeGraphContext'));
19
- return useAsyncState(async () => space && registry.getOrCreateGraph(space), [space, registry]);
19
+ const [graph] = useAsyncState(async () => {
20
+ if (space) {
21
+ const graph = registry.getOrCreateGraph(space);
22
+ await graph.open();
23
+ return graph;
24
+ }
25
+ }, [space, registry]);
26
+
27
+ return graph;
20
28
  };
@@ -4,9 +4,7 @@
4
4
 
5
5
  import { useEffect, useState } from 'react';
6
6
 
7
- import { type Space } from '@dxos/react-client/echo';
8
-
9
- import { useComputeGraph } from './useComputeGraph';
7
+ import { type ComputeGraph } from '../graph';
10
8
  import { SheetModel } from '../model';
11
9
  import { type SheetType } from '../types';
12
10
 
@@ -15,14 +13,13 @@ export type UseSheetModelOptions = {
15
13
  };
16
14
 
17
15
  export const useSheetModel = (
18
- space?: Space,
16
+ graph?: ComputeGraph,
19
17
  sheet?: SheetType,
20
18
  { readonly }: UseSheetModelOptions = {},
21
19
  ): SheetModel | undefined => {
22
- const graph = useComputeGraph(space);
23
20
  const [model, setModel] = useState<SheetModel>();
24
21
  useEffect(() => {
25
- if (!space || !graph || !sheet) {
22
+ if (!graph || !sheet) {
26
23
  return;
27
24
  }
28
25
 
@@ -37,7 +34,7 @@ export const useSheetModel = (
37
34
  clearTimeout(t);
38
35
  void model?.close();
39
36
  };
40
- }, [space, sheet, graph, readonly]);
37
+ }, [graph, sheet, readonly]);
41
38
 
42
39
  return model;
43
40
  };
@@ -2,13 +2,13 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { pluginMeta } from '@dxos/app-framework';
5
+ import { type PluginMeta } from '@dxos/app-framework';
6
6
 
7
7
  export const SHEET_PLUGIN = 'dxos.org/plugin/sheet';
8
8
 
9
- export default pluginMeta({
9
+ export default {
10
10
  id: SHEET_PLUGIN,
11
11
  name: 'Sheet',
12
12
  description: 'A simple spreadsheet plugin.',
13
13
  icon: 'ph--grid-nine--regular',
14
- });
14
+ } satisfies PluginMeta;
@@ -60,3 +60,5 @@ export const createDecorations = () => {
60
60
  getAllDecorations,
61
61
  } as const;
62
62
  };
63
+
64
+ export type Decorations = ReturnType<typeof createDecorations>;
@@ -3,17 +3,20 @@
3
3
  //
4
4
 
5
5
  import { type ClassNameValue } from '@dxos/react-ui-types';
6
+ import { FieldValueType } from '@dxos/schema';
6
7
 
7
8
  import { type SheetModel } from './sheet-model';
8
9
  import { type CellAddress, inRange } from '../defs';
9
10
  import { addressToIndex, rangeFromIndex } from '../defs';
10
- import { ValueTypeEnum } from '../types';
11
11
 
12
12
  export type CellFormat = {
13
13
  value?: string;
14
14
  classNames?: ClassNameValue;
15
15
  };
16
16
 
17
+ /**
18
+ * @deprecated See react-ui-data.
19
+ */
17
20
  export class FormattingModel {
18
21
  constructor(private readonly _model: SheetModel) {}
19
22
 
@@ -31,7 +34,7 @@ export class FormattingModel {
31
34
 
32
35
  // Cell-specific formatting.
33
36
  const idx = addressToIndex(this._model.sheet, cell);
34
- let formatting = this._model.sheet.formatting?.[idx] ?? {};
37
+ let formatting = this._model.sheet.formatting.find?.(({ range }) => range === idx);
35
38
  const classNames = [...(formatting?.classNames ?? [])];
36
39
 
37
40
  // Range formatting.
@@ -55,7 +58,7 @@ export class FormattingModel {
55
58
 
56
59
  const type = formatting?.type ?? this._model.getValueType(cell);
57
60
  switch (type) {
58
- case ValueTypeEnum.Boolean: {
61
+ case FieldValueType.Boolean: {
59
62
  return {
60
63
  value: (value as boolean).toLocaleString().toUpperCase(),
61
64
  classNames: [...classNames, value ? '!text-greenText' : '!text-orangeText'],
@@ -66,15 +69,15 @@ export class FormattingModel {
66
69
  // Numbers.
67
70
  //
68
71
 
69
- case ValueTypeEnum.Number: {
72
+ case FieldValueType.Number: {
70
73
  return { value: value.toLocaleString(locales), classNames: [...classNames, defaultNumber] };
71
74
  }
72
75
 
73
- case ValueTypeEnum.Percent: {
76
+ case FieldValueType.Percent: {
74
77
  return { value: (value as number) * 100 + '%', classNames: [...classNames, defaultNumber] };
75
78
  }
76
79
 
77
- case ValueTypeEnum.Currency: {
80
+ case FieldValueType.Currency: {
78
81
  return {
79
82
  value: (value as number).toLocaleString(locales, {
80
83
  style: 'currency',
@@ -90,17 +93,17 @@ export class FormattingModel {
90
93
  // Dates.
91
94
  //
92
95
 
93
- case ValueTypeEnum.DateTime: {
96
+ case FieldValueType.DateTime: {
94
97
  const date = this._model.toLocalDate(value as number);
95
98
  return { value: date.toLocaleString(locales), classNames };
96
99
  }
97
100
 
98
- case ValueTypeEnum.Date: {
101
+ case FieldValueType.Date: {
99
102
  const date = this._model.toLocalDate(value as number);
100
103
  return { value: date.toLocaleDateString(locales), classNames };
101
104
  }
102
105
 
103
- case ValueTypeEnum.Time: {
106
+ case FieldValueType.Time: {
104
107
  const date = this._model.toLocalDate(value as number);
105
108
  return { value: date.toLocaleTimeString(locales), classNames };
106
109
  }
@@ -2,5 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ export * from './decorations';
5
6
  export * from './formatting-model';
6
7
  export * from './sheet-model';
@@ -0,0 +1,57 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { afterEach, beforeEach, describe, expect, test } from 'vitest';
6
+
7
+ import { Trigger } from '@dxos/async';
8
+ import { FunctionType } from '@dxos/plugin-script/types';
9
+
10
+ import { SheetModel } from './sheet-model';
11
+ import { addressFromA1Notation, createSheet } from '../defs';
12
+ import { TestBuilder, testFunctionPlugins } from '../graph/testing';
13
+ import { type CellScalarValue } from '../types';
14
+
15
+ describe('SheetModel', () => {
16
+ let testBuilder: TestBuilder;
17
+ beforeEach(async () => {
18
+ testBuilder = new TestBuilder({ types: [FunctionType], plugins: testFunctionPlugins });
19
+ await testBuilder.open();
20
+ });
21
+ afterEach(async () => {
22
+ await testBuilder.close();
23
+ });
24
+
25
+ test('async function', async () => {
26
+ const space = await testBuilder.client.spaces.create();
27
+ const graph = testBuilder.registry.createGraph(space);
28
+ await graph.open();
29
+
30
+ // TODO(burdon): Create via factory.
31
+ const sheet = createSheet({ rows: 5, columns: 5 });
32
+ const model = new SheetModel(graph, sheet);
33
+ await model.open();
34
+ testBuilder.ctx.onDispose(() => model.close());
35
+
36
+ // Trigger waits for function invocation.
37
+ const trigger = new Trigger<CellScalarValue>();
38
+ model.setValue(addressFromA1Notation('A1'), '=TEST(100)');
39
+ model.update.once((update) => {
40
+ const { type } = update;
41
+ if (type === 'valuesUpdated') {
42
+ const value = model.getValue(addressFromA1Notation('A1'));
43
+ trigger.wake(value);
44
+ }
45
+ });
46
+
47
+ // Initial value will be null.
48
+ const v1 = model.getValue(addressFromA1Notation('A1'));
49
+ expect(v1).to.be.null;
50
+ expect(graph.context.info.invocations.TEST).not.to.exist;
51
+
52
+ // Wait until async update triggered.
53
+ const v2 = await trigger.wait();
54
+ expect(v2).to.eq(100);
55
+ expect(graph.context.info.invocations.TEST).to.eq(1);
56
+ });
57
+ });