@dxos/plugin-sheet 0.6.12-main.ed7cda7 → 0.6.12-staging.0b4bb48

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 (260) hide show
  1. package/dist/lib/browser/{chunk-U2JHW3L6.mjs → SheetContainer-U4H5D34A.mjs} +240 -1020
  2. package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-APHOLYUB.mjs +175 -0
  4. package/dist/lib/browser/chunk-APHOLYUB.mjs.map +7 -0
  5. package/dist/lib/{node-esm/chunk-D6KU5MI7.mjs → browser/chunk-D5AGLXJP.mjs} +670 -360
  6. package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-T3NJFTD4.mjs → chunk-FUAGSXA4.mjs} +15 -8
  8. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-QILRZNE5.mjs → chunk-JRL5LGCE.mjs} +5 -2
  10. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-NU4PBN33.mjs +8 -0
  12. package/dist/lib/browser/chunk-NU4PBN33.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +56 -68
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/meta.mjs +1 -1
  17. package/dist/lib/browser/testing.mjs +92 -0
  18. package/dist/lib/browser/testing.mjs.map +7 -0
  19. package/dist/lib/browser/types.mjs +6 -4
  20. package/dist/lib/node/{chunk-OTTD7FBK.cjs → SheetContainer-AXQV3ZT5.cjs} +279 -1050
  21. package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-DD6FIXWC.cjs → chunk-5KKJ4NPP.cjs} +667 -360
  23. package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-BNARJ5GM.cjs → chunk-BJ6ZD7MN.cjs} +18 -5
  25. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +7 -0
  26. package/dist/lib/node/chunk-CN3RPESU.cjs +202 -0
  27. package/dist/lib/node/chunk-CN3RPESU.cjs.map +7 -0
  28. package/dist/lib/node/{chunk-Q3HBHPRL.cjs → chunk-DSYKOI4E.cjs} +20 -12
  29. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +7 -0
  30. package/dist/lib/node/chunk-PYXHNAAK.cjs +40 -0
  31. package/dist/lib/node/chunk-PYXHNAAK.cjs.map +7 -0
  32. package/dist/lib/node/index.cjs +64 -83
  33. package/dist/lib/node/index.cjs.map +3 -3
  34. package/dist/lib/node/meta.cjs +3 -3
  35. package/dist/lib/node/meta.cjs.map +1 -1
  36. package/dist/lib/node/meta.json +1 -1
  37. package/dist/lib/node/testing.cjs +111 -0
  38. package/dist/lib/node/testing.cjs.map +7 -0
  39. package/dist/lib/node/types.cjs +12 -10
  40. package/dist/lib/node/types.cjs.map +2 -2
  41. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  42. package/dist/types/src/components/CellEditor/CellEditor.d.ts +3 -23
  43. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -1
  44. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts +2 -2
  45. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/CellEditor/extension.d.ts +1 -1
  47. package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
  48. package/dist/types/src/{graph → components/ComputeGraph}/async-function.d.ts +1 -1
  49. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +1 -0
  50. package/dist/types/src/{graph/custom-function.d.ts → components/ComputeGraph/custom.d.ts} +1 -1
  51. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +1 -0
  52. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +1 -0
  53. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +12 -0
  54. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +1 -0
  55. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +2 -0
  56. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +1 -0
  57. package/dist/types/src/components/ComputeGraph/graph.d.ts +26 -0
  58. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +1 -0
  59. package/dist/types/src/components/ComputeGraph/index.d.ts +3 -1
  60. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  61. package/dist/types/src/components/Sheet/Sheet.d.ts +1 -1
  62. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  63. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +6 -5
  64. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/Sheet/formatting.d.ts +14 -0
  66. package/dist/types/src/components/Sheet/formatting.d.ts.map +1 -0
  67. package/dist/types/src/components/Sheet/grid.d.ts +2 -2
  68. package/dist/types/src/components/Sheet/grid.d.ts.map +1 -1
  69. package/dist/types/src/components/Sheet/nav.d.ts +3 -3
  70. package/dist/types/src/components/Sheet/nav.d.ts.map +1 -1
  71. package/dist/types/src/components/Sheet/sheet-context.d.ts +5 -6
  72. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
  73. package/dist/types/src/components/SheetContainer.d.ts +3 -2
  74. package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
  75. package/dist/types/src/components/Toolbar/Toolbar.d.ts +3 -19
  76. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  77. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +13 -18
  78. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  79. package/dist/types/src/components/index.d.ts +2 -2
  80. package/dist/types/src/components/index.d.ts.map +1 -1
  81. package/dist/types/src/meta.d.ts +4 -1
  82. package/dist/types/src/meta.d.ts.map +1 -1
  83. package/dist/types/src/{graph/function-defs.d.ts → model/functions.d.ts} +1 -1
  84. package/dist/types/src/model/functions.d.ts.map +1 -0
  85. package/dist/types/src/model/index.d.ts +3 -2
  86. package/dist/types/src/model/index.d.ts.map +1 -1
  87. package/dist/types/src/model/model.browser.test.d.ts +2 -0
  88. package/dist/types/src/model/model.browser.test.d.ts.map +1 -0
  89. package/dist/types/src/model/{sheet-model.d.ts → model.d.ts} +64 -9
  90. package/dist/types/src/model/model.d.ts.map +1 -0
  91. package/dist/types/src/{defs → model}/types.d.ts +3 -8
  92. package/dist/types/src/model/types.d.ts.map +1 -0
  93. package/dist/types/src/model/types.test.d.ts.map +1 -0
  94. package/dist/types/src/model/util.d.ts +15 -0
  95. package/dist/types/src/model/util.d.ts.map +1 -0
  96. package/dist/types/src/testing.d.ts +9 -0
  97. package/dist/types/src/testing.d.ts.map +1 -0
  98. package/dist/types/src/translations.d.ts +12 -17
  99. package/dist/types/src/translations.d.ts.map +1 -1
  100. package/dist/types/src/types.d.ts +3 -83
  101. package/dist/types/src/types.d.ts.map +1 -1
  102. package/package.json +41 -48
  103. package/src/SheetPlugin.tsx +70 -43
  104. package/src/components/CellEditor/CellEditor.stories.tsx +3 -4
  105. package/src/components/CellEditor/CellEditor.tsx +9 -59
  106. package/src/components/CellEditor/extension.test.ts +5 -4
  107. package/src/components/CellEditor/extension.ts +3 -1
  108. package/src/{graph → components/ComputeGraph}/async-function.ts +1 -3
  109. package/src/{graph/custom-function.ts → components/ComputeGraph/custom.ts} +6 -2
  110. package/src/{graph → components/ComputeGraph}/edge-function.ts +1 -2
  111. package/src/components/ComputeGraph/graph-context.tsx +50 -0
  112. package/src/components/ComputeGraph/graph.browser.test.ts +50 -0
  113. package/src/components/ComputeGraph/graph.ts +62 -0
  114. package/src/components/ComputeGraph/index.ts +3 -1
  115. package/src/components/Sheet/Sheet.stories.tsx +82 -45
  116. package/src/components/Sheet/Sheet.tsx +18 -57
  117. package/src/{model/formatting-model.ts → components/Sheet/formatting.ts} +13 -20
  118. package/src/components/Sheet/grid.ts +3 -3
  119. package/src/components/Sheet/nav.ts +19 -19
  120. package/src/components/Sheet/sheet-context.tsx +78 -16
  121. package/src/components/SheetContainer.tsx +19 -73
  122. package/src/components/Toolbar/Toolbar.tsx +12 -53
  123. package/src/components/index.ts +0 -1
  124. package/src/meta.tsx +5 -1
  125. package/src/model/index.ts +3 -2
  126. package/src/model/model.browser.test.ts +100 -0
  127. package/src/model/model.ts +550 -0
  128. package/src/{defs → model}/types.test.ts +9 -8
  129. package/src/{defs → model}/types.ts +14 -23
  130. package/src/model/util.ts +36 -0
  131. package/src/testing.ts +50 -0
  132. package/src/translations.ts +1 -6
  133. package/src/types.ts +5 -30
  134. package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs +0 -261
  135. package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs.map +0 -7
  136. package/dist/lib/browser/chunk-6ZMQVB4Z.mjs +0 -2923
  137. package/dist/lib/browser/chunk-6ZMQVB4Z.mjs.map +0 -7
  138. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +0 -7
  139. package/dist/lib/browser/chunk-T3NJFTD4.mjs.map +0 -7
  140. package/dist/lib/browser/chunk-U2JHW3L6.mjs.map +0 -7
  141. package/dist/lib/browser/graph-T27BOBOV.mjs +0 -21
  142. package/dist/lib/browser/graph-T27BOBOV.mjs.map +0 -7
  143. package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs +0 -279
  144. package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs.map +0 -7
  145. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +0 -7
  146. package/dist/lib/node/chunk-DD6FIXWC.cjs.map +0 -7
  147. package/dist/lib/node/chunk-OTTD7FBK.cjs.map +0 -7
  148. package/dist/lib/node/chunk-Q3HBHPRL.cjs.map +0 -7
  149. package/dist/lib/node/graph-SPKGX7W4.cjs +0 -43
  150. package/dist/lib/node/graph-SPKGX7W4.cjs.map +0 -7
  151. package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs +0 -262
  152. package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs.map +0 -7
  153. package/dist/lib/node-esm/chunk-7HVSOTGA.mjs +0 -2553
  154. package/dist/lib/node-esm/chunk-7HVSOTGA.mjs.map +0 -7
  155. package/dist/lib/node-esm/chunk-BMNA27EX.mjs +0 -76
  156. package/dist/lib/node-esm/chunk-BMNA27EX.mjs.map +0 -7
  157. package/dist/lib/node-esm/chunk-D6KU5MI7.mjs.map +0 -7
  158. package/dist/lib/node-esm/chunk-IU2L277A.mjs +0 -17
  159. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +0 -7
  160. package/dist/lib/node-esm/graph-U67IO4UC.mjs +0 -22
  161. package/dist/lib/node-esm/graph-U67IO4UC.mjs.map +0 -7
  162. package/dist/lib/node-esm/index.mjs +0 -261
  163. package/dist/lib/node-esm/index.mjs.map +0 -7
  164. package/dist/lib/node-esm/meta.json +0 -1
  165. package/dist/lib/node-esm/meta.mjs +0 -10
  166. package/dist/lib/node-esm/meta.mjs.map +0 -7
  167. package/dist/lib/node-esm/types.mjs +0 -21
  168. package/dist/lib/node-esm/types.mjs.map +0 -7
  169. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +0 -11
  170. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +0 -1
  171. package/dist/types/src/components/GridSheet/GridSheet.d.ts +0 -10
  172. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +0 -1
  173. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +0 -9
  174. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +0 -1
  175. package/dist/types/src/components/GridSheet/util.d.ts +0 -7
  176. package/dist/types/src/components/GridSheet/util.d.ts.map +0 -1
  177. package/dist/types/src/components/Sheet/decorations.d.ts +0 -24
  178. package/dist/types/src/components/Sheet/decorations.d.ts.map +0 -1
  179. package/dist/types/src/components/Sheet/threads.d.ts +0 -2
  180. package/dist/types/src/components/Sheet/threads.d.ts.map +0 -1
  181. package/dist/types/src/defs/index.d.ts +0 -3
  182. package/dist/types/src/defs/index.d.ts.map +0 -1
  183. package/dist/types/src/defs/types.d.ts.map +0 -1
  184. package/dist/types/src/defs/types.test.d.ts.map +0 -1
  185. package/dist/types/src/defs/util.d.ts +0 -43
  186. package/dist/types/src/defs/util.d.ts.map +0 -1
  187. package/dist/types/src/extensions/compute.d.ts +0 -5
  188. package/dist/types/src/extensions/compute.d.ts.map +0 -1
  189. package/dist/types/src/extensions/compute.stories.d.ts +0 -26
  190. package/dist/types/src/extensions/compute.stories.d.ts.map +0 -1
  191. package/dist/types/src/extensions/index.d.ts +0 -2
  192. package/dist/types/src/extensions/index.d.ts.map +0 -1
  193. package/dist/types/src/graph/async-function.d.ts.map +0 -1
  194. package/dist/types/src/graph/compute-graph.browser.test.d.ts +0 -2
  195. package/dist/types/src/graph/compute-graph.browser.test.d.ts.map +0 -1
  196. package/dist/types/src/graph/compute-graph.d.ts +0 -81
  197. package/dist/types/src/graph/compute-graph.d.ts.map +0 -1
  198. package/dist/types/src/graph/compute-graph.stories.d.ts +0 -10
  199. package/dist/types/src/graph/compute-graph.stories.d.ts.map +0 -1
  200. package/dist/types/src/graph/compute-node.d.ts +0 -19
  201. package/dist/types/src/graph/compute-node.d.ts.map +0 -1
  202. package/dist/types/src/graph/custom-function.d.ts.map +0 -1
  203. package/dist/types/src/graph/edge-function.d.ts.map +0 -1
  204. package/dist/types/src/graph/function-defs.d.ts.map +0 -1
  205. package/dist/types/src/graph/hyperformula.test.d.ts +0 -2
  206. package/dist/types/src/graph/hyperformula.test.d.ts.map +0 -1
  207. package/dist/types/src/graph/index.d.ts +0 -4
  208. package/dist/types/src/graph/index.d.ts.map +0 -1
  209. package/dist/types/src/graph/util.d.ts +0 -2
  210. package/dist/types/src/graph/util.d.ts.map +0 -1
  211. package/dist/types/src/hooks/hooks.stories.d.ts +0 -11
  212. package/dist/types/src/hooks/hooks.stories.d.ts.map +0 -1
  213. package/dist/types/src/hooks/index.d.ts +0 -4
  214. package/dist/types/src/hooks/index.d.ts.map +0 -1
  215. package/dist/types/src/hooks/useComputeGraph.d.ts +0 -7
  216. package/dist/types/src/hooks/useComputeGraph.d.ts.map +0 -1
  217. package/dist/types/src/hooks/useFormattingModel.d.ts +0 -3
  218. package/dist/types/src/hooks/useFormattingModel.d.ts.map +0 -1
  219. package/dist/types/src/hooks/useSheetModel.d.ts +0 -8
  220. package/dist/types/src/hooks/useSheetModel.d.ts.map +0 -1
  221. package/dist/types/src/model/formatting-model.d.ts +0 -16
  222. package/dist/types/src/model/formatting-model.d.ts.map +0 -1
  223. package/dist/types/src/model/sheet-model.d.ts.map +0 -1
  224. package/dist/types/src/sanity.test.d.ts +0 -2
  225. package/dist/types/src/sanity.test.d.ts.map +0 -1
  226. package/dist/types/src/testing/index.d.ts +0 -2
  227. package/dist/types/src/testing/index.d.ts.map +0 -1
  228. package/dist/types/src/testing/testing.d.ts +0 -9
  229. package/dist/types/src/testing/testing.d.ts.map +0 -1
  230. package/dist/vendor/hyperformula.mjs +0 -37145
  231. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +0 -20
  232. package/src/components/GridSheet/GridSheet.stories.tsx +0 -35
  233. package/src/components/GridSheet/GridSheet.tsx +0 -153
  234. package/src/components/GridSheet/util.ts +0 -108
  235. package/src/components/Sheet/decorations.ts +0 -62
  236. package/src/components/Sheet/threads.tsx +0 -205
  237. package/src/defs/index.ts +0 -6
  238. package/src/defs/util.ts +0 -135
  239. package/src/extensions/compute.stories.tsx +0 -151
  240. package/src/extensions/compute.ts +0 -98
  241. package/src/extensions/index.ts +0 -5
  242. package/src/graph/compute-graph.browser.test.ts +0 -104
  243. package/src/graph/compute-graph.stories.tsx +0 -92
  244. package/src/graph/compute-graph.ts +0 -290
  245. package/src/graph/compute-node.ts +0 -51
  246. package/src/graph/hyperformula.test.ts +0 -15
  247. package/src/graph/index.ts +0 -7
  248. package/src/graph/util.ts +0 -8
  249. package/src/hooks/hooks.stories.tsx +0 -50
  250. package/src/hooks/index.ts +0 -7
  251. package/src/hooks/useComputeGraph.ts +0 -20
  252. package/src/hooks/useFormattingModel.ts +0 -11
  253. package/src/hooks/useSheetModel.ts +0 -43
  254. package/src/model/sheet-model.ts +0 -399
  255. package/src/sanity.test.ts +0 -40
  256. package/src/testing/index.ts +0 -5
  257. package/src/testing/testing.tsx +0 -66
  258. /package/dist/types/src/{graph → components/ComputeGraph}/edge-function.d.ts +0 -0
  259. /package/dist/types/src/{defs → model}/types.test.d.ts +0 -0
  260. /package/src/{graph/function-defs.ts → model/functions.ts} +0 -0
@@ -14,13 +14,10 @@ import {
14
14
  preventNewline,
15
15
  useTextEditor,
16
16
  } from '@dxos/react-ui-editor';
17
- import { type GridEditBox } from '@dxos/react-ui-grid';
18
-
19
- type EditorKeyEvent = Pick<KeyboardEvent<HTMLInputElement>, 'key'> & { shift?: boolean };
20
17
 
21
18
  export type EditorKeysProps = {
22
- onClose: (value: string | undefined, event: EditorKeyEvent) => void;
23
- onNav?: (value: string | undefined, event: EditorKeyEvent) => void;
19
+ onClose: (value: string | undefined) => void;
20
+ onNav?: (value: string | undefined, ev: Pick<KeyboardEvent<HTMLInputElement>, 'key'>) => void;
24
21
  };
25
22
 
26
23
  export const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {
@@ -60,29 +57,14 @@ export const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {
60
57
  {
61
58
  key: 'Enter',
62
59
  run: (editor) => {
63
- onClose(editor.state.doc.toString(), { key: 'Enter' });
64
- return true;
65
- },
66
- shift: (editor) => {
67
- onClose(editor.state.doc.toString(), { key: 'Enter', shift: true });
68
- return true;
69
- },
70
- },
71
- {
72
- key: 'Tab',
73
- run: (editor) => {
74
- onClose(editor.state.doc.toString(), { key: 'Tab' });
75
- return true;
76
- },
77
- shift: (editor) => {
78
- onClose(editor.state.doc.toString(), { key: 'Tab', shift: true });
60
+ onClose(editor.state.doc.toString());
79
61
  return true;
80
62
  },
81
63
  },
82
64
  {
83
65
  key: 'Escape',
84
66
  run: () => {
85
- onClose(undefined, { key: 'Escape' });
67
+ onClose(undefined);
86
68
  return true;
87
69
  },
88
70
  },
@@ -92,35 +74,10 @@ export const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {
92
74
  export type CellEditorProps = {
93
75
  value?: string;
94
76
  extension?: Extension;
95
- variant?: keyof typeof editorVariants;
96
- box?: GridEditBox;
97
- gridId?: string;
98
77
  } & Pick<UseTextEditorProps, 'autoFocus'> &
99
78
  Pick<DOMAttributes<HTMLInputElement>, 'onBlur' | 'onKeyDown'>;
100
79
 
101
- const editorVariants = {
102
- // TODO(thure): remove when legacy is no longer used.
103
- legacy: {
104
- root: 'flex w-full',
105
- editor: 'flex w-full [&>.cm-scroller]:scrollbar-none',
106
- content: '!px-2 !py-1',
107
- },
108
- grid: {
109
- root: 'absolute z-[1]',
110
- editor: '[&>.cm-scroller]:scrollbar-none tabular-nums',
111
- content: '!border !border-transparent !p-0.5',
112
- },
113
- };
114
-
115
- export const CellEditor = ({
116
- value,
117
- extension,
118
- autoFocus,
119
- onBlur,
120
- variant = 'legacy',
121
- box,
122
- gridId,
123
- }: CellEditorProps) => {
80
+ export const CellEditor = ({ value, extension, autoFocus, onBlur }: CellEditorProps) => {
124
81
  const { themeMode } = useThemeContext();
125
82
  const { parentRef } = useTextEditor(() => {
126
83
  return {
@@ -141,23 +98,16 @@ export const CellEditor = ({
141
98
  themeMode,
142
99
  slots: {
143
100
  editor: {
144
- className: editorVariants[variant].editor,
101
+ className: 'flex w-full [&>.cm-scroller]:scrollbar-none',
145
102
  },
146
103
  content: {
147
- className: editorVariants[variant].content,
104
+ className: '!px-2 !py-1',
148
105
  },
149
106
  },
150
107
  }),
151
108
  ],
152
109
  };
153
- }, [extension, autoFocus, value, variant, onBlur]);
110
+ }, [extension]);
154
111
 
155
- return (
156
- <div
157
- ref={parentRef}
158
- className={editorVariants[variant].root}
159
- style={box}
160
- {...(gridId && { 'data-grid': gridId })}
161
- />
162
- );
112
+ return <div ref={parentRef} className='flex w-full' />;
163
113
  };
@@ -6,11 +6,12 @@ import { CompletionContext, type CompletionSource } from '@codemirror/autocomple
6
6
  import { EditorState } from '@codemirror/state';
7
7
  // @ts-ignore
8
8
  import { testTree } from '@lezer/generator/test';
9
+ import { expect } from 'chai';
9
10
  import { spreadsheet } from 'codemirror-lang-spreadsheet';
10
- import { describe, expect, test } from 'vitest';
11
+ import { describe, test } from 'vitest';
11
12
 
12
13
  import { sheetExtension } from './extension';
13
- import { defaultFunctions } from '../../graph';
14
+ import { defaultFunctions } from '../../model/functions';
14
15
 
15
16
  describe('formula parser', () => {
16
17
  const {
@@ -36,8 +37,8 @@ describe('formula parser', () => {
36
37
  extensions: sheetExtension({ functions }),
37
38
  });
38
39
 
39
- const [fn] = state.languageDataAt<CompletionSource>('autocomplete', text.length);
40
- const result = await fn(new CompletionContext(state, text.length, true));
40
+ const [f] = state.languageDataAt<CompletionSource>('autocomplete', text.length);
41
+ const result = await f(new CompletionContext(state, text.length, true));
41
42
  expect(result?.options).to.have.length(1);
42
43
  });
43
44
  });
@@ -20,7 +20,7 @@ import { spreadsheet } from 'codemirror-lang-spreadsheet';
20
20
 
21
21
  import { mx } from '@dxos/react-ui-theme';
22
22
 
23
- import { type FunctionDefinition } from '../../graph';
23
+ import { type FunctionDefinition } from '../../model';
24
24
 
25
25
  /**
26
26
  * https://codemirror.net/examples/styling
@@ -165,6 +165,8 @@ export const sheetExtension = ({ functions = [] }: SheetExtensionOptions): Exten
165
165
  icons: false,
166
166
  tooltipClass: () =>
167
167
  mx(
168
+ // TODO(burdon): Factor out fragments.
169
+ // TODO(burdon): Size to make width same as column.
168
170
  '!-left-[1px] !top-[33px] !-m-0 border !border-t-0 [&>ul]:!min-w-[198px]',
169
171
  '[&>ul>li[aria-selected]]:!bg-accentSurface',
170
172
  'border-separator',
@@ -2,6 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { CellError, ErrorType, EmptyValue, FunctionPlugin, type HyperFormula } from 'hyperformula';
5
6
  import { type InterpreterState } from 'hyperformula/typings/interpreter/InterpreterState';
6
7
  import { type InterpreterValue } from 'hyperformula/typings/interpreter/InterpreterValue';
7
8
  import { type ProcedureAst } from 'hyperformula/typings/parser';
@@ -11,8 +12,6 @@ import { debounce, type UnsubscribeCallback } from '@dxos/async';
11
12
  import { type Space } from '@dxos/client/echo';
12
13
  import { log } from '@dxos/log';
13
14
 
14
- import { CellError, ErrorType, EmptyValue, FunctionPlugin, type HyperFormula } from '#hyperformula';
15
-
16
15
  // TODO(burdon): API gateways!
17
16
  // https://publicapis.io
18
17
  // https://api-ninjas.com/api/cryptoprice
@@ -83,7 +82,6 @@ export class FunctionContext {
83
82
  }, this._options.recalculationDelay);
84
83
  }
85
84
 
86
- // TODO(burdon): Remove?
87
85
  get space() {
88
86
  return this._space;
89
87
  }
@@ -2,14 +2,18 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { FunctionArgumentType } from 'hyperformula';
5
6
  import { type InterpreterState } from 'hyperformula/typings/interpreter/InterpreterState';
6
7
  import { type ProcedureAst } from 'hyperformula/typings/parser';
7
8
 
8
9
  import { getDeep } from '@dxos/util';
9
10
 
10
- import { FunctionArgumentType } from '#hyperformula';
11
11
  import { type AsyncFunction, FunctionPluginAsync } from './async-function';
12
- import { parseNumberString } from './util';
12
+
13
+ // TODO(burdon): Factor out.
14
+ const parseNumberString = (str: string): number => {
15
+ return parseFloat(str.replace(/[^\d.]/g, ''));
16
+ };
13
17
 
14
18
  /**
15
19
  * https://hyperformula.handsontable.com/guide/custom-functions.html#add-a-simple-custom-function
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  import { effect } from '@preact/signals-core';
6
+ import { CellError, ErrorType, FunctionArgumentType } from 'hyperformula';
6
7
  import { type InterpreterState } from 'hyperformula/typings/interpreter/InterpreterState';
7
8
  import { type ProcedureAst } from 'hyperformula/typings/parser';
8
9
 
@@ -12,7 +13,6 @@ import { getUserFunctionUrlInMetadata } from '@dxos/plugin-script/edge';
12
13
  import { FunctionType } from '@dxos/plugin-script/types';
13
14
  import { nonNullable } from '@dxos/util';
14
15
 
15
- import { CellError, ErrorType, FunctionArgumentType } from '#hyperformula';
16
16
  import { type AsyncFunction, FunctionPluginAsync } from './async-function';
17
17
 
18
18
  const EDGE_FUNCTION_TTL = 10_000;
@@ -59,7 +59,6 @@ export class EdgeFunctionPlugin extends FunctionPluginAsync {
59
59
  headers: { 'Content-Type': 'application/json' },
60
60
  body: JSON.stringify({ args: args.filter(nonNullable) }),
61
61
  });
62
-
63
62
  return await result.text();
64
63
  };
65
64
 
@@ -0,0 +1,50 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React, { createContext, type PropsWithChildren, useContext, useEffect } from 'react';
6
+
7
+ import { type Space } from '@dxos/react-client/echo';
8
+
9
+ import { type FunctionContextOptions } from './async-function';
10
+ import { CustomPlugin, CustomPluginTranslations } from './custom';
11
+ import { EdgeFunctionPlugin, EdgeFunctionPluginTranslations } from './edge-function';
12
+ import { createComputeGraph, type ComputeGraph } from './graph';
13
+
14
+ export type ComputeGraphContextType = {
15
+ graphs: Record<string, ComputeGraph>;
16
+ setGraph: (key: string, graph: ComputeGraph) => void;
17
+ };
18
+
19
+ export const ComputeGraphContext = createContext<ComputeGraphContextType>({ graphs: {}, setGraph: () => {} });
20
+
21
+ export const ComputeGraphContextProvider = ({
22
+ children,
23
+ graphs,
24
+ setGraph,
25
+ }: PropsWithChildren<ComputeGraphContextType>) => {
26
+ return <ComputeGraphContext.Provider value={{ graphs, setGraph }}>{children}</ComputeGraphContext.Provider>;
27
+ };
28
+
29
+ export const useComputeGraph = (space: Space, options?: Partial<FunctionContextOptions>): ComputeGraph => {
30
+ const { graphs, setGraph } = useContext(ComputeGraphContext);
31
+ const graph =
32
+ graphs[space.id] ??
33
+ createComputeGraph(
34
+ [
35
+ { plugin: EdgeFunctionPlugin, translations: EdgeFunctionPluginTranslations },
36
+ // TODO(wittjosiah): Remove. Needed for current test sheet generated data.
37
+ { plugin: CustomPlugin, translations: CustomPluginTranslations },
38
+ ],
39
+ space,
40
+ options,
41
+ );
42
+
43
+ useEffect(() => {
44
+ if (!graphs[space.id]) {
45
+ setGraph(space.id, graph);
46
+ }
47
+ }, [space]);
48
+
49
+ return graph;
50
+ };
@@ -0,0 +1,50 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { expect } from 'chai';
6
+ import { describe, test } from 'vitest';
7
+
8
+ import { Trigger } from '@dxos/async';
9
+
10
+ import { CustomPlugin, CustomPluginTranslations } from './custom';
11
+ import { createComputeGraph } from './graph';
12
+ import { addressFromA1Notation, SheetModel } from '../../model';
13
+ import { type CellScalarValue, createSheet } from '../../types';
14
+
15
+ /**
16
+ * VITEST_ENV=chrome p vitest --watch
17
+ * NOTE: Browser test required for hyperformula due to raw translation files.
18
+ */
19
+ describe('compute graph', () => {
20
+ const createModel = async () => {
21
+ const graph = createComputeGraph([{ plugin: CustomPlugin, translations: CustomPluginTranslations }]);
22
+ const sheet = createSheet();
23
+ const model = new SheetModel(graph, sheet, undefined, { rows: 5, columns: 5 });
24
+ graph.update.on(() => model.update.emit());
25
+ return { graph, model };
26
+ };
27
+
28
+ test('async function', async () => {
29
+ const { graph, model } = await createModel();
30
+
31
+ // Triggers function.
32
+ model.setValue(addressFromA1Notation('A1'), '=TEST()');
33
+
34
+ const trigger = new Trigger<CellScalarValue>();
35
+ model.update.on(() => {
36
+ const value = model.getValue(addressFromA1Notation('A1'));
37
+ trigger.wake(value);
38
+ });
39
+
40
+ // Get initial value (i.e., null).
41
+ const v1 = model.getValue(addressFromA1Notation('A1'));
42
+ expect(v1).to.be.null;
43
+ expect(graph.context.info.invocations.TEST).to.eq(undefined);
44
+
45
+ // Wait until async update triggered.
46
+ const v2 = await trigger.wait();
47
+ expect(v2).not.to.be.null;
48
+ expect(graph.context.info.invocations.TEST).to.eq(1);
49
+ });
50
+ });
@@ -0,0 +1,62 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type FunctionPluginDefinition, HyperFormula } from 'hyperformula';
6
+ import { type FunctionTranslationsPackage } from 'hyperformula/typings/interpreter';
7
+
8
+ import { Event } from '@dxos/async';
9
+ import { type Space } from '@dxos/client/echo';
10
+ import { PublicKey } from '@dxos/keys';
11
+ import { log } from '@dxos/log';
12
+
13
+ import { FunctionContext, type FunctionContextOptions } from './async-function';
14
+
15
+ /**
16
+ * Create root graph for space.
17
+ */
18
+ export const createComputeGraph = (
19
+ // TODO(wittjosiah): Factor out this type to make these easier to define.
20
+ functionPlugins: { plugin: FunctionPluginDefinition; translations: FunctionTranslationsPackage }[] = [],
21
+ space?: Space,
22
+ options?: Partial<FunctionContextOptions>,
23
+ ): ComputeGraph => {
24
+ functionPlugins.forEach(({ plugin, translations }) => {
25
+ HyperFormula.registerFunctionPlugin(plugin, translations);
26
+ });
27
+
28
+ const hf = HyperFormula.buildEmpty({ licenseKey: 'gpl-v3' });
29
+ return new ComputeGraph(hf, space, options);
30
+ };
31
+
32
+ /**
33
+ * Per-space compute and dependency graph.
34
+ */
35
+ // TODO(burdon): Create instance for each space.
36
+ export class ComputeGraph {
37
+ public readonly id = `graph-${PublicKey.random().truncate()}`;
38
+ public readonly update = new Event();
39
+
40
+ // The context is passed to all functions.
41
+ public readonly context = new FunctionContext(
42
+ this.hf,
43
+ this._space,
44
+ () => {
45
+ this.refresh();
46
+ },
47
+ this._options,
48
+ );
49
+
50
+ constructor(
51
+ public readonly hf: HyperFormula,
52
+ private readonly _space?: Space,
53
+ private readonly _options?: Partial<FunctionContextOptions>,
54
+ ) {
55
+ this.hf.updateConfig({ context: this.context });
56
+ }
57
+
58
+ refresh() {
59
+ log('refresh', { id: this.id });
60
+ this.update.emit();
61
+ }
62
+ }
@@ -2,4 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './ComputeGraphContextProvider';
5
+ export * from './async-function';
6
+ export * from './custom';
7
+ export * from './graph';
@@ -4,33 +4,31 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import React, { useState } from 'react';
7
+ import { type Decorator } from '@storybook/react';
8
+ import React, { useContext, useEffect, useState } from 'react';
8
9
 
10
+ import { Client } from '@dxos/client';
11
+ import { type EchoReactiveObject } from '@dxos/echo-schema';
9
12
  import { log } from '@dxos/log';
10
- import { type Space, useSpace } from '@dxos/react-client/echo';
11
- import { withClientProvider } from '@dxos/react-client/testing';
13
+ import { getSpace, type Space } from '@dxos/react-client/echo';
12
14
  import { Button } from '@dxos/react-ui';
13
15
  import { mx } from '@dxos/react-ui-theme';
14
- import { withLayout, withTheme } from '@dxos/storybook-utils';
16
+ import { withTheme, withLayout } from '@dxos/storybook-utils';
15
17
 
16
18
  import { Sheet } from './Sheet';
17
19
  import { type SizeMap } from './grid';
18
20
  import { useSheetContext } from './sheet-context';
19
- import { addressToIndex, rangeToIndex } from '../../defs';
20
- import { useComputeGraph } from '../../hooks';
21
- import { useTestSheet, withGraphDecorator } from '../../testing';
22
- import { SheetType, ValueTypeEnum } from '../../types';
21
+ import { createTestSheet, testSheetName } from '../../testing';
22
+ import { ValueTypeEnum, SheetType } from '../../types';
23
+ import { type ComputeGraph, createComputeGraph } from '../ComputeGraph';
24
+ // TODO(wittjosiah): Refactor. This is not exported from ./components due to depending on ECHO.
25
+ import { ComputeGraphContext, ComputeGraphContextProvider, useComputeGraph } from '../ComputeGraph/graph-context';
23
26
  import { Toolbar, type ToolbarActionHandler } from '../Toolbar';
24
27
 
25
28
  // TODO(burdon): Allow toolbar to access sheet context; provide state for current cursor/range.
26
29
  const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) => {
27
30
  const { model, cursor, range } = useSheetContext();
28
31
 
29
- const graph = useComputeGraph(space);
30
- const handleRefresh = () => {
31
- graph?.refresh();
32
- };
33
-
34
32
  // TODO(burdon): Factor out.
35
33
  const handleAction: ToolbarActionHandler = ({ type }) => {
36
34
  log.info('action', { type, cursor, range });
@@ -38,7 +36,7 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
38
36
  return;
39
37
  }
40
38
 
41
- const idx = range ? rangeToIndex(model.sheet, range) : addressToIndex(model.sheet, cursor);
39
+ const idx = range ? model.rangeToIndex(range) : model.addressToIndex(cursor);
42
40
  model.sheet.formatting[idx] ??= {};
43
41
  const format = model.sheet.formatting[idx];
44
42
 
@@ -77,12 +75,14 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
77
75
  format.precision = 2;
78
76
  break;
79
77
  }
80
- case 'comment': {
81
- break;
82
- }
83
78
  }
84
79
  };
85
80
 
81
+ const graph = useComputeGraph(space);
82
+ const handleRefresh = () => {
83
+ graph.refresh();
84
+ };
85
+
86
86
  return (
87
87
  <div className='flex flex-col overflow-hidden'>
88
88
  <Toolbar.Root onAction={handleAction}>
@@ -99,43 +99,56 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
99
99
  );
100
100
  };
101
101
 
102
+ const withGraphDecorator: Decorator = (Story) => {
103
+ const [graphs, setGraphs] = useState<Record<string, ComputeGraph>>({});
104
+
105
+ const setGraph = (key: string, graph: ComputeGraph) => {
106
+ if (!graph.hf.doesSheetExist(testSheetName)) {
107
+ const sheetName = graph.hf.addSheet(testSheetName);
108
+ const sheet = graph.hf.getSheetId(sheetName)!;
109
+ graph.hf.setCellContents({ sheet, col: 0, row: 0 }, Math.random());
110
+ }
111
+
112
+ setGraphs((graphs) => ({ ...graphs, [key]: graph }));
113
+ };
114
+
115
+ return (
116
+ <ComputeGraphContextProvider graphs={graphs} setGraph={setGraph}>
117
+ <Story />
118
+ </ComputeGraphContextProvider>
119
+ );
120
+ };
121
+
102
122
  export default {
103
123
  title: 'plugin-sheet/Sheet',
104
124
  component: Sheet,
105
- decorators: [
106
- withClientProvider({ types: [SheetType], createIdentity: true }),
107
- withGraphDecorator,
108
- withTheme,
109
- withLayout({ fullscreen: true, tooltips: true, classNames: 'inset-4' }),
110
- ],
125
+ decorators: [withTheme, withLayout({ fullscreen: true, tooltips: true, classNames: 'inset-4' }), withGraphDecorator],
111
126
  };
112
127
 
113
128
  export const Default = () => {
114
129
  const [debug, setDebug] = useState(false);
115
- const space = useSpace();
116
- const graph = useComputeGraph(space);
117
- const sheet = useTestSheet(space, graph);
118
- if (!space || !sheet) {
130
+ const sheet = useTestSheet();
131
+ const space = getSpace(sheet);
132
+ if (!sheet || !space) {
119
133
  return null;
120
134
  }
121
135
 
122
136
  return (
123
- <Sheet.Root space={space} sheet={sheet} onInfo={() => setDebug((debug) => !debug)}>
137
+ <Sheet.Root sheet={sheet} space={space} onInfo={() => setDebug((debug) => !debug)}>
124
138
  <SheetWithToolbar debug={debug} space={space} />
125
139
  </Sheet.Root>
126
140
  );
127
141
  };
128
142
 
129
143
  export const Debug = () => {
130
- const space = useSpace();
131
- const graph = useComputeGraph(space);
132
- const sheet = useTestSheet(space, graph);
144
+ const sheet = useTestSheet();
145
+ const space = getSpace(sheet);
133
146
  if (!sheet || !space) {
134
147
  return null;
135
148
  }
136
149
 
137
150
  return (
138
- <Sheet.Root space={space} sheet={sheet}>
151
+ <Sheet.Root sheet={sheet} space={space}>
139
152
  <Sheet.Main />
140
153
  <Sheet.Debug />
141
154
  </Sheet.Root>
@@ -144,15 +157,14 @@ export const Debug = () => {
144
157
 
145
158
  export const Rows = () => {
146
159
  const [rowSizes, setRowSizes] = useState<SizeMap>({});
147
- const space = useSpace();
148
- const graph = useComputeGraph(space);
149
- const sheet = useTestSheet(space, graph);
160
+ const sheet = useTestSheet();
161
+ const space = getSpace(sheet);
150
162
  if (!sheet || !space) {
151
163
  return null;
152
164
  }
153
165
 
154
166
  return (
155
- <Sheet.Root space={space} sheet={sheet}>
167
+ <Sheet.Root sheet={sheet} space={space}>
156
168
  <Sheet.Rows
157
169
  rows={sheet.rows}
158
170
  sizes={rowSizes}
@@ -164,15 +176,14 @@ export const Rows = () => {
164
176
 
165
177
  export const Columns = () => {
166
178
  const [columnSizes, setColumnSizes] = useState<SizeMap>({});
167
- const space = useSpace();
168
- const graph = useComputeGraph(space);
169
- const sheet = useTestSheet(space, graph);
179
+ const sheet = useTestSheet();
180
+ const space = getSpace(sheet);
170
181
  if (!sheet || !space) {
171
182
  return null;
172
183
  }
173
184
 
174
185
  return (
175
- <Sheet.Root space={space} sheet={sheet}>
186
+ <Sheet.Root sheet={sheet} space={space}>
176
187
  <Sheet.Columns
177
188
  columns={sheet.columns}
178
189
  sizes={columnSizes}
@@ -183,19 +194,18 @@ export const Columns = () => {
183
194
  };
184
195
 
185
196
  export const Main = () => {
186
- const space = useSpace();
187
- const graph = useComputeGraph(space);
188
- const sheet = useTestSheet(space, graph);
197
+ const sheet = useTestSheet();
198
+ const space = getSpace(sheet);
189
199
  if (!sheet || !space) {
190
200
  return null;
191
201
  }
192
202
 
193
203
  return (
194
- <Sheet.Root space={space} sheet={sheet}>
204
+ <Sheet.Root sheet={sheet} space={space}>
195
205
  <Sheet.Grid
196
206
  size={{
197
207
  numRows: 50,
198
- numCols: 26,
208
+ numColumns: 26,
199
209
  }}
200
210
  rows={sheet.rows}
201
211
  columns={sheet.columns}
@@ -248,3 +258,30 @@ export const GridLayout = () => {
248
258
  const Cell = ({ className, label }: { className?: string; label: string }) => (
249
259
  <div className={mx('flex items-center justify-center border', className)}>{label}</div>
250
260
  );
261
+
262
+ const useTestSheet = () => {
263
+ const { graphs, setGraph } = useContext(ComputeGraphContext);
264
+ const [sheet, setSheet] = useState<EchoReactiveObject<SheetType>>();
265
+ useEffect(() => {
266
+ const t = setTimeout(async () => {
267
+ const client = new Client();
268
+ await client.initialize();
269
+ await client.halo.createIdentity();
270
+ const space = await client.spaces.create();
271
+ client.addTypes([SheetType]);
272
+
273
+ const graph = graphs[space.id] ?? createComputeGraph();
274
+ if (!graphs[space.id]) {
275
+ setGraph(space.id, graph);
276
+ }
277
+
278
+ const sheet = await createTestSheet({ graph });
279
+ space.db.add(sheet);
280
+ setSheet(sheet);
281
+ });
282
+
283
+ return () => clearTimeout(t);
284
+ }, []);
285
+
286
+ return sheet;
287
+ };