@dxos/plugin-sheet 0.6.11 → 0.6.12-main.5a87ad5

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 (263) hide show
  1. package/dist/lib/browser/SheetContainer-VISF3VUB.mjs +261 -0
  2. package/dist/lib/browser/SheetContainer-VISF3VUB.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-JRL5LGCE.mjs → chunk-QILRZNE5.mjs} +2 -5
  4. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-FUAGSXA4.mjs → chunk-WZMOZKQZ.mjs} +9 -16
  6. package/dist/lib/browser/chunk-WZMOZKQZ.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-D5AGLXJP.mjs → chunk-Z2XOOC2R.mjs} +385 -678
  8. package/dist/lib/browser/chunk-Z2XOOC2R.mjs.map +7 -0
  9. package/dist/lib/browser/{SheetContainer-U4H5D34A.mjs → chunk-ZLJ2GRE2.mjs} +1151 -240
  10. package/dist/lib/browser/chunk-ZLJ2GRE2.mjs.map +7 -0
  11. package/dist/lib/browser/graph-4XFKIHRL.mjs +21 -0
  12. package/dist/lib/browser/graph-4XFKIHRL.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +74 -60
  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/types.mjs +4 -6
  18. package/dist/lib/node/SheetContainer-2MEALQWW.cjs +279 -0
  19. package/dist/lib/node/SheetContainer-2MEALQWW.cjs.map +7 -0
  20. package/dist/lib/node/{SheetContainer-AXQV3ZT5.cjs → chunk-6DQABRGJ.cjs} +1182 -279
  21. package/dist/lib/node/chunk-6DQABRGJ.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-DSYKOI4E.cjs → chunk-AOP42UAA.cjs} +13 -21
  23. package/dist/lib/node/chunk-AOP42UAA.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-BJ6ZD7MN.cjs → chunk-BNARJ5GM.cjs} +5 -18
  25. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +7 -0
  26. package/dist/lib/node/{chunk-5KKJ4NPP.cjs → chunk-P5QYYEHQ.cjs} +388 -676
  27. package/dist/lib/node/chunk-P5QYYEHQ.cjs.map +7 -0
  28. package/dist/lib/node/graph-2LRDUXBZ.cjs +43 -0
  29. package/dist/lib/node/graph-2LRDUXBZ.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +86 -66
  31. package/dist/lib/node/index.cjs.map +3 -3
  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-RPSUSXWS.mjs +262 -0
  38. package/dist/lib/node-esm/SheetContainer-RPSUSXWS.mjs.map +7 -0
  39. package/dist/lib/node-esm/chunk-4MM7THJW.mjs +2944 -0
  40. package/dist/lib/node-esm/chunk-4MM7THJW.mjs.map +7 -0
  41. package/dist/lib/node-esm/chunk-5RLTCIE2.mjs +2684 -0
  42. package/dist/lib/node-esm/chunk-5RLTCIE2.mjs.map +7 -0
  43. package/dist/lib/node-esm/chunk-IU2L277A.mjs +17 -0
  44. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +7 -0
  45. package/dist/lib/node-esm/chunk-RR2AO4SM.mjs +76 -0
  46. package/dist/lib/node-esm/chunk-RR2AO4SM.mjs.map +7 -0
  47. package/dist/lib/node-esm/graph-WG5EKOMO.mjs +22 -0
  48. package/dist/lib/node-esm/graph-WG5EKOMO.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +263 -0
  50. package/dist/lib/node-esm/index.mjs.map +7 -0
  51. package/dist/lib/node-esm/meta.json +1 -0
  52. package/dist/lib/node-esm/meta.mjs +10 -0
  53. package/dist/lib/node-esm/meta.mjs.map +7 -0
  54. package/dist/lib/node-esm/types.mjs +21 -0
  55. package/dist/lib/node-esm/types.mjs.map +7 -0
  56. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  57. package/dist/types/src/components/CellEditor/CellEditor.d.ts +23 -3
  58. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -1
  59. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts +2 -2
  60. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -1
  61. package/dist/types/src/components/CellEditor/extension.d.ts +1 -1
  62. package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
  63. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +11 -0
  64. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -0
  65. package/dist/types/src/components/ComputeGraph/index.d.ts +1 -3
  66. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  67. package/dist/types/src/components/GridSheet/GridSheet.d.ts +10 -0
  68. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -0
  69. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +9 -0
  70. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -0
  71. package/dist/types/src/components/GridSheet/util.d.ts +7 -0
  72. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -0
  73. package/dist/types/src/components/Sheet/Sheet.d.ts +1 -1
  74. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  75. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +5 -6
  76. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/Sheet/decorations.d.ts +24 -0
  78. package/dist/types/src/components/Sheet/decorations.d.ts.map +1 -0
  79. package/dist/types/src/components/Sheet/grid.d.ts +2 -2
  80. package/dist/types/src/components/Sheet/grid.d.ts.map +1 -1
  81. package/dist/types/src/components/Sheet/nav.d.ts +3 -3
  82. package/dist/types/src/components/Sheet/nav.d.ts.map +1 -1
  83. package/dist/types/src/components/Sheet/sheet-context.d.ts +8 -7
  84. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
  85. package/dist/types/src/components/Sheet/threads.d.ts +2 -0
  86. package/dist/types/src/components/Sheet/threads.d.ts.map +1 -0
  87. package/dist/types/src/components/SheetContainer.d.ts +2 -3
  88. package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
  89. package/dist/types/src/components/Toolbar/Toolbar.d.ts +19 -3
  90. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  91. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +18 -13
  92. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/index.d.ts +2 -2
  94. package/dist/types/src/components/index.d.ts.map +1 -1
  95. package/dist/types/src/defs/index.d.ts +3 -0
  96. package/dist/types/src/defs/index.d.ts.map +1 -0
  97. package/dist/types/src/{model → defs}/types.d.ts +8 -3
  98. package/dist/types/src/defs/types.d.ts.map +1 -0
  99. package/dist/types/src/defs/types.test.d.ts.map +1 -0
  100. package/dist/types/src/defs/util.d.ts +43 -0
  101. package/dist/types/src/defs/util.d.ts.map +1 -0
  102. package/dist/types/src/extensions/compute.d.ts +9 -0
  103. package/dist/types/src/extensions/compute.d.ts.map +1 -0
  104. package/dist/types/src/extensions/compute.stories.d.ts +26 -0
  105. package/dist/types/src/extensions/compute.stories.d.ts.map +1 -0
  106. package/dist/types/src/extensions/index.d.ts +2 -0
  107. package/dist/types/src/extensions/index.d.ts.map +1 -0
  108. package/dist/types/src/{components/ComputeGraph → graph}/async-function.d.ts +8 -2
  109. package/dist/types/src/graph/async-function.d.ts.map +1 -0
  110. package/dist/types/src/graph/compute-graph.d.ts +84 -0
  111. package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
  112. package/dist/types/src/graph/compute-graph.stories.d.ts +10 -0
  113. package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
  114. package/dist/types/src/graph/compute-graph.test.d.ts +2 -0
  115. package/dist/types/src/graph/compute-graph.test.d.ts.map +1 -0
  116. package/dist/types/src/graph/compute-node.d.ts +26 -0
  117. package/dist/types/src/graph/compute-node.d.ts.map +1 -0
  118. package/dist/types/src/graph/edge-function.d.ts.map +1 -0
  119. package/dist/types/src/{model/functions.d.ts → graph/function-defs.d.ts} +1 -1
  120. package/dist/types/src/graph/function-defs.d.ts.map +1 -0
  121. package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
  122. package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
  123. package/dist/types/src/graph/index.d.ts +4 -0
  124. package/dist/types/src/graph/index.d.ts.map +1 -0
  125. package/dist/types/src/{components/ComputeGraph/custom.d.ts → graph/testing/custom-function.d.ts} +4 -2
  126. package/dist/types/src/graph/testing/custom-function.d.ts.map +1 -0
  127. package/dist/types/src/graph/testing/index.d.ts +2 -0
  128. package/dist/types/src/graph/testing/index.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 -3
  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 -65
  148. package/dist/types/src/model/sheet-model.d.ts.map +1 -0
  149. package/dist/types/src/sanity.test.d.ts +2 -0
  150. package/dist/types/src/sanity.test.d.ts.map +1 -0
  151. package/dist/types/src/testing/index.d.ts +2 -0
  152. package/dist/types/src/testing/index.d.ts.map +1 -0
  153. package/dist/types/src/testing/testing.d.ts +8 -0
  154. package/dist/types/src/testing/testing.d.ts.map +1 -0
  155. package/dist/types/src/translations.d.ts +17 -12
  156. package/dist/types/src/translations.d.ts.map +1 -1
  157. package/dist/types/src/types.d.ts +86 -5
  158. package/dist/types/src/types.d.ts.map +1 -1
  159. package/dist/vendor/hyperformula.mjs +37145 -0
  160. package/package.json +48 -41
  161. package/src/SheetPlugin.tsx +48 -73
  162. package/src/components/CellEditor/CellEditor.stories.tsx +5 -4
  163. package/src/components/CellEditor/CellEditor.tsx +59 -9
  164. package/src/components/CellEditor/extension.test.ts +4 -5
  165. package/src/components/CellEditor/extension.ts +1 -3
  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 +153 -0
  170. package/src/components/GridSheet/util.ts +108 -0
  171. package/src/components/Sheet/Sheet.stories.tsx +52 -88
  172. package/src/components/Sheet/Sheet.tsx +57 -18
  173. package/src/components/Sheet/decorations.ts +62 -0
  174. package/src/components/Sheet/grid.ts +3 -3
  175. package/src/components/Sheet/nav.ts +19 -19
  176. package/src/components/Sheet/sheet-context.tsx +18 -80
  177. package/src/components/Sheet/threads.tsx +205 -0
  178. package/src/components/SheetContainer.tsx +73 -19
  179. package/src/components/Toolbar/Toolbar.tsx +53 -12
  180. package/src/components/index.ts +1 -0
  181. package/src/defs/index.ts +6 -0
  182. package/src/{model → defs}/types.test.ts +8 -9
  183. package/src/{model → defs}/types.ts +24 -14
  184. package/src/defs/util.ts +151 -0
  185. package/src/extensions/compute.stories.tsx +153 -0
  186. package/src/extensions/compute.ts +131 -0
  187. package/src/extensions/index.ts +5 -0
  188. package/src/{components/ComputeGraph → graph}/async-function.ts +15 -6
  189. package/src/graph/compute-graph.stories.tsx +93 -0
  190. package/src/graph/compute-graph.test.ts +127 -0
  191. package/src/graph/compute-graph.ts +313 -0
  192. package/src/graph/compute-node.ts +62 -0
  193. package/src/{components/ComputeGraph → graph}/edge-function.ts +3 -3
  194. package/src/graph/hyperformula.test.ts +15 -0
  195. package/src/graph/index.ts +7 -0
  196. package/src/{components/ComputeGraph/custom.ts → graph/testing/custom-function.ts} +11 -7
  197. package/src/graph/testing/index.ts +5 -0
  198. package/src/graph/util.ts +8 -0
  199. package/src/hooks/hooks.stories.tsx +50 -0
  200. package/src/hooks/index.ts +7 -0
  201. package/src/hooks/useComputeGraph.ts +21 -0
  202. package/src/hooks/useFormattingModel.ts +11 -0
  203. package/src/hooks/useSheetModel.ts +40 -0
  204. package/src/meta.tsx +1 -5
  205. package/src/{components/Sheet/formatting.ts → model/formatting-model.ts} +20 -13
  206. package/src/model/index.ts +2 -3
  207. package/src/model/sheet-model.ts +414 -0
  208. package/src/sanity.test.ts +40 -0
  209. package/src/testing/index.ts +5 -0
  210. package/src/testing/testing.tsx +68 -0
  211. package/src/translations.ts +6 -1
  212. package/src/types.ts +31 -6
  213. package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +0 -7
  214. package/dist/lib/browser/chunk-APHOLYUB.mjs +0 -175
  215. package/dist/lib/browser/chunk-APHOLYUB.mjs.map +0 -7
  216. package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +0 -7
  218. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
  219. package/dist/lib/browser/chunk-NU4PBN33.mjs +0 -8
  220. package/dist/lib/browser/chunk-NU4PBN33.mjs.map +0 -7
  221. package/dist/lib/browser/testing.mjs +0 -92
  222. package/dist/lib/browser/testing.mjs.map +0 -7
  223. package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +0 -7
  224. package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +0 -7
  225. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
  226. package/dist/lib/node/chunk-CN3RPESU.cjs +0 -202
  227. package/dist/lib/node/chunk-CN3RPESU.cjs.map +0 -7
  228. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +0 -7
  229. package/dist/lib/node/chunk-PYXHNAAK.cjs +0 -40
  230. package/dist/lib/node/chunk-PYXHNAAK.cjs.map +0 -7
  231. package/dist/lib/node/testing.cjs +0 -111
  232. package/dist/lib/node/testing.cjs.map +0 -7
  233. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
  234. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
  235. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
  236. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
  237. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
  238. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
  239. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
  240. package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
  241. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
  242. package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
  243. package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
  244. package/dist/types/src/model/functions.d.ts.map +0 -1
  245. package/dist/types/src/model/model.browser.test.d.ts +0 -2
  246. package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
  247. package/dist/types/src/model/model.d.ts.map +0 -1
  248. package/dist/types/src/model/types.d.ts.map +0 -1
  249. package/dist/types/src/model/types.test.d.ts.map +0 -1
  250. package/dist/types/src/model/util.d.ts +0 -15
  251. package/dist/types/src/model/util.d.ts.map +0 -1
  252. package/dist/types/src/testing.d.ts +0 -9
  253. package/dist/types/src/testing.d.ts.map +0 -1
  254. package/src/components/ComputeGraph/graph-context.tsx +0 -50
  255. package/src/components/ComputeGraph/graph.browser.test.ts +0 -50
  256. package/src/components/ComputeGraph/graph.ts +0 -62
  257. package/src/model/model.browser.test.ts +0 -100
  258. package/src/model/model.ts +0 -550
  259. package/src/model/util.ts +0 -36
  260. package/src/testing.ts +0 -50
  261. /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
  262. /package/dist/types/src/{components/ComputeGraph → graph}/edge-function.d.ts +0 -0
  263. /package/src/{model/functions.ts → graph/function-defs.ts} +0 -0
@@ -0,0 +1,153 @@
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 { dxGridCellIndexToSheetCellAddress, 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 sheetRowDefault = { size: 32, resizeable: true };
53
+ const sheetColDefault = { size: 180, resizeable: true };
54
+
55
+ const GridSheetImpl = ({
56
+ model,
57
+ formatting,
58
+ __gridScope,
59
+ }: GridScopedProps<{ model: SheetModel; formatting: FormattingModel }>) => {
60
+ const { editing, setEditing } = useGridContext('GridSheetCellEditor', __gridScope);
61
+ const dxGrid = useRef<DxGridElement | null>(null);
62
+ const rangeNotifier = useRef<CellRangeNotifier>();
63
+
64
+ // TODO(burdon): Validate formula before closing: hf.validateFormula();
65
+ const handleClose = useCallback<NonNullable<EditorKeysProps['onClose']> | NonNullable<EditorKeysProps['onNav']>>(
66
+ (value, { key, shift }) => {
67
+ if (value !== undefined) {
68
+ model.setValue(dxGridCellIndexToSheetCellAddress(editing)!, value);
69
+ }
70
+ setEditing(null);
71
+ const axis = ['Enter', 'ArrowUp', 'ArrowDown'].includes(key)
72
+ ? 'row'
73
+ : ['Tab', 'ArrowLeft', 'ArrowRight'].includes(key)
74
+ ? 'col'
75
+ : undefined;
76
+ const delta = key.startsWith('Arrow') ? (['ArrowUp', 'ArrowLeft'].includes(key) ? -1 : 1) : shift ? -1 : 1;
77
+ dxGrid.current?.refocus(axis, delta);
78
+ },
79
+ [model, editing, setEditing],
80
+ );
81
+
82
+ const handleAxisResize = useCallback<NonNullable<GridContentProps['onAxisResize']>>(
83
+ ({ axis, size, index: numericIndex }) => {
84
+ if (axis === 'row') {
85
+ const rowId = model.sheet.rows[parseInt(numericIndex)];
86
+ model.sheet.rowMeta[rowId] ??= {};
87
+ model.sheet.rowMeta[rowId].size = size;
88
+ } else {
89
+ const columnId = model.sheet.columns[parseInt(numericIndex)];
90
+ model.sheet.columnMeta[columnId] ??= {};
91
+ model.sheet.columnMeta[columnId].size = size;
92
+ }
93
+ },
94
+ [model],
95
+ );
96
+
97
+ const handleSelect = useCallback<NonNullable<GridContentProps['onSelect']>>(
98
+ ({ minCol, maxCol, minRow, maxRow }) => {
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
+ // Update range selection in formula.
105
+ rangeNotifier.current?.(rangeToA1Notation(range));
106
+ }
107
+ },
108
+ [editing],
109
+ );
110
+
111
+ const { columns, rows } = useSheetModelDxGridProps(dxGrid, model, formatting);
112
+
113
+ const extension = useMemo(
114
+ () => [
115
+ editorKeys({ onClose: handleClose, ...(editing?.initialContent && { onNav: handleClose }) }),
116
+ sheetExtension({ functions: model.graph.getFunctions() }),
117
+ rangeExtension((fn) => (rangeNotifier.current = fn)),
118
+ ],
119
+ [model, handleClose, editing],
120
+ );
121
+
122
+ return (
123
+ <>
124
+ <GridSheetCellEditor model={model} extension={extension} />
125
+ <Grid.Content
126
+ initialCells={{}}
127
+ columns={columns}
128
+ rows={rows}
129
+ onAxisResize={handleAxisResize}
130
+ onSelect={handleSelect}
131
+ rowDefault={sheetRowDefault}
132
+ columnDefault={sheetColDefault}
133
+ ref={dxGrid}
134
+ />
135
+ </>
136
+ );
137
+ };
138
+
139
+ export type GridSheetProps = { graph?: ComputeGraph; sheet?: SheetType } & UseSheetModelOptions;
140
+
141
+ export const GridSheet = ({ graph, sheet, ...options }: GridSheetProps) => {
142
+ const model = useSheetModel(graph, 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
+ };
@@ -0,0 +1,108 @@
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 DxGridCells,
13
+ type DxGridAxisMeta,
14
+ type DxGridRange,
15
+ } from '@dxos/react-ui-grid';
16
+ import { mx } from '@dxos/react-ui-theme';
17
+
18
+ import { type CellAddress } from '../../defs';
19
+ import { type SheetModel, type FormattingModel } from '../../model';
20
+
21
+ export const dxGridCellIndexToSheetCellAddress = (gridEditing: GridEditing): CellAddress | null => {
22
+ if (!gridEditing) {
23
+ return null;
24
+ }
25
+ const [colStr, rowStr] = gridEditing.index.split(',');
26
+ return {
27
+ col: parseInt(colStr),
28
+ row: parseInt(rowStr),
29
+ };
30
+ };
31
+
32
+ const createDxGridColumns = (model: SheetModel): DxGridAxisMeta => {
33
+ return model.sheet.columns.reduce((acc: DxGridAxisMeta, columnId, numericIndex) => {
34
+ if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {
35
+ acc[numericIndex] = { size: model.sheet.columnMeta[columnId].size, resizeable: true };
36
+ }
37
+ return acc;
38
+ }, {});
39
+ };
40
+
41
+ const createDxGridRows = (model: SheetModel): DxGridAxisMeta => {
42
+ return model.sheet.rows.reduce((acc: DxGridAxisMeta, rowId, numericIndex) => {
43
+ if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {
44
+ acc[numericIndex] = { size: model.sheet.rowMeta[rowId].size, resizeable: true };
45
+ }
46
+ return acc;
47
+ }, {});
48
+ };
49
+
50
+ const cellGetter = (model: SheetModel, formatting: FormattingModel) => {
51
+ // TODO(thure): Actually use the cache.
52
+ let _cachedBounds: DxGridRange | null = null;
53
+ const cachedCells: DxGridCells = {};
54
+ return (nextBounds: DxGridRange): DxGridCells => {
55
+ [...Array(nextBounds.end.col - nextBounds.start.col)].forEach((_, c0) => {
56
+ return [...Array(nextBounds.end.row - nextBounds.start.row)].forEach((_, r0) => {
57
+ const col = nextBounds.start.col + c0;
58
+ const row = nextBounds.start.row + r0;
59
+ const cell = formatting.getFormatting({ col, row });
60
+ if (cell.value) {
61
+ cachedCells[`${col},${row}`] = { value: cell.value, className: mx(cell.classNames) };
62
+ }
63
+ });
64
+ });
65
+ _cachedBounds = nextBounds;
66
+ return cachedCells;
67
+ };
68
+ };
69
+
70
+ export const useSheetModelDxGridProps = (
71
+ dxGridRef: MutableRefObject<DxGridElement | null>,
72
+ model: SheetModel,
73
+ formatting: FormattingModel,
74
+ ): Pick<GridContentProps, 'columns' | 'rows'> => {
75
+ const [columns, setColumns] = useState<DxGridAxisMeta>(createDxGridColumns(model));
76
+ const [rows, setRows] = useState<DxGridAxisMeta>(createDxGridColumns(model));
77
+
78
+ useLayoutEffect(() => {
79
+ const cellsAccessor = createDocAccessor(model.sheet, ['cells']);
80
+ if (dxGridRef.current) {
81
+ dxGridRef.current.getCells = cellGetter(model, formatting);
82
+ }
83
+ const handleCellsUpdate = () => {
84
+ dxGridRef.current?.requestUpdate('initialCells');
85
+ };
86
+ cellsAccessor.handle.addListener('change', handleCellsUpdate);
87
+ return () => cellsAccessor.handle.removeListener('change', handleCellsUpdate);
88
+ }, [model, formatting]);
89
+
90
+ useEffect(() => {
91
+ const columnMetaAccessor = createDocAccessor(model.sheet, ['columnMeta']);
92
+ const rowMetaAccessor = createDocAccessor(model.sheet, ['rowMeta']);
93
+ const handleColumnMetaUpdate = () => {
94
+ setColumns(createDxGridColumns(model));
95
+ };
96
+ const handleRowMetaUpdate = () => {
97
+ setRows(createDxGridRows(model));
98
+ };
99
+ columnMetaAccessor.handle.addListener('change', handleColumnMetaUpdate);
100
+ rowMetaAccessor.handle.addListener('change', handleRowMetaUpdate);
101
+ return () => {
102
+ columnMetaAccessor.handle.removeListener('change', handleColumnMetaUpdate);
103
+ rowMetaAccessor.handle.removeListener('change', handleRowMetaUpdate);
104
+ };
105
+ }, [model]);
106
+
107
+ return { columns, rows };
108
+ };
@@ -4,31 +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 { 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';
19
+ import { addressToIndex, rangeToIndex } from '../../defs';
20
+ import { type ComputeGraph } from '../../graph';
21
+ import { testPlugins } from '../../graph/testing';
22
+ import { useComputeGraph } from '../../hooks';
23
+ import { createTestCells, useTestSheet, withComputeGraphDecorator } from '../../testing';
24
+ import { SheetType, ValueTypeEnum } from '../../types';
26
25
  import { Toolbar, type ToolbarActionHandler } from '../Toolbar';
27
26
 
28
27
  // TODO(burdon): Allow toolbar to access sheet context; provide state for current cursor/range.
29
- const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) => {
28
+ const SheetWithToolbar = ({ graph, debug }: { graph: ComputeGraph; debug?: boolean }) => {
30
29
  const { model, cursor, range } = useSheetContext();
31
30
 
31
+ const handleRefresh = () => {
32
+ // graph?.refresh(); // TODO(burdon): ???
33
+ };
34
+
32
35
  // TODO(burdon): Factor out.
33
36
  const handleAction: ToolbarActionHandler = ({ type }) => {
34
37
  log.info('action', { type, cursor, range });
@@ -36,7 +39,7 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
36
39
  return;
37
40
  }
38
41
 
39
- const idx = range ? model.rangeToIndex(range) : model.addressToIndex(cursor);
42
+ const idx = range ? rangeToIndex(model.sheet, range) : addressToIndex(model.sheet, cursor);
40
43
  model.sheet.formatting[idx] ??= {};
41
44
  const format = model.sheet.formatting[idx];
42
45
 
@@ -75,14 +78,12 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
75
78
  format.precision = 2;
76
79
  break;
77
80
  }
81
+ case 'comment': {
82
+ break;
83
+ }
78
84
  }
79
85
  };
80
86
 
81
- const graph = useComputeGraph(space);
82
- const handleRefresh = () => {
83
- graph.refresh();
84
- };
85
-
86
87
  return (
87
88
  <div className='flex flex-col overflow-hidden'>
88
89
  <Toolbar.Root onAction={handleAction}>
@@ -99,56 +100,43 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
99
100
  );
100
101
  };
101
102
 
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
-
122
103
  export default {
123
104
  title: 'plugin-sheet/Sheet',
124
105
  component: Sheet,
125
- decorators: [withTheme, withLayout({ fullscreen: true, tooltips: true, classNames: 'inset-4' }), withGraphDecorator],
106
+ decorators: [
107
+ withClientProvider({ types: [SheetType], createIdentity: true }),
108
+ withComputeGraphDecorator({ plugins: testPlugins }),
109
+ withTheme,
110
+ withLayout({ fullscreen: true, tooltips: true, classNames: 'inset-4' }),
111
+ ],
126
112
  };
127
113
 
128
114
  export const Default = () => {
129
115
  const [debug, setDebug] = useState(false);
130
- const sheet = useTestSheet();
131
- const space = getSpace(sheet);
132
- if (!sheet || !space) {
116
+ const space = useSpace();
117
+ const graph = useComputeGraph(space);
118
+ const sheet = useTestSheet(space, graph, { cells: createTestCells() });
119
+ if (!graph || !sheet) {
133
120
  return null;
134
121
  }
135
122
 
136
123
  return (
137
- <Sheet.Root sheet={sheet} space={space} onInfo={() => setDebug((debug) => !debug)}>
138
- <SheetWithToolbar debug={debug} space={space} />
124
+ <Sheet.Root graph={graph} sheet={sheet} onInfo={() => setDebug((debug) => !debug)}>
125
+ <SheetWithToolbar graph={graph} debug={debug} />
139
126
  </Sheet.Root>
140
127
  );
141
128
  };
142
129
 
143
130
  export const Debug = () => {
144
- const sheet = useTestSheet();
145
- const space = getSpace(sheet);
146
- if (!sheet || !space) {
131
+ const space = useSpace();
132
+ const graph = useComputeGraph(space);
133
+ const sheet = useTestSheet(space, graph, { cells: createTestCells() });
134
+ if (!graph || !sheet) {
147
135
  return null;
148
136
  }
149
137
 
150
138
  return (
151
- <Sheet.Root sheet={sheet} space={space}>
139
+ <Sheet.Root graph={graph} sheet={sheet}>
152
140
  <Sheet.Main />
153
141
  <Sheet.Debug />
154
142
  </Sheet.Root>
@@ -157,14 +145,15 @@ export const Debug = () => {
157
145
 
158
146
  export const Rows = () => {
159
147
  const [rowSizes, setRowSizes] = useState<SizeMap>({});
160
- const sheet = useTestSheet();
161
- const space = getSpace(sheet);
162
- if (!sheet || !space) {
148
+ const space = useSpace();
149
+ const graph = useComputeGraph(space);
150
+ const sheet = useTestSheet(space, graph);
151
+ if (!graph || !sheet) {
163
152
  return null;
164
153
  }
165
154
 
166
155
  return (
167
- <Sheet.Root sheet={sheet} space={space}>
156
+ <Sheet.Root graph={graph} sheet={sheet}>
168
157
  <Sheet.Rows
169
158
  rows={sheet.rows}
170
159
  sizes={rowSizes}
@@ -176,14 +165,15 @@ export const Rows = () => {
176
165
 
177
166
  export const Columns = () => {
178
167
  const [columnSizes, setColumnSizes] = useState<SizeMap>({});
179
- const sheet = useTestSheet();
180
- const space = getSpace(sheet);
181
- if (!sheet || !space) {
168
+ const space = useSpace();
169
+ const graph = useComputeGraph(space);
170
+ const sheet = useTestSheet(space, graph);
171
+ if (!graph || !sheet) {
182
172
  return null;
183
173
  }
184
174
 
185
175
  return (
186
- <Sheet.Root sheet={sheet} space={space}>
176
+ <Sheet.Root graph={graph} sheet={sheet}>
187
177
  <Sheet.Columns
188
178
  columns={sheet.columns}
189
179
  sizes={columnSizes}
@@ -194,18 +184,19 @@ export const Columns = () => {
194
184
  };
195
185
 
196
186
  export const Main = () => {
197
- const sheet = useTestSheet();
198
- const space = getSpace(sheet);
199
- if (!sheet || !space) {
187
+ const space = useSpace();
188
+ const graph = useComputeGraph(space);
189
+ const sheet = useTestSheet(space, graph, { cells: createTestCells() });
190
+ if (!graph || !sheet) {
200
191
  return null;
201
192
  }
202
193
 
203
194
  return (
204
- <Sheet.Root sheet={sheet} space={space}>
195
+ <Sheet.Root graph={graph} sheet={sheet}>
205
196
  <Sheet.Grid
206
197
  size={{
207
198
  numRows: 50,
208
- numColumns: 26,
199
+ numCols: 26,
209
200
  }}
210
201
  rows={sheet.rows}
211
202
  columns={sheet.columns}
@@ -258,30 +249,3 @@ export const GridLayout = () => {
258
249
  const Cell = ({ className, label }: { className?: string; label: string }) => (
259
250
  <div className={mx('flex items-center justify-center border', className)}>{label}</div>
260
251
  );
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
- };
@@ -60,6 +60,7 @@ import {
60
60
  } from './grid';
61
61
  import { type GridSize, handleArrowNav, handleNav, useRangeSelect } from './nav';
62
62
  import { type SheetContextProps, SheetContextProvider, useSheetContext } from './sheet-context';
63
+ import { useThreads } from './threads';
63
64
  import { getRectUnion, getRelativeClientRect, scrollIntoView } from './util';
64
65
  import {
65
66
  type CellIndex,
@@ -68,7 +69,9 @@ import {
68
69
  columnLetter,
69
70
  posEquals,
70
71
  rangeToA1Notation,
71
- } from '../../model';
72
+ addressToIndex,
73
+ addressFromIndex,
74
+ } from '../../defs';
72
75
  import {
73
76
  CellEditor,
74
77
  type CellRangeNotifier,
@@ -135,12 +138,16 @@ const SheetRoot = ({ children, ...props }: PropsWithChildren<SheetContextProps>)
135
138
 
136
139
  type SheetMainProps = ThemedClassName<Partial<GridSize>>;
137
140
 
138
- const SheetMain = forwardRef<HTMLDivElement, SheetMainProps>(({ classNames, numRows, numColumns }, forwardRef) => {
141
+ const SheetMain = forwardRef<HTMLDivElement, SheetMainProps>(({ classNames, numRows, numCols }, forwardRef) => {
139
142
  const { model, cursor, setCursor, setRange, setEditing } = useSheetContext();
140
143
 
141
144
  // Scrolling.
142
145
  const { rowsRef, columnsRef, contentRef } = useScrollHandlers();
143
146
 
147
+ // Threads.
148
+ // TODO(Zan): Move this to an extension once we have an extension model.
149
+ useThreads();
150
+
144
151
  //
145
152
  // Order of Row/columns.
146
153
  //
@@ -170,21 +177,21 @@ const SheetMain = forwardRef<HTMLDivElement, SheetMainProps>(({ classNames, numR
170
177
  }, [rows, columns]);
171
178
 
172
179
  const handleMoveRows: SheetRowsProps['onMove'] = (from, to, num = 1) => {
173
- const cursorIdx = cursor ? model.addressToIndex(cursor) : undefined;
180
+ const cursorIdx = cursor ? addressToIndex(model.sheet, cursor) : undefined;
174
181
  const [rows] = model.sheet.rows.splice(from, num);
175
182
  model.sheet.rows.splice(to, 0, rows);
176
183
  if (cursorIdx) {
177
- setCursor(model.addressFromIndex(cursorIdx));
184
+ setCursor(addressFromIndex(model.sheet, cursorIdx));
178
185
  }
179
186
  setRows([...model.sheet.rows]);
180
187
  };
181
188
 
182
189
  const handleMoveColumns: SheetColumnsProps['onMove'] = (from, to, num = 1) => {
183
- const cursorIdx = cursor ? model.addressToIndex(cursor) : undefined;
190
+ const cursorIdx = cursor ? addressToIndex(model.sheet, cursor) : undefined;
184
191
  const columns = model.sheet.columns.splice(from, num);
185
192
  model.sheet.columns.splice(to, 0, ...columns);
186
193
  if (cursorIdx) {
187
- setCursor(model.addressFromIndex(cursorIdx));
194
+ setCursor(addressFromIndex(model.sheet, cursorIdx));
188
195
  }
189
196
  setColumns([...model.sheet.columns]);
190
197
  };
@@ -256,8 +263,8 @@ const SheetMain = forwardRef<HTMLDivElement, SheetMainProps>(({ classNames, numR
256
263
  ref={columnsRef}
257
264
  columns={columns}
258
265
  sizes={columnSizes}
259
- selected={cursor?.column}
260
- onSelect={(column) => setCursor(cursor?.column === column ? undefined : { row: -1, column })}
266
+ selected={cursor?.col}
267
+ onSelect={(col) => setCursor(cursor?.col === col ? undefined : { row: -1, col })}
261
268
  onResize={handleResizeColumn}
262
269
  onMove={handleMoveColumns}
263
270
  />
@@ -267,13 +274,13 @@ const SheetMain = forwardRef<HTMLDivElement, SheetMainProps>(({ classNames, numR
267
274
  rows={rows}
268
275
  sizes={rowSizes}
269
276
  selected={cursor?.row}
270
- onSelect={(row) => setCursor(cursor?.row === row ? undefined : { row, column: -1 })}
277
+ onSelect={(row) => setCursor(cursor?.row === row ? undefined : { row, col: -1 })}
271
278
  onResize={handleResizeRow}
272
279
  onMove={handleMoveRows}
273
280
  />
274
281
  <SheetGrid
275
282
  ref={contentRef}
276
- size={{ numRows: numRows ?? rows.length, numColumns: numColumns ?? columns.length }}
283
+ size={{ numRows: numRows ?? rows.length, numCols: numCols ?? columns.length }}
277
284
  rows={rows}
278
285
  columns={columns}
279
286
  rowSizes={rowSizes}
@@ -878,11 +885,11 @@ const SheetGrid = forwardRef<HTMLDivElement, SheetGridProps>(
878
885
 
879
886
  {/* Grid cells. */}
880
887
  {rowRange.map(({ row, top, height }) => {
881
- return columnRange.map(({ column, left, width }) => {
888
+ return columnRange.map(({ col, left, width }) => {
882
889
  const style: CSSProperties = { position: 'absolute', top, left, width, height };
883
- const cell = { row, column };
890
+ const cell: CellAddress = { row, col };
884
891
  const id = addressToA1Notation(cell);
885
- const idx = model.addressToIndex(cell);
892
+ const idx = addressToIndex(model.sheet, cell);
886
893
  const active = posEquals(cursor, cell);
887
894
  if (active && editing) {
888
895
  const value = initialText.current ?? model.getCellText(cell) ?? '';
@@ -1003,16 +1010,46 @@ type SheetCellProps = {
1003
1010
  };
1004
1011
 
1005
1012
  const SheetCell = ({ id, cell, style, active, onSelect }: SheetCellProps) => {
1006
- const { formatting, editing, setRange } = useSheetContext();
1013
+ const {
1014
+ formatting,
1015
+ editing,
1016
+ setRange,
1017
+ decorations,
1018
+ model: { sheet },
1019
+ } = useSheetContext();
1007
1020
  const { value, classNames } = formatting.getFormatting(cell);
1008
1021
 
1022
+ const decorationsForCell = decorations.getDecorationsForCell(addressToIndex(sheet, cell)) ?? [];
1023
+ const decorationAddedClasses = useMemo(
1024
+ () => decorationsForCell.flatMap((d) => d.classNames ?? []),
1025
+ [decorationsForCell],
1026
+ );
1027
+ const decoratedContent = decorationsForCell.reduce(
1028
+ (children, { decorate }) => {
1029
+ if (!decorate) {
1030
+ return children;
1031
+ }
1032
+ const DecoratorComponent = decorate;
1033
+ return <DecoratorComponent>{children}</DecoratorComponent>;
1034
+ },
1035
+ <div
1036
+ role='none'
1037
+ className={mx(
1038
+ 'flex flex-grow bs-full is-full px-2 items-center truncate cursor-pointer',
1039
+ ...decorationAddedClasses,
1040
+ )}
1041
+ >
1042
+ {value}
1043
+ </div>,
1044
+ );
1045
+
1009
1046
  return (
1010
1047
  <div
1011
1048
  {...{ [`data-${CELL_DATA_KEY}`]: id }}
1012
1049
  role='cell'
1013
1050
  style={style}
1014
1051
  className={mx(
1015
- 'flex w-full h-full px-2 py-1 truncate items-center border border-gridLine cursor-pointer',
1052
+ 'border border-gridLine cursor-pointer',
1016
1053
  fragments.cell,
1017
1054
  active && ['z-20', fragments.cellSelected],
1018
1055
  classNames,
@@ -1026,7 +1063,7 @@ const SheetCell = ({ id, cell, style, active, onSelect }: SheetCellProps) => {
1026
1063
  }}
1027
1064
  onDoubleClick={() => onSelect?.(cell, true)}
1028
1065
  >
1029
- {value}
1066
+ {decoratedContent}
1030
1067
  </div>
1031
1068
  );
1032
1069
  };
@@ -1045,10 +1082,11 @@ const GridCellEditor = ({ style, value, onNav, onClose }: GridCellEditorProps) =
1045
1082
  notifier.current?.(rangeToA1Notation(range));
1046
1083
  }
1047
1084
  }, [range]);
1085
+
1048
1086
  const extension = useMemo(
1049
1087
  () => [
1050
1088
  editorKeys({ onNav, onClose }),
1051
- sheetExtension({ functions: model.functions }),
1089
+ sheetExtension({ functions: model.graph.getFunctions() }),
1052
1090
  rangeExtension((fn) => (notifier.current = fn)),
1053
1091
  ],
1054
1092
  [model],
@@ -1072,12 +1110,13 @@ const GridCellEditor = ({ style, value, onNav, onClose }: GridCellEditorProps) =
1072
1110
 
1073
1111
  const SheetStatusBar = () => {
1074
1112
  const { model, cursor, range } = useSheetContext();
1113
+
1075
1114
  let value;
1076
1115
  let isFormula = false;
1077
1116
  if (cursor) {
1078
1117
  value = model.getCellValue(cursor);
1079
1118
  if (typeof value === 'string' && value.charAt(0) === '=') {
1080
- value = model.mapFormulaBindingFromId(model.mapFormulaIndicesToRefs(value));
1119
+ value = model.graph.mapFunctionBindingFromId(model.mapFormulaIndicesToRefs(value));
1081
1120
  isFormula = true;
1082
1121
  } else if (value != null) {
1083
1122
  value = String(value);