@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
@@ -1,191 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { type MouseEvent, useEffect, useState } from 'react';
6
-
7
- import { type CellAddress, type CellIndex, addressFromA1Notation, addressToA1Notation } from '../../defs';
8
-
9
- // export type Bounds = Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>;
10
- // export type Dimension = Pick<DOMRect, 'width' | 'height'>;
11
-
12
- export type SizeMap = Record<string, number>;
13
-
14
- export type RowPosition = { row: number } & Pick<DOMRect, 'top' | 'height'>;
15
- export type ColumnPosition = { col: number } & Pick<DOMRect, 'left' | 'width'>;
16
-
17
- export const axisWidth = 'calc(var(--rail-size)-2px)';
18
- export const axisHeight = 34;
19
-
20
- export const minWidth = 40;
21
- export const maxWidth = 800;
22
-
23
- export const minHeight = axisHeight;
24
- export const maxHeight = 400;
25
-
26
- export const defaultWidth = 200;
27
- export const defaultHeight = minHeight;
28
-
29
- /**
30
- * Cell nodes are identified by their A1 notation.
31
- */
32
- export const CELL_DATA_KEY = 'cell';
33
-
34
- export type GridLayoutProps = {
35
- rows: CellIndex[];
36
- columns: CellIndex[];
37
- rowSizes?: SizeMap;
38
- columnSizes?: SizeMap;
39
- };
40
-
41
- export type GridLayout = {
42
- width: number;
43
- height: number;
44
- rowRange: RowPosition[];
45
- columnRange: ColumnPosition[];
46
- };
47
-
48
- /**
49
- * Calculates the grid geometry for the current viewport.
50
- */
51
- export const useGridLayout = ({
52
- scroller,
53
- size,
54
- rows,
55
- columns,
56
- rowSizes,
57
- columnSizes,
58
- }: GridLayoutProps & {
59
- scroller: HTMLDivElement | null;
60
- size: { width: number; height: number };
61
- }): GridLayout => {
62
- const [rowPositions, setRowPositions] = useState<RowPosition[]>([]);
63
- useEffect(() => {
64
- if (!rowSizes) {
65
- return;
66
- }
67
-
68
- let y = 0;
69
- setRowPositions(
70
- rows.map((idx, i) => {
71
- const height = rowSizes?.[idx] ?? defaultHeight;
72
- const top = y;
73
- y += height - 1;
74
- return { row: i, top, height };
75
- }),
76
- );
77
- }, [rows, rowSizes]);
78
-
79
- const [columnPositions, setColumnPositions] = useState<ColumnPosition[]>([]);
80
- useEffect(() => {
81
- if (!columns) {
82
- return;
83
- }
84
-
85
- let x = 0;
86
- setColumnPositions(
87
- columns.map((idx, i) => {
88
- const width = columnSizes?.[idx] ?? defaultWidth;
89
- const left = x;
90
- x += width - 1;
91
- return { col: i, left, width };
92
- }),
93
- );
94
- }, [columns, columnSizes]);
95
-
96
- const height = rowPositions.length
97
- ? rowPositions[rowPositions.length - 1].top + rowPositions[rowPositions.length - 1].height
98
- : 0;
99
-
100
- const width = columnPositions.length
101
- ? columnPositions[columnPositions.length - 1].left + columnPositions[columnPositions.length - 1].width
102
- : 0;
103
-
104
- //
105
- // Virtual window.
106
- // TODO(burdon): Preserve edit state, selection.
107
- // TODO(burdon): BUG: Doesn't scroll to cursor if jump to end.
108
- //
109
-
110
- const [{ rowRange, columnRange }, setWindow] = useState<{
111
- rowRange: RowPosition[];
112
- columnRange: ColumnPosition[];
113
- }>({ rowRange: [], columnRange: [] });
114
- useEffect(() => {
115
- const handleScroll = () => {
116
- if (!scroller) {
117
- return;
118
- }
119
-
120
- const { scrollLeft: left, scrollTop: top, clientWidth: width, clientHeight: height } = scroller;
121
-
122
- let rowStart = 0;
123
- let rowEnd = 0;
124
- for (let i = 0; i < rowPositions.length; i++) {
125
- const row = rowPositions[i];
126
- if (row.top <= top) {
127
- rowStart = i;
128
- }
129
- if (row.top + row.height >= top + height) {
130
- rowEnd = i;
131
- break;
132
- }
133
- }
134
-
135
- let columnStart = 0;
136
- let columnEnd = 0;
137
- for (let i = 0; i < columnPositions.length; i++) {
138
- const column = columnPositions[i];
139
- if (column.left <= left) {
140
- columnStart = i;
141
- }
142
- if (column.left + column.width >= left + width) {
143
- columnEnd = i;
144
- break;
145
- }
146
- }
147
-
148
- const overscan = 5;
149
- setWindow({
150
- rowRange: rowPositions.slice(
151
- Math.max(0, rowStart - overscan),
152
- Math.min(rowPositions.length, rowEnd + overscan),
153
- ),
154
- columnRange: columnPositions.slice(
155
- Math.max(0, columnStart - overscan),
156
- Math.min(columnPositions.length, columnEnd + overscan),
157
- ),
158
- });
159
- };
160
-
161
- scroller?.addEventListener('scroll', handleScroll);
162
- handleScroll();
163
- return () => {
164
- scroller?.removeEventListener('scroll', handleScroll);
165
- };
166
- }, [size.width, size.height, rowPositions, columnPositions]);
167
-
168
- return { width, height, rowRange, columnRange };
169
- };
170
-
171
- /**
172
- * Find child node at mouse pointer.
173
- */
174
- export const getCellAtPointer = (event: MouseEvent): CellAddress | undefined => {
175
- const element = document.elementFromPoint(event.clientX, event.clientY);
176
- const root = element?.closest<HTMLDivElement>(`[data-${CELL_DATA_KEY}]`);
177
- if (root) {
178
- const value = root.dataset[CELL_DATA_KEY];
179
- if (value) {
180
- return addressFromA1Notation(value);
181
- }
182
- }
183
- };
184
-
185
- /**
186
- * Get element.
187
- */
188
- export const getCellElement = (root: HTMLElement, cell: CellAddress): HTMLElement | null => {
189
- const pos = addressToA1Notation(cell);
190
- return root.querySelector(`[data-${CELL_DATA_KEY}="${pos}"]`);
191
- };
@@ -1,157 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { type KeyboardEvent, type MouseEventHandler, useState } from 'react';
6
-
7
- import { getCellAtPointer } from './grid';
8
- import { type CellAddress, type CellRange, posEquals } from '../../defs';
9
-
10
- export type GridSize = {
11
- numRows: number;
12
- numCols: number;
13
- };
14
-
15
- /**
16
- * Calculate next range based on arrow keys.
17
- */
18
- export const handleNav = (
19
- ev: KeyboardEvent<HTMLInputElement>,
20
- cursor: CellAddress | undefined,
21
- range: CellRange | undefined,
22
- size: GridSize,
23
- ): { cursor?: CellAddress; range?: CellRange } => {
24
- if (cursor && ev.shiftKey) {
25
- // Navigate from the furthest point.
26
- const opposite = range?.to ?? { ...cursor };
27
- switch (ev.key) {
28
- case 'ArrowUp': {
29
- if (opposite.row > 0) {
30
- opposite.row -= 1;
31
- }
32
- break;
33
- }
34
- case 'ArrowDown': {
35
- if (opposite.row < size.numRows - 1) {
36
- opposite.row += 1;
37
- }
38
- break;
39
- }
40
- case 'ArrowLeft': {
41
- if (opposite.col > 0) {
42
- opposite.col -= 1;
43
- }
44
- break;
45
- }
46
- case 'ArrowRight': {
47
- if (opposite.col < size.numCols - 1) {
48
- opposite.col += 1;
49
- }
50
- break;
51
- }
52
- }
53
-
54
- return { cursor, range: { from: cursor, to: opposite } };
55
- }
56
-
57
- const next = handleArrowNav(ev, cursor, size);
58
- return { cursor: next };
59
- };
60
-
61
- /**
62
- * Calculate next cell based on arrow keys.
63
- */
64
- export const handleArrowNav = (
65
- ev: Pick<KeyboardEvent<HTMLInputElement>, 'key' | 'metaKey'>,
66
- cursor: CellAddress | undefined,
67
- { numRows, numCols }: GridSize,
68
- ): CellAddress | undefined => {
69
- switch (ev.key) {
70
- case 'ArrowUp':
71
- if (cursor === undefined) {
72
- return { row: 0, col: 0 };
73
- } else if (cursor.row > 0) {
74
- return { row: ev.metaKey ? 0 : cursor.row - 1, col: cursor.col };
75
- }
76
- break;
77
- case 'ArrowDown':
78
- if (cursor === undefined) {
79
- return { row: 0, col: 0 };
80
- } else if (cursor.row < numRows - 1) {
81
- return { row: ev.metaKey ? numRows - 1 : cursor.row + 1, col: cursor.col };
82
- }
83
- break;
84
- case 'ArrowLeft':
85
- if (cursor === undefined) {
86
- return { row: 0, col: 0 };
87
- } else if (cursor.col > 0) {
88
- return { row: cursor.row, col: ev.metaKey ? 0 : cursor.col - 1 };
89
- }
90
- break;
91
- case 'ArrowRight':
92
- if (cursor === undefined) {
93
- return { row: 0, col: 0 };
94
- } else if (cursor.col < numCols - 1) {
95
- return { row: cursor.row, col: ev.metaKey ? numCols - 1 : cursor.col + 1 };
96
- }
97
- break;
98
- case 'Home':
99
- return { row: 0, col: 0 };
100
- case 'End':
101
- return { row: numRows - 1, col: numCols - 1 };
102
- }
103
- };
104
-
105
- /**
106
- * Hook to manage range drag handlers.
107
- */
108
- // TODO(burdon): Memoize callbacks?
109
- export const useRangeSelect = (
110
- cb: (event: 'start' | 'move' | 'end', range: CellRange | undefined) => void,
111
- ): {
112
- range: CellRange | undefined;
113
- handlers: {
114
- onMouseDown: MouseEventHandler<HTMLDivElement>;
115
- onMouseMove: MouseEventHandler<HTMLDivElement>;
116
- onMouseUp: MouseEventHandler<HTMLDivElement>;
117
- };
118
- } => {
119
- const [from, setFrom] = useState<CellAddress | undefined>();
120
- const [to, setTo] = useState<CellAddress | undefined>();
121
-
122
- const onMouseDown: MouseEventHandler<HTMLDivElement> = (ev) => {
123
- const current = getCellAtPointer(ev);
124
- setFrom(current);
125
- if (current) {
126
- setTimeout(() => cb('start', { from: current }));
127
- }
128
- };
129
-
130
- const onMouseMove: MouseEventHandler<HTMLDivElement> = (ev) => {
131
- if (from) {
132
- let current = getCellAtPointer(ev);
133
- if (posEquals(current, from)) {
134
- current = undefined;
135
- }
136
- setTo(current);
137
- setTimeout(() => cb('move', { from, to: current }));
138
- }
139
- };
140
-
141
- const onMouseUp: MouseEventHandler<HTMLDivElement> = (ev) => {
142
- if (from) {
143
- let current = getCellAtPointer(ev);
144
- if (posEquals(current, from)) {
145
- current = undefined;
146
- }
147
- setFrom(undefined);
148
- setTo(undefined);
149
- setTimeout(() => cb('end', current ? { from, to: current } : undefined));
150
- }
151
- };
152
-
153
- return {
154
- range: from ? { from, to } : undefined,
155
- handlers: { onMouseDown, onMouseMove, onMouseUp },
156
- };
157
- };
@@ -1,56 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- /**
6
- * Gets the relative client rect of an element within a parent container.
7
- * NOTE: This is stable even when the parent is scrolling.
8
- * https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
9
- * @param root Parent container (e.g., scrollable container).
10
- * @param element
11
- */
12
- export const getRelativeClientRect = (root: HTMLElement, element: HTMLElement): DOMRect => {
13
- const rootRect = root.getBoundingClientRect();
14
- const elementRect = element.getBoundingClientRect();
15
- return new DOMRect(
16
- elementRect.left - rootRect.left + root.scrollLeft,
17
- elementRect.top - rootRect.top + root.scrollTop,
18
- elementRect.width,
19
- elementRect.height,
20
- );
21
- };
22
-
23
- /**
24
- * Union of two rectangles.
25
- */
26
- export const getRectUnion = (b1: DOMRect, b2: DOMRect): Pick<DOMRect, 'left' | 'top' | 'width' | 'height'> => {
27
- return {
28
- left: Math.min(b1.left, b2.left),
29
- top: Math.min(b1.top, b2.top),
30
- width: Math.abs(b1.left - b2.left) + (b1.left > b2.left ? b1.width : b2.width),
31
- height: Math.abs(b1.top - b2.top) + (b1.height > b2.height ? b1.height : b2.height),
32
- };
33
- };
34
-
35
- /**
36
- * Scroll to cell.
37
- * We need to correct for the DOM `scrollIntoView` function which doesn't show the border.
38
- */
39
- export const scrollIntoView = (scrollContainer: HTMLElement, el: HTMLElement) => {
40
- el.scrollIntoView({ block: 'nearest', inline: 'nearest' });
41
-
42
- const cellBounds = el.getBoundingClientRect();
43
- const scrollerBounds = scrollContainer.getBoundingClientRect();
44
-
45
- if (cellBounds.top < scrollerBounds.top) {
46
- scrollContainer.scrollTop -= scrollerBounds.top - cellBounds.top;
47
- } else if (cellBounds.bottom >= scrollerBounds.bottom - 1) {
48
- scrollContainer.scrollTop += 2 + scrollerBounds.bottom - cellBounds.bottom;
49
- }
50
-
51
- if (cellBounds.left < scrollerBounds.left) {
52
- scrollContainer.scrollLeft -= scrollerBounds.left - cellBounds.left;
53
- } else if (cellBounds.right >= scrollerBounds.right) {
54
- scrollContainer.scrollLeft += 2 + scrollerBounds.right - cellBounds.right;
55
- }
56
- };
@@ -1,88 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import React, { useCallback } from 'react';
6
-
7
- import { useIntentDispatcher } from '@dxos/app-framework';
8
- import { fullyQualifiedId } from '@dxos/react-client/echo';
9
- import { useIsDirectlyAttended } from '@dxos/react-ui-attention';
10
- import { focusRing, mx } from '@dxos/react-ui-theme';
11
-
12
- import { Sheet, type SheetRootProps } from './Sheet';
13
- import { Toolbar, type ToolbarAction } from './Toolbar';
14
-
15
- // TODO(Zan): Factor out, copied this from MarkdownPlugin.
16
- const attentionFragment = mx(
17
- 'group-focus-within/editor:attention-surface group-[[aria-current]]/editor:attention-surface',
18
- 'group-focus-within/editor:border-separator',
19
- );
20
-
21
- // TODO(Zan): Factor out, copied this from MarkdownPlugin.
22
- export const sectionToolbarLayout =
23
- 'bs-[--rail-action] bg-[--sticky-bg] sticky block-start-0 __-block-start-px transition-opacity';
24
-
25
- const SheetContainer = ({ sheet, space, role }: SheetRootProps & { role?: string }) => {
26
- const dispatch = useIntentDispatcher();
27
-
28
- const id = fullyQualifiedId(sheet);
29
- const isDirectlyAttended = useIsDirectlyAttended(id);
30
-
31
- // TODO(Zan): Centralise the toolbar action handler. Current implementation in stories.
32
- const handleAction = useCallback(
33
- (action: ToolbarAction) => {
34
- switch (action.type) {
35
- case 'comment': {
36
- // TODO(Zan): We shouldn't hardcode the action ID.
37
- void dispatch({
38
- action: 'dxos.org/plugin/thread/action/create',
39
- data: {
40
- cursor: action.anchor,
41
- name: action.cellContent,
42
- subject: sheet,
43
- },
44
- });
45
- }
46
- }
47
- },
48
- [sheet, dispatch],
49
- );
50
-
51
- return (
52
- <div role='none' className={role === 'article' ? 'row-span-2 grid grid-rows-subgrid' : undefined}>
53
- <Sheet.Root space={space} sheet={sheet}>
54
- <div role='none' className={mx('flex flex-0 justify-center overflow-x-auto')}>
55
- <Toolbar.Root
56
- onAction={handleAction}
57
- classNames={mx(
58
- role === 'section'
59
- ? ['z-[2] group-focus-within/section:visible', !isDirectlyAttended && 'invisible', sectionToolbarLayout]
60
- : 'group-focus-within/editor:border-separator group-[[aria-current]]/editor:border-separator',
61
- )}
62
- >
63
- {/* TODO(Zan): Restore some of this functionality */}
64
- {/* <Toolbar.Styles /> */}
65
- {/* <Toolbar.Format /> */}
66
- {/* <Toolbar.Alignment /> */}
67
- <Toolbar.Separator />
68
- <Toolbar.Actions />
69
- </Toolbar.Root>
70
- </div>
71
- <div
72
- role='none'
73
- className={mx(
74
- role === 'section' && 'aspect-square border-is border-bs border-be border-separator',
75
- role === 'article' &&
76
- 'flex is-full overflow-hidden focus-visible:ring-inset row-span-1 data-[toolbar=disabled]:pbs-2 data-[toolbar=disabled]:row-span-2 border-bs border-separator',
77
- focusRing,
78
- attentionFragment,
79
- )}
80
- >
81
- <Sheet.Main />
82
- </div>
83
- </Sheet.Root>
84
- </div>
85
- );
86
- };
87
-
88
- export default SheetContainer;
@@ -1,72 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { type Icon } from '@phosphor-icons/react';
6
- import React from 'react';
7
-
8
- import {
9
- Toolbar as NaturalToolbar,
10
- Tooltip,
11
- type ToolbarButtonProps as NaturalToolbarButtonProps,
12
- type ToolbarToggleGroupItemProps as NaturalToolbarToggleGroupItemProps,
13
- } from '@dxos/react-ui';
14
- import { getSize } from '@dxos/react-ui-theme';
15
-
16
- // TODO(burdon): Factor out in common with react-ui-editor.
17
-
18
- export const iconStyles = getSize(5);
19
- export const buttonStyles = 'min-bs-0 p-2';
20
- export const tooltipProps = { side: 'top' as const, classNames: 'z-10' };
21
-
22
- export const ToolbarSeparator = () => <div role='separator' className='grow' />;
23
-
24
- //
25
- // ToolbarButton
26
- //
27
-
28
- type ToolbarButtonProps = NaturalToolbarButtonProps & { Icon: Icon };
29
-
30
- export const ToolbarButton = ({ Icon, children, ...props }: ToolbarButtonProps) => {
31
- return (
32
- <Tooltip.Root>
33
- <Tooltip.Trigger asChild>
34
- <NaturalToolbar.Button variant='ghost' {...props} classNames={buttonStyles}>
35
- <Icon className={iconStyles} />
36
- <span className='sr-only'>{children}</span>
37
- </NaturalToolbar.Button>
38
- </Tooltip.Trigger>
39
- <Tooltip.Portal>
40
- <Tooltip.Content {...tooltipProps}>
41
- {children}
42
- <Tooltip.Arrow />
43
- </Tooltip.Content>
44
- </Tooltip.Portal>
45
- </Tooltip.Root>
46
- );
47
- };
48
-
49
- //
50
- // ToolbarToggleButton
51
- //
52
-
53
- export type ToolbarToggleButtonProps = NaturalToolbarToggleGroupItemProps & { Icon: Icon };
54
-
55
- export const ToolbarToggleButton = ({ Icon, children, ...props }: ToolbarToggleButtonProps) => {
56
- return (
57
- <Tooltip.Root>
58
- <Tooltip.Trigger asChild>
59
- <NaturalToolbar.ToggleGroupItem variant='ghost' {...props} classNames={buttonStyles}>
60
- <Icon className={iconStyles} />
61
- <span className='sr-only'>{children}</span>
62
- </NaturalToolbar.ToggleGroupItem>
63
- </Tooltip.Trigger>
64
- <Tooltip.Portal>
65
- <Tooltip.Content {...tooltipProps}>
66
- {children}
67
- <Tooltip.Arrow />
68
- </Tooltip.Content>
69
- </Tooltip.Portal>
70
- </Tooltip.Root>
71
- );
72
- };
@@ -1,104 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { describe, expect, test } from 'vitest';
6
-
7
- import { Trigger } from '@dxos/async';
8
- import { Client } from '@dxos/client';
9
- import { create } from '@dxos/client/echo';
10
- import { Context } from '@dxos/context';
11
- import { type S } from '@dxos/echo-schema';
12
- import { FunctionType } from '@dxos/plugin-script/types';
13
-
14
- import { createComputeGraphRegistry } from './compute-graph';
15
- import { addressFromA1Notation, createSheet } from '../defs';
16
- import { SheetModel } from '../model';
17
- import { type CellScalarValue } from '../types';
18
-
19
- // TODO(burdon): Vitest issues:
20
- // - Cannot test Hyperformula
21
- // - throws "Cannot convert undefined or null to object" in vitest (without browser).
22
- // - throws "process.nextTick is not a function" (with browser)
23
- // - throws "Buffer already defined" (if nodeExternal: true in config)
24
- // - Need better docs; esp. vitest config.
25
- // - NOTE: For non-browser tests, import types from x-plugin/types (otherwise will bring in react deps).
26
- // - Can't add flags to our tools?
27
- // - test.only / test.skip ignored?
28
-
29
- /**
30
- * NOTE: Browser test required for hyperformula due to raw translation files.
31
- */
32
- describe('compute graph', () => {
33
- // TODO(burdon): Replace with builder.
34
- const createModel = async (types?: S.Schema<any>[]) => {
35
- const ctx = new Context();
36
- const client = new Client();
37
- if (types) {
38
- client.addTypes(types);
39
- }
40
- await client.initialize();
41
- await client.halo.createIdentity();
42
- const space = await client.spaces.create();
43
- ctx.onDispose(() => client.destroy());
44
-
45
- const registry = createComputeGraphRegistry();
46
- await registry.open(ctx);
47
-
48
- const graph = await registry.createGraph(space);
49
- await graph.open(ctx);
50
-
51
- const sheet = createSheet({ rows: 5, columns: 5 });
52
- const model = new SheetModel(graph, sheet);
53
- await model.open(ctx);
54
-
55
- // TODO(burdon): Move event propagation into graph.
56
- graph.update.on(() => model.update.emit());
57
-
58
- return { space, graph, model };
59
- };
60
-
61
- test('map functions', async () => {
62
- const { space, graph } = await createModel([FunctionType]);
63
-
64
- // Create script.
65
- const fn = space.db.add(create(FunctionType, { version: 1, binding: 'TEST' }));
66
- const id = graph.mapFunctionBindingToId('TEST()');
67
- expect(id).to.eq(`${fn.id}()`);
68
- });
69
-
70
- test('cross-node references', async () => {
71
- const { graph } = await createModel();
72
-
73
- // Create ndoes.
74
- const node1 = graph.getOrCreateNode('node-1');
75
- const node2 = graph.getOrCreateNode('node-2');
76
- node1.hf.setCellContents({ sheet: node1.sheetId, row: 1, col: 1 }, 100);
77
- node2.hf.setCellContents({ sheet: node2.sheetId, row: 1, col: 1 }, `=${node1.sheetId}!A1`);
78
- const value1 = node1.hf.getCellValue({ sheet: node1.sheetId, col: 1, row: 1 });
79
- const value2 = node1.hf.getCellValue({ sheet: node2.sheetId, col: 1, row: 1 });
80
- expect(value1).to.eq(value2);
81
- });
82
-
83
- test('async function', async () => {
84
- const { graph, model } = await createModel();
85
-
86
- // Triggers function.
87
- model.setValue(addressFromA1Notation('A1'), '=TEST()');
88
- const trigger = new Trigger<CellScalarValue>();
89
- model.update.on(() => {
90
- const value = model.getValue(addressFromA1Notation('A1'));
91
- trigger.wake(value);
92
- });
93
-
94
- // Get initial value (i.e., null).
95
- const v1 = model.getValue(addressFromA1Notation('A1'));
96
- expect(v1).to.be.null;
97
- expect(graph.context.info.invocations.TEST).to.eq(undefined);
98
-
99
- // Wait until async update triggered.
100
- const v2 = await trigger.wait();
101
- expect(v2).not.to.be.null;
102
- expect(graph.context.info.invocations.TEST).to.eq(1);
103
- });
104
- });