@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
@@ -2,70 +2,66 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { useCallback, useMemo, useRef } from 'react';
5
+ import React, { useCallback, useMemo, useRef, type FocusEvent, type WheelEvent } from 'react';
6
6
 
7
- import { type Space } from '@dxos/client/echo';
7
+ import { useAttention } from '@dxos/react-ui-attention';
8
8
  import {
9
9
  type DxGridElement,
10
10
  Grid,
11
11
  type GridContentProps,
12
- type GridScopedProps,
13
- useGridContext,
14
- } from '@dxos/react-ui-grid';
15
-
16
- import { dxGridCellIndexToSheetCellAddress, useSheetModelDxGridProps } from './util';
17
- import { rangeToA1Notation, type CellRange } from '../../defs';
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
12
  editorKeys,
26
13
  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;
14
+ GridCellEditor,
15
+ closestCell,
16
+ } from '@dxos/react-ui-grid';
17
+
18
+ import { colLabelCell, dxGridCellIndexToSheetCellAddress, rowLabelCell, useSheetModelDxGridProps } from './util';
19
+ import { rangeToA1Notation, type CellRange, DEFAULT_COLUMNS, DEFAULT_ROWS } from '../../defs';
20
+ import { rangeExtension, sheetExtension, type CellRangeNotifier } from '../../extensions';
21
+ import { useUpdateFocusedCellOnThreadSelection } from '../../hooks';
22
+ import { useSheetContext } from '../SheetContext';
23
+
24
+ const initialCells = {
25
+ grid: {},
26
+ frozenColsStart: [...Array(64)].reduce((acc, _, i) => {
27
+ acc[`0,${i}`] = rowLabelCell(i);
28
+ return acc;
29
+ }, {}),
30
+ frozenRowsStart: [...Array(12)].reduce((acc, _, i) => {
31
+ acc[`${i},0`] = colLabelCell(i);
32
+ return acc;
33
+ }, {}),
34
+ };
35
+
36
+ const frozen = {
37
+ frozenColsStart: 1,
38
+ frozenRowsStart: 1,
50
39
  };
51
40
 
52
- const sheetRowDefault = { size: 32, resizeable: true };
53
- const sheetColDefault = { size: 180, resizeable: true };
41
+ const sheetRowDefault = { grid: { size: 32, resizeable: true } };
42
+ const sheetColDefault = { frozenColsStart: { size: 48 }, grid: { size: 180, resizeable: true } };
54
43
 
55
- const GridSheetImpl = ({
56
- model,
57
- formatting,
58
- __gridScope,
59
- }: GridScopedProps<{ model: SheetModel; formatting: FormattingModel }>) => {
60
- const { editing, setEditing } = useGridContext('GridSheetCellEditor', __gridScope);
44
+ export const GridSheet = () => {
45
+ const { id, model, formatting, editing, setEditing, setCursor, setRange } = useSheetContext();
61
46
  const dxGrid = useRef<DxGridElement | null>(null);
62
47
  const rangeNotifier = useRef<CellRangeNotifier>();
48
+ const { hasAttention } = useAttention(id);
49
+
50
+ const handleFocus = useCallback(
51
+ (event: FocusEvent) => {
52
+ if (!editing) {
53
+ const cell = closestCell(event.target);
54
+ setCursor(cell && cell.plane === 'grid' ? { col: cell.col, row: cell.row } : undefined);
55
+ }
56
+ },
57
+ [editing],
58
+ );
63
59
 
64
60
  // TODO(burdon): Validate formula before closing: hf.validateFormula();
65
61
  const handleClose = useCallback<NonNullable<EditorKeysProps['onClose']> | NonNullable<EditorKeysProps['onNav']>>(
66
62
  (value, { key, shift }) => {
67
63
  if (value !== undefined) {
68
- model.setValue(dxGridCellIndexToSheetCellAddress(editing)!, value);
64
+ model.setValue(dxGridCellIndexToSheetCellAddress(editing!.index), value);
69
65
  }
70
66
  setEditing(null);
71
67
  const axis = ['Enter', 'ArrowUp', 'ArrowDown'].includes(key)
@@ -96,19 +92,31 @@ const GridSheetImpl = ({
96
92
 
97
93
  const handleSelect = useCallback<NonNullable<GridContentProps['onSelect']>>(
98
94
  ({ minCol, maxCol, minRow, maxRow }) => {
95
+ const range: CellRange = { from: { col: minCol, row: minRow } };
96
+ if (minCol !== maxCol || minRow !== maxRow) {
97
+ range.to = { col: maxCol, row: maxRow };
98
+ }
99
99
  if (editing) {
100
- const range: CellRange = { from: { col: minCol, row: minRow } };
101
- if (minCol !== maxCol || minRow !== maxRow) {
102
- range.to = { col: maxCol, row: maxRow };
103
- }
104
100
  // Update range selection in formula.
105
101
  rangeNotifier.current?.(rangeToA1Notation(range));
102
+ } else {
103
+ // Setting range while editing causes focus to move to null, avoid doing so.
104
+ setRange(range.to ? range : undefined);
106
105
  }
107
106
  },
108
107
  [editing],
109
108
  );
110
109
 
111
- const { cells, columns, rows } = useSheetModelDxGridProps(model, formatting);
110
+ const handleWheel = useCallback(
111
+ (event: WheelEvent) => {
112
+ if (!hasAttention) {
113
+ event.stopPropagation();
114
+ }
115
+ },
116
+ [hasAttention],
117
+ );
118
+
119
+ const { columns, rows } = useSheetModelDxGridProps(dxGrid, model, formatting);
112
120
 
113
121
  const extension = useMemo(
114
122
  () => [
@@ -119,35 +127,35 @@ const GridSheetImpl = ({
119
127
  [model, handleClose, editing],
120
128
  );
121
129
 
130
+ const getCellContent = useCallback(
131
+ (index: string) => {
132
+ const cell = dxGridCellIndexToSheetCellAddress(index);
133
+ return model.getCellText(cell);
134
+ },
135
+ [model],
136
+ );
137
+
138
+ useUpdateFocusedCellOnThreadSelection(model, dxGrid);
139
+
122
140
  return (
123
141
  <>
124
- <GridSheetCellEditor model={model} extension={extension} />
142
+ <GridCellEditor getCellContent={getCellContent} extension={extension} />
125
143
  <Grid.Content
126
- cells={cells}
144
+ initialCells={initialCells}
145
+ limitColumns={DEFAULT_COLUMNS}
146
+ limitRows={DEFAULT_ROWS}
127
147
  columns={columns}
128
148
  rows={rows}
129
149
  onAxisResize={handleAxisResize}
130
150
  onSelect={handleSelect}
131
151
  rowDefault={sheetRowDefault}
132
152
  columnDefault={sheetColDefault}
153
+ frozen={frozen}
154
+ onFocus={handleFocus}
155
+ onWheelCapture={handleWheel}
156
+ className='[--dx-grid-base:var(--surface-bg)]'
133
157
  ref={dxGrid}
134
158
  />
135
159
  </>
136
160
  );
137
161
  };
138
-
139
- export type GridSheetProps = { space?: Space; sheet?: SheetType } & UseSheetModelOptions;
140
-
141
- export const GridSheet = ({ space, sheet, ...options }: GridSheetProps) => {
142
- const model = useSheetModel(space, sheet, options);
143
- const formatting = useFormattingModel(model);
144
- if (!model || !formatting) {
145
- return null;
146
- }
147
-
148
- return (
149
- <Grid.Root id={model.id}>
150
- <GridSheetImpl model={model} formatting={formatting} />
151
- </Grid.Root>
152
- );
153
- };
@@ -9,12 +9,12 @@ import React, { useEffect, useMemo, useState } from 'react';
9
9
  import { Client } from '@dxos/client';
10
10
  import { createDocAccessor, type EchoReactiveObject } from '@dxos/client/echo';
11
11
  import { automerge } from '@dxos/react-ui-editor';
12
+ import { CellEditor, type CellEditorProps } from '@dxos/react-ui-grid';
12
13
  import { withTheme } from '@dxos/storybook-utils';
13
14
 
14
15
  import { HyperFormula } from '#hyperformula';
15
- import { CellEditor, type CellEditorProps } from './CellEditor';
16
- import { sheetExtension } from './extension';
17
16
  import { createSheet } from '../../defs';
17
+ import { sheetExtension } from '../../extensions';
18
18
  import { defaultFunctions } from '../../graph';
19
19
  import { SheetType } from '../../types';
20
20
 
@@ -42,14 +42,13 @@ const AutomergeStory = ({ value, ...props }: StoryProps) => {
42
42
  const [object, setObject] = useState<EchoReactiveObject<SheetType>>();
43
43
  useEffect(() => {
44
44
  setTimeout(async () => {
45
- const client = new Client();
45
+ const client = new Client({ types: [SheetType] });
46
46
  await client.initialize();
47
47
  await client.halo.createIdentity();
48
48
  const space = await client.spaces.create();
49
- client.addTypes([SheetType]);
50
49
 
51
50
  const sheet = createSheet();
52
- sheet.title = 'Test';
51
+ sheet.name = 'Test';
53
52
  sheet.cells[cell] = { value };
54
53
  space.db.add(sheet);
55
54
  setObject(sheet);
@@ -2,4 +2,4 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './Sheet';
5
+ export * from './GridSheet';
@@ -2,67 +2,122 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { useEffect, useState } from 'react';
5
+ import { type MutableRefObject, useEffect, useLayoutEffect, useState } from 'react';
6
6
 
7
7
  import { createDocAccessor } from '@dxos/react-client/echo';
8
- import { type GridEditing, type GridContentProps } from '@dxos/react-ui-grid';
8
+ import {
9
+ type GridContentProps,
10
+ type DxGridElement,
11
+ type DxGridAxisMeta,
12
+ type DxGridPlane,
13
+ type DxGridPlaneRange,
14
+ type DxGridPlaneCells,
15
+ colToA1Notation,
16
+ rowToA1Notation,
17
+ } from '@dxos/react-ui-grid';
9
18
  import { mx } from '@dxos/react-ui-theme';
10
19
 
11
- import { addressFromIndex, type CellAddress } from '../../defs';
20
+ import { type CellAddress } from '../../defs';
12
21
  import { type SheetModel, type FormattingModel } from '../../model';
13
22
 
14
- export const dxGridCellIndexToSheetCellAddress = (gridEditing: GridEditing): CellAddress | null => {
15
- if (!gridEditing) {
16
- return null;
17
- }
18
- const [colStr, rowStr] = gridEditing.index.split(',');
23
+ export const dxGridCellIndexToSheetCellAddress = (index: string): CellAddress => {
24
+ const [colStr, rowStr] = index.split(',');
19
25
  return {
20
26
  col: parseInt(colStr),
21
27
  row: parseInt(rowStr),
22
28
  };
23
29
  };
24
30
 
25
- const createDxGridCells = (model: SheetModel, formatting: FormattingModel) => {
26
- return Object.keys(model.sheet.cells).reduce((acc: NonNullable<GridContentProps['cells']>, sheetCellIndex) => {
27
- const address = addressFromIndex(model.sheet, sheetCellIndex);
28
- const cell = formatting.getFormatting(address);
29
- if (cell.value) {
30
- acc[`${address.col},${address.row}`] = { value: cell.value, className: mx(cell.classNames) };
31
- }
32
- return acc;
33
- }, {});
31
+ const createDxGridColumns = (model: SheetModel): DxGridAxisMeta => {
32
+ return model.sheet.columns.reduce(
33
+ (acc: DxGridAxisMeta, columnId, numericIndex) => {
34
+ if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {
35
+ acc.grid[numericIndex] = { size: model.sheet.columnMeta[columnId].size, resizeable: true };
36
+ }
37
+ return acc;
38
+ },
39
+ { grid: {} },
40
+ );
34
41
  };
35
42
 
36
- const createDxGridColumns = (model: SheetModel): GridContentProps['columns'] => {
37
- return model.sheet.columns.reduce((acc: NonNullable<GridContentProps['columns']>, columnId, numericIndex) => {
38
- if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {
39
- acc[numericIndex] = { size: model.sheet.columnMeta[columnId].size, resizeable: true };
40
- }
41
- return acc;
42
- }, {});
43
+ const createDxGridRows = (model: SheetModel): DxGridAxisMeta => {
44
+ return model.sheet.rows.reduce(
45
+ (acc: DxGridAxisMeta, rowId, numericIndex) => {
46
+ if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {
47
+ acc.grid[numericIndex] = { size: model.sheet.rowMeta[rowId].size, resizeable: true };
48
+ }
49
+ return acc;
50
+ },
51
+ { grid: {} },
52
+ );
53
+ };
54
+
55
+ const gridCellGetter = (model: SheetModel, formatting: FormattingModel) => {
56
+ // TODO(thure): Actually use the cache.
57
+ const cachedGridCells: DxGridPlaneCells = {};
58
+ return (nextBounds: DxGridPlaneRange): DxGridPlaneCells => {
59
+ [...Array(nextBounds.end.col - nextBounds.start.col)].forEach((_, c0) => {
60
+ return [...Array(nextBounds.end.row - nextBounds.start.row)].forEach((_, r0) => {
61
+ const col = nextBounds.start.col + c0;
62
+ const row = nextBounds.start.row + r0;
63
+ const cell = formatting.getFormatting({ col, row });
64
+ if (cell.value) {
65
+ cachedGridCells;
66
+ cachedGridCells[`${col},${row}`] = { value: cell.value, className: mx(cell.classNames) };
67
+ }
68
+ });
69
+ });
70
+ return cachedGridCells;
71
+ };
43
72
  };
44
73
 
45
- const createDxGridRows = (model: SheetModel): GridContentProps['rows'] => {
46
- return model.sheet.rows.reduce((acc: NonNullable<GridContentProps['rows']>, rowId, numericIndex) => {
47
- if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {
48
- acc[numericIndex] = { size: model.sheet.rowMeta[rowId].size, resizeable: true };
74
+ export const rowLabelCell = (row: number) => ({
75
+ value: rowToA1Notation(row),
76
+ className: 'text-end !pie-1',
77
+ resizeHandle: 'row',
78
+ });
79
+
80
+ export const colLabelCell = (col: number) => ({ value: colToA1Notation(col), resizeHandle: 'col' });
81
+
82
+ const cellGetter = (model: SheetModel, formatting: FormattingModel) => {
83
+ const getGridCells = gridCellGetter(model, formatting);
84
+ return (nextBounds: DxGridPlaneRange, plane: DxGridPlane): DxGridPlaneCells => {
85
+ switch (plane) {
86
+ case 'grid':
87
+ return getGridCells(nextBounds);
88
+ case 'frozenColsStart':
89
+ return [...Array(nextBounds.end.row - nextBounds.start.row)].reduce((acc, _, r0) => {
90
+ const r = nextBounds.start.row + r0;
91
+ acc[`0,${r}`] = rowLabelCell(r);
92
+ return acc;
93
+ }, {});
94
+ case 'frozenRowsStart':
95
+ return [...Array(nextBounds.end.col - nextBounds.start.col)].reduce((acc, _, c0) => {
96
+ const c = nextBounds.start.col + c0;
97
+ acc[`${c},0`] = colLabelCell(c);
98
+ return acc;
99
+ }, {});
100
+ default:
101
+ return {};
49
102
  }
50
- return acc;
51
- }, {});
103
+ };
52
104
  };
53
105
 
54
106
  export const useSheetModelDxGridProps = (
107
+ dxGridRef: MutableRefObject<DxGridElement | null>,
55
108
  model: SheetModel,
56
109
  formatting: FormattingModel,
57
- ): Pick<GridContentProps, 'cells' | 'columns' | 'rows'> => {
58
- const [dxGridCells, setDxGridCells] = useState<GridContentProps['cells']>(createDxGridCells(model, formatting));
59
- const [dxGridColumns, setDxGridColumns] = useState<GridContentProps['columns']>(createDxGridColumns(model));
60
- const [dxGridRows, setDxGridRows] = useState<GridContentProps['rows']>(createDxGridColumns(model));
110
+ ): Pick<GridContentProps, 'columns' | 'rows'> => {
111
+ const [columns, setColumns] = useState<DxGridAxisMeta>(createDxGridColumns(model));
112
+ const [rows, setRows] = useState<DxGridAxisMeta>(createDxGridColumns(model));
61
113
 
62
- useEffect(() => {
114
+ useLayoutEffect(() => {
63
115
  const cellsAccessor = createDocAccessor(model.sheet, ['cells']);
116
+ if (dxGridRef.current) {
117
+ dxGridRef.current.getCells = cellGetter(model, formatting);
118
+ }
64
119
  const handleCellsUpdate = () => {
65
- setDxGridCells(createDxGridCells(model, formatting));
120
+ dxGridRef.current?.requestUpdate('initialCells');
66
121
  };
67
122
  cellsAccessor.handle.addListener('change', handleCellsUpdate);
68
123
  return () => cellsAccessor.handle.removeListener('change', handleCellsUpdate);
@@ -72,10 +127,10 @@ export const useSheetModelDxGridProps = (
72
127
  const columnMetaAccessor = createDocAccessor(model.sheet, ['columnMeta']);
73
128
  const rowMetaAccessor = createDocAccessor(model.sheet, ['rowMeta']);
74
129
  const handleColumnMetaUpdate = () => {
75
- setDxGridColumns(createDxGridColumns(model));
130
+ setColumns(createDxGridColumns(model));
76
131
  };
77
132
  const handleRowMetaUpdate = () => {
78
- setDxGridRows(createDxGridRows(model));
133
+ setRows(createDxGridRows(model));
79
134
  };
80
135
  columnMetaAccessor.handle.addListener('change', handleColumnMetaUpdate);
81
136
  rowMetaAccessor.handle.addListener('change', handleRowMetaUpdate);
@@ -85,5 +140,5 @@ export const useSheetModelDxGridProps = (
85
140
  };
86
141
  }, [model]);
87
142
 
88
- return { cells: dxGridCells, columns: dxGridColumns, rows: dxGridRows };
143
+ return { columns, rows };
89
144
  };
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { useSpace } from '@dxos/react-client/echo';
8
+ import { withClientProvider } from '@dxos/react-client/testing';
9
+ import { withTheme, withLayout } from '@dxos/storybook-utils';
10
+
11
+ import { SheetContainer } from './SheetContainer';
12
+ import { useComputeGraph } from '../../hooks';
13
+ import { useTestSheet, withComputeGraphDecorator } from '../../testing';
14
+ import { SheetType } from '../../types';
15
+
16
+ export default {
17
+ title: 'plugin-sheet/SheetContainer',
18
+ component: SheetContainer,
19
+ decorators: [
20
+ withClientProvider({ types: [SheetType], createSpace: true }),
21
+ withComputeGraphDecorator(),
22
+ withTheme,
23
+ withLayout({
24
+ fullscreen: true,
25
+ tooltips: true,
26
+ classNames: 'grid grid-cols-1 grid-rows-[min-content_minmax(0,1fr)_min-content]',
27
+ }),
28
+ ],
29
+ };
30
+
31
+ export const Basic = () => {
32
+ const space = useSpace();
33
+ const graph = useComputeGraph(space);
34
+ const sheet = useTestSheet(space, graph);
35
+ if (!sheet || !graph) {
36
+ return null;
37
+ }
38
+
39
+ return <SheetContainer graph={graph} sheet={sheet} role='article' />;
40
+ };
@@ -0,0 +1,52 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import React, { useCallback } from 'react';
6
+
7
+ import { useIntentDispatcher } from '@dxos/app-framework';
8
+
9
+ import { FunctionEditor } from '../FunctionEditor';
10
+ import { GridSheet } from '../GridSheet';
11
+ import { SheetProvider, type SheetProviderProps } from '../SheetContext';
12
+ import { Toolbar, type ToolbarAction } from '../Toolbar';
13
+
14
+ export const SheetContainer = ({ graph, sheet, role }: SheetProviderProps & { role?: string }) => {
15
+ const dispatch = useIntentDispatcher();
16
+
17
+ // TODO(Zan): Centralise the toolbar action handler. Current implementation in stories.
18
+ const handleAction = useCallback(
19
+ (action: ToolbarAction) => {
20
+ switch (action.type) {
21
+ case 'comment': {
22
+ // TODO(Zan): We shouldn't hardcode the action ID.
23
+ void dispatch({
24
+ action: 'dxos.org/plugin/thread/action/create',
25
+ data: {
26
+ cursor: action.anchor,
27
+ name: action.cellContent,
28
+ subject: sheet,
29
+ },
30
+ });
31
+ }
32
+ }
33
+ },
34
+ [sheet, dispatch],
35
+ );
36
+
37
+ return (
38
+ <SheetProvider sheet={sheet} graph={graph}>
39
+ <Toolbar.Root onAction={handleAction} role={role}>
40
+ <Toolbar.Styles />
41
+ <Toolbar.Format />
42
+ <Toolbar.Alignment />
43
+ <Toolbar.Separator />
44
+ <Toolbar.Actions />
45
+ </Toolbar.Root>
46
+ <div role='none' className='border-bs border-separator grid cols-1 rows-[1fr_min-content] min-bs-0'>
47
+ <GridSheet />
48
+ <FunctionEditor />
49
+ </div>
50
+ </SheetProvider>
51
+ );
52
+ };
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { SheetContainer } from './SheetContainer';
6
+
7
+ export default SheetContainer;
@@ -5,15 +5,18 @@
5
5
  import React, { type PropsWithChildren, createContext, useContext, useMemo, useState } from 'react';
6
6
 
7
7
  import { invariant } from '@dxos/invariant';
8
- import { type Space } from '@dxos/react-client/echo';
8
+ import { fullyQualifiedId } from '@dxos/react-client/echo';
9
+ import { Grid, useGridContext, type GridScopedProps, type GridEditing } from '@dxos/react-ui-grid';
9
10
 
10
- import { createDecorations } from './decorations';
11
11
  import { type CellAddress, type CellRange } from '../../defs';
12
- import { useSheetModel, useFormattingModel } from '../../hooks';
13
- import { type FormattingModel, type SheetModel } from '../../model';
12
+ import { type ComputeGraph } from '../../graph';
13
+ import { useSheetModel, useFormattingModel, useSelectThreadOnCellFocus, useThreadDecorations } from '../../hooks';
14
+ import { type FormattingModel, type SheetModel, createDecorations } from '../../model';
14
15
  import { type SheetType } from '../../types';
15
16
 
16
- export type SheetContextType = {
17
+ export type SheetContextValue = {
18
+ id: string;
19
+
17
20
  model: SheetModel;
18
21
  formatting: FormattingModel;
19
22
 
@@ -25,8 +28,8 @@ export type SheetContextType = {
25
28
  setRange: (range: CellRange | undefined) => void;
26
29
 
27
30
  // Editing state (undefined if not editing).
28
- editing: boolean;
29
- setEditing: (editing: boolean) => void;
31
+ editing: GridEditing;
32
+ setEditing: (editing: GridEditing) => void;
30
33
 
31
34
  // Events.
32
35
  // TODO(burdon): Generalize.
@@ -36,47 +39,45 @@ export type SheetContextType = {
36
39
  decorations: ReturnType<typeof createDecorations>;
37
40
  };
38
41
 
39
- const SheetContext = createContext<SheetContextType | null>(null);
42
+ const SheetContext = createContext<SheetContextValue | null>(null);
40
43
 
41
- export const useSheetContext = (): SheetContextType => {
44
+ export const useSheetContext = (): SheetContextValue => {
42
45
  const context = useContext(SheetContext);
43
46
  invariant(context);
44
47
  return context;
45
48
  };
46
49
 
47
- export type SheetContextProps = {
48
- sheet: SheetType;
49
- space: Space;
50
- readonly?: boolean;
51
- } & Pick<SheetContextType, 'onInfo'>;
52
-
53
- export const SheetContextProvider = ({
54
- children,
55
- sheet,
56
- space,
57
- readonly,
50
+ const SheetProviderImpl = ({
51
+ model,
52
+ formatting,
58
53
  onInfo,
59
- }: PropsWithChildren<SheetContextProps>) => {
60
- const model = useSheetModel(space, sheet, { readonly });
61
- const formatting = useFormattingModel(model);
54
+ children,
55
+ __gridScope,
56
+ }: GridScopedProps<PropsWithChildren<Pick<SheetContextValue, 'onInfo' | 'model' | 'formatting'>>>) => {
57
+ const { id, editing, setEditing } = useGridContext('SheetProvider', __gridScope);
62
58
 
63
59
  // TODO(Zan): Impl. set range and set cursor that scrolls to that cell or range if it is not visible.
60
+ const decorations = useMemo(() => createDecorations(), []);
61
+
62
+ // TODO(thure): Reconnect these.
64
63
  const [cursor, setCursor] = useState<CellAddress>();
65
64
  const [range, setRange] = useState<CellRange>();
66
- const [editing, setEditing] = useState<boolean>(false);
67
- const decorations = useMemo(() => createDecorations(), []);
68
65
 
69
- return !model || !formatting ? null : (
66
+ useSelectThreadOnCellFocus(model, cursor);
67
+ useThreadDecorations(model, decorations);
68
+
69
+ return (
70
70
  <SheetContext.Provider
71
71
  value={{
72
+ id,
72
73
  model,
73
74
  formatting,
75
+ editing,
76
+ setEditing,
74
77
  cursor,
75
78
  setCursor,
76
79
  range,
77
80
  setRange,
78
- editing,
79
- setEditing,
80
81
  // TODO(burdon): Change to event.
81
82
  onInfo,
82
83
  decorations,
@@ -86,3 +87,22 @@ export const SheetContextProvider = ({
86
87
  </SheetContext.Provider>
87
88
  );
88
89
  };
90
+
91
+ export type SheetProviderProps = {
92
+ graph: ComputeGraph;
93
+ sheet: SheetType;
94
+ readonly?: boolean;
95
+ } & Pick<SheetContextValue, 'onInfo'>;
96
+
97
+ export const SheetProvider = ({ children, graph, sheet, readonly, onInfo }: PropsWithChildren<SheetProviderProps>) => {
98
+ const model = useSheetModel(graph, sheet, { readonly });
99
+ const formatting = useFormattingModel(model);
100
+
101
+ return !model || !formatting ? null : (
102
+ <Grid.Root id={fullyQualifiedId(sheet)}>
103
+ <SheetProviderImpl model={model} formatting={formatting} onInfo={onInfo}>
104
+ {children}
105
+ </SheetProviderImpl>
106
+ </Grid.Root>
107
+ );
108
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './SheetContext';