@dxos/plugin-sheet 0.6.12-main.5cc132e → 0.6.12-main.89e9959

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 (273) hide show
  1. package/dist/lib/browser/SheetContainer-LG77O4RM.mjs +262 -0
  2. package/dist/lib/browser/SheetContainer-LG77O4RM.mjs.map +7 -0
  3. package/dist/lib/browser/{SheetContainer-Y7ZMFBAP.mjs → chunk-CHQAW4F4.mjs} +982 -508
  4. package/dist/lib/browser/chunk-CHQAW4F4.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-GNNVBNCX.mjs → chunk-GSV5QNLD.mjs} +409 -686
  6. package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-JRL5LGCE.mjs → chunk-QILRZNE5.mjs} +2 -5
  8. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +7 -0
  9. package/dist/lib/{node-esm/chunk-WUPTZUTX.mjs → browser/chunk-WZMOZKQZ.mjs} +5 -15
  10. package/dist/lib/browser/chunk-WZMOZKQZ.mjs.map +7 -0
  11. package/dist/lib/browser/graph-M4IQ76QX.mjs +33 -0
  12. package/dist/lib/browser/graph-M4IQ76QX.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +86 -59
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/meta.mjs +1 -1
  17. package/dist/lib/browser/types.mjs +4 -6
  18. package/dist/lib/node/SheetContainer-OZ7DHH4L.cjs +280 -0
  19. package/dist/lib/node/SheetContainer-OZ7DHH4L.cjs.map +7 -0
  20. package/dist/lib/node/{SheetContainer-KEOKUKAQ.cjs → chunk-5FTFZL5W.cjs} +1036 -558
  21. package/dist/lib/node/chunk-5FTFZL5W.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-ZRQZFV5T.cjs → chunk-5XPK2V4A.cjs} +418 -691
  23. package/dist/lib/node/chunk-5XPK2V4A.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-VJU3NPUJ.cjs → chunk-AOP42UAA.cjs} +9 -20
  25. package/dist/lib/node/chunk-AOP42UAA.cjs.map +7 -0
  26. package/dist/lib/node/{chunk-BJ6ZD7MN.cjs → chunk-BNARJ5GM.cjs} +5 -18
  27. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +7 -0
  28. package/dist/lib/node/graph-Q3N2X26H.cjs +55 -0
  29. package/dist/lib/node/graph-Q3N2X26H.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +98 -66
  31. package/dist/lib/node/index.cjs.map +4 -4
  32. package/dist/lib/node/meta.cjs +3 -3
  33. package/dist/lib/node/meta.cjs.map +1 -1
  34. package/dist/lib/node/meta.json +1 -1
  35. package/dist/lib/node/types.cjs +10 -12
  36. package/dist/lib/node/types.cjs.map +2 -2
  37. package/dist/lib/node-esm/SheetContainer-4XS2G25Z.mjs +263 -0
  38. package/dist/lib/node-esm/SheetContainer-4XS2G25Z.mjs.map +7 -0
  39. package/dist/lib/node-esm/{chunk-GNNVBNCX.mjs → chunk-5WPZCXNS.mjs} +411 -686
  40. package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +7 -0
  41. package/dist/lib/node-esm/{chunk-JRL5LGCE.mjs → chunk-IU2L277A.mjs} +4 -5
  42. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +7 -0
  43. package/dist/lib/node-esm/{SheetContainer-Y7ZMFBAP.mjs → chunk-KK3XL37M.mjs} +983 -508
  44. package/dist/lib/node-esm/chunk-KK3XL37M.mjs.map +7 -0
  45. package/dist/lib/{browser/chunk-WUPTZUTX.mjs → node-esm/chunk-RR2AO4SM.mjs} +6 -15
  46. package/dist/lib/node-esm/chunk-RR2AO4SM.mjs.map +7 -0
  47. package/dist/lib/node-esm/graph-SMPUMOV2.mjs +34 -0
  48. package/dist/lib/node-esm/graph-SMPUMOV2.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +87 -59
  50. package/dist/lib/node-esm/index.mjs.map +4 -4
  51. package/dist/lib/node-esm/meta.json +1 -1
  52. package/dist/lib/node-esm/meta.mjs +2 -1
  53. package/dist/lib/node-esm/types.mjs +5 -6
  54. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  55. package/dist/types/src/components/CellEditor/CellEditor.d.ts +23 -3
  56. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -1
  57. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts +2 -2
  58. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -1
  59. package/dist/types/src/components/CellEditor/extension.d.ts +1 -1
  60. package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
  61. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +11 -0
  62. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -0
  63. package/dist/types/src/components/ComputeGraph/index.d.ts +1 -3
  64. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  65. package/dist/types/src/components/GridSheet/GridSheet.d.ts +10 -0
  66. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -0
  67. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +9 -0
  68. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -0
  69. package/dist/types/src/components/GridSheet/util.d.ts +16 -0
  70. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -0
  71. package/dist/types/src/components/Sheet/Sheet.d.ts +1 -1
  72. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  73. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +5 -6
  74. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
  75. package/dist/types/src/components/Sheet/grid.d.ts +2 -2
  76. package/dist/types/src/components/Sheet/grid.d.ts.map +1 -1
  77. package/dist/types/src/components/Sheet/nav.d.ts +3 -3
  78. package/dist/types/src/components/Sheet/nav.d.ts.map +1 -1
  79. package/dist/types/src/components/Sheet/sheet-context.d.ts +6 -7
  80. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
  81. package/dist/types/src/components/Sheet/threads.d.ts.map +1 -1
  82. package/dist/types/src/components/SheetContainer.d.ts +1 -1
  83. package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
  84. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  85. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +1 -1
  86. package/dist/types/src/components/index.d.ts +2 -1
  87. package/dist/types/src/components/index.d.ts.map +1 -1
  88. package/dist/types/src/defs/index.d.ts +3 -0
  89. package/dist/types/src/defs/index.d.ts.map +1 -0
  90. package/dist/types/src/{model → defs}/types.d.ts +8 -3
  91. package/dist/types/src/defs/types.d.ts.map +1 -0
  92. package/dist/types/src/defs/types.test.d.ts.map +1 -0
  93. package/dist/types/src/{model → defs}/util.d.ts +8 -4
  94. package/dist/types/src/defs/util.d.ts.map +1 -0
  95. package/dist/types/src/extensions/compute.d.ts +6 -0
  96. package/dist/types/src/extensions/compute.d.ts.map +1 -0
  97. package/dist/types/src/extensions/compute.stories.d.ts +26 -0
  98. package/dist/types/src/extensions/compute.stories.d.ts.map +1 -0
  99. package/dist/types/src/extensions/index.d.ts +2 -0
  100. package/dist/types/src/extensions/index.d.ts.map +1 -0
  101. package/dist/types/src/graph/compute-graph-registry.d.ts +34 -0
  102. package/dist/types/src/graph/compute-graph-registry.d.ts.map +1 -0
  103. package/dist/types/src/graph/compute-graph.d.ts +64 -0
  104. package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
  105. package/dist/types/src/graph/compute-graph.stories.d.ts +10 -0
  106. package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
  107. package/dist/types/src/graph/compute-graph.test.d.ts +2 -0
  108. package/dist/types/src/graph/compute-graph.test.d.ts.map +1 -0
  109. package/dist/types/src/graph/compute-node.d.ts +26 -0
  110. package/dist/types/src/graph/compute-node.d.ts.map +1 -0
  111. package/dist/types/src/{components/ComputeGraph → graph/functions}/async-function.d.ts +14 -5
  112. package/dist/types/src/graph/functions/async-function.d.ts.map +1 -0
  113. package/dist/types/src/graph/functions/edge-function.d.ts +21 -0
  114. package/dist/types/src/graph/functions/edge-function.d.ts.map +1 -0
  115. package/dist/types/src/{model/functions.d.ts → graph/functions/function-defs.d.ts} +1 -1
  116. package/dist/types/src/graph/functions/function-defs.d.ts.map +1 -0
  117. package/dist/types/src/graph/functions/index.d.ts +4 -0
  118. package/dist/types/src/graph/functions/index.d.ts.map +1 -0
  119. package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
  120. package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
  121. package/dist/types/src/graph/index.d.ts +5 -0
  122. package/dist/types/src/graph/index.d.ts.map +1 -0
  123. package/dist/types/src/graph/testing/index.d.ts +3 -0
  124. package/dist/types/src/graph/testing/index.d.ts.map +1 -0
  125. package/dist/types/src/graph/testing/test-builder.d.ts +15 -0
  126. package/dist/types/src/graph/testing/test-builder.d.ts.map +1 -0
  127. package/dist/types/src/graph/testing/test-plugin.d.ts +36 -0
  128. package/dist/types/src/graph/testing/test-plugin.d.ts.map +1 -0
  129. package/dist/types/src/graph/util.d.ts +2 -0
  130. package/dist/types/src/graph/util.d.ts.map +1 -0
  131. package/dist/types/src/hooks/hooks.stories.d.ts +11 -0
  132. package/dist/types/src/hooks/hooks.stories.d.ts.map +1 -0
  133. package/dist/types/src/hooks/index.d.ts +4 -0
  134. package/dist/types/src/hooks/index.d.ts.map +1 -0
  135. package/dist/types/src/hooks/useComputeGraph.d.ts +7 -0
  136. package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -0
  137. package/dist/types/src/hooks/useFormattingModel.d.ts +3 -0
  138. package/dist/types/src/hooks/useFormattingModel.d.ts.map +1 -0
  139. package/dist/types/src/hooks/useSheetModel.d.ts +8 -0
  140. package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -0
  141. package/dist/types/src/meta.d.ts +1 -4
  142. package/dist/types/src/meta.d.ts.map +1 -1
  143. package/dist/types/src/model/formatting-model.d.ts +16 -0
  144. package/dist/types/src/model/formatting-model.d.ts.map +1 -0
  145. package/dist/types/src/model/index.d.ts +2 -4
  146. package/dist/types/src/model/index.d.ts.map +1 -1
  147. package/dist/types/src/model/{model.d.ts → sheet-model.d.ts} +10 -49
  148. package/dist/types/src/model/sheet-model.d.ts.map +1 -0
  149. package/dist/types/src/model/sheet-model.test.d.ts +2 -0
  150. package/dist/types/src/model/sheet-model.test.d.ts.map +1 -0
  151. package/dist/types/src/sanity.test.d.ts +2 -0
  152. package/dist/types/src/sanity.test.d.ts.map +1 -0
  153. package/dist/types/src/testing/index.d.ts +2 -0
  154. package/dist/types/src/testing/index.d.ts.map +1 -0
  155. package/dist/types/src/testing/testing.d.ts +8 -0
  156. package/dist/types/src/testing/testing.d.ts.map +1 -0
  157. package/dist/types/src/types.d.ts +15 -4
  158. package/dist/types/src/types.d.ts.map +1 -1
  159. package/dist/vendor/hyperformula.mjs +37145 -0
  160. package/package.json +48 -44
  161. package/src/SheetPlugin.tsx +46 -62
  162. package/src/components/CellEditor/CellEditor.stories.tsx +6 -6
  163. package/src/components/CellEditor/CellEditor.tsx +59 -9
  164. package/src/components/CellEditor/extension.test.ts +3 -4
  165. package/src/components/CellEditor/extension.ts +5 -6
  166. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +20 -0
  167. package/src/components/ComputeGraph/index.ts +1 -3
  168. package/src/components/GridSheet/GridSheet.stories.tsx +36 -0
  169. package/src/components/GridSheet/GridSheet.tsx +171 -0
  170. package/src/components/GridSheet/util.ts +148 -0
  171. package/src/components/Sheet/Sheet.stories.tsx +48 -88
  172. package/src/components/Sheet/Sheet.tsx +42 -24
  173. package/src/components/Sheet/grid.ts +3 -3
  174. package/src/components/Sheet/nav.ts +19 -19
  175. package/src/components/Sheet/sheet-context.tsx +12 -82
  176. package/src/components/Sheet/threads.tsx +10 -6
  177. package/src/components/SheetContainer.tsx +13 -15
  178. package/src/components/Toolbar/Toolbar.tsx +1 -2
  179. package/src/components/index.ts +1 -0
  180. package/src/defs/index.ts +6 -0
  181. package/src/{model → defs}/types.test.ts +7 -7
  182. package/src/{model → defs}/types.ts +24 -14
  183. package/src/{model → defs}/util.ts +65 -17
  184. package/src/extensions/compute.stories.tsx +151 -0
  185. package/src/extensions/compute.ts +147 -0
  186. package/src/extensions/index.ts +5 -0
  187. package/src/graph/compute-graph-registry.ts +90 -0
  188. package/src/graph/compute-graph.stories.tsx +93 -0
  189. package/src/graph/compute-graph.test.ts +87 -0
  190. package/src/graph/compute-graph.ts +242 -0
  191. package/src/graph/compute-node.ts +63 -0
  192. package/src/{components/ComputeGraph → graph/functions}/async-function.ts +25 -15
  193. package/src/{components/ComputeGraph → graph/functions}/edge-function.ts +16 -14
  194. package/src/graph/functions/index.ts +7 -0
  195. package/src/graph/hyperformula.test.ts +14 -0
  196. package/src/graph/index.ts +8 -0
  197. package/src/graph/testing/index.ts +6 -0
  198. package/src/graph/testing/test-builder.ts +54 -0
  199. package/src/{components/ComputeGraph/custom.ts → graph/testing/test-plugin.ts} +44 -14
  200. package/src/graph/util.ts +8 -0
  201. package/src/hooks/hooks.stories.tsx +50 -0
  202. package/src/hooks/index.ts +7 -0
  203. package/src/hooks/useComputeGraph.ts +28 -0
  204. package/src/hooks/useFormattingModel.ts +11 -0
  205. package/src/hooks/useSheetModel.ts +40 -0
  206. package/src/meta.tsx +1 -5
  207. package/src/{components/Sheet/formatting.ts → model/formatting-model.ts} +20 -13
  208. package/src/model/index.ts +2 -4
  209. package/src/model/sheet-model.test.ts +59 -0
  210. package/src/model/{model.ts → sheet-model.ts} +88 -188
  211. package/src/sanity.test.ts +40 -0
  212. package/src/testing/index.ts +5 -0
  213. package/src/testing/testing.tsx +68 -0
  214. package/src/types.ts +15 -13
  215. package/dist/lib/browser/SheetContainer-Y7ZMFBAP.mjs.map +0 -7
  216. package/dist/lib/browser/chunk-GNNVBNCX.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
  218. package/dist/lib/browser/chunk-PGKZPKUD.mjs +0 -175
  219. package/dist/lib/browser/chunk-PGKZPKUD.mjs.map +0 -7
  220. package/dist/lib/browser/chunk-VBF7YENS.mjs +0 -8
  221. package/dist/lib/browser/chunk-VBF7YENS.mjs.map +0 -7
  222. package/dist/lib/browser/chunk-WUPTZUTX.mjs.map +0 -7
  223. package/dist/lib/browser/testing.mjs +0 -92
  224. package/dist/lib/browser/testing.mjs.map +0 -7
  225. package/dist/lib/node/SheetContainer-KEOKUKAQ.cjs.map +0 -7
  226. package/dist/lib/node/chunk-57PB2HPY.cjs +0 -40
  227. package/dist/lib/node/chunk-57PB2HPY.cjs.map +0 -7
  228. package/dist/lib/node/chunk-6LWBQAQZ.cjs +0 -202
  229. package/dist/lib/node/chunk-6LWBQAQZ.cjs.map +0 -7
  230. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
  231. package/dist/lib/node/chunk-VJU3NPUJ.cjs.map +0 -7
  232. package/dist/lib/node/chunk-ZRQZFV5T.cjs.map +0 -7
  233. package/dist/lib/node/testing.cjs +0 -111
  234. package/dist/lib/node/testing.cjs.map +0 -7
  235. package/dist/lib/node-esm/SheetContainer-Y7ZMFBAP.mjs.map +0 -7
  236. package/dist/lib/node-esm/chunk-GNNVBNCX.mjs.map +0 -7
  237. package/dist/lib/node-esm/chunk-JRL5LGCE.mjs.map +0 -7
  238. package/dist/lib/node-esm/chunk-PGKZPKUD.mjs +0 -175
  239. package/dist/lib/node-esm/chunk-PGKZPKUD.mjs.map +0 -7
  240. package/dist/lib/node-esm/chunk-VBF7YENS.mjs +0 -8
  241. package/dist/lib/node-esm/chunk-VBF7YENS.mjs.map +0 -7
  242. package/dist/lib/node-esm/chunk-WUPTZUTX.mjs.map +0 -7
  243. package/dist/lib/node-esm/testing.mjs +0 -92
  244. package/dist/lib/node-esm/testing.mjs.map +0 -7
  245. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
  246. package/dist/types/src/components/ComputeGraph/custom.d.ts +0 -21
  247. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
  248. package/dist/types/src/components/ComputeGraph/edge-function.d.ts +0 -20
  249. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
  250. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
  251. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
  252. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
  253. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
  254. package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
  255. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
  256. package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
  257. package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
  258. package/dist/types/src/model/functions.d.ts.map +0 -1
  259. package/dist/types/src/model/model.browser.test.d.ts +0 -2
  260. package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
  261. package/dist/types/src/model/model.d.ts.map +0 -1
  262. package/dist/types/src/model/types.d.ts.map +0 -1
  263. package/dist/types/src/model/types.test.d.ts.map +0 -1
  264. package/dist/types/src/model/util.d.ts.map +0 -1
  265. package/dist/types/src/testing.d.ts +0 -9
  266. package/dist/types/src/testing.d.ts.map +0 -1
  267. package/src/components/ComputeGraph/graph-context.tsx +0 -50
  268. package/src/components/ComputeGraph/graph.browser.test.ts +0 -49
  269. package/src/components/ComputeGraph/graph.ts +0 -62
  270. package/src/model/model.browser.test.ts +0 -99
  271. package/src/testing.ts +0 -50
  272. /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
  273. /package/src/{model/functions.ts → graph/functions/function-defs.ts} +0 -0
@@ -0,0 +1,171 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React, { useCallback, useMemo, useRef } from 'react';
6
+
7
+ import {
8
+ type DxGridElement,
9
+ Grid,
10
+ type GridContentProps,
11
+ type GridScopedProps,
12
+ useGridContext,
13
+ } from '@dxos/react-ui-grid';
14
+
15
+ import { colLabelCell, dxGridCellIndexToSheetCellAddress, rowLabelCell, useSheetModelDxGridProps } from './util';
16
+ import { rangeToA1Notation, type CellRange } from '../../defs';
17
+ import { type ComputeGraph } from '../../graph';
18
+ import { useFormattingModel, useSheetModel, type UseSheetModelOptions } from '../../hooks';
19
+ import { type SheetModel, type FormattingModel } from '../../model';
20
+ import { type SheetType } from '../../types';
21
+ import {
22
+ CellEditor,
23
+ type CellEditorProps,
24
+ type CellRangeNotifier,
25
+ editorKeys,
26
+ type EditorKeysProps,
27
+ rangeExtension,
28
+ sheetExtension,
29
+ } from '../CellEditor';
30
+
31
+ const GridSheetCellEditor = ({
32
+ model,
33
+ extension,
34
+ __gridScope,
35
+ }: GridScopedProps<Pick<CellEditorProps, 'extension'> & { model: SheetModel }>) => {
36
+ const { id, editing, setEditing, editBox } = useGridContext('GridSheetCellEditor', __gridScope);
37
+ const cell = dxGridCellIndexToSheetCellAddress(editing);
38
+
39
+ return editing ? (
40
+ <CellEditor
41
+ variant='grid'
42
+ value={editing.initialContent ?? (cell ? model.getCellText(cell) : undefined)}
43
+ autoFocus
44
+ box={editBox}
45
+ onBlur={() => setEditing(null)}
46
+ extension={extension}
47
+ gridId={id}
48
+ />
49
+ ) : null;
50
+ };
51
+
52
+ const initialCells = {
53
+ grid: {},
54
+ frozenColsStart: [...Array(64)].reduce((acc, _, i) => {
55
+ acc[`0,${i}`] = rowLabelCell(i);
56
+ return acc;
57
+ }, {}),
58
+ frozenRowsStart: [...Array(12)].reduce((acc, _, i) => {
59
+ acc[`${i},0`] = colLabelCell(i);
60
+ return acc;
61
+ }, {}),
62
+ };
63
+
64
+ const frozen = {
65
+ frozenColsStart: 1,
66
+ frozenRowsStart: 1,
67
+ };
68
+
69
+ const sheetRowDefault = { grid: { size: 32, resizeable: true } };
70
+ const sheetColDefault = { frozenColsStart: { size: 48 }, grid: { size: 180, resizeable: true } };
71
+
72
+ const GridSheetImpl = ({
73
+ model,
74
+ formatting,
75
+ __gridScope,
76
+ }: GridScopedProps<{ model: SheetModel; formatting: FormattingModel }>) => {
77
+ const { editing, setEditing } = useGridContext('GridSheetCellEditor', __gridScope);
78
+ const dxGrid = useRef<DxGridElement | null>(null);
79
+ const rangeNotifier = useRef<CellRangeNotifier>();
80
+
81
+ // TODO(burdon): Validate formula before closing: hf.validateFormula();
82
+ const handleClose = useCallback<NonNullable<EditorKeysProps['onClose']> | NonNullable<EditorKeysProps['onNav']>>(
83
+ (value, { key, shift }) => {
84
+ if (value !== undefined) {
85
+ model.setValue(dxGridCellIndexToSheetCellAddress(editing)!, value);
86
+ }
87
+ setEditing(null);
88
+ const axis = ['Enter', 'ArrowUp', 'ArrowDown'].includes(key)
89
+ ? 'row'
90
+ : ['Tab', 'ArrowLeft', 'ArrowRight'].includes(key)
91
+ ? 'col'
92
+ : undefined;
93
+ const delta = key.startsWith('Arrow') ? (['ArrowUp', 'ArrowLeft'].includes(key) ? -1 : 1) : shift ? -1 : 1;
94
+ dxGrid.current?.refocus(axis, delta);
95
+ },
96
+ [model, editing, setEditing],
97
+ );
98
+
99
+ const handleAxisResize = useCallback<NonNullable<GridContentProps['onAxisResize']>>(
100
+ ({ axis, size, index: numericIndex }) => {
101
+ if (axis === 'row') {
102
+ const rowId = model.sheet.rows[parseInt(numericIndex)];
103
+ model.sheet.rowMeta[rowId] ??= {};
104
+ model.sheet.rowMeta[rowId].size = size;
105
+ } else {
106
+ const columnId = model.sheet.columns[parseInt(numericIndex)];
107
+ model.sheet.columnMeta[columnId] ??= {};
108
+ model.sheet.columnMeta[columnId].size = size;
109
+ }
110
+ },
111
+ [model],
112
+ );
113
+
114
+ const handleSelect = useCallback<NonNullable<GridContentProps['onSelect']>>(
115
+ ({ minCol, maxCol, minRow, maxRow }) => {
116
+ if (editing) {
117
+ const range: CellRange = { from: { col: minCol, row: minRow } };
118
+ if (minCol !== maxCol || minRow !== maxRow) {
119
+ range.to = { col: maxCol, row: maxRow };
120
+ }
121
+ // Update range selection in formula.
122
+ rangeNotifier.current?.(rangeToA1Notation(range));
123
+ }
124
+ },
125
+ [editing],
126
+ );
127
+
128
+ const { columns, rows } = useSheetModelDxGridProps(dxGrid, model, formatting);
129
+
130
+ const extension = useMemo(
131
+ () => [
132
+ editorKeys({ onClose: handleClose, ...(editing?.initialContent && { onNav: handleClose }) }),
133
+ sheetExtension({ functions: model.graph.getFunctions() }),
134
+ rangeExtension((fn) => (rangeNotifier.current = fn)),
135
+ ],
136
+ [model, handleClose, editing],
137
+ );
138
+
139
+ return (
140
+ <>
141
+ <GridSheetCellEditor model={model} extension={extension} />
142
+ <Grid.Content
143
+ initialCells={initialCells}
144
+ columns={columns}
145
+ rows={rows}
146
+ onAxisResize={handleAxisResize}
147
+ onSelect={handleSelect}
148
+ rowDefault={sheetRowDefault}
149
+ columnDefault={sheetColDefault}
150
+ frozen={frozen}
151
+ ref={dxGrid}
152
+ />
153
+ </>
154
+ );
155
+ };
156
+
157
+ export type GridSheetProps = { graph?: ComputeGraph; sheet?: SheetType } & UseSheetModelOptions;
158
+
159
+ export const GridSheet = ({ graph, sheet, ...options }: GridSheetProps) => {
160
+ const model = useSheetModel(graph, sheet, options);
161
+ const formatting = useFormattingModel(model);
162
+ if (!model || !formatting) {
163
+ return null;
164
+ }
165
+
166
+ return (
167
+ <Grid.Root id={model.id}>
168
+ <GridSheetImpl model={model} formatting={formatting} />
169
+ </Grid.Root>
170
+ );
171
+ };
@@ -0,0 +1,148 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type MutableRefObject, useEffect, useLayoutEffect, useState } from 'react';
6
+
7
+ import { createDocAccessor } from '@dxos/react-client/echo';
8
+ import {
9
+ type GridEditing,
10
+ type GridContentProps,
11
+ type DxGridElement,
12
+ type DxGridAxisMeta,
13
+ type DxGridPlane,
14
+ type DxGridPlaneRange,
15
+ type DxGridPlaneCells,
16
+ colToA1Notation,
17
+ rowToA1Notation,
18
+ } from '@dxos/react-ui-grid';
19
+ import { mx } from '@dxos/react-ui-theme';
20
+
21
+ import { type CellAddress } from '../../defs';
22
+ import { type SheetModel, type FormattingModel } from '../../model';
23
+
24
+ export const dxGridCellIndexToSheetCellAddress = (gridEditing: GridEditing): CellAddress | null => {
25
+ if (!gridEditing) {
26
+ return null;
27
+ }
28
+ const [colStr, rowStr] = gridEditing.index.split(',');
29
+ return {
30
+ col: parseInt(colStr),
31
+ row: parseInt(rowStr),
32
+ };
33
+ };
34
+
35
+ const createDxGridColumns = (model: SheetModel): DxGridAxisMeta => {
36
+ return model.sheet.columns.reduce(
37
+ (acc: DxGridAxisMeta, columnId, numericIndex) => {
38
+ if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {
39
+ acc.grid[numericIndex] = { size: model.sheet.columnMeta[columnId].size, resizeable: true };
40
+ }
41
+ return acc;
42
+ },
43
+ { grid: {} },
44
+ );
45
+ };
46
+
47
+ const createDxGridRows = (model: SheetModel): DxGridAxisMeta => {
48
+ return model.sheet.rows.reduce(
49
+ (acc: DxGridAxisMeta, rowId, numericIndex) => {
50
+ if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {
51
+ acc.grid[numericIndex] = { size: model.sheet.rowMeta[rowId].size, resizeable: true };
52
+ }
53
+ return acc;
54
+ },
55
+ { grid: {} },
56
+ );
57
+ };
58
+
59
+ const gridCellGetter = (model: SheetModel, formatting: FormattingModel) => {
60
+ // TODO(thure): Actually use the cache.
61
+ const cachedGridCells: DxGridPlaneCells = {};
62
+ return (nextBounds: DxGridPlaneRange): DxGridPlaneCells => {
63
+ [...Array(nextBounds.end.col - nextBounds.start.col)].forEach((_, c0) => {
64
+ return [...Array(nextBounds.end.row - nextBounds.start.row)].forEach((_, r0) => {
65
+ const col = nextBounds.start.col + c0;
66
+ const row = nextBounds.start.row + r0;
67
+ const cell = formatting.getFormatting({ col, row });
68
+ if (cell.value) {
69
+ cachedGridCells;
70
+ cachedGridCells[`${col},${row}`] = { value: cell.value, className: mx(cell.classNames) };
71
+ }
72
+ });
73
+ });
74
+ return cachedGridCells;
75
+ };
76
+ };
77
+
78
+ export const rowLabelCell = (row: number) => ({
79
+ value: rowToA1Notation(row),
80
+ className: 'text-end !pie-1',
81
+ resizeHandle: 'row',
82
+ });
83
+
84
+ export const colLabelCell = (col: number) => ({ value: colToA1Notation(col), resizeHandle: 'col' });
85
+
86
+ const cellGetter = (model: SheetModel, formatting: FormattingModel) => {
87
+ const getGridCells = gridCellGetter(model, formatting);
88
+ return (nextBounds: DxGridPlaneRange, plane: DxGridPlane): DxGridPlaneCells => {
89
+ switch (plane) {
90
+ case 'grid':
91
+ return getGridCells(nextBounds);
92
+ case 'frozenColsStart':
93
+ return [...Array(nextBounds.end.row - nextBounds.start.row)].reduce((acc, _, r0) => {
94
+ const r = nextBounds.start.row + r0;
95
+ acc[`0,${r}`] = rowLabelCell(r);
96
+ return acc;
97
+ }, {});
98
+ case 'frozenRowsStart':
99
+ return [...Array(nextBounds.end.col - nextBounds.start.col)].reduce((acc, _, c0) => {
100
+ const c = nextBounds.start.col + c0;
101
+ acc[`${c},0`] = colLabelCell(c);
102
+ return acc;
103
+ }, {});
104
+ default:
105
+ return {};
106
+ }
107
+ };
108
+ };
109
+
110
+ export const useSheetModelDxGridProps = (
111
+ dxGridRef: MutableRefObject<DxGridElement | null>,
112
+ model: SheetModel,
113
+ formatting: FormattingModel,
114
+ ): Pick<GridContentProps, 'columns' | 'rows'> => {
115
+ const [columns, setColumns] = useState<DxGridAxisMeta>(createDxGridColumns(model));
116
+ const [rows, setRows] = useState<DxGridAxisMeta>(createDxGridColumns(model));
117
+
118
+ useLayoutEffect(() => {
119
+ const cellsAccessor = createDocAccessor(model.sheet, ['cells']);
120
+ if (dxGridRef.current) {
121
+ dxGridRef.current.getCells = cellGetter(model, formatting);
122
+ }
123
+ const handleCellsUpdate = () => {
124
+ dxGridRef.current?.requestUpdate('initialCells');
125
+ };
126
+ cellsAccessor.handle.addListener('change', handleCellsUpdate);
127
+ return () => cellsAccessor.handle.removeListener('change', handleCellsUpdate);
128
+ }, [model, formatting]);
129
+
130
+ useEffect(() => {
131
+ const columnMetaAccessor = createDocAccessor(model.sheet, ['columnMeta']);
132
+ const rowMetaAccessor = createDocAccessor(model.sheet, ['rowMeta']);
133
+ const handleColumnMetaUpdate = () => {
134
+ setColumns(createDxGridColumns(model));
135
+ };
136
+ const handleRowMetaUpdate = () => {
137
+ setRows(createDxGridRows(model));
138
+ };
139
+ columnMetaAccessor.handle.addListener('change', handleColumnMetaUpdate);
140
+ rowMetaAccessor.handle.addListener('change', handleRowMetaUpdate);
141
+ return () => {
142
+ columnMetaAccessor.handle.removeListener('change', handleColumnMetaUpdate);
143
+ rowMetaAccessor.handle.removeListener('change', handleRowMetaUpdate);
144
+ };
145
+ }, [model]);
146
+
147
+ return { columns, rows };
148
+ };
@@ -4,32 +4,34 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type Decorator } from '@storybook/react';
8
- import React, { useContext, useEffect, useState } from 'react';
7
+ import React, { useState } from 'react';
9
8
 
10
- import { Client } from '@dxos/client';
11
- import { type EchoReactiveObject } from '@dxos/echo-schema';
12
9
  import { log } from '@dxos/log';
13
- import { getSpace, type Space } from '@dxos/react-client/echo';
10
+ import { useSpace } from '@dxos/react-client/echo';
11
+ import { withClientProvider } from '@dxos/react-client/testing';
14
12
  import { Button } from '@dxos/react-ui';
15
13
  import { mx } from '@dxos/react-ui-theme';
16
- import { withTheme, withLayout } from '@dxos/storybook-utils';
14
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
17
15
 
18
16
  import { Sheet } from './Sheet';
19
17
  import { type SizeMap } from './grid';
20
18
  import { useSheetContext } from './sheet-context';
21
- import { addressToIndex, rangeToIndex } from '../../model';
22
- import { createTestSheet, testSheetName } from '../../testing';
23
- import { ValueTypeEnum, SheetType } from '../../types';
24
- import { type ComputeGraph, createComputeGraph } from '../ComputeGraph';
25
- // TODO(wittjosiah): Refactor. This is not exported from ./components due to depending on ECHO.
26
- import { ComputeGraphContext, ComputeGraphContextProvider, useComputeGraph } from '../ComputeGraph/graph-context';
19
+ import { addressToIndex, rangeToIndex } from '../../defs';
20
+ import { type ComputeGraph } from '../../graph';
21
+ import { testFunctionPlugins } from '../../graph/testing';
22
+ import { useComputeGraph } from '../../hooks';
23
+ import { createTestCells, useTestSheet, withComputeGraphDecorator } from '../../testing';
24
+ import { SheetType, ValueTypeEnum } from '../../types';
27
25
  import { Toolbar, type ToolbarActionHandler } from '../Toolbar';
28
26
 
29
27
  // TODO(burdon): Allow toolbar to access sheet context; provide state for current cursor/range.
30
- const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) => {
28
+ const SheetWithToolbar = ({ graph, debug }: { graph: ComputeGraph; debug?: boolean }) => {
31
29
  const { model, cursor, range } = useSheetContext();
32
30
 
31
+ const handleRefresh = () => {
32
+ // graph?.refresh(); // TODO(burdon): ???
33
+ };
34
+
33
35
  // TODO(burdon): Factor out.
34
36
  const handleAction: ToolbarActionHandler = ({ type }) => {
35
37
  log.info('action', { type, cursor, range });
@@ -82,11 +84,6 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
82
84
  }
83
85
  };
84
86
 
85
- const graph = useComputeGraph(space);
86
- const handleRefresh = () => {
87
- graph.refresh();
88
- };
89
-
90
87
  return (
91
88
  <div className='flex flex-col overflow-hidden'>
92
89
  <Toolbar.Root onAction={handleAction}>
@@ -103,56 +100,43 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
103
100
  );
104
101
  };
105
102
 
106
- const withGraphDecorator: Decorator = (Story) => {
107
- const [graphs, setGraphs] = useState<Record<string, ComputeGraph>>({});
108
-
109
- const setGraph = (key: string, graph: ComputeGraph) => {
110
- if (!graph.hf.doesSheetExist(testSheetName)) {
111
- const sheetName = graph.hf.addSheet(testSheetName);
112
- const sheet = graph.hf.getSheetId(sheetName)!;
113
- graph.hf.setCellContents({ sheet, col: 0, row: 0 }, Math.random());
114
- }
115
-
116
- setGraphs((graphs) => ({ ...graphs, [key]: graph }));
117
- };
118
-
119
- return (
120
- <ComputeGraphContextProvider graphs={graphs} setGraph={setGraph}>
121
- <Story />
122
- </ComputeGraphContextProvider>
123
- );
124
- };
125
-
126
103
  export default {
127
104
  title: 'plugin-sheet/Sheet',
128
105
  component: Sheet,
129
- decorators: [withTheme, withLayout({ fullscreen: true, tooltips: true, classNames: 'inset-4' }), withGraphDecorator],
106
+ decorators: [
107
+ withClientProvider({ types: [SheetType], createIdentity: true }),
108
+ withComputeGraphDecorator({ plugins: testFunctionPlugins }),
109
+ withTheme,
110
+ withLayout({ fullscreen: true, tooltips: true, classNames: 'inset-4' }),
111
+ ],
130
112
  };
131
113
 
132
114
  export const Default = () => {
133
115
  const [debug, setDebug] = useState(false);
134
- const sheet = useTestSheet();
135
- const space = getSpace(sheet);
136
- if (!sheet || !space) {
116
+ const space = useSpace();
117
+ const graph = useComputeGraph(space);
118
+ const sheet = useTestSheet(space, graph, { cells: createTestCells() });
119
+ if (!graph || !sheet) {
137
120
  return null;
138
121
  }
139
122
 
140
123
  return (
141
- <Sheet.Root sheet={sheet} space={space} onInfo={() => setDebug((debug) => !debug)}>
142
- <SheetWithToolbar debug={debug} space={space} />
124
+ <Sheet.Root graph={graph} sheet={sheet} onInfo={() => setDebug((debug) => !debug)}>
125
+ <SheetWithToolbar graph={graph} debug={debug} />
143
126
  </Sheet.Root>
144
127
  );
145
128
  };
146
129
 
147
130
  export const Debug = () => {
148
- const sheet = useTestSheet();
149
- const space = getSpace(sheet);
150
- if (!sheet || !space) {
131
+ const space = useSpace();
132
+ const graph = useComputeGraph(space);
133
+ const sheet = useTestSheet(space, graph, { cells: createTestCells() });
134
+ if (!graph || !sheet) {
151
135
  return null;
152
136
  }
153
137
 
154
138
  return (
155
- <Sheet.Root sheet={sheet} space={space}>
139
+ <Sheet.Root graph={graph} sheet={sheet}>
156
140
  <Sheet.Main />
157
141
  <Sheet.Debug />
158
142
  </Sheet.Root>
@@ -161,14 +145,15 @@ export const Debug = () => {
161
145
 
162
146
  export const Rows = () => {
163
147
  const [rowSizes, setRowSizes] = useState<SizeMap>({});
164
- const sheet = useTestSheet();
165
- const space = getSpace(sheet);
166
- if (!sheet || !space) {
148
+ const space = useSpace();
149
+ const graph = useComputeGraph(space);
150
+ const sheet = useTestSheet(space, graph);
151
+ if (!graph || !sheet) {
167
152
  return null;
168
153
  }
169
154
 
170
155
  return (
171
- <Sheet.Root sheet={sheet} space={space}>
156
+ <Sheet.Root graph={graph} sheet={sheet}>
172
157
  <Sheet.Rows
173
158
  rows={sheet.rows}
174
159
  sizes={rowSizes}
@@ -180,14 +165,15 @@ export const Rows = () => {
180
165
 
181
166
  export const Columns = () => {
182
167
  const [columnSizes, setColumnSizes] = useState<SizeMap>({});
183
- const sheet = useTestSheet();
184
- const space = getSpace(sheet);
185
- if (!sheet || !space) {
168
+ const space = useSpace();
169
+ const graph = useComputeGraph(space);
170
+ const sheet = useTestSheet(space, graph);
171
+ if (!graph || !sheet) {
186
172
  return null;
187
173
  }
188
174
 
189
175
  return (
190
- <Sheet.Root sheet={sheet} space={space}>
176
+ <Sheet.Root graph={graph} sheet={sheet}>
191
177
  <Sheet.Columns
192
178
  columns={sheet.columns}
193
179
  sizes={columnSizes}
@@ -198,18 +184,19 @@ export const Columns = () => {
198
184
  };
199
185
 
200
186
  export const Main = () => {
201
- const sheet = useTestSheet();
202
- const space = getSpace(sheet);
203
- if (!sheet || !space) {
187
+ const space = useSpace();
188
+ const graph = useComputeGraph(space);
189
+ const sheet = useTestSheet(space, graph, { cells: createTestCells() });
190
+ if (!graph || !sheet) {
204
191
  return null;
205
192
  }
206
193
 
207
194
  return (
208
- <Sheet.Root sheet={sheet} space={space}>
195
+ <Sheet.Root graph={graph} sheet={sheet}>
209
196
  <Sheet.Grid
210
197
  size={{
211
198
  numRows: 50,
212
- numColumns: 26,
199
+ numCols: 26,
213
200
  }}
214
201
  rows={sheet.rows}
215
202
  columns={sheet.columns}
@@ -262,30 +249,3 @@ export const GridLayout = () => {
262
249
  const Cell = ({ className, label }: { className?: string; label: string }) => (
263
250
  <div className={mx('flex items-center justify-center border', className)}>{label}</div>
264
251
  );
265
-
266
- const useTestSheet = () => {
267
- const { graphs, setGraph } = useContext(ComputeGraphContext);
268
- const [sheet, setSheet] = useState<EchoReactiveObject<SheetType>>();
269
- useEffect(() => {
270
- const t = setTimeout(async () => {
271
- const client = new Client();
272
- await client.initialize();
273
- await client.halo.createIdentity();
274
- const space = await client.spaces.create();
275
- client.addTypes([SheetType]);
276
-
277
- const graph = graphs[space.id] ?? createComputeGraph();
278
- if (!graphs[space.id]) {
279
- setGraph(space.id, graph);
280
- }
281
-
282
- const sheet = await createTestSheet({ graph });
283
- space.db.add(sheet);
284
- setSheet(sheet);
285
- });
286
-
287
- return () => clearTimeout(t);
288
- }, []);
289
-
290
- return sheet;
291
- };