@dxos/plugin-sheet 0.6.13-main.ed424a1 → 0.6.13

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 (323) hide show
  1. package/dist/lib/browser/SheetContainer-U4H5D34A.mjs +1772 -0
  2. package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-APHOLYUB.mjs +175 -0
  4. package/dist/lib/browser/chunk-APHOLYUB.mjs.map +7 -0
  5. package/dist/lib/{node-esm/chunk-5WPZCXNS.mjs → browser/chunk-D5AGLXJP.mjs} +678 -411
  6. package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-FUAGSXA4.mjs +82 -0
  8. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-JRL5LGCE.mjs +18 -0
  10. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-NU4PBN33.mjs +8 -0
  12. package/dist/lib/browser/chunk-NU4PBN33.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +62 -93
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/meta.mjs +1 -1
  17. package/dist/lib/browser/testing.mjs +92 -0
  18. package/dist/lib/browser/testing.mjs.map +7 -0
  19. package/dist/lib/browser/types.mjs +12 -6
  20. package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs +1765 -0
  21. package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-5XPK2V4A.cjs → chunk-5KKJ4NPP.cjs} +678 -418
  23. package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +7 -0
  24. package/dist/lib/node/chunk-BJ6ZD7MN.cjs +51 -0
  25. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +7 -0
  26. package/dist/lib/node/chunk-CN3RPESU.cjs +202 -0
  27. package/dist/lib/node/chunk-CN3RPESU.cjs.map +7 -0
  28. package/dist/lib/node/{chunk-NZARD7UP.cjs → chunk-DSYKOI4E.cjs} +51 -40
  29. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +7 -0
  30. package/dist/lib/node/chunk-PYXHNAAK.cjs +40 -0
  31. package/dist/lib/node/chunk-PYXHNAAK.cjs.map +7 -0
  32. package/dist/lib/node/index.cjs +69 -105
  33. package/dist/lib/node/index.cjs.map +3 -3
  34. package/dist/lib/node/meta.cjs +3 -3
  35. package/dist/lib/node/meta.cjs.map +1 -1
  36. package/dist/lib/node/meta.json +1 -1
  37. package/dist/lib/node/testing.cjs +111 -0
  38. package/dist/lib/node/testing.cjs.map +7 -0
  39. package/dist/lib/node/types.cjs +15 -9
  40. package/dist/lib/node/types.cjs.map +2 -2
  41. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  42. package/dist/types/src/components/CellEditor/CellEditor.d.ts +14 -0
  43. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -0
  44. package/dist/types/src/components/{GridSheet/SheetCellEditor.stories.d.ts → CellEditor/CellEditor.stories.d.ts} +4 -4
  45. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -0
  46. package/dist/types/src/{extensions/editor → components/CellEditor}/extension.d.ts +1 -1
  47. package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -0
  48. package/dist/types/src/components/CellEditor/extension.test.d.ts.map +1 -0
  49. package/dist/types/src/components/CellEditor/index.d.ts +3 -0
  50. package/dist/types/src/components/CellEditor/index.d.ts.map +1 -0
  51. package/dist/types/src/{graph/functions → components/ComputeGraph}/async-function.d.ts +5 -14
  52. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +1 -0
  53. package/dist/types/src/components/ComputeGraph/custom.d.ts +21 -0
  54. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +1 -0
  55. package/dist/types/src/components/ComputeGraph/edge-function.d.ts +20 -0
  56. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +1 -0
  57. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +12 -0
  58. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +1 -0
  59. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +2 -0
  60. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +1 -0
  61. package/dist/types/src/components/ComputeGraph/graph.d.ts +26 -0
  62. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +1 -0
  63. package/dist/types/src/components/ComputeGraph/index.d.ts +3 -1
  64. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  65. package/dist/types/src/components/Sheet/Sheet.d.ts +55 -0
  66. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -0
  67. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +54 -0
  68. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -0
  69. package/dist/types/src/components/Sheet/formatting.d.ts +14 -0
  70. package/dist/types/src/components/Sheet/formatting.d.ts.map +1 -0
  71. package/dist/types/src/components/Sheet/grid.d.ts +52 -0
  72. package/dist/types/src/components/Sheet/grid.d.ts.map +1 -0
  73. package/dist/types/src/components/Sheet/index.d.ts +2 -0
  74. package/dist/types/src/components/Sheet/index.d.ts.map +1 -0
  75. package/dist/types/src/components/Sheet/nav.d.ts +29 -0
  76. package/dist/types/src/components/Sheet/nav.d.ts.map +1 -0
  77. package/dist/types/src/components/Sheet/sheet-context.d.ts +25 -0
  78. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -0
  79. package/dist/types/src/components/Sheet/util.d.ts +18 -0
  80. package/dist/types/src/components/Sheet/util.d.ts.map +1 -0
  81. package/dist/types/src/components/SheetContainer.d.ts +9 -0
  82. package/dist/types/src/components/SheetContainer.d.ts.map +1 -0
  83. package/dist/types/src/components/Toolbar/Toolbar.d.ts +9 -33
  84. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  85. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +15 -19
  86. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  87. package/dist/types/src/components/Toolbar/common.d.ts +20 -0
  88. package/dist/types/src/components/Toolbar/common.d.ts.map +1 -0
  89. package/dist/types/src/components/index.d.ts +2 -3
  90. package/dist/types/src/components/index.d.ts.map +1 -1
  91. package/dist/types/src/meta.d.ts +9 -3
  92. package/dist/types/src/meta.d.ts.map +1 -1
  93. package/dist/types/src/{graph/functions/function-defs.d.ts → model/functions.d.ts} +1 -1
  94. package/dist/types/src/model/functions.d.ts.map +1 -0
  95. package/dist/types/src/model/index.d.ts +3 -2
  96. package/dist/types/src/model/index.d.ts.map +1 -1
  97. package/dist/types/src/model/model.browser.test.d.ts +2 -0
  98. package/dist/types/src/model/model.browser.test.d.ts.map +1 -0
  99. package/dist/types/src/model/{sheet-model.d.ts → model.d.ts} +67 -13
  100. package/dist/types/src/model/model.d.ts.map +1 -0
  101. package/dist/types/src/{defs → model}/types.d.ts +3 -8
  102. package/dist/types/src/model/types.d.ts.map +1 -0
  103. package/dist/types/src/model/types.test.d.ts.map +1 -0
  104. package/dist/types/src/model/util.d.ts +15 -0
  105. package/dist/types/src/model/util.d.ts.map +1 -0
  106. package/dist/types/src/testing.d.ts +9 -0
  107. package/dist/types/src/testing.d.ts.map +1 -0
  108. package/dist/types/src/translations.d.ts +12 -17
  109. package/dist/types/src/translations.d.ts.map +1 -1
  110. package/dist/types/src/types.d.ts +40 -125
  111. package/dist/types/src/types.d.ts.map +1 -1
  112. package/package.json +52 -58
  113. package/src/SheetPlugin.tsx +74 -52
  114. package/src/components/{GridSheet/SheetCellEditor.stories.tsx → CellEditor/CellEditor.stories.tsx} +8 -8
  115. package/src/components/CellEditor/CellEditor.tsx +113 -0
  116. package/src/{extensions/editor → components/CellEditor}/extension.test.ts +6 -4
  117. package/src/{extensions/editor → components/CellEditor}/extension.ts +6 -5
  118. package/src/{extensions/editor → components/CellEditor}/index.ts +1 -0
  119. package/src/{graph/functions → components/ComputeGraph}/async-function.ts +15 -25
  120. package/src/{graph/testing/test-plugin.ts → components/ComputeGraph/custom.ts} +14 -44
  121. package/src/{graph/functions → components/ComputeGraph}/edge-function.ts +14 -16
  122. package/src/components/ComputeGraph/graph-context.tsx +50 -0
  123. package/src/components/ComputeGraph/graph.browser.test.ts +50 -0
  124. package/src/components/ComputeGraph/graph.ts +62 -0
  125. package/src/components/ComputeGraph/index.ts +3 -1
  126. package/src/components/Sheet/Sheet.stories.tsx +287 -0
  127. package/src/components/Sheet/Sheet.tsx +1160 -0
  128. package/src/components/Sheet/formatting.ts +106 -0
  129. package/src/components/Sheet/grid.ts +191 -0
  130. package/src/{testing → components/Sheet}/index.ts +1 -1
  131. package/src/components/Sheet/nav.ts +157 -0
  132. package/src/components/Sheet/sheet-context.tsx +150 -0
  133. package/src/components/Sheet/util.ts +56 -0
  134. package/src/components/SheetContainer.tsx +34 -0
  135. package/src/components/Toolbar/Toolbar.tsx +112 -242
  136. package/src/components/Toolbar/common.tsx +72 -0
  137. package/src/components/index.ts +0 -2
  138. package/src/meta.tsx +18 -0
  139. package/src/model/index.ts +3 -2
  140. package/src/model/model.browser.test.ts +100 -0
  141. package/src/model/model.ts +550 -0
  142. package/src/{defs → model}/types.test.ts +9 -8
  143. package/src/{defs → model}/types.ts +14 -24
  144. package/src/model/util.ts +36 -0
  145. package/src/testing.ts +50 -0
  146. package/src/translations.ts +1 -6
  147. package/src/types.ts +47 -40
  148. package/dist/lib/browser/SheetContainer-RVRACGCZ.mjs +0 -290
  149. package/dist/lib/browser/SheetContainer-RVRACGCZ.mjs.map +0 -7
  150. package/dist/lib/browser/chunk-BWN5DZWZ.mjs +0 -74
  151. package/dist/lib/browser/chunk-BWN5DZWZ.mjs.map +0 -7
  152. package/dist/lib/browser/chunk-D3QTX46O.mjs +0 -14
  153. package/dist/lib/browser/chunk-D3QTX46O.mjs.map +0 -7
  154. package/dist/lib/browser/chunk-GSV5QNLD.mjs +0 -2966
  155. package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +0 -7
  156. package/dist/lib/browser/chunk-HOG37RYS.mjs +0 -1528
  157. package/dist/lib/browser/chunk-HOG37RYS.mjs.map +0 -7
  158. package/dist/lib/browser/graph-M4IQ76QX.mjs +0 -33
  159. package/dist/lib/browser/graph-M4IQ76QX.mjs.map +0 -7
  160. package/dist/lib/node/SheetContainer-J7XROAMN.cjs +0 -300
  161. package/dist/lib/node/SheetContainer-J7XROAMN.cjs.map +0 -7
  162. package/dist/lib/node/chunk-5XPK2V4A.cjs.map +0 -7
  163. package/dist/lib/node/chunk-AXQZA2YS.cjs +0 -1527
  164. package/dist/lib/node/chunk-AXQZA2YS.cjs.map +0 -7
  165. package/dist/lib/node/chunk-NZARD7UP.cjs.map +0 -7
  166. package/dist/lib/node/chunk-QIFIGEKV.cjs +0 -37
  167. package/dist/lib/node/chunk-QIFIGEKV.cjs.map +0 -7
  168. package/dist/lib/node/graph-Q3N2X26H.cjs +0 -55
  169. package/dist/lib/node/graph-Q3N2X26H.cjs.map +0 -7
  170. package/dist/lib/node-esm/SheetContainer-YWQVKHQB.mjs +0 -291
  171. package/dist/lib/node-esm/SheetContainer-YWQVKHQB.mjs.map +0 -7
  172. package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +0 -7
  173. package/dist/lib/node-esm/chunk-BPXXIAOQ.mjs +0 -1529
  174. package/dist/lib/node-esm/chunk-BPXXIAOQ.mjs.map +0 -7
  175. package/dist/lib/node-esm/chunk-VCYJWE3O.mjs +0 -16
  176. package/dist/lib/node-esm/chunk-VCYJWE3O.mjs.map +0 -7
  177. package/dist/lib/node-esm/chunk-WFDTY3IC.mjs +0 -75
  178. package/dist/lib/node-esm/chunk-WFDTY3IC.mjs.map +0 -7
  179. package/dist/lib/node-esm/graph-SMPUMOV2.mjs +0 -34
  180. package/dist/lib/node-esm/graph-SMPUMOV2.mjs.map +0 -7
  181. package/dist/lib/node-esm/index.mjs +0 -280
  182. package/dist/lib/node-esm/index.mjs.map +0 -7
  183. package/dist/lib/node-esm/meta.json +0 -1
  184. package/dist/lib/node-esm/meta.mjs +0 -10
  185. package/dist/lib/node-esm/meta.mjs.map +0 -7
  186. package/dist/lib/node-esm/types.mjs +0 -17
  187. package/dist/lib/node-esm/types.mjs.map +0 -7
  188. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +0 -11
  189. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +0 -1
  190. package/dist/types/src/components/FunctionEditor/FunctionEditor.d.ts +0 -3
  191. package/dist/types/src/components/FunctionEditor/FunctionEditor.d.ts.map +0 -1
  192. package/dist/types/src/components/FunctionEditor/index.d.ts +0 -2
  193. package/dist/types/src/components/FunctionEditor/index.d.ts.map +0 -1
  194. package/dist/types/src/components/GridSheet/GridSheet.d.ts +0 -3
  195. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +0 -1
  196. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +0 -9
  197. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +0 -1
  198. package/dist/types/src/components/GridSheet/SheetCellEditor.stories.d.ts.map +0 -1
  199. package/dist/types/src/components/GridSheet/index.d.ts +0 -2
  200. package/dist/types/src/components/GridSheet/index.d.ts.map +0 -1
  201. package/dist/types/src/components/GridSheet/util.d.ts +0 -16
  202. package/dist/types/src/components/GridSheet/util.d.ts.map +0 -1
  203. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts +0 -6
  204. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts.map +0 -1
  205. package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts +0 -11
  206. package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts.map +0 -1
  207. package/dist/types/src/components/SheetContainer/index.d.ts +0 -3
  208. package/dist/types/src/components/SheetContainer/index.d.ts.map +0 -1
  209. package/dist/types/src/components/SheetContext/SheetContext.d.ts +0 -26
  210. package/dist/types/src/components/SheetContext/SheetContext.d.ts.map +0 -1
  211. package/dist/types/src/components/SheetContext/index.d.ts +0 -2
  212. package/dist/types/src/components/SheetContext/index.d.ts.map +0 -1
  213. package/dist/types/src/defs/index.d.ts +0 -4
  214. package/dist/types/src/defs/index.d.ts.map +0 -1
  215. package/dist/types/src/defs/sheet-range-types.d.ts +0 -13
  216. package/dist/types/src/defs/sheet-range-types.d.ts.map +0 -1
  217. package/dist/types/src/defs/types.d.ts.map +0 -1
  218. package/dist/types/src/defs/types.test.d.ts.map +0 -1
  219. package/dist/types/src/defs/util.d.ts +0 -43
  220. package/dist/types/src/defs/util.d.ts.map +0 -1
  221. package/dist/types/src/extensions/compute.d.ts +0 -6
  222. package/dist/types/src/extensions/compute.d.ts.map +0 -1
  223. package/dist/types/src/extensions/compute.stories.d.ts +0 -26
  224. package/dist/types/src/extensions/compute.stories.d.ts.map +0 -1
  225. package/dist/types/src/extensions/editor/extension.d.ts.map +0 -1
  226. package/dist/types/src/extensions/editor/extension.test.d.ts.map +0 -1
  227. package/dist/types/src/extensions/editor/index.d.ts +0 -2
  228. package/dist/types/src/extensions/editor/index.d.ts.map +0 -1
  229. package/dist/types/src/extensions/index.d.ts +0 -3
  230. package/dist/types/src/extensions/index.d.ts.map +0 -1
  231. package/dist/types/src/graph/compute-graph-registry.d.ts +0 -34
  232. package/dist/types/src/graph/compute-graph-registry.d.ts.map +0 -1
  233. package/dist/types/src/graph/compute-graph.d.ts +0 -64
  234. package/dist/types/src/graph/compute-graph.d.ts.map +0 -1
  235. package/dist/types/src/graph/compute-graph.stories.d.ts +0 -10
  236. package/dist/types/src/graph/compute-graph.stories.d.ts.map +0 -1
  237. package/dist/types/src/graph/compute-graph.test.d.ts +0 -2
  238. package/dist/types/src/graph/compute-graph.test.d.ts.map +0 -1
  239. package/dist/types/src/graph/compute-node.d.ts +0 -26
  240. package/dist/types/src/graph/compute-node.d.ts.map +0 -1
  241. package/dist/types/src/graph/functions/async-function.d.ts.map +0 -1
  242. package/dist/types/src/graph/functions/edge-function.d.ts +0 -21
  243. package/dist/types/src/graph/functions/edge-function.d.ts.map +0 -1
  244. package/dist/types/src/graph/functions/function-defs.d.ts.map +0 -1
  245. package/dist/types/src/graph/functions/index.d.ts +0 -4
  246. package/dist/types/src/graph/functions/index.d.ts.map +0 -1
  247. package/dist/types/src/graph/hyperformula.test.d.ts +0 -2
  248. package/dist/types/src/graph/hyperformula.test.d.ts.map +0 -1
  249. package/dist/types/src/graph/index.d.ts +0 -5
  250. package/dist/types/src/graph/index.d.ts.map +0 -1
  251. package/dist/types/src/graph/testing/index.d.ts +0 -3
  252. package/dist/types/src/graph/testing/index.d.ts.map +0 -1
  253. package/dist/types/src/graph/testing/test-builder.d.ts +0 -15
  254. package/dist/types/src/graph/testing/test-builder.d.ts.map +0 -1
  255. package/dist/types/src/graph/testing/test-plugin.d.ts +0 -36
  256. package/dist/types/src/graph/testing/test-plugin.d.ts.map +0 -1
  257. package/dist/types/src/graph/util.d.ts +0 -2
  258. package/dist/types/src/graph/util.d.ts.map +0 -1
  259. package/dist/types/src/hooks/hooks.stories.d.ts +0 -11
  260. package/dist/types/src/hooks/hooks.stories.d.ts.map +0 -1
  261. package/dist/types/src/hooks/index.d.ts +0 -4
  262. package/dist/types/src/hooks/index.d.ts.map +0 -1
  263. package/dist/types/src/hooks/threads.d.ts +0 -8
  264. package/dist/types/src/hooks/threads.d.ts.map +0 -1
  265. package/dist/types/src/hooks/useComputeGraph.d.ts +0 -7
  266. package/dist/types/src/hooks/useComputeGraph.d.ts.map +0 -1
  267. package/dist/types/src/hooks/useSheetModel.d.ts +0 -8
  268. package/dist/types/src/hooks/useSheetModel.d.ts.map +0 -1
  269. package/dist/types/src/model/decorations.d.ts +0 -25
  270. package/dist/types/src/model/decorations.d.ts.map +0 -1
  271. package/dist/types/src/model/sheet-model.d.ts.map +0 -1
  272. package/dist/types/src/model/sheet-model.test.d.ts +0 -2
  273. package/dist/types/src/model/sheet-model.test.d.ts.map +0 -1
  274. package/dist/types/src/sanity.test.d.ts +0 -2
  275. package/dist/types/src/sanity.test.d.ts.map +0 -1
  276. package/dist/types/src/testing/index.d.ts +0 -2
  277. package/dist/types/src/testing/index.d.ts.map +0 -1
  278. package/dist/types/src/testing/testing.d.ts +0 -8
  279. package/dist/types/src/testing/testing.d.ts.map +0 -1
  280. package/dist/vendor/hyperformula.mjs +0 -37145
  281. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +0 -20
  282. package/src/components/FunctionEditor/FunctionEditor.tsx +0 -45
  283. package/src/components/FunctionEditor/index.ts +0 -5
  284. package/src/components/GridSheet/GridSheet.stories.tsx +0 -41
  285. package/src/components/GridSheet/GridSheet.tsx +0 -163
  286. package/src/components/GridSheet/index.ts +0 -5
  287. package/src/components/GridSheet/util.ts +0 -158
  288. package/src/components/SheetContainer/SheetContainer.stories.tsx +0 -40
  289. package/src/components/SheetContainer/SheetContainer.tsx +0 -27
  290. package/src/components/SheetContainer/index.ts +0 -7
  291. package/src/components/SheetContext/SheetContext.tsx +0 -104
  292. package/src/components/SheetContext/index.ts +0 -5
  293. package/src/defs/index.ts +0 -7
  294. package/src/defs/sheet-range-types.ts +0 -46
  295. package/src/defs/util.ts +0 -151
  296. package/src/extensions/compute.stories.tsx +0 -151
  297. package/src/extensions/compute.ts +0 -147
  298. package/src/extensions/index.ts +0 -6
  299. package/src/graph/compute-graph-registry.ts +0 -90
  300. package/src/graph/compute-graph.stories.tsx +0 -93
  301. package/src/graph/compute-graph.test.ts +0 -87
  302. package/src/graph/compute-graph.ts +0 -242
  303. package/src/graph/compute-node.ts +0 -63
  304. package/src/graph/functions/index.ts +0 -7
  305. package/src/graph/hyperformula.test.ts +0 -14
  306. package/src/graph/index.ts +0 -8
  307. package/src/graph/testing/index.ts +0 -6
  308. package/src/graph/testing/test-builder.ts +0 -54
  309. package/src/graph/util.ts +0 -8
  310. package/src/hooks/hooks.stories.tsx +0 -50
  311. package/src/hooks/index.ts +0 -7
  312. package/src/hooks/threads.ts +0 -147
  313. package/src/hooks/useComputeGraph.ts +0 -28
  314. package/src/hooks/useSheetModel.ts +0 -40
  315. package/src/meta.ts +0 -14
  316. package/src/model/decorations.ts +0 -64
  317. package/src/model/sheet-model.test.ts +0 -57
  318. package/src/model/sheet-model.ts +0 -418
  319. package/src/sanity.test.ts +0 -40
  320. package/src/testing/testing.tsx +0 -68
  321. /package/dist/types/src/{extensions/editor → components/CellEditor}/extension.test.d.ts +0 -0
  322. /package/dist/types/src/{defs → model}/types.test.d.ts +0 -0
  323. /package/src/{graph/functions/function-defs.ts → model/functions.ts} +0 -0
@@ -0,0 +1,1772 @@
1
+ import {
2
+ useComputeGraph
3
+ } from "./chunk-APHOLYUB.mjs";
4
+ import {
5
+ SheetModel,
6
+ addressFromA1Notation,
7
+ addressToA1Notation,
8
+ columnLetter,
9
+ defaultFunctions,
10
+ inRange,
11
+ posEquals,
12
+ rangeToA1Notation
13
+ } from "./chunk-D5AGLXJP.mjs";
14
+ import {
15
+ ValueTypeEnum
16
+ } from "./chunk-FUAGSXA4.mjs";
17
+ import "./chunk-JRL5LGCE.mjs";
18
+
19
+ // packages/plugins/plugin-sheet/src/components/SheetContainer.tsx
20
+ import React4 from "react";
21
+ import { mx as mx3 } from "@dxos/react-ui-theme";
22
+
23
+ // packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx
24
+ import { DndContext, DragOverlay, KeyboardSensor, MouseSensor, TouchSensor, useDraggable, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
25
+ import { restrictToHorizontalAxis, restrictToVerticalAxis } from "@dnd-kit/modifiers";
26
+ import { getEventCoordinates, useCombinedRefs } from "@dnd-kit/utilities";
27
+ import { Function as FunctionIcon } from "@phosphor-icons/react";
28
+ import { Resizable } from "re-resizable";
29
+ import React3, { forwardRef, useEffect as useEffect3, useImperativeHandle, useMemo, useRef, useState as useState4 } from "react";
30
+ import { createPortal } from "react-dom";
31
+ import { useResizeDetector } from "react-resize-detector";
32
+ import { debounce } from "@dxos/async";
33
+ import { fullyQualifiedId as fullyQualifiedId2, createDocAccessor } from "@dxos/client/echo";
34
+ import { log } from "@dxos/log";
35
+ import { createAttendableAttributes, useHasAttention } from "@dxos/react-ui-attention";
36
+ import { mx as mx2 } from "@dxos/react-ui-theme";
37
+
38
+ // packages/plugins/plugin-sheet/src/components/Sheet/grid.ts
39
+ import { useEffect, useState } from "react";
40
+ var axisWidth = "calc(var(--rail-size)-2px)";
41
+ var axisHeight = 34;
42
+ var minWidth = 40;
43
+ var maxWidth = 800;
44
+ var minHeight = axisHeight;
45
+ var maxHeight = 400;
46
+ var defaultWidth = 200;
47
+ var defaultHeight = minHeight;
48
+ var CELL_DATA_KEY = "cell";
49
+ var useGridLayout = ({ scroller, size, rows, columns, rowSizes, columnSizes }) => {
50
+ const [rowPositions, setRowPositions] = useState([]);
51
+ useEffect(() => {
52
+ if (!rowSizes) {
53
+ return;
54
+ }
55
+ let y = 0;
56
+ setRowPositions(rows.map((idx, i) => {
57
+ const height2 = rowSizes?.[idx] ?? defaultHeight;
58
+ const top = y;
59
+ y += height2 - 1;
60
+ return {
61
+ row: i,
62
+ top,
63
+ height: height2
64
+ };
65
+ }));
66
+ }, [
67
+ rows,
68
+ rowSizes
69
+ ]);
70
+ const [columnPositions, setColumnPositions] = useState([]);
71
+ useEffect(() => {
72
+ if (!columns) {
73
+ return;
74
+ }
75
+ let x = 0;
76
+ setColumnPositions(columns.map((idx, i) => {
77
+ const width2 = columnSizes?.[idx] ?? defaultWidth;
78
+ const left = x;
79
+ x += width2 - 1;
80
+ return {
81
+ column: i,
82
+ left,
83
+ width: width2
84
+ };
85
+ }));
86
+ }, [
87
+ columns,
88
+ columnSizes
89
+ ]);
90
+ const height = rowPositions.length ? rowPositions[rowPositions.length - 1].top + rowPositions[rowPositions.length - 1].height : 0;
91
+ const width = columnPositions.length ? columnPositions[columnPositions.length - 1].left + columnPositions[columnPositions.length - 1].width : 0;
92
+ const [{ rowRange, columnRange }, setWindow] = useState({
93
+ rowRange: [],
94
+ columnRange: []
95
+ });
96
+ useEffect(() => {
97
+ const handleScroll = () => {
98
+ if (!scroller) {
99
+ return;
100
+ }
101
+ const { scrollLeft: left, scrollTop: top, clientWidth: width2, clientHeight: height2 } = scroller;
102
+ let rowStart = 0;
103
+ let rowEnd = 0;
104
+ for (let i = 0; i < rowPositions.length; i++) {
105
+ const row = rowPositions[i];
106
+ if (row.top <= top) {
107
+ rowStart = i;
108
+ }
109
+ if (row.top + row.height >= top + height2) {
110
+ rowEnd = i;
111
+ break;
112
+ }
113
+ }
114
+ let columnStart = 0;
115
+ let columnEnd = 0;
116
+ for (let i = 0; i < columnPositions.length; i++) {
117
+ const column = columnPositions[i];
118
+ if (column.left <= left) {
119
+ columnStart = i;
120
+ }
121
+ if (column.left + column.width >= left + width2) {
122
+ columnEnd = i;
123
+ break;
124
+ }
125
+ }
126
+ const overscan = 5;
127
+ setWindow({
128
+ rowRange: rowPositions.slice(Math.max(0, rowStart - overscan), Math.min(rowPositions.length, rowEnd + overscan)),
129
+ columnRange: columnPositions.slice(Math.max(0, columnStart - overscan), Math.min(columnPositions.length, columnEnd + overscan))
130
+ });
131
+ };
132
+ scroller?.addEventListener("scroll", handleScroll);
133
+ handleScroll();
134
+ return () => {
135
+ scroller?.removeEventListener("scroll", handleScroll);
136
+ };
137
+ }, [
138
+ size.width,
139
+ size.height,
140
+ rowPositions,
141
+ columnPositions
142
+ ]);
143
+ return {
144
+ width,
145
+ height,
146
+ rowRange,
147
+ columnRange
148
+ };
149
+ };
150
+ var getCellAtPointer = (event) => {
151
+ const element = document.elementFromPoint(event.clientX, event.clientY);
152
+ const root = element?.closest(`[data-${CELL_DATA_KEY}]`);
153
+ if (root) {
154
+ const value = root.dataset[CELL_DATA_KEY];
155
+ if (value) {
156
+ return addressFromA1Notation(value);
157
+ }
158
+ }
159
+ };
160
+ var getCellElement = (root, cell) => {
161
+ const pos = addressToA1Notation(cell);
162
+ return root.querySelector(`[data-${CELL_DATA_KEY}="${pos}"]`);
163
+ };
164
+
165
+ // packages/plugins/plugin-sheet/src/components/Sheet/nav.ts
166
+ import { useState as useState2 } from "react";
167
+ var handleNav = (ev, cursor, range, size) => {
168
+ if (cursor && ev.shiftKey) {
169
+ const opposite = range?.to ?? {
170
+ ...cursor
171
+ };
172
+ switch (ev.key) {
173
+ case "ArrowUp": {
174
+ if (opposite.row > 0) {
175
+ opposite.row -= 1;
176
+ }
177
+ break;
178
+ }
179
+ case "ArrowDown": {
180
+ if (opposite.row < size.numRows - 1) {
181
+ opposite.row += 1;
182
+ }
183
+ break;
184
+ }
185
+ case "ArrowLeft": {
186
+ if (opposite.column > 0) {
187
+ opposite.column -= 1;
188
+ }
189
+ break;
190
+ }
191
+ case "ArrowRight": {
192
+ if (opposite.column < size.numColumns - 1) {
193
+ opposite.column += 1;
194
+ }
195
+ break;
196
+ }
197
+ }
198
+ return {
199
+ cursor,
200
+ range: {
201
+ from: cursor,
202
+ to: opposite
203
+ }
204
+ };
205
+ }
206
+ const next = handleArrowNav(ev, cursor, size);
207
+ return {
208
+ cursor: next
209
+ };
210
+ };
211
+ var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
212
+ switch (ev.key) {
213
+ case "ArrowUp":
214
+ if (cursor === void 0) {
215
+ return {
216
+ row: 0,
217
+ column: 0
218
+ };
219
+ } else if (cursor.row > 0) {
220
+ return {
221
+ row: ev.metaKey ? 0 : cursor.row - 1,
222
+ column: cursor.column
223
+ };
224
+ }
225
+ break;
226
+ case "ArrowDown":
227
+ if (cursor === void 0) {
228
+ return {
229
+ row: 0,
230
+ column: 0
231
+ };
232
+ } else if (cursor.row < numRows - 1) {
233
+ return {
234
+ row: ev.metaKey ? numRows - 1 : cursor.row + 1,
235
+ column: cursor.column
236
+ };
237
+ }
238
+ break;
239
+ case "ArrowLeft":
240
+ if (cursor === void 0) {
241
+ return {
242
+ row: 0,
243
+ column: 0
244
+ };
245
+ } else if (cursor.column > 0) {
246
+ return {
247
+ row: cursor.row,
248
+ column: ev.metaKey ? 0 : cursor.column - 1
249
+ };
250
+ }
251
+ break;
252
+ case "ArrowRight":
253
+ if (cursor === void 0) {
254
+ return {
255
+ row: 0,
256
+ column: 0
257
+ };
258
+ } else if (cursor.column < numColumns - 1) {
259
+ return {
260
+ row: cursor.row,
261
+ column: ev.metaKey ? numColumns - 1 : cursor.column + 1
262
+ };
263
+ }
264
+ break;
265
+ case "Home":
266
+ return {
267
+ row: 0,
268
+ column: 0
269
+ };
270
+ case "End":
271
+ return {
272
+ row: numRows - 1,
273
+ column: numColumns - 1
274
+ };
275
+ }
276
+ };
277
+ var useRangeSelect = (cb) => {
278
+ const [from, setFrom] = useState2();
279
+ const [to, setTo] = useState2();
280
+ const onMouseDown = (ev) => {
281
+ const current = getCellAtPointer(ev);
282
+ setFrom(current);
283
+ if (current) {
284
+ setTimeout(() => cb("start", {
285
+ from: current
286
+ }));
287
+ }
288
+ };
289
+ const onMouseMove = (ev) => {
290
+ if (from) {
291
+ let current = getCellAtPointer(ev);
292
+ if (posEquals(current, from)) {
293
+ current = void 0;
294
+ }
295
+ setTo(current);
296
+ setTimeout(() => cb("move", {
297
+ from,
298
+ to: current
299
+ }));
300
+ }
301
+ };
302
+ const onMouseUp = (ev) => {
303
+ if (from) {
304
+ let current = getCellAtPointer(ev);
305
+ if (posEquals(current, from)) {
306
+ current = void 0;
307
+ }
308
+ setFrom(void 0);
309
+ setTo(void 0);
310
+ setTimeout(() => cb("end", current ? {
311
+ from,
312
+ to: current
313
+ } : void 0));
314
+ }
315
+ };
316
+ return {
317
+ range: from ? {
318
+ from,
319
+ to
320
+ } : void 0,
321
+ handlers: {
322
+ onMouseDown,
323
+ onMouseMove,
324
+ onMouseUp
325
+ }
326
+ };
327
+ };
328
+
329
+ // packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx
330
+ import React, { createContext, useContext, useState as useState3, useEffect as useEffect2 } from "react";
331
+ import { invariant } from "@dxos/invariant";
332
+ import { fullyQualifiedId } from "@dxos/react-client/echo";
333
+
334
+ // packages/plugins/plugin-sheet/src/components/Sheet/formatting.ts
335
+ var FormattingModel = class {
336
+ constructor(model) {
337
+ this.model = model;
338
+ }
339
+ /**
340
+ * Get formatted string value and className for cell.
341
+ */
342
+ getFormatting(cell) {
343
+ const value = this.model.getValue(cell);
344
+ if (value === void 0 || value === null) {
345
+ return {};
346
+ }
347
+ const locales = void 0;
348
+ const idx = this.model.addressToIndex(cell);
349
+ let formatting = this.model.sheet.formatting?.[idx] ?? {};
350
+ const classNames = [
351
+ ...formatting?.classNames ?? []
352
+ ];
353
+ for (const [idx2, _formatting] of Object.entries(this.model.sheet.formatting)) {
354
+ const range = this.model.rangeFromIndex(idx2);
355
+ if (inRange(range, cell)) {
356
+ if (_formatting.classNames) {
357
+ classNames.push(..._formatting.classNames);
358
+ }
359
+ if (_formatting.type) {
360
+ formatting = _formatting;
361
+ }
362
+ }
363
+ }
364
+ const defaultNumber = "justify-end font-mono";
365
+ const type = formatting?.type ?? this.model.getValueType(cell);
366
+ switch (type) {
367
+ case ValueTypeEnum.Boolean: {
368
+ return {
369
+ value: value.toLocaleString().toUpperCase(),
370
+ classNames: [
371
+ ...classNames,
372
+ value ? "!text-greenText" : "!text-orangeText"
373
+ ]
374
+ };
375
+ }
376
+ //
377
+ // Numbers.
378
+ //
379
+ case ValueTypeEnum.Number: {
380
+ return {
381
+ value: value.toLocaleString(locales),
382
+ classNames: [
383
+ ...classNames,
384
+ defaultNumber
385
+ ]
386
+ };
387
+ }
388
+ case ValueTypeEnum.Percent: {
389
+ return {
390
+ value: value * 100 + "%",
391
+ classNames: [
392
+ ...classNames,
393
+ defaultNumber
394
+ ]
395
+ };
396
+ }
397
+ case ValueTypeEnum.Currency: {
398
+ return {
399
+ value: value.toLocaleString(locales, {
400
+ style: "currency",
401
+ currency: "USD",
402
+ minimumFractionDigits: 2,
403
+ maximumFractionDigits: 2
404
+ }),
405
+ classNames: [
406
+ ...classNames,
407
+ defaultNumber
408
+ ]
409
+ };
410
+ }
411
+ //
412
+ // Dates.
413
+ //
414
+ case ValueTypeEnum.DateTime: {
415
+ const date = this.model.toLocalDate(value);
416
+ return {
417
+ value: date.toLocaleString(locales),
418
+ classNames
419
+ };
420
+ }
421
+ case ValueTypeEnum.Date: {
422
+ const date = this.model.toLocalDate(value);
423
+ return {
424
+ value: date.toLocaleDateString(locales),
425
+ classNames
426
+ };
427
+ }
428
+ case ValueTypeEnum.Time: {
429
+ const date = this.model.toLocalDate(value);
430
+ return {
431
+ value: date.toLocaleTimeString(locales),
432
+ classNames
433
+ };
434
+ }
435
+ default: {
436
+ return {
437
+ value: String(value),
438
+ classNames
439
+ };
440
+ }
441
+ }
442
+ }
443
+ };
444
+
445
+ // packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx
446
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx";
447
+ var OBJECT_ID_LENGTH = 60;
448
+ var SheetContext = /* @__PURE__ */ createContext(null);
449
+ var useSheetContext = () => {
450
+ const context = useContext(SheetContext);
451
+ invariant(context, void 0, {
452
+ F: __dxlog_file,
453
+ L: 45,
454
+ S: void 0,
455
+ A: [
456
+ "context",
457
+ ""
458
+ ]
459
+ });
460
+ return context;
461
+ };
462
+ var mapFormulaBindingToId = (functions) => (formula) => {
463
+ return formula.replace(/([a-zA-Z0-9]+)\((.*)\)/g, (match, binding, args) => {
464
+ if (defaultFunctions.find((fn2) => fn2.name === binding) || binding === "EDGE") {
465
+ return match;
466
+ }
467
+ const fn = functions.find((fn2) => fn2.binding === binding);
468
+ if (fn) {
469
+ return `${fullyQualifiedId(fn)}(${args})`;
470
+ } else {
471
+ return match;
472
+ }
473
+ });
474
+ };
475
+ var mapFormulaBindingFromId = (functions) => (formula) => {
476
+ return formula.replace(/([a-zA-Z0-9]+):([a-zA-Z0-9]+)\((.*)\)/g, (match, spaceId, objectId, args) => {
477
+ const id = `${spaceId}:${objectId}`;
478
+ if (id.length !== OBJECT_ID_LENGTH) {
479
+ return match;
480
+ }
481
+ const fn = functions.find((fn2) => fullyQualifiedId(fn2) === id);
482
+ if (fn?.binding) {
483
+ return `${fn.binding}(${args})`;
484
+ } else {
485
+ return match;
486
+ }
487
+ });
488
+ };
489
+ var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...options }) => {
490
+ const graph = useComputeGraph(space, options);
491
+ const [cursor, setCursor] = useState3();
492
+ const [range, setRange] = useState3();
493
+ const [editing, setEditing] = useState3(false);
494
+ const [[model, formatting] = [], setModels] = useState3(void 0);
495
+ useEffect2(() => {
496
+ let model2;
497
+ let formatting2;
498
+ const t = setTimeout(async () => {
499
+ model2 = new SheetModel(graph, sheet, space, {
500
+ readonly,
501
+ mapFormulaBindingToId,
502
+ mapFormulaBindingFromId
503
+ });
504
+ await model2.initialize();
505
+ formatting2 = new FormattingModel(model2);
506
+ setModels([
507
+ model2,
508
+ formatting2
509
+ ]);
510
+ });
511
+ return () => {
512
+ clearTimeout(t);
513
+ void model2?.destroy();
514
+ };
515
+ }, [
516
+ graph,
517
+ readonly
518
+ ]);
519
+ if (!model || !formatting) {
520
+ return null;
521
+ }
522
+ return /* @__PURE__ */ React.createElement(SheetContext.Provider, {
523
+ value: {
524
+ model,
525
+ formatting,
526
+ cursor,
527
+ setCursor,
528
+ range,
529
+ setRange,
530
+ editing,
531
+ setEditing,
532
+ // TODO(burdon): Change to event.
533
+ onInfo
534
+ }
535
+ }, children);
536
+ };
537
+
538
+ // packages/plugins/plugin-sheet/src/components/Sheet/util.ts
539
+ var getRelativeClientRect = (root, element) => {
540
+ const rootRect = root.getBoundingClientRect();
541
+ const elementRect = element.getBoundingClientRect();
542
+ return new DOMRect(elementRect.left - rootRect.left + root.scrollLeft, elementRect.top - rootRect.top + root.scrollTop, elementRect.width, elementRect.height);
543
+ };
544
+ var getRectUnion = (b1, b2) => {
545
+ return {
546
+ left: Math.min(b1.left, b2.left),
547
+ top: Math.min(b1.top, b2.top),
548
+ width: Math.abs(b1.left - b2.left) + (b1.left > b2.left ? b1.width : b2.width),
549
+ height: Math.abs(b1.top - b2.top) + (b1.height > b2.height ? b1.height : b2.height)
550
+ };
551
+ };
552
+ var scrollIntoView = (scrollContainer, el) => {
553
+ el.scrollIntoView({
554
+ block: "nearest",
555
+ inline: "nearest"
556
+ });
557
+ const cellBounds = el.getBoundingClientRect();
558
+ const scrollerBounds = scrollContainer.getBoundingClientRect();
559
+ if (cellBounds.top < scrollerBounds.top) {
560
+ scrollContainer.scrollTop -= scrollerBounds.top - cellBounds.top;
561
+ } else if (cellBounds.bottom >= scrollerBounds.bottom - 1) {
562
+ scrollContainer.scrollTop += 2 + scrollerBounds.bottom - cellBounds.bottom;
563
+ }
564
+ if (cellBounds.left < scrollerBounds.left) {
565
+ scrollContainer.scrollLeft -= scrollerBounds.left - cellBounds.left;
566
+ } else if (cellBounds.right >= scrollerBounds.right) {
567
+ scrollContainer.scrollLeft += 2 + scrollerBounds.right - cellBounds.right;
568
+ }
569
+ };
570
+
571
+ // packages/plugins/plugin-sheet/src/components/CellEditor/CellEditor.tsx
572
+ import { EditorView, keymap } from "@codemirror/view";
573
+ import React2 from "react";
574
+ import { useThemeContext } from "@dxos/react-ui";
575
+ import { createBasicExtensions, createThemeExtensions, preventNewline, useTextEditor } from "@dxos/react-ui-editor";
576
+ var editorKeys = ({ onNav, onClose }) => {
577
+ return keymap.of([
578
+ {
579
+ key: "ArrowUp",
580
+ run: (editor) => {
581
+ const value = editor.state.doc.toString();
582
+ onNav?.(value, {
583
+ key: "ArrowUp"
584
+ });
585
+ return !!onNav;
586
+ }
587
+ },
588
+ {
589
+ key: "ArrowDown",
590
+ run: (editor) => {
591
+ const value = editor.state.doc.toString();
592
+ onNav?.(value, {
593
+ key: "ArrowDown"
594
+ });
595
+ return !!onNav;
596
+ }
597
+ },
598
+ {
599
+ key: "ArrowLeft",
600
+ run: (editor) => {
601
+ const value = editor.state.doc.toString();
602
+ onNav?.(value, {
603
+ key: "ArrowLeft"
604
+ });
605
+ return !!onNav;
606
+ }
607
+ },
608
+ {
609
+ key: "ArrowRight",
610
+ run: (editor) => {
611
+ const value = editor.state.doc.toString();
612
+ onNav?.(value, {
613
+ key: "ArrowRight"
614
+ });
615
+ return !!onNav;
616
+ }
617
+ },
618
+ {
619
+ key: "Enter",
620
+ run: (editor) => {
621
+ onClose(editor.state.doc.toString());
622
+ return true;
623
+ }
624
+ },
625
+ {
626
+ key: "Escape",
627
+ run: () => {
628
+ onClose(void 0);
629
+ return true;
630
+ }
631
+ }
632
+ ]);
633
+ };
634
+ var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
635
+ const { themeMode } = useThemeContext();
636
+ const { parentRef } = useTextEditor(() => {
637
+ return {
638
+ autoFocus,
639
+ initialValue: value,
640
+ selection: {
641
+ anchor: value?.length ?? 0
642
+ },
643
+ extensions: [
644
+ extension ?? [],
645
+ preventNewline,
646
+ EditorView.focusChangeEffect.of((_, focusing) => {
647
+ if (!focusing) {
648
+ onBlur?.({
649
+ type: "blur"
650
+ });
651
+ }
652
+ return null;
653
+ }),
654
+ createBasicExtensions({
655
+ lineWrapping: false
656
+ }),
657
+ createThemeExtensions({
658
+ themeMode,
659
+ slots: {
660
+ editor: {
661
+ className: "flex w-full [&>.cm-scroller]:scrollbar-none"
662
+ },
663
+ content: {
664
+ className: "!px-2 !py-1"
665
+ }
666
+ }
667
+ })
668
+ ]
669
+ };
670
+ }, [
671
+ extension
672
+ ]);
673
+ return /* @__PURE__ */ React2.createElement("div", {
674
+ ref: parentRef,
675
+ className: "flex w-full"
676
+ });
677
+ };
678
+
679
+ // packages/plugins/plugin-sheet/src/components/CellEditor/extension.ts
680
+ import { acceptCompletion, autocompletion, completionStatus, startCompletion } from "@codemirror/autocomplete";
681
+ import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
682
+ import { Facet } from "@codemirror/state";
683
+ import { ViewPlugin, keymap as keymap2 } from "@codemirror/view";
684
+ import { tags } from "@lezer/highlight";
685
+ import { spreadsheet } from "codemirror-lang-spreadsheet";
686
+ import { mx } from "@dxos/react-ui-theme";
687
+ var highlightStyles = HighlightStyle.define([
688
+ // Function.
689
+ {
690
+ tag: tags.name,
691
+ class: "text-accentText"
692
+ },
693
+ // Range.
694
+ {
695
+ tag: tags.tagName,
696
+ class: "text-pinkText"
697
+ },
698
+ // Values.
699
+ {
700
+ tag: tags.number,
701
+ class: "text-tealText"
702
+ },
703
+ {
704
+ tag: tags.bool,
705
+ class: "text-tealText"
706
+ },
707
+ {
708
+ tag: tags.string,
709
+ class: "text-tealText"
710
+ },
711
+ // Error.
712
+ {
713
+ tag: tags.invalid,
714
+ class: "text-unAccent"
715
+ }
716
+ ]);
717
+ var languageFacet = Facet.define();
718
+ var sheetExtension = ({ functions = [] }) => {
719
+ const { extension, language } = spreadsheet({
720
+ idiom: "en-US",
721
+ decimalSeparator: "."
722
+ });
723
+ const createCompletion = (name) => {
724
+ const { section = "Custom", description, syntax } = functions.find((value) => value.name === name) ?? {};
725
+ return {
726
+ section,
727
+ label: name,
728
+ info: () => {
729
+ if (!description && !syntax) {
730
+ return null;
731
+ }
732
+ const root = document.createElement("div");
733
+ root.className = "flex flex-col gap-2 text-sm";
734
+ const title = document.createElement("h2");
735
+ title.innerText = name;
736
+ title.className = "text-lg font-mono text-accentText";
737
+ root.appendChild(title);
738
+ if (description) {
739
+ const info = document.createElement("p");
740
+ info.innerText = description;
741
+ info.className = "text-subdued";
742
+ root.appendChild(info);
743
+ }
744
+ if (syntax) {
745
+ const detail = document.createElement("pre");
746
+ detail.innerText = syntax;
747
+ detail.className = "whitespace-pre-wrap text-greenText";
748
+ root.appendChild(detail);
749
+ }
750
+ return root;
751
+ },
752
+ apply: (view, completion, from, to) => {
753
+ const insertParens = to === view.state.doc.toString().length;
754
+ view.dispatch(view.state.update({
755
+ changes: {
756
+ from,
757
+ to,
758
+ insert: completion.label + (insertParens ? "()" : "")
759
+ },
760
+ selection: {
761
+ anchor: from + completion.label.length + 1
762
+ }
763
+ }));
764
+ }
765
+ };
766
+ };
767
+ return [
768
+ extension,
769
+ languageFacet.of(language),
770
+ language.data.of({
771
+ autocomplete: (context) => {
772
+ if (context.state.doc.toString()[0] !== "=") {
773
+ return null;
774
+ }
775
+ const match = context.matchBefore(/\w*/);
776
+ if (!match || match.from === match.to) {
777
+ return null;
778
+ }
779
+ const text = match.text.toUpperCase();
780
+ if (!context.explicit && match.text.length < 2) {
781
+ return null;
782
+ }
783
+ return {
784
+ from: match.from,
785
+ options: functions?.filter(({ name }) => name.startsWith(text)).map(({ name }) => createCompletion(name)) ?? []
786
+ };
787
+ }
788
+ }),
789
+ syntaxHighlighting(highlightStyles),
790
+ autocompletion({
791
+ aboveCursor: false,
792
+ defaultKeymap: true,
793
+ activateOnTyping: true,
794
+ // NOTE: Useful for debugging.
795
+ closeOnBlur: false,
796
+ icons: false,
797
+ tooltipClass: () => mx(
798
+ // TODO(burdon): Factor out fragments.
799
+ // TODO(burdon): Size to make width same as column.
800
+ "!-left-[1px] !top-[33px] !-m-0 border !border-t-0 [&>ul]:!min-w-[198px]",
801
+ "[&>ul>li[aria-selected]]:!bg-accentSurface",
802
+ "border-separator"
803
+ )
804
+ }),
805
+ keymap2.of([
806
+ {
807
+ key: "Tab",
808
+ run: (view) => {
809
+ return completionStatus(view.state) === "active" ? acceptCompletion(view) : startCompletion(view);
810
+ }
811
+ }
812
+ ])
813
+ ];
814
+ };
815
+ var rangeExtension = (onInit) => {
816
+ let view;
817
+ let activeRange;
818
+ const provider = (range) => {
819
+ if (activeRange) {
820
+ view.dispatch(view.state.update({
821
+ changes: {
822
+ ...activeRange,
823
+ insert: range.toString()
824
+ },
825
+ selection: {
826
+ anchor: activeRange.from + range.length
827
+ }
828
+ }));
829
+ }
830
+ view.focus();
831
+ };
832
+ return ViewPlugin.fromClass(class {
833
+ constructor(_view) {
834
+ view = _view;
835
+ onInit(provider);
836
+ }
837
+ update(view2) {
838
+ const { anchor } = view2.state.selection.ranges[0];
839
+ activeRange = void 0;
840
+ const [language] = view2.state.facet(languageFacet);
841
+ const { topNode } = language.parser.parse(view2.state.doc.toString());
842
+ visitTree(topNode, ({ type, from, to }) => {
843
+ if (from <= anchor && to >= anchor) {
844
+ switch (type.name) {
845
+ case "Function": {
846
+ activeRange = {
847
+ from: to,
848
+ to
849
+ };
850
+ break;
851
+ }
852
+ case "CloseParen": {
853
+ activeRange = {
854
+ from,
855
+ to: from
856
+ };
857
+ break;
858
+ }
859
+ case "RangeToken":
860
+ case "CellToken":
861
+ activeRange = {
862
+ from,
863
+ to
864
+ };
865
+ return true;
866
+ }
867
+ }
868
+ return false;
869
+ });
870
+ if (!activeRange && view2.state.doc.toString()[0] === "=") {
871
+ activeRange = {
872
+ from: 1,
873
+ to: view2.state.doc.toString().length
874
+ };
875
+ }
876
+ }
877
+ });
878
+ };
879
+ var visitTree = (node, callback) => {
880
+ if (callback(node)) {
881
+ return true;
882
+ }
883
+ for (let child = node.firstChild; child !== null; child = child.nextSibling) {
884
+ if (visitTree(child, callback)) {
885
+ return true;
886
+ }
887
+ }
888
+ return false;
889
+ };
890
+
891
+ // packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx
892
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx";
893
+ var fragments = {
894
+ axis: "bg-axisSurface text-axisText text-xs select-none",
895
+ axisSelected: "bg-attention text-baseText",
896
+ cell: "bg-gridCell",
897
+ cellSelected: "bg-gridCellSelected text-baseText border !border-accentSurface"
898
+ };
899
+ var SheetRoot = ({ children, ...props }) => {
900
+ return /* @__PURE__ */ React3.createElement(SheetContextProvider, props, children);
901
+ };
902
+ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns }, forwardRef2) => {
903
+ const { model, cursor, setCursor, setRange, setEditing } = useSheetContext();
904
+ const { rowsRef, columnsRef, contentRef } = useScrollHandlers();
905
+ const [rows, setRows] = useState4([
906
+ ...model.sheet.rows
907
+ ]);
908
+ const [columns, setColumns] = useState4([
909
+ ...model.sheet.columns
910
+ ]);
911
+ useEffect3(() => {
912
+ const rowsAccessor = createDocAccessor(model.sheet, [
913
+ "rows"
914
+ ]);
915
+ const columnsAccessor = createDocAccessor(model.sheet, [
916
+ "columns"
917
+ ]);
918
+ const handleUpdate = debounce(() => {
919
+ setRows([
920
+ ...model.sheet.rows
921
+ ]);
922
+ setColumns([
923
+ ...model.sheet.columns
924
+ ]);
925
+ }, 100);
926
+ rowsAccessor.handle.addListener("change", handleUpdate);
927
+ columnsAccessor.handle.addListener("change", handleUpdate);
928
+ handleUpdate();
929
+ return () => {
930
+ rowsAccessor.handle.removeListener("change", handleUpdate);
931
+ columnsAccessor.handle.removeListener("change", handleUpdate);
932
+ };
933
+ }, [
934
+ model
935
+ ]);
936
+ useEffect3(() => {
937
+ model.reset();
938
+ }, [
939
+ rows,
940
+ columns
941
+ ]);
942
+ const handleMoveRows = (from, to, num = 1) => {
943
+ const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
944
+ const [rows2] = model.sheet.rows.splice(from, num);
945
+ model.sheet.rows.splice(to, 0, rows2);
946
+ if (cursorIdx) {
947
+ setCursor(model.addressFromIndex(cursorIdx));
948
+ }
949
+ setRows([
950
+ ...model.sheet.rows
951
+ ]);
952
+ };
953
+ const handleMoveColumns = (from, to, num = 1) => {
954
+ const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
955
+ const columns2 = model.sheet.columns.splice(from, num);
956
+ model.sheet.columns.splice(to, 0, ...columns2);
957
+ if (cursorIdx) {
958
+ setCursor(model.addressFromIndex(cursorIdx));
959
+ }
960
+ setColumns([
961
+ ...model.sheet.columns
962
+ ]);
963
+ };
964
+ const [rowSizes, setRowSizes] = useState4();
965
+ const [columnSizes, setColumnSizes] = useState4();
966
+ useEffect3(() => {
967
+ const rowAccessor = createDocAccessor(model.sheet, [
968
+ "rowMeta"
969
+ ]);
970
+ const columnAccessor = createDocAccessor(model.sheet, [
971
+ "columnMeta"
972
+ ]);
973
+ const handleUpdate = debounce(() => {
974
+ const mapSizes = (values) => values.reduce((map, [idx, meta]) => {
975
+ if (meta.size) {
976
+ map[idx] = meta.size;
977
+ }
978
+ return map;
979
+ }, {});
980
+ setRowSizes(mapSizes(Object.entries(model.sheet.rowMeta)));
981
+ setColumnSizes(mapSizes(Object.entries(model.sheet.columnMeta)));
982
+ }, 100);
983
+ rowAccessor.handle.addListener("change", handleUpdate);
984
+ columnAccessor.handle.addListener("change", handleUpdate);
985
+ handleUpdate();
986
+ return () => {
987
+ rowAccessor.handle.removeListener("change", handleUpdate);
988
+ columnAccessor.handle.removeListener("change", handleUpdate);
989
+ };
990
+ }, [
991
+ model
992
+ ]);
993
+ const handleResizeRow = (idx, size, save) => {
994
+ if (save) {
995
+ model.sheet.rowMeta[idx] ??= {};
996
+ model.sheet.rowMeta[idx].size = size;
997
+ } else {
998
+ setRowSizes((sizes) => ({
999
+ ...sizes,
1000
+ [idx]: size
1001
+ }));
1002
+ }
1003
+ };
1004
+ const handleResizeColumn = (idx, size, save) => {
1005
+ if (save) {
1006
+ model.sheet.columnMeta[idx] ??= {};
1007
+ model.sheet.columnMeta[idx].size = size;
1008
+ } else {
1009
+ setColumnSizes((sizes) => ({
1010
+ ...sizes,
1011
+ [idx]: size
1012
+ }));
1013
+ }
1014
+ };
1015
+ return /* @__PURE__ */ React3.createElement("div", {
1016
+ role: "none",
1017
+ className: mx2("grid grid-cols-[calc(var(--rail-size)-2px)_1fr] grid-rows-[32px_1fr_32px] bs-full is-full overflow-hidden", classNames)
1018
+ }, /* @__PURE__ */ React3.createElement(GridCorner, {
1019
+ onClick: () => {
1020
+ setCursor(void 0);
1021
+ setRange(void 0);
1022
+ setEditing(false);
1023
+ }
1024
+ }), /* @__PURE__ */ React3.createElement(SheetColumns, {
1025
+ ref: columnsRef,
1026
+ columns,
1027
+ sizes: columnSizes,
1028
+ selected: cursor?.column,
1029
+ onSelect: (column) => setCursor(cursor?.column === column ? void 0 : {
1030
+ row: -1,
1031
+ column
1032
+ }),
1033
+ onResize: handleResizeColumn,
1034
+ onMove: handleMoveColumns
1035
+ }), /* @__PURE__ */ React3.createElement(SheetRows, {
1036
+ ref: rowsRef,
1037
+ rows,
1038
+ sizes: rowSizes,
1039
+ selected: cursor?.row,
1040
+ onSelect: (row) => setCursor(cursor?.row === row ? void 0 : {
1041
+ row,
1042
+ column: -1
1043
+ }),
1044
+ onResize: handleResizeRow,
1045
+ onMove: handleMoveRows
1046
+ }), /* @__PURE__ */ React3.createElement(SheetGrid, {
1047
+ ref: contentRef,
1048
+ size: {
1049
+ numRows: numRows ?? rows.length,
1050
+ numColumns: numColumns ?? columns.length
1051
+ },
1052
+ rows,
1053
+ columns,
1054
+ rowSizes,
1055
+ columnSizes
1056
+ }), /* @__PURE__ */ React3.createElement(GridCorner, null), /* @__PURE__ */ React3.createElement(SheetStatusBar, null));
1057
+ });
1058
+ var useScrollHandlers = () => {
1059
+ const rowsRef = useRef(null);
1060
+ const columnsRef = useRef(null);
1061
+ const contentRef = useRef(null);
1062
+ useEffect3(() => {
1063
+ const handleRowsScroll = (ev) => {
1064
+ const { scrollTop } = ev.target;
1065
+ if (!rowsRef.current.dataset.locked) {
1066
+ contentRef.current.scrollTop = scrollTop;
1067
+ }
1068
+ };
1069
+ const handleColumnsScroll = (ev) => {
1070
+ const { scrollLeft } = ev.target;
1071
+ if (!columnsRef.current.dataset.locked) {
1072
+ contentRef.current.scrollLeft = scrollLeft;
1073
+ }
1074
+ };
1075
+ const handleContentScroll = (ev) => {
1076
+ const { scrollTop, scrollLeft } = ev.target;
1077
+ rowsRef.current.scrollTop = scrollTop;
1078
+ columnsRef.current.scrollLeft = scrollLeft;
1079
+ };
1080
+ const rows = rowsRef.current;
1081
+ const columns = columnsRef.current;
1082
+ const content = contentRef.current;
1083
+ rows.addEventListener("scroll", handleRowsScroll);
1084
+ columns.addEventListener("scroll", handleColumnsScroll);
1085
+ content.addEventListener("scroll", handleContentScroll);
1086
+ return () => {
1087
+ rows.removeEventListener("scroll", handleRowsScroll);
1088
+ columns.removeEventListener("scroll", handleColumnsScroll);
1089
+ content.removeEventListener("scroll", handleContentScroll);
1090
+ };
1091
+ }, []);
1092
+ return {
1093
+ rowsRef,
1094
+ columnsRef,
1095
+ contentRef
1096
+ };
1097
+ };
1098
+ var GridCorner = (props) => {
1099
+ return /* @__PURE__ */ React3.createElement("div", {
1100
+ className: fragments.axis,
1101
+ ...props
1102
+ });
1103
+ };
1104
+ var MovingOverlay = ({ label }) => {
1105
+ return /* @__PURE__ */ React3.createElement("div", {
1106
+ className: "flex w-full h-full justify-center items-center text-sm p-1 bg-gridOverlay cursor-pointer"
1107
+ }, label);
1108
+ };
1109
+ var mouseConstraints = {
1110
+ distance: 10
1111
+ };
1112
+ var touchConstraints = {
1113
+ delay: 250,
1114
+ tolerance: 5
1115
+ };
1116
+ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, onResize, onMove }, forwardRef2) => {
1117
+ const mouseSensor = useSensor(MouseSensor, {
1118
+ activationConstraint: mouseConstraints
1119
+ });
1120
+ const touchSensor = useSensor(TouchSensor, {
1121
+ activationConstraint: touchConstraints
1122
+ });
1123
+ const keyboardSensor = useSensor(KeyboardSensor, {});
1124
+ const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
1125
+ const [active, setActive] = useState4(null);
1126
+ const handleDragStart = ({ active: active2 }) => {
1127
+ setActive(active2);
1128
+ };
1129
+ const handleDragEnd = ({ over, active: active2 }) => {
1130
+ if (over && over.id !== active2.id) {
1131
+ setActive(null);
1132
+ onMove?.(active2.data.current.index, over.data.current.index);
1133
+ }
1134
+ };
1135
+ const snapToCenter = ({ activatorEvent, draggingNodeRect, transform }) => {
1136
+ if (draggingNodeRect && activatorEvent) {
1137
+ const activatorCoordinates = getEventCoordinates(activatorEvent);
1138
+ if (!activatorCoordinates) {
1139
+ return transform;
1140
+ }
1141
+ const offset = activatorCoordinates.y - draggingNodeRect.top;
1142
+ return {
1143
+ ...transform,
1144
+ y: transform.y + offset - draggingNodeRect.height / 2
1145
+ };
1146
+ }
1147
+ return transform;
1148
+ };
1149
+ return /* @__PURE__ */ React3.createElement("div", {
1150
+ className: "relative flex grow overflow-hidden"
1151
+ }, /* @__PURE__ */ React3.createElement("div", {
1152
+ className: mx2("z-20 absolute inset-0 border-y border-gridLine pointer-events-none"),
1153
+ style: {
1154
+ width: axisWidth
1155
+ }
1156
+ }), /* @__PURE__ */ React3.createElement("div", {
1157
+ ref: forwardRef2,
1158
+ role: "rowheader",
1159
+ className: "grow overflow-y-auto scrollbar-none"
1160
+ }, /* @__PURE__ */ React3.createElement(DndContext, {
1161
+ sensors,
1162
+ modifiers: [
1163
+ restrictToVerticalAxis,
1164
+ snapToCenter
1165
+ ],
1166
+ onDragStart: handleDragStart,
1167
+ onDragEnd: handleDragEnd
1168
+ }, /* @__PURE__ */ React3.createElement("div", {
1169
+ className: "flex flex-col",
1170
+ style: {
1171
+ width: axisWidth
1172
+ }
1173
+ }, rows.map((idx, index) => /* @__PURE__ */ React3.createElement(GridRowCell, {
1174
+ key: idx,
1175
+ idx,
1176
+ index,
1177
+ label: String(index + 1),
1178
+ size: sizes?.[idx] ?? defaultHeight,
1179
+ resize: index < rows.length - 1,
1180
+ selected: selected === index,
1181
+ onResize,
1182
+ onSelect
1183
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(DragOverlay, null, active && /* @__PURE__ */ React3.createElement(MovingOverlay, {
1184
+ label: String(active.data.current.index + 1)
1185
+ })), document.body))));
1186
+ });
1187
+ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResize }) => {
1188
+ const { setNodeRef: setDroppableNodeRef } = useDroppable({
1189
+ id: idx,
1190
+ data: {
1191
+ index
1192
+ }
1193
+ });
1194
+ const { setNodeRef: setDraggableNodeRef, attributes, listeners, isDragging, over } = useDraggable({
1195
+ id: idx,
1196
+ data: {
1197
+ index
1198
+ }
1199
+ });
1200
+ const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
1201
+ const [initialSize, setInitialSize] = useState4(size);
1202
+ const [resizing, setResizing] = useState4(false);
1203
+ const scrollHandler = useRef();
1204
+ const handleResizeStart = (_ev, _dir, elementRef) => {
1205
+ const scrollContainer = elementRef.closest('[role="rowheader"]');
1206
+ const scrollTop = scrollContainer.scrollTop;
1207
+ scrollHandler.current = (ev) => ev.target.scrollTop = scrollTop;
1208
+ scrollContainer.addEventListener("scroll", scrollHandler.current);
1209
+ scrollContainer.dataset.locked = "true";
1210
+ setResizing(true);
1211
+ };
1212
+ const handleResize = (_ev, _dir, _elementRef, { height }) => {
1213
+ onResize?.(idx, initialSize + height);
1214
+ };
1215
+ const handleResizeStop = (_ev, _dir, elementRef, { height }) => {
1216
+ const scrollContainer = elementRef.closest('[role="rowheader"]');
1217
+ scrollContainer.removeEventListener("scroll", scrollHandler.current);
1218
+ delete scrollContainer.dataset.locked;
1219
+ scrollHandler.current = void 0;
1220
+ setInitialSize(initialSize + height);
1221
+ onResize?.(idx, initialSize + height, true);
1222
+ setResizing(false);
1223
+ };
1224
+ return /* @__PURE__ */ React3.createElement(Resizable, {
1225
+ enable: {
1226
+ bottom: resize
1227
+ },
1228
+ size: {
1229
+ height: size - 1
1230
+ },
1231
+ minHeight: minHeight - 1,
1232
+ maxHeight,
1233
+ onResizeStart: handleResizeStart,
1234
+ onResize: handleResize,
1235
+ onResizeStop: handleResizeStop
1236
+ }, /* @__PURE__ */ React3.createElement("div", {
1237
+ ref: setNodeRef,
1238
+ ...attributes,
1239
+ ...listeners,
1240
+ className: mx2("flex h-full items-center justify-center cursor-pointer", "border-t border-gridLine focus-visible:outline-none", fragments.axis, selected && fragments.axisSelected, isDragging && fragments.axisSelected),
1241
+ onClick: () => onSelect?.(index)
1242
+ }, /* @__PURE__ */ React3.createElement("span", {
1243
+ className: "flex w-full justify-center"
1244
+ }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React3.createElement("div", {
1245
+ className: "z-20 absolute top-0 w-full min-h-[4px] border-b-4 border-accentSurface"
1246
+ }), resizing && /* @__PURE__ */ React3.createElement("div", {
1247
+ className: "z-20 absolute bottom-0 w-full min-h-[4px] border-b-4 border-accentSurface"
1248
+ })));
1249
+ };
1250
+ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSelect, onResize, onMove }, forwardRef2) => {
1251
+ const mouseSensor = useSensor(MouseSensor, {
1252
+ activationConstraint: mouseConstraints
1253
+ });
1254
+ const touchSensor = useSensor(TouchSensor, {
1255
+ activationConstraint: touchConstraints
1256
+ });
1257
+ const keyboardSensor = useSensor(KeyboardSensor, {});
1258
+ const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
1259
+ const [active, setActive] = useState4(null);
1260
+ const handleDragStart = ({ active: active2 }) => {
1261
+ setActive(active2);
1262
+ };
1263
+ const handleDragEnd = ({ active: active2, over }) => {
1264
+ if (over && over.id !== active2.id) {
1265
+ setActive(null);
1266
+ onMove?.(active2.data.current.index, over.data.current.index);
1267
+ }
1268
+ };
1269
+ const snapToCenter = ({ activatorEvent, draggingNodeRect, transform }) => {
1270
+ if (draggingNodeRect && activatorEvent) {
1271
+ const activatorCoordinates = getEventCoordinates(activatorEvent);
1272
+ if (!activatorCoordinates) {
1273
+ return transform;
1274
+ }
1275
+ const offset = activatorCoordinates.x - draggingNodeRect.left;
1276
+ return {
1277
+ ...transform,
1278
+ x: transform.x + offset - draggingNodeRect.width / 2
1279
+ };
1280
+ }
1281
+ return transform;
1282
+ };
1283
+ return /* @__PURE__ */ React3.createElement("div", {
1284
+ className: "relative flex grow overflow-hidden"
1285
+ }, /* @__PURE__ */ React3.createElement("div", {
1286
+ className: mx2("z-20 absolute inset-0 border-x border-gridLine pointer-events-none"),
1287
+ style: {
1288
+ height: axisHeight
1289
+ }
1290
+ }), /* @__PURE__ */ React3.createElement("div", {
1291
+ ref: forwardRef2,
1292
+ role: "columnheader",
1293
+ className: "grow overflow-x-auto scrollbar-none"
1294
+ }, /* @__PURE__ */ React3.createElement(DndContext, {
1295
+ autoScroll: {
1296
+ enabled: true
1297
+ },
1298
+ sensors,
1299
+ modifiers: [
1300
+ restrictToHorizontalAxis,
1301
+ snapToCenter
1302
+ ],
1303
+ onDragStart: handleDragStart,
1304
+ onDragEnd: handleDragEnd
1305
+ }, /* @__PURE__ */ React3.createElement("div", {
1306
+ className: "flex h-full",
1307
+ style: {
1308
+ height: axisHeight
1309
+ }
1310
+ }, columns.map((idx, index) => /* @__PURE__ */ React3.createElement(GridColumnCell, {
1311
+ key: idx,
1312
+ idx,
1313
+ index,
1314
+ label: columnLetter(index),
1315
+ size: sizes?.[idx] ?? defaultWidth,
1316
+ resize: index < columns.length - 1,
1317
+ selected: selected === index,
1318
+ onResize,
1319
+ onSelect
1320
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(DragOverlay, null, active && /* @__PURE__ */ React3.createElement(MovingOverlay, {
1321
+ label: columnLetter(active.data.current.index)
1322
+ })), document.body))));
1323
+ });
1324
+ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onResize }) => {
1325
+ const { setNodeRef: setDroppableNodeRef } = useDroppable({
1326
+ id: idx,
1327
+ data: {
1328
+ index
1329
+ }
1330
+ });
1331
+ const { setNodeRef: setDraggableNodeRef, attributes, listeners, over, isDragging } = useDraggable({
1332
+ id: idx,
1333
+ data: {
1334
+ index
1335
+ }
1336
+ });
1337
+ const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
1338
+ const [initialSize, setInitialSize] = useState4(size);
1339
+ const [resizing, setResizing] = useState4(false);
1340
+ const scrollHandler = useRef();
1341
+ const handleResizeStart = (_ev, _dir, elementRef) => {
1342
+ const scrollContainer = elementRef.closest('[role="columnheader"]');
1343
+ const scrollLeft = scrollContainer.scrollLeft;
1344
+ scrollHandler.current = (ev) => ev.target.scrollLeft = scrollLeft;
1345
+ scrollContainer.addEventListener("scroll", scrollHandler.current);
1346
+ scrollContainer.dataset.locked = "true";
1347
+ setResizing(true);
1348
+ };
1349
+ const handleResize = (_ev, _dir, _elementRef, { width }) => {
1350
+ onResize?.(idx, initialSize + width);
1351
+ };
1352
+ const handleResizeStop = (_ev, _dir, elementRef, { width }) => {
1353
+ const scrollContainer = elementRef.closest('[role="columnheader"]');
1354
+ scrollContainer.removeEventListener("scroll", scrollHandler.current);
1355
+ delete scrollContainer.dataset.locked;
1356
+ scrollHandler.current = void 0;
1357
+ setInitialSize(initialSize + width);
1358
+ onResize?.(idx, initialSize + width, true);
1359
+ setResizing(false);
1360
+ };
1361
+ return /* @__PURE__ */ React3.createElement(Resizable, {
1362
+ enable: {
1363
+ right: resize
1364
+ },
1365
+ size: {
1366
+ width: size - 1
1367
+ },
1368
+ minWidth: minWidth - 1,
1369
+ maxWidth,
1370
+ onResizeStart: handleResizeStart,
1371
+ onResize: handleResize,
1372
+ onResizeStop: handleResizeStop
1373
+ }, /* @__PURE__ */ React3.createElement("div", {
1374
+ ref: setNodeRef,
1375
+ ...attributes,
1376
+ ...listeners,
1377
+ className: mx2("flex h-full items-center justify-center cursor-pointer", "border-l border-gridLine focus-visible:outline-none", fragments.axis, selected && fragments.axisSelected, isDragging && fragments.axisSelected),
1378
+ onClick: () => onSelect?.(index)
1379
+ }, /* @__PURE__ */ React3.createElement("span", {
1380
+ className: "flex w-full justify-center"
1381
+ }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React3.createElement("div", {
1382
+ className: "z-20 absolute left-0 h-full min-w-[4px] border-l-4 border-accentSurface"
1383
+ }), resizing && /* @__PURE__ */ React3.createElement("div", {
1384
+ className: "z-20 absolute right-0 h-full min-h-[4px] border-l-4 border-accentSurface"
1385
+ })));
1386
+ };
1387
+ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, columnSizes }, forwardRef2) => {
1388
+ const { ref: containerRef, width: containerWidth = 0, height: containerHeight = 0 } = useResizeDetector({
1389
+ refreshRate: 200
1390
+ });
1391
+ const scrollerRef = useRef(null);
1392
+ useImperativeHandle(forwardRef2, () => scrollerRef.current);
1393
+ const { model, cursor, range, editing, setCursor, setRange, setEditing, onInfo } = useSheetContext();
1394
+ const initialText = useRef();
1395
+ const quickEdit = useRef(false);
1396
+ const [, forceUpdate] = useState4({});
1397
+ useEffect3(() => {
1398
+ const unsubscribe = model.update.on(() => {
1399
+ log("updated", {
1400
+ id: model.id
1401
+ }, {
1402
+ F: __dxlog_file2,
1403
+ L: 730,
1404
+ S: void 0,
1405
+ C: (f, a) => f(...a)
1406
+ });
1407
+ forceUpdate({});
1408
+ });
1409
+ return () => {
1410
+ unsubscribe();
1411
+ };
1412
+ }, [
1413
+ model
1414
+ ]);
1415
+ const inputRef = useRef(null);
1416
+ const handleKeyDown = (ev) => {
1417
+ const isMacOS = /Mac|iPhone|iPod|iPad/.test(navigator.userAgent);
1418
+ if (cursor && (isMacOS && ev.metaKey || ev.ctrlKey)) {
1419
+ switch (ev.key) {
1420
+ case "x": {
1421
+ model.cut(range ?? {
1422
+ from: cursor
1423
+ });
1424
+ return;
1425
+ }
1426
+ case "c": {
1427
+ model.copy(range ?? {
1428
+ from: cursor
1429
+ });
1430
+ return;
1431
+ }
1432
+ case "v": {
1433
+ model.paste(cursor);
1434
+ return;
1435
+ }
1436
+ case "z": {
1437
+ if (ev.shiftKey) {
1438
+ model.redo();
1439
+ } else {
1440
+ model.undo();
1441
+ }
1442
+ return;
1443
+ }
1444
+ }
1445
+ }
1446
+ switch (ev.key) {
1447
+ case "ArrowUp":
1448
+ case "ArrowDown":
1449
+ case "ArrowLeft":
1450
+ case "ArrowRight":
1451
+ case "Home":
1452
+ case "End": {
1453
+ const next = handleNav(ev, cursor, range, size);
1454
+ setRange(next.range);
1455
+ if (next.cursor) {
1456
+ setCursor(next.cursor);
1457
+ const element = getCellElement(scrollerRef.current, next.cursor);
1458
+ if (element) {
1459
+ scrollIntoView(scrollerRef.current, element);
1460
+ }
1461
+ }
1462
+ break;
1463
+ }
1464
+ case "Backspace": {
1465
+ if (cursor) {
1466
+ if (range) {
1467
+ model.clear(range);
1468
+ } else {
1469
+ model.setValue(cursor, null);
1470
+ }
1471
+ }
1472
+ break;
1473
+ }
1474
+ case "Escape": {
1475
+ setRange(void 0);
1476
+ break;
1477
+ }
1478
+ case "Enter": {
1479
+ ev.stopPropagation();
1480
+ if (cursor) {
1481
+ setEditing(true);
1482
+ }
1483
+ break;
1484
+ }
1485
+ case "?": {
1486
+ onInfo?.();
1487
+ break;
1488
+ }
1489
+ default: {
1490
+ if (ev.key.length === 1) {
1491
+ initialText.current = ev.key;
1492
+ quickEdit.current = true;
1493
+ setEditing(true);
1494
+ }
1495
+ }
1496
+ }
1497
+ };
1498
+ const { handlers } = useRangeSelect((event, range2) => {
1499
+ switch (event) {
1500
+ case "start": {
1501
+ setRange(void 0);
1502
+ break;
1503
+ }
1504
+ default: {
1505
+ setRange(range2);
1506
+ }
1507
+ }
1508
+ });
1509
+ const { width, height, rowRange, columnRange } = useGridLayout({
1510
+ scroller: scrollerRef.current,
1511
+ size: {
1512
+ width: containerWidth,
1513
+ height: containerHeight
1514
+ },
1515
+ rows,
1516
+ columns,
1517
+ rowSizes,
1518
+ columnSizes
1519
+ });
1520
+ const id = fullyQualifiedId2(model.sheet);
1521
+ const attendableAttrs = createAttendableAttributes(id);
1522
+ const hasAttention = useHasAttention(id);
1523
+ return /* @__PURE__ */ React3.createElement("div", {
1524
+ ref: containerRef,
1525
+ role: "grid",
1526
+ className: "relative flex grow overflow-hidden"
1527
+ }, /* @__PURE__ */ React3.createElement("div", {
1528
+ className: mx2("z-20 absolute inset-0 border border-gridLine pointer-events-none")
1529
+ }), /* @__PURE__ */ React3.createElement("div", {
1530
+ ref: scrollerRef,
1531
+ className: mx2("grow", hasAttention && "overflow-auto scrollbar-thin")
1532
+ }, /* @__PURE__ */ React3.createElement("div", {
1533
+ className: "relative select-none",
1534
+ style: {
1535
+ width,
1536
+ height
1537
+ },
1538
+ onClick: () => inputRef.current?.focus(),
1539
+ ...handlers
1540
+ }, scrollerRef.current && /* @__PURE__ */ React3.createElement(SelectionOverlay, {
1541
+ root: scrollerRef.current
1542
+ }), rowRange.map(({ row, top, height: height2 }) => {
1543
+ return columnRange.map(({ column, left, width: width2 }) => {
1544
+ const style = {
1545
+ position: "absolute",
1546
+ top,
1547
+ left,
1548
+ width: width2,
1549
+ height: height2
1550
+ };
1551
+ const cell = {
1552
+ row,
1553
+ column
1554
+ };
1555
+ const id2 = addressToA1Notation(cell);
1556
+ const idx = model.addressToIndex(cell);
1557
+ const active = posEquals(cursor, cell);
1558
+ if (active && editing) {
1559
+ const value = initialText.current ?? model.getCellText(cell) ?? "";
1560
+ const handleClose = (value2) => {
1561
+ initialText.current = void 0;
1562
+ quickEdit.current = false;
1563
+ if (value2 !== void 0) {
1564
+ model.setValue(cell, value2);
1565
+ const next = handleArrowNav({
1566
+ key: "ArrowDown",
1567
+ metaKey: false
1568
+ }, cursor, size);
1569
+ if (next) {
1570
+ setCursor(next);
1571
+ }
1572
+ }
1573
+ inputRef.current?.focus();
1574
+ setEditing(false);
1575
+ };
1576
+ const handleNav2 = (value2, { key }) => {
1577
+ initialText.current = void 0;
1578
+ model.setValue(cell, value2 ?? null);
1579
+ const next = handleArrowNav({
1580
+ key,
1581
+ metaKey: false
1582
+ }, cursor, size);
1583
+ if (next) {
1584
+ setCursor(next);
1585
+ }
1586
+ inputRef.current?.focus();
1587
+ setEditing(false);
1588
+ };
1589
+ return /* @__PURE__ */ React3.createElement(GridCellEditor, {
1590
+ key: idx,
1591
+ value,
1592
+ style,
1593
+ onNav: quickEdit.current ? handleNav2 : void 0,
1594
+ onClose: handleClose
1595
+ });
1596
+ }
1597
+ return /* @__PURE__ */ React3.createElement(SheetCell, {
1598
+ key: id2,
1599
+ id: id2,
1600
+ cell,
1601
+ active,
1602
+ style,
1603
+ onSelect: (cell2, edit) => {
1604
+ setEditing(edit);
1605
+ setCursor(cell2);
1606
+ }
1607
+ });
1608
+ });
1609
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement("input", {
1610
+ ref: inputRef,
1611
+ autoFocus: true,
1612
+ className: "absolute w-[1px] h-[1px] bg-transparent outline-none border-none caret-transparent",
1613
+ onKeyDown: handleKeyDown,
1614
+ ...attendableAttrs
1615
+ }), document.body));
1616
+ });
1617
+ var SelectionOverlay = ({ root }) => {
1618
+ const { range } = useSheetContext();
1619
+ if (!range) {
1620
+ return null;
1621
+ }
1622
+ const c1 = getCellElement(root, range.from);
1623
+ const c2 = range.to ? getCellElement(root, range.to) : c1;
1624
+ if (!c1 || !c2) {
1625
+ return null;
1626
+ }
1627
+ const b1 = getRelativeClientRect(root, c1);
1628
+ const b2 = getRelativeClientRect(root, c2);
1629
+ const bounds = getRectUnion(b1, b2);
1630
+ return /* @__PURE__ */ React3.createElement("div", {
1631
+ role: "none",
1632
+ style: bounds,
1633
+ className: "z-10 absolute pointer-events-none bg-gridSelectionOverlay border border-gridOverlay"
1634
+ });
1635
+ };
1636
+ var SheetCell = ({ id, cell, style, active, onSelect }) => {
1637
+ const { formatting, editing, setRange } = useSheetContext();
1638
+ const { value, classNames } = formatting.getFormatting(cell);
1639
+ return /* @__PURE__ */ React3.createElement("div", {
1640
+ [`data-${CELL_DATA_KEY}`]: id,
1641
+ role: "cell",
1642
+ style,
1643
+ className: mx2("flex w-full h-full px-2 py-1 truncate items-center border border-gridLine cursor-pointer", fragments.cell, active && [
1644
+ "z-20",
1645
+ fragments.cellSelected
1646
+ ], classNames),
1647
+ onClick: () => {
1648
+ if (editing) {
1649
+ setRange?.({
1650
+ from: cell
1651
+ });
1652
+ } else {
1653
+ onSelect?.(cell, false);
1654
+ }
1655
+ },
1656
+ onDoubleClick: () => onSelect?.(cell, true)
1657
+ }, value);
1658
+ };
1659
+ var GridCellEditor = ({ style, value, onNav, onClose }) => {
1660
+ const { model, range } = useSheetContext();
1661
+ const notifier = useRef();
1662
+ useEffect3(() => {
1663
+ if (range) {
1664
+ notifier.current?.(rangeToA1Notation(range));
1665
+ }
1666
+ }, [
1667
+ range
1668
+ ]);
1669
+ const extension = useMemo(() => [
1670
+ editorKeys({
1671
+ onNav,
1672
+ onClose
1673
+ }),
1674
+ sheetExtension({
1675
+ functions: model.functions
1676
+ }),
1677
+ rangeExtension((fn) => notifier.current = fn)
1678
+ ], [
1679
+ model
1680
+ ]);
1681
+ return /* @__PURE__ */ React3.createElement("div", {
1682
+ role: "cell",
1683
+ style,
1684
+ className: mx2("z-20 flex", fragments.cellSelected),
1685
+ onClick: (ev) => ev.stopPropagation()
1686
+ }, /* @__PURE__ */ React3.createElement(CellEditor, {
1687
+ autoFocus: true,
1688
+ value,
1689
+ extension
1690
+ }));
1691
+ };
1692
+ var SheetStatusBar = () => {
1693
+ const { model, cursor, range } = useSheetContext();
1694
+ let value;
1695
+ let isFormula = false;
1696
+ if (cursor) {
1697
+ value = model.getCellValue(cursor);
1698
+ if (typeof value === "string" && value.charAt(0) === "=") {
1699
+ value = model.mapFormulaBindingFromId(model.mapFormulaIndicesToRefs(value));
1700
+ isFormula = true;
1701
+ } else if (value != null) {
1702
+ value = String(value);
1703
+ }
1704
+ }
1705
+ return /* @__PURE__ */ React3.createElement("div", {
1706
+ className: mx2("flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x border-gridLine")
1707
+ }, /* @__PURE__ */ React3.createElement("div", {
1708
+ className: "flex gap-4 items-center"
1709
+ }, /* @__PURE__ */ React3.createElement("div", {
1710
+ className: "flex w-16 items-center font-mono"
1711
+ }, range && rangeToA1Notation(range) || cursor && addressToA1Notation(cursor)), /* @__PURE__ */ React3.createElement("div", {
1712
+ className: "flex gap-2 items-center"
1713
+ }, /* @__PURE__ */ React3.createElement(FunctionIcon, {
1714
+ className: mx2("text-greenText", isFormula ? "visible" : "invisible")
1715
+ }), /* @__PURE__ */ React3.createElement("span", {
1716
+ className: "font-mono"
1717
+ }, value))));
1718
+ };
1719
+ var SheetDebug = () => {
1720
+ const { model, cursor, range } = useSheetContext();
1721
+ const [, forceUpdate] = useState4({});
1722
+ useEffect3(() => {
1723
+ const accessor = createDocAccessor(model.sheet, []);
1724
+ const handleUpdate = () => forceUpdate({});
1725
+ accessor.handle.addListener("change", handleUpdate);
1726
+ handleUpdate();
1727
+ return () => {
1728
+ accessor.handle.removeListener("change", handleUpdate);
1729
+ };
1730
+ }, [
1731
+ model
1732
+ ]);
1733
+ return /* @__PURE__ */ React3.createElement("div", {
1734
+ className: mx2("z-20 absolute right-0 top-20 bottom-20 w-[30rem] overflow-auto scrollbar-thin", "border border-gridLine text-xs bg-neutral-50 dark:bg-black text-cyan-500 font-mono p-1 opacity-80")
1735
+ }, /* @__PURE__ */ React3.createElement("pre", {
1736
+ className: "whitespace-pre-wrap"
1737
+ }, JSON.stringify({
1738
+ cursor,
1739
+ range,
1740
+ cells: model.sheet.cells,
1741
+ rowMeta: model.sheet.rowMeta,
1742
+ columnMeta: model.sheet.columnMeta,
1743
+ formatting: model.sheet.formatting
1744
+ }, void 0, 2)));
1745
+ };
1746
+ var Sheet = {
1747
+ Root: SheetRoot,
1748
+ Main: SheetMain,
1749
+ Rows: SheetRows,
1750
+ Columns: SheetColumns,
1751
+ Grid: SheetGrid,
1752
+ Cell: SheetCell,
1753
+ StatusBar: SheetStatusBar,
1754
+ Debug: SheetDebug
1755
+ };
1756
+
1757
+ // packages/plugins/plugin-sheet/src/components/SheetContainer.tsx
1758
+ var SheetContainer = ({ sheet, space, role, remoteFunctionUrl }) => {
1759
+ return /* @__PURE__ */ React4.createElement("div", {
1760
+ role: "none",
1761
+ className: mx3("flex", role === "article" && "row-span-2", role === "section" && "aspect-square border-y border-is border-separator")
1762
+ }, /* @__PURE__ */ React4.createElement(Sheet.Root, {
1763
+ sheet,
1764
+ space,
1765
+ remoteFunctionUrl
1766
+ }, /* @__PURE__ */ React4.createElement(Sheet.Main, null)));
1767
+ };
1768
+ var SheetContainer_default = SheetContainer;
1769
+ export {
1770
+ SheetContainer_default as default
1771
+ };
1772
+ //# sourceMappingURL=SheetContainer-U4H5D34A.mjs.map