@dxos/plugin-sheet 0.6.11 → 0.6.12-main.568932b

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 (277) hide show
  1. package/dist/lib/browser/SheetContainer-T2QWJOFD.mjs +262 -0
  2. package/dist/lib/browser/SheetContainer-T2QWJOFD.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-FUAGSXA4.mjs → chunk-5ZMVZYGB.mjs} +24 -19
  4. package/dist/lib/browser/chunk-5ZMVZYGB.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-GSV5QNLD.mjs +2966 -0
  6. package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-JRL5LGCE.mjs → chunk-QILRZNE5.mjs} +2 -5
  8. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +7 -0
  9. package/dist/lib/browser/{SheetContainer-U4H5D34A.mjs → chunk-ZL2V5UJR.mjs} +1182 -249
  10. package/dist/lib/browser/chunk-ZL2V5UJR.mjs.map +7 -0
  11. package/dist/lib/browser/graph-M4IQ76QX.mjs +33 -0
  12. package/dist/lib/browser/graph-M4IQ76QX.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +96 -60
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/meta.mjs +1 -1
  17. package/dist/lib/browser/types.mjs +4 -6
  18. package/dist/lib/node/SheetContainer-PV5ET4UJ.cjs +280 -0
  19. package/dist/lib/node/SheetContainer-PV5ET4UJ.cjs.map +7 -0
  20. package/dist/lib/node/{SheetContainer-AXQV3ZT5.cjs → chunk-2K53Z2TU.cjs} +1212 -287
  21. package/dist/lib/node/chunk-2K53Z2TU.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-5KKJ4NPP.cjs → chunk-5XPK2V4A.cjs} +418 -678
  23. package/dist/lib/node/chunk-5XPK2V4A.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-BJ6ZD7MN.cjs → chunk-BNARJ5GM.cjs} +5 -18
  25. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +7 -0
  26. package/dist/lib/node/{chunk-DSYKOI4E.cjs → chunk-STAVQ2JE.cjs} +28 -24
  27. package/dist/lib/node/chunk-STAVQ2JE.cjs.map +7 -0
  28. package/dist/lib/node/graph-Q3N2X26H.cjs +55 -0
  29. package/dist/lib/node/graph-Q3N2X26H.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +106 -66
  31. package/dist/lib/node/index.cjs.map +4 -4
  32. package/dist/lib/node/meta.cjs +3 -3
  33. package/dist/lib/node/meta.cjs.map +1 -1
  34. package/dist/lib/node/meta.json +1 -1
  35. package/dist/lib/node/types.cjs +10 -12
  36. package/dist/lib/node/types.cjs.map +2 -2
  37. package/dist/lib/node-esm/SheetContainer-FOZD2WLT.mjs +263 -0
  38. package/dist/lib/node-esm/SheetContainer-FOZD2WLT.mjs.map +7 -0
  39. package/dist/lib/node-esm/chunk-2HAM45RC.mjs +88 -0
  40. package/dist/lib/node-esm/chunk-2HAM45RC.mjs.map +7 -0
  41. package/dist/lib/{browser/chunk-D5AGLXJP.mjs → node-esm/chunk-5WPZCXNS.mjs} +411 -678
  42. package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +7 -0
  43. package/dist/lib/node-esm/chunk-IU2L277A.mjs +17 -0
  44. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +7 -0
  45. package/dist/lib/node-esm/chunk-QEUCIHIN.mjs +2706 -0
  46. package/dist/lib/node-esm/chunk-QEUCIHIN.mjs.map +7 -0
  47. package/dist/lib/node-esm/graph-SMPUMOV2.mjs +34 -0
  48. package/dist/lib/node-esm/graph-SMPUMOV2.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +285 -0
  50. package/dist/lib/node-esm/index.mjs.map +7 -0
  51. package/dist/lib/node-esm/meta.json +1 -0
  52. package/dist/lib/node-esm/meta.mjs +10 -0
  53. package/dist/lib/node-esm/meta.mjs.map +7 -0
  54. package/dist/lib/node-esm/types.mjs +21 -0
  55. package/dist/lib/node-esm/types.mjs.map +7 -0
  56. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  57. package/dist/types/src/components/CellEditor/CellEditor.d.ts +23 -3
  58. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -1
  59. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts +2 -2
  60. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -1
  61. package/dist/types/src/components/CellEditor/extension.d.ts +1 -1
  62. package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
  63. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +11 -0
  64. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -0
  65. package/dist/types/src/components/ComputeGraph/index.d.ts +1 -3
  66. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  67. package/dist/types/src/components/GridSheet/GridSheet.d.ts +10 -0
  68. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -0
  69. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +9 -0
  70. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -0
  71. package/dist/types/src/components/GridSheet/util.d.ts +16 -0
  72. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -0
  73. package/dist/types/src/components/Sheet/Sheet.d.ts +1 -1
  74. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  75. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +5 -6
  76. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/Sheet/decorations.d.ts +24 -0
  78. package/dist/types/src/components/Sheet/decorations.d.ts.map +1 -0
  79. package/dist/types/src/components/Sheet/grid.d.ts +2 -2
  80. package/dist/types/src/components/Sheet/grid.d.ts.map +1 -1
  81. package/dist/types/src/components/Sheet/nav.d.ts +3 -3
  82. package/dist/types/src/components/Sheet/nav.d.ts.map +1 -1
  83. package/dist/types/src/components/Sheet/sheet-context.d.ts +8 -7
  84. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
  85. package/dist/types/src/components/Sheet/threads.d.ts +2 -0
  86. package/dist/types/src/components/Sheet/threads.d.ts.map +1 -0
  87. package/dist/types/src/components/SheetContainer.d.ts +2 -3
  88. package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
  89. package/dist/types/src/components/Toolbar/Toolbar.d.ts +19 -3
  90. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  91. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +18 -13
  92. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/index.d.ts +2 -2
  94. package/dist/types/src/components/index.d.ts.map +1 -1
  95. package/dist/types/src/defs/index.d.ts +3 -0
  96. package/dist/types/src/defs/index.d.ts.map +1 -0
  97. package/dist/types/src/{model → defs}/types.d.ts +8 -3
  98. package/dist/types/src/defs/types.d.ts.map +1 -0
  99. package/dist/types/src/defs/types.test.d.ts.map +1 -0
  100. package/dist/types/src/defs/util.d.ts +43 -0
  101. package/dist/types/src/defs/util.d.ts.map +1 -0
  102. package/dist/types/src/extensions/compute.d.ts +6 -0
  103. package/dist/types/src/extensions/compute.d.ts.map +1 -0
  104. package/dist/types/src/extensions/compute.stories.d.ts +26 -0
  105. package/dist/types/src/extensions/compute.stories.d.ts.map +1 -0
  106. package/dist/types/src/extensions/index.d.ts +2 -0
  107. package/dist/types/src/extensions/index.d.ts.map +1 -0
  108. package/dist/types/src/graph/compute-graph-registry.d.ts +34 -0
  109. package/dist/types/src/graph/compute-graph-registry.d.ts.map +1 -0
  110. package/dist/types/src/graph/compute-graph.d.ts +64 -0
  111. package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
  112. package/dist/types/src/graph/compute-graph.stories.d.ts +10 -0
  113. package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
  114. package/dist/types/src/graph/compute-graph.test.d.ts +2 -0
  115. package/dist/types/src/graph/compute-graph.test.d.ts.map +1 -0
  116. package/dist/types/src/graph/compute-node.d.ts +26 -0
  117. package/dist/types/src/graph/compute-node.d.ts.map +1 -0
  118. package/dist/types/src/{components/ComputeGraph → graph/functions}/async-function.d.ts +14 -5
  119. package/dist/types/src/graph/functions/async-function.d.ts.map +1 -0
  120. package/dist/types/src/graph/functions/edge-function.d.ts +21 -0
  121. package/dist/types/src/graph/functions/edge-function.d.ts.map +1 -0
  122. package/dist/types/src/{model/functions.d.ts → graph/functions/function-defs.d.ts} +1 -1
  123. package/dist/types/src/graph/functions/function-defs.d.ts.map +1 -0
  124. package/dist/types/src/graph/functions/index.d.ts +4 -0
  125. package/dist/types/src/graph/functions/index.d.ts.map +1 -0
  126. package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
  127. package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
  128. package/dist/types/src/graph/index.d.ts +5 -0
  129. package/dist/types/src/graph/index.d.ts.map +1 -0
  130. package/dist/types/src/graph/testing/index.d.ts +3 -0
  131. package/dist/types/src/graph/testing/index.d.ts.map +1 -0
  132. package/dist/types/src/graph/testing/test-builder.d.ts +15 -0
  133. package/dist/types/src/graph/testing/test-builder.d.ts.map +1 -0
  134. package/dist/types/src/graph/testing/test-plugin.d.ts +36 -0
  135. package/dist/types/src/graph/testing/test-plugin.d.ts.map +1 -0
  136. package/dist/types/src/graph/util.d.ts +2 -0
  137. package/dist/types/src/graph/util.d.ts.map +1 -0
  138. package/dist/types/src/hooks/hooks.stories.d.ts +11 -0
  139. package/dist/types/src/hooks/hooks.stories.d.ts.map +1 -0
  140. package/dist/types/src/hooks/index.d.ts +4 -0
  141. package/dist/types/src/hooks/index.d.ts.map +1 -0
  142. package/dist/types/src/hooks/useComputeGraph.d.ts +7 -0
  143. package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -0
  144. package/dist/types/src/hooks/useFormattingModel.d.ts +3 -0
  145. package/dist/types/src/hooks/useFormattingModel.d.ts.map +1 -0
  146. package/dist/types/src/hooks/useSheetModel.d.ts +8 -0
  147. package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -0
  148. package/dist/types/src/meta.d.ts +1 -4
  149. package/dist/types/src/meta.d.ts.map +1 -1
  150. package/dist/types/src/model/formatting-model.d.ts +16 -0
  151. package/dist/types/src/model/formatting-model.d.ts.map +1 -0
  152. package/dist/types/src/model/index.d.ts +2 -3
  153. package/dist/types/src/model/index.d.ts.map +1 -1
  154. package/dist/types/src/model/{model.d.ts → sheet-model.d.ts} +10 -65
  155. package/dist/types/src/model/sheet-model.d.ts.map +1 -0
  156. package/dist/types/src/model/sheet-model.test.d.ts +2 -0
  157. package/dist/types/src/model/sheet-model.test.d.ts.map +1 -0
  158. package/dist/types/src/sanity.test.d.ts +2 -0
  159. package/dist/types/src/sanity.test.d.ts.map +1 -0
  160. package/dist/types/src/testing/index.d.ts +2 -0
  161. package/dist/types/src/testing/index.d.ts.map +1 -0
  162. package/dist/types/src/testing/testing.d.ts +8 -0
  163. package/dist/types/src/testing/testing.d.ts.map +1 -0
  164. package/dist/types/src/translations.d.ts +17 -12
  165. package/dist/types/src/translations.d.ts.map +1 -1
  166. package/dist/types/src/types.d.ts +86 -5
  167. package/dist/types/src/types.d.ts.map +1 -1
  168. package/dist/vendor/hyperformula.mjs +37145 -0
  169. package/package.json +55 -47
  170. package/src/SheetPlugin.tsx +50 -73
  171. package/src/components/CellEditor/CellEditor.stories.tsx +6 -6
  172. package/src/components/CellEditor/CellEditor.tsx +59 -9
  173. package/src/components/CellEditor/extension.test.ts +4 -6
  174. package/src/components/CellEditor/extension.ts +5 -6
  175. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +20 -0
  176. package/src/components/ComputeGraph/index.ts +1 -3
  177. package/src/components/GridSheet/GridSheet.stories.tsx +36 -0
  178. package/src/components/GridSheet/GridSheet.tsx +171 -0
  179. package/src/components/GridSheet/util.ts +148 -0
  180. package/src/components/Sheet/Sheet.stories.tsx +52 -88
  181. package/src/components/Sheet/Sheet.tsx +87 -32
  182. package/src/components/Sheet/decorations.ts +62 -0
  183. package/src/components/Sheet/grid.ts +3 -3
  184. package/src/components/Sheet/nav.ts +19 -19
  185. package/src/components/Sheet/sheet-context.tsx +18 -80
  186. package/src/components/Sheet/threads.tsx +205 -0
  187. package/src/components/SheetContainer.tsx +68 -16
  188. package/src/components/Toolbar/Toolbar.tsx +53 -12
  189. package/src/components/index.ts +1 -0
  190. package/src/defs/index.ts +6 -0
  191. package/src/{model → defs}/types.test.ts +8 -9
  192. package/src/{model → defs}/types.ts +24 -14
  193. package/src/defs/util.ts +151 -0
  194. package/src/extensions/compute.stories.tsx +151 -0
  195. package/src/extensions/compute.ts +147 -0
  196. package/src/extensions/index.ts +5 -0
  197. package/src/graph/compute-graph-registry.ts +90 -0
  198. package/src/graph/compute-graph.stories.tsx +93 -0
  199. package/src/graph/compute-graph.test.ts +87 -0
  200. package/src/graph/compute-graph.ts +242 -0
  201. package/src/graph/compute-node.ts +63 -0
  202. package/src/{components/ComputeGraph → graph/functions}/async-function.ts +25 -15
  203. package/src/{components/ComputeGraph → graph/functions}/edge-function.ts +16 -14
  204. package/src/graph/functions/index.ts +7 -0
  205. package/src/graph/hyperformula.test.ts +14 -0
  206. package/src/graph/index.ts +8 -0
  207. package/src/graph/testing/index.ts +6 -0
  208. package/src/graph/testing/test-builder.ts +54 -0
  209. package/src/{components/ComputeGraph/custom.ts → graph/testing/test-plugin.ts} +44 -14
  210. package/src/graph/util.ts +8 -0
  211. package/src/hooks/hooks.stories.tsx +50 -0
  212. package/src/hooks/index.ts +7 -0
  213. package/src/hooks/useComputeGraph.ts +28 -0
  214. package/src/hooks/useFormattingModel.ts +11 -0
  215. package/src/hooks/useSheetModel.ts +40 -0
  216. package/src/meta.tsx +1 -5
  217. package/src/{components/Sheet/formatting.ts → model/formatting-model.ts} +20 -13
  218. package/src/model/index.ts +2 -3
  219. package/src/model/sheet-model.test.ts +57 -0
  220. package/src/model/sheet-model.ts +416 -0
  221. package/src/sanity.test.ts +40 -0
  222. package/src/testing/index.ts +5 -0
  223. package/src/testing/testing.tsx +68 -0
  224. package/src/translations.ts +6 -1
  225. package/src/types.ts +35 -10
  226. package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +0 -7
  227. package/dist/lib/browser/chunk-APHOLYUB.mjs +0 -175
  228. package/dist/lib/browser/chunk-APHOLYUB.mjs.map +0 -7
  229. package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +0 -7
  230. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +0 -7
  231. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
  232. package/dist/lib/browser/chunk-NU4PBN33.mjs +0 -8
  233. package/dist/lib/browser/chunk-NU4PBN33.mjs.map +0 -7
  234. package/dist/lib/browser/testing.mjs +0 -92
  235. package/dist/lib/browser/testing.mjs.map +0 -7
  236. package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +0 -7
  237. package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +0 -7
  238. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
  239. package/dist/lib/node/chunk-CN3RPESU.cjs +0 -202
  240. package/dist/lib/node/chunk-CN3RPESU.cjs.map +0 -7
  241. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +0 -7
  242. package/dist/lib/node/chunk-PYXHNAAK.cjs +0 -40
  243. package/dist/lib/node/chunk-PYXHNAAK.cjs.map +0 -7
  244. package/dist/lib/node/testing.cjs +0 -111
  245. package/dist/lib/node/testing.cjs.map +0 -7
  246. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
  247. package/dist/types/src/components/ComputeGraph/custom.d.ts +0 -21
  248. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
  249. package/dist/types/src/components/ComputeGraph/edge-function.d.ts +0 -20
  250. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
  251. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
  252. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
  253. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
  254. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
  255. package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
  256. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
  257. package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
  258. package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
  259. package/dist/types/src/model/functions.d.ts.map +0 -1
  260. package/dist/types/src/model/model.browser.test.d.ts +0 -2
  261. package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
  262. package/dist/types/src/model/model.d.ts.map +0 -1
  263. package/dist/types/src/model/types.d.ts.map +0 -1
  264. package/dist/types/src/model/types.test.d.ts.map +0 -1
  265. package/dist/types/src/model/util.d.ts +0 -15
  266. package/dist/types/src/model/util.d.ts.map +0 -1
  267. package/dist/types/src/testing.d.ts +0 -9
  268. package/dist/types/src/testing.d.ts.map +0 -1
  269. package/src/components/ComputeGraph/graph-context.tsx +0 -50
  270. package/src/components/ComputeGraph/graph.browser.test.ts +0 -50
  271. package/src/components/ComputeGraph/graph.ts +0 -62
  272. package/src/model/model.browser.test.ts +0 -100
  273. package/src/model/model.ts +0 -550
  274. package/src/model/util.ts +0 -36
  275. package/src/testing.ts +0 -50
  276. /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
  277. /package/src/{model/functions.ts → graph/functions/function-defs.ts} +0 -0
@@ -1,24 +1,13 @@
1
1
  import {
2
- useComputeGraph
3
- } from "./chunk-APHOLYUB.mjs";
2
+ SheetType,
3
+ ValueTypeEnum
4
+ } from "./chunk-5ZMVZYGB.mjs";
4
5
  import {
5
- SheetModel,
6
- addressFromA1Notation,
7
- addressToA1Notation,
8
- columnLetter,
9
- defaultFunctions,
10
- inRange,
11
- posEquals,
12
- rangeToA1Notation
13
- } from "./chunk-D5AGLXJP.mjs";
6
+ SHEET_PLUGIN
7
+ } from "./chunk-QILRZNE5.mjs";
14
8
  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";
9
+ createSheetName
10
+ } from "./chunk-GSV5QNLD.mjs";
22
11
 
23
12
  // packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx
24
13
  import { DndContext, DragOverlay, KeyboardSensor, MouseSensor, TouchSensor, useDraggable, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
@@ -26,17 +15,183 @@ import { restrictToHorizontalAxis, restrictToVerticalAxis } from "@dnd-kit/modif
26
15
  import { getEventCoordinates, useCombinedRefs } from "@dnd-kit/utilities";
27
16
  import { Function as FunctionIcon } from "@phosphor-icons/react";
28
17
  import { Resizable } from "re-resizable";
29
- import React3, { forwardRef, useEffect as useEffect3, useImperativeHandle, useMemo, useRef, useState as useState4 } from "react";
18
+ import React6, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo4, useRef, useState as useState5 } from "react";
30
19
  import { createPortal } from "react-dom";
31
20
  import { useResizeDetector } from "react-resize-detector";
32
- import { debounce } from "@dxos/async";
21
+ import { debounce as debounce2 } from "@dxos/async";
33
22
  import { fullyQualifiedId as fullyQualifiedId2, createDocAccessor } from "@dxos/client/echo";
34
- import { log } from "@dxos/log";
35
- import { createAttendableAttributes, useHasAttention } from "@dxos/react-ui-attention";
23
+ import { log as log2 } from "@dxos/log";
24
+ import { ATTENABLE_ATTRIBUTE, useAttendableAttributes, useAttention, useAttentionPath } from "@dxos/react-ui-attention";
36
25
  import { mx as mx2 } from "@dxos/react-ui-theme";
37
26
 
38
27
  // packages/plugins/plugin-sheet/src/components/Sheet/grid.ts
39
28
  import { useEffect, useState } from "react";
29
+
30
+ // packages/plugins/plugin-sheet/src/defs/types.ts
31
+ import { invariant } from "@dxos/invariant";
32
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/defs/types.ts";
33
+ var DEFAULT_ROWS = 50;
34
+ var DEFAULT_COLUMNS = 26;
35
+ var MAX_ROWS = 500;
36
+ var MAX_COLUMNS = 26 * 2;
37
+ var posEquals = (a, b) => {
38
+ return a?.col === b?.col && a?.row === b?.row;
39
+ };
40
+ var columnLetter = (col) => {
41
+ invariant(col < MAX_COLUMNS, `Invalid column: ${col}`, {
42
+ F: __dxlog_file,
43
+ L: 26,
44
+ S: void 0,
45
+ A: [
46
+ "col < MAX_COLUMNS",
47
+ "`Invalid column: ${col}`"
48
+ ]
49
+ });
50
+ return (col >= 26 ? String.fromCharCode("A".charCodeAt(0) + Math.floor(col / 26) - 1) : "") + String.fromCharCode("A".charCodeAt(0) + col % 26);
51
+ };
52
+ var addressToA1Notation = ({ col, row }) => {
53
+ return `${columnLetter(col)}${row + 1}`;
54
+ };
55
+ var addressFromA1Notation = (ref) => {
56
+ const match = ref.match(/([A-Z]+)(\d+)/);
57
+ invariant(match, `Invalid notation: ${ref}`, {
58
+ F: __dxlog_file,
59
+ L: 40,
60
+ S: void 0,
61
+ A: [
62
+ "match",
63
+ "`Invalid notation: ${ref}`"
64
+ ]
65
+ });
66
+ return {
67
+ row: parseInt(match[2], 10) - 1,
68
+ col: match[1].split("").reduce((acc, c) => acc * 26 + c.charCodeAt(0) - "A".charCodeAt(0) + 1, 0) - 1
69
+ };
70
+ };
71
+ var rangeToA1Notation = (range) => {
72
+ return [
73
+ range?.from && addressToA1Notation(range?.from),
74
+ range?.to && addressToA1Notation(range?.to)
75
+ ].filter(Boolean).join(":");
76
+ };
77
+ var inRange = (range, cell) => {
78
+ if (!range) {
79
+ return false;
80
+ }
81
+ const { from, to } = range;
82
+ if (from && posEquals(from, cell) || to && posEquals(to, cell)) {
83
+ return true;
84
+ }
85
+ if (!from || !to) {
86
+ return false;
87
+ }
88
+ const { col: c1, row: r1 } = from;
89
+ const { col: c2, row: r2 } = to;
90
+ const cMin = Math.min(c1, c2);
91
+ const cMax = Math.max(c1, c2);
92
+ const rMin = Math.min(r1, r2);
93
+ const rMax = Math.max(r1, r2);
94
+ const { col, row } = cell;
95
+ return col >= cMin && col <= cMax && row >= rMin && row <= rMax;
96
+ };
97
+
98
+ // packages/plugins/plugin-sheet/src/defs/util.ts
99
+ import { randomBytes } from "@dxos/crypto";
100
+ import { create } from "@dxos/echo-schema";
101
+ var ApiError = class extends Error {
102
+ };
103
+ var ReadonlyException = class extends ApiError {
104
+ };
105
+ var RangeException = class extends ApiError {
106
+ constructor(n) {
107
+ super();
108
+ }
109
+ };
110
+ var createIndex = (length = 8) => {
111
+ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
112
+ const charactersLength = characters.length;
113
+ const randomBuffer = randomBytes(length);
114
+ return Array.from(randomBuffer, (byte) => characters[byte % charactersLength]).join("");
115
+ };
116
+ var createIndices = (length) => Array.from({
117
+ length
118
+ }).map(() => createIndex());
119
+ var insertIndices = (indices, i, n, max) => {
120
+ if (i + n > max) {
121
+ throw new RangeException(i + n);
122
+ }
123
+ const idx = createIndices(n);
124
+ indices.splice(i, 0, ...idx);
125
+ };
126
+ var initialize = (sheet, { rows = DEFAULT_ROWS, columns = DEFAULT_COLUMNS } = {}) => {
127
+ if (!sheet.rows.length) {
128
+ insertIndices(sheet.rows, 0, rows, MAX_ROWS);
129
+ }
130
+ if (!sheet.columns.length) {
131
+ insertIndices(sheet.columns, 0, columns, MAX_COLUMNS);
132
+ }
133
+ };
134
+ var createSheet = ({ name, cells, ...size } = {}) => {
135
+ const sheet = create(SheetType, {
136
+ name,
137
+ cells: {},
138
+ rows: [],
139
+ columns: [],
140
+ rowMeta: {},
141
+ columnMeta: {},
142
+ formatting: {}
143
+ });
144
+ initialize(sheet, size);
145
+ if (cells) {
146
+ Object.entries(cells).forEach(([key, { value }]) => {
147
+ const idx = addressToIndex(sheet, addressFromA1Notation(key));
148
+ sheet.cells[idx] = {
149
+ value
150
+ };
151
+ });
152
+ }
153
+ return sheet;
154
+ };
155
+ var addressToIndex = (sheet, cell) => {
156
+ return `${sheet.columns[cell.col]}@${sheet.rows[cell.row]}`;
157
+ };
158
+ var addressFromIndex = (sheet, idx) => {
159
+ const [column, row] = idx.split("@");
160
+ return {
161
+ col: sheet.columns.indexOf(column),
162
+ row: sheet.rows.indexOf(row)
163
+ };
164
+ };
165
+ var rangeFromIndex = (sheet, idx) => {
166
+ const [from, to] = idx.split(":").map((index) => addressFromIndex(sheet, index));
167
+ return {
168
+ from,
169
+ to
170
+ };
171
+ };
172
+ var closest = (cursor, cells) => {
173
+ let closestCell;
174
+ let closestDistance = Number.MAX_SAFE_INTEGER;
175
+ for (const cell of cells) {
176
+ const distance = Math.abs(cell.row - cursor.row) + Math.abs(cell.col - cursor.col);
177
+ if (distance < closestDistance) {
178
+ closestCell = cell;
179
+ closestDistance = distance;
180
+ }
181
+ }
182
+ return closestCell;
183
+ };
184
+ var compareIndexPositions = (sheet, indexA, indexB) => {
185
+ const { row: rowA, col: columnA } = addressFromIndex(sheet, indexA);
186
+ const { row: rowB, col: columnB } = addressFromIndex(sheet, indexB);
187
+ if (rowA !== rowB) {
188
+ return rowA - rowB;
189
+ } else {
190
+ return columnA - columnB;
191
+ }
192
+ };
193
+
194
+ // packages/plugins/plugin-sheet/src/components/Sheet/grid.ts
40
195
  var axisWidth = "calc(var(--rail-size)-2px)";
41
196
  var axisHeight = 34;
42
197
  var minWidth = 40;
@@ -78,7 +233,7 @@ var useGridLayout = ({ scroller, size, rows, columns, rowSizes, columnSizes }) =
78
233
  const left = x;
79
234
  x += width2 - 1;
80
235
  return {
81
- column: i,
236
+ col: i,
82
237
  left,
83
238
  width: width2
84
239
  };
@@ -183,14 +338,14 @@ var handleNav = (ev, cursor, range, size) => {
183
338
  break;
184
339
  }
185
340
  case "ArrowLeft": {
186
- if (opposite.column > 0) {
187
- opposite.column -= 1;
341
+ if (opposite.col > 0) {
342
+ opposite.col -= 1;
188
343
  }
189
344
  break;
190
345
  }
191
346
  case "ArrowRight": {
192
- if (opposite.column < size.numColumns - 1) {
193
- opposite.column += 1;
347
+ if (opposite.col < size.numCols - 1) {
348
+ opposite.col += 1;
194
349
  }
195
350
  break;
196
351
  }
@@ -208,18 +363,18 @@ var handleNav = (ev, cursor, range, size) => {
208
363
  cursor: next
209
364
  };
210
365
  };
211
- var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
366
+ var handleArrowNav = (ev, cursor, { numRows, numCols }) => {
212
367
  switch (ev.key) {
213
368
  case "ArrowUp":
214
369
  if (cursor === void 0) {
215
370
  return {
216
371
  row: 0,
217
- column: 0
372
+ col: 0
218
373
  };
219
374
  } else if (cursor.row > 0) {
220
375
  return {
221
376
  row: ev.metaKey ? 0 : cursor.row - 1,
222
- column: cursor.column
377
+ col: cursor.col
223
378
  };
224
379
  }
225
380
  break;
@@ -227,12 +382,12 @@ var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
227
382
  if (cursor === void 0) {
228
383
  return {
229
384
  row: 0,
230
- column: 0
385
+ col: 0
231
386
  };
232
387
  } else if (cursor.row < numRows - 1) {
233
388
  return {
234
389
  row: ev.metaKey ? numRows - 1 : cursor.row + 1,
235
- column: cursor.column
390
+ col: cursor.col
236
391
  };
237
392
  }
238
393
  break;
@@ -240,12 +395,12 @@ var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
240
395
  if (cursor === void 0) {
241
396
  return {
242
397
  row: 0,
243
- column: 0
398
+ col: 0
244
399
  };
245
- } else if (cursor.column > 0) {
400
+ } else if (cursor.col > 0) {
246
401
  return {
247
402
  row: cursor.row,
248
- column: ev.metaKey ? 0 : cursor.column - 1
403
+ col: ev.metaKey ? 0 : cursor.col - 1
249
404
  };
250
405
  }
251
406
  break;
@@ -253,24 +408,24 @@ var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
253
408
  if (cursor === void 0) {
254
409
  return {
255
410
  row: 0,
256
- column: 0
411
+ col: 0
257
412
  };
258
- } else if (cursor.column < numColumns - 1) {
413
+ } else if (cursor.col < numCols - 1) {
259
414
  return {
260
415
  row: cursor.row,
261
- column: ev.metaKey ? numColumns - 1 : cursor.column + 1
416
+ col: ev.metaKey ? numCols - 1 : cursor.col + 1
262
417
  };
263
418
  }
264
419
  break;
265
420
  case "Home":
266
421
  return {
267
422
  row: 0,
268
- column: 0
423
+ col: 0
269
424
  };
270
425
  case "End":
271
426
  return {
272
427
  row: numRows - 1,
273
- column: numColumns - 1
428
+ col: numCols - 1
274
429
  };
275
430
  }
276
431
  };
@@ -327,31 +482,110 @@ var useRangeSelect = (cb) => {
327
482
  };
328
483
 
329
484
  // 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";
485
+ import React3, { createContext as createContext2, useContext as useContext2, useMemo as useMemo2, useState as useState4 } from "react";
486
+ import { invariant as invariant3 } from "@dxos/invariant";
487
+
488
+ // packages/plugins/plugin-sheet/src/components/Sheet/decorations.ts
489
+ import { create as create2 } from "@dxos/echo-schema";
490
+ var createDecorations = () => {
491
+ const { decorations } = create2({
492
+ decorations: {}
493
+ });
494
+ const addDecoration = (cellIndex, decorator) => {
495
+ decorations[cellIndex] = [
496
+ ...decorations[cellIndex] || [],
497
+ decorator
498
+ ];
499
+ };
500
+ const removeDecoration = (cellIndex, type) => {
501
+ if (type) {
502
+ decorations[cellIndex] = (decorations[cellIndex] || []).filter((d) => d.type !== type);
503
+ } else {
504
+ delete decorations[cellIndex];
505
+ }
506
+ };
507
+ const getDecorationsForCell = (cellIndex) => {
508
+ return decorations[cellIndex];
509
+ };
510
+ const getAllDecorations = () => {
511
+ const result = [];
512
+ for (const decoratorArray of Object.values(decorations)) {
513
+ for (const decorator of decoratorArray) {
514
+ result.push(decorator);
515
+ }
516
+ }
517
+ return result;
518
+ };
519
+ return {
520
+ addDecoration,
521
+ removeDecoration,
522
+ getDecorationsForCell,
523
+ getAllDecorations
524
+ };
525
+ };
526
+
527
+ // packages/plugins/plugin-sheet/src/hooks/useComputeGraph.ts
528
+ import { useContext } from "react";
529
+ import { raise } from "@dxos/debug";
530
+ import { useAsyncState } from "@dxos/react-hooks";
531
+
532
+ // packages/plugins/plugin-sheet/src/components/index.ts
533
+ import React2 from "react";
534
+
535
+ // packages/plugins/plugin-sheet/src/components/ComputeGraph/ComputeGraphContextProvider.tsx
536
+ import React, { createContext } from "react";
537
+ var ComputeGraphContext = /* @__PURE__ */ createContext(void 0);
538
+ var ComputeGraphContextProvider = ({ registry, children }) => {
539
+ return /* @__PURE__ */ React.createElement(ComputeGraphContext.Provider, {
540
+ value: {
541
+ registry
542
+ }
543
+ }, children);
544
+ };
545
+
546
+ // packages/plugins/plugin-sheet/src/components/index.ts
547
+ var SheetContainer = React2.lazy(() => import("./SheetContainer-T2QWJOFD.mjs"));
548
+
549
+ // packages/plugins/plugin-sheet/src/hooks/useComputeGraph.ts
550
+ var useComputeGraph = (space) => {
551
+ const { registry } = useContext(ComputeGraphContext) ?? raise(new Error("Missing ComputeGraphContext"));
552
+ const [graph] = useAsyncState(async () => {
553
+ if (space) {
554
+ const graph2 = registry.getOrCreateGraph(space);
555
+ await graph2.open();
556
+ return graph2;
557
+ }
558
+ }, [
559
+ space,
560
+ registry
561
+ ]);
562
+ return graph;
563
+ };
333
564
 
334
- // packages/plugins/plugin-sheet/src/components/Sheet/formatting.ts
565
+ // packages/plugins/plugin-sheet/src/hooks/useFormattingModel.ts
566
+ import { useMemo } from "react";
567
+
568
+ // packages/plugins/plugin-sheet/src/model/formatting-model.ts
335
569
  var FormattingModel = class {
336
- constructor(model) {
337
- this.model = model;
570
+ constructor(_model) {
571
+ this._model = _model;
338
572
  }
339
573
  /**
340
574
  * Get formatted string value and className for cell.
341
575
  */
342
576
  getFormatting(cell) {
343
- const value = this.model.getValue(cell);
577
+ const value = this._model.getValue(cell);
344
578
  if (value === void 0 || value === null) {
345
579
  return {};
346
580
  }
347
581
  const locales = void 0;
348
- const idx = this.model.addressToIndex(cell);
349
- let formatting = this.model.sheet.formatting?.[idx] ?? {};
582
+ const idx = addressToIndex(this._model.sheet, cell);
583
+ let formatting = this._model.sheet.formatting?.[idx] ?? {};
350
584
  const classNames = [
351
585
  ...formatting?.classNames ?? []
352
586
  ];
353
- for (const [idx2, _formatting] of Object.entries(this.model.sheet.formatting)) {
354
- const range = this.model.rangeFromIndex(idx2);
587
+ for (const [idx2, _formatting] of Object.entries(this._model.sheet.formatting)) {
588
+ const range = rangeFromIndex(this._model.sheet, idx2);
355
589
  if (inRange(range, cell)) {
356
590
  if (_formatting.classNames) {
357
591
  classNames.push(..._formatting.classNames);
@@ -362,7 +596,7 @@ var FormattingModel = class {
362
596
  }
363
597
  }
364
598
  const defaultNumber = "justify-end font-mono";
365
- const type = formatting?.type ?? this.model.getValueType(cell);
599
+ const type = formatting?.type ?? this._model.getValueType(cell);
366
600
  switch (type) {
367
601
  case ValueTypeEnum.Boolean: {
368
602
  return {
@@ -412,21 +646,21 @@ var FormattingModel = class {
412
646
  // Dates.
413
647
  //
414
648
  case ValueTypeEnum.DateTime: {
415
- const date = this.model.toLocalDate(value);
649
+ const date = this._model.toLocalDate(value);
416
650
  return {
417
651
  value: date.toLocaleString(locales),
418
652
  classNames
419
653
  };
420
654
  }
421
655
  case ValueTypeEnum.Date: {
422
- const date = this.model.toLocalDate(value);
656
+ const date = this._model.toLocalDate(value);
423
657
  return {
424
658
  value: date.toLocaleDateString(locales),
425
659
  classNames
426
660
  };
427
661
  }
428
662
  case ValueTypeEnum.Time: {
429
- const date = this.model.toLocalDate(value);
663
+ const date = this._model.toLocalDate(value);
430
664
  return {
431
665
  value: date.toLocaleTimeString(locales),
432
666
  classNames
@@ -442,84 +676,554 @@ var FormattingModel = class {
442
676
  }
443
677
  };
444
678
 
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;
679
+ // packages/plugins/plugin-sheet/src/model/sheet-model.ts
680
+ import { Event } from "@dxos/async";
681
+ import { Resource } from "@dxos/context";
682
+ import { getTypename } from "@dxos/echo-schema";
683
+ import { invariant as invariant2 } from "@dxos/invariant";
684
+ import { PublicKey } from "@dxos/keys";
685
+ import { log } from "@dxos/log";
686
+ import { DetailedCellError, ExportedCellChange } from "#hyperformula";
687
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/model/sheet-model.ts";
688
+ var typeMap = {
689
+ BOOLEAN: ValueTypeEnum.Boolean,
690
+ NUMBER_RAW: ValueTypeEnum.Number,
691
+ NUMBER_PERCENT: ValueTypeEnum.Percent,
692
+ NUMBER_CURRENCY: ValueTypeEnum.Currency,
693
+ NUMBER_DATETIME: ValueTypeEnum.DateTime,
694
+ NUMBER_DATE: ValueTypeEnum.Date,
695
+ NUMBER_TIME: ValueTypeEnum.Time
461
696
  };
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;
697
+ var getTopLeft = (range) => {
698
+ const to = range.to ?? range.from;
699
+ return {
700
+ row: Math.min(range.from.row, to.row),
701
+ col: Math.min(range.from.col, to.col)
702
+ };
703
+ };
704
+ var toSimpleCellAddress = (sheet, cell) => ({
705
+ sheet,
706
+ row: cell.row,
707
+ col: cell.col
708
+ });
709
+ var toModelRange = (sheet, range) => ({
710
+ start: toSimpleCellAddress(sheet, range.from),
711
+ end: toSimpleCellAddress(sheet, range.to ?? range.from)
712
+ });
713
+ var SheetModel = class extends Resource {
714
+ constructor(_graph, _sheet, _options = {}) {
715
+ super();
716
+ this._graph = _graph;
717
+ this._sheet = _sheet;
718
+ this._options = _options;
719
+ this.id = `model-${PublicKey.random().truncate()}`;
720
+ this.update = new Event();
721
+ }
722
+ get graph() {
723
+ return this._graph;
724
+ }
725
+ get sheet() {
726
+ return this._sheet;
727
+ }
728
+ get readonly() {
729
+ return this._options.readonly;
730
+ }
731
+ get bounds() {
732
+ return {
733
+ rows: this._sheet.rows.length,
734
+ columns: this._sheet.columns.length
735
+ };
736
+ }
737
+ /**
738
+ * Initialize sheet and engine.
739
+ */
740
+ async _open() {
741
+ log("initialize", {
742
+ id: this.id
743
+ }, {
744
+ F: __dxlog_file2,
745
+ L: 104,
746
+ S: this,
747
+ C: (f, a) => f(...a)
748
+ });
749
+ initialize(this._sheet);
750
+ this._node = this._graph.getOrCreateNode(createSheetName({
751
+ type: getTypename(this._sheet),
752
+ id: this._sheet.id
753
+ }));
754
+ await this._node.open();
755
+ const unsubscribe = this._node.update.on((event) => this.update.emit(event));
756
+ this._ctx.onDispose(unsubscribe);
757
+ this.reset();
758
+ }
759
+ /**
760
+ * Update engine.
761
+ * NOTE: This resets the undo history.
762
+ * @deprecated
763
+ */
764
+ reset() {
765
+ invariant2(this._node, void 0, {
766
+ F: __dxlog_file2,
767
+ L: 124,
768
+ S: this,
769
+ A: [
770
+ "this._node",
771
+ ""
772
+ ]
773
+ });
774
+ this._node.graph.hf.clearSheet(this._node.sheetId);
775
+ Object.entries(this._sheet.cells).forEach(([key, { value }]) => {
776
+ invariant2(this._node, void 0, {
777
+ F: __dxlog_file2,
778
+ L: 127,
779
+ S: this,
780
+ A: [
781
+ "this._node",
782
+ ""
783
+ ]
784
+ });
785
+ const { col, row } = addressFromIndex(this._sheet, key);
786
+ if (typeof value === "string" && value.charAt(0) === "=") {
787
+ value = this._graph.mapFormulaToNative(this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value)));
788
+ }
789
+ this._node.graph.hf.setCellContents({
790
+ sheet: this._node.sheetId,
791
+ row,
792
+ col
793
+ }, value);
794
+ });
795
+ }
796
+ /**
797
+ * Recalculate formulas.
798
+ * NOTE: This resets the undo history.
799
+ * https://hyperformula.handsontable.com/guide/volatile-functions.html#volatile-actions
800
+ * @deprecated
801
+ */
802
+ // TODO(burdon): Remove.
803
+ recalculate() {
804
+ this._node?.graph.hf.rebuildAndRecalculate();
805
+ }
806
+ insertRows(i, n = 1) {
807
+ insertIndices(this._sheet.rows, i, n, MAX_ROWS);
808
+ this.reset();
809
+ }
810
+ insertColumns(i, n = 1) {
811
+ insertIndices(this._sheet.columns, i, n, MAX_COLUMNS);
812
+ this.reset();
813
+ }
814
+ //
815
+ // Undoable actions.
816
+ // TODO(burdon): Group undoable methods; consistently update hf/sheet.
817
+ //
818
+ /**
819
+ * Clear range of values.
820
+ */
821
+ clear(range) {
822
+ invariant2(this._node, void 0, {
823
+ F: __dxlog_file2,
824
+ L: 169,
825
+ S: this,
826
+ A: [
827
+ "this._node",
828
+ ""
829
+ ]
830
+ });
831
+ const topLeft = getTopLeft(range);
832
+ const values = this._iterRange(range, () => null);
833
+ this._node.graph.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);
834
+ this._iterRange(range, (cell) => {
835
+ const idx = addressToIndex(this._sheet, cell);
836
+ delete this._sheet.cells[idx];
837
+ });
838
+ }
839
+ cut(range) {
840
+ invariant2(this._node, void 0, {
841
+ F: __dxlog_file2,
842
+ L: 180,
843
+ S: this,
844
+ A: [
845
+ "this._node",
846
+ ""
847
+ ]
848
+ });
849
+ this._node.graph.hf.cut(toModelRange(this._node.sheetId, range));
850
+ this._iterRange(range, (cell) => {
851
+ const idx = addressToIndex(this._sheet, cell);
852
+ delete this._sheet.cells[idx];
853
+ });
854
+ }
855
+ copy(range) {
856
+ invariant2(this._node, void 0, {
857
+ F: __dxlog_file2,
858
+ L: 189,
859
+ S: this,
860
+ A: [
861
+ "this._node",
862
+ ""
863
+ ]
864
+ });
865
+ this._node.graph.hf.copy(toModelRange(this._node.sheetId, range));
866
+ }
867
+ paste(cell) {
868
+ invariant2(this._node, void 0, {
869
+ F: __dxlog_file2,
870
+ L: 194,
871
+ S: this,
872
+ A: [
873
+ "this._node",
874
+ ""
875
+ ]
876
+ });
877
+ if (!this._node.graph.hf.isClipboardEmpty()) {
878
+ const changes = this._node.graph.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));
879
+ for (const change of changes) {
880
+ if (change instanceof ExportedCellChange) {
881
+ const { address, newValue } = change;
882
+ const idx = addressToIndex(this._sheet, {
883
+ row: address.row,
884
+ col: address.col
885
+ });
886
+ this._sheet.cells[idx] = {
887
+ value: newValue
888
+ };
889
+ }
890
+ }
891
+ }
892
+ }
893
+ // TODO(burdon): Display undo/redo state.
894
+ undo() {
895
+ invariant2(this._node, void 0, {
896
+ F: __dxlog_file2,
897
+ L: 209,
898
+ S: this,
899
+ A: [
900
+ "this._node",
901
+ ""
902
+ ]
903
+ });
904
+ if (this._node.graph.hf.isThereSomethingToUndo()) {
905
+ this._node.graph.hf.undo();
906
+ }
907
+ }
908
+ redo() {
909
+ invariant2(this._node, void 0, {
910
+ F: __dxlog_file2,
911
+ L: 217,
912
+ S: this,
913
+ A: [
914
+ "this._node",
915
+ ""
916
+ ]
917
+ });
918
+ if (this._node.graph.hf.isThereSomethingToRedo()) {
919
+ this._node.graph.hf.redo();
920
+ }
921
+ }
922
+ /**
923
+ * Get value from sheet.
924
+ */
925
+ getCellValue(cell) {
926
+ const idx = addressToIndex(this._sheet, cell);
927
+ return this._sheet.cells[idx]?.value ?? null;
928
+ }
929
+ /**
930
+ * Get value as a string for editing.
931
+ */
932
+ getCellText(cell) {
933
+ const value = this.getCellValue(cell);
934
+ if (value == null) {
935
+ return void 0;
466
936
  }
467
- const fn = functions.find((fn2) => fn2.binding === binding);
468
- if (fn) {
469
- return `${fullyQualifiedId(fn)}(${args})`;
937
+ if (typeof value === "string" && value.charAt(0) === "=") {
938
+ return this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value));
470
939
  } else {
471
- return match;
940
+ return String(value);
472
941
  }
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;
942
+ }
943
+ /**
944
+ * Get array of raw values from sheet.
945
+ */
946
+ getCellValues(range) {
947
+ return this._iterRange(range, (cell) => this.getCellValue(cell));
948
+ }
949
+ /**
950
+ * Gets the regular or computed value from the engine.
951
+ */
952
+ getValue(cell) {
953
+ invariant2(this._node, void 0, {
954
+ F: __dxlog_file2,
955
+ L: 260,
956
+ S: this,
957
+ A: [
958
+ "this._node",
959
+ ""
960
+ ]
961
+ });
962
+ const value = this._node.graph.hf.getCellValue(toSimpleCellAddress(this._node.sheetId, cell));
963
+ if (value instanceof DetailedCellError) {
964
+ return value.toString();
965
+ }
966
+ return value;
967
+ }
968
+ /**
969
+ * Get value type.
970
+ */
971
+ getValueType(cell) {
972
+ invariant2(this._node, void 0, {
973
+ F: __dxlog_file2,
974
+ L: 273,
975
+ S: this,
976
+ A: [
977
+ "this._node",
978
+ ""
979
+ ]
980
+ });
981
+ const addr = toSimpleCellAddress(this._node.sheetId, cell);
982
+ const type = this._node.graph.hf.getCellValueDetailedType(addr);
983
+ return typeMap[type];
984
+ }
985
+ /**
986
+ * Sets the value, updating the sheet and engine.
987
+ */
988
+ setValue(cell, value) {
989
+ invariant2(this._node, void 0, {
990
+ F: __dxlog_file2,
991
+ L: 283,
992
+ S: this,
993
+ A: [
994
+ "this._node",
995
+ ""
996
+ ]
997
+ });
998
+ if (this._options.readonly) {
999
+ throw new ReadonlyException();
1000
+ }
1001
+ let refresh = false;
1002
+ if (cell.row >= this._sheet.rows.length) {
1003
+ insertIndices(this._sheet.rows, cell.row, 1, MAX_ROWS);
1004
+ refresh = true;
1005
+ }
1006
+ if (cell.col >= this._sheet.columns.length) {
1007
+ insertIndices(this._sheet.columns, cell.col, 1, MAX_COLUMNS);
1008
+ refresh = true;
480
1009
  }
481
- const fn = functions.find((fn2) => fullyQualifiedId(fn2) === id);
482
- if (fn?.binding) {
483
- return `${fn.binding}(${args})`;
1010
+ if (refresh) {
1011
+ this.reset();
1012
+ }
1013
+ this._node.graph.hf.setCellContents({
1014
+ sheet: this._node.sheetId,
1015
+ row: cell.row,
1016
+ col: cell.col
1017
+ }, [
1018
+ [
1019
+ typeof value === "string" && value.charAt(0) === "=" ? this._graph.mapFormulaToNative(value) : value
1020
+ ]
1021
+ ]);
1022
+ const idx = addressToIndex(this._sheet, cell);
1023
+ if (value === void 0 || value === null) {
1024
+ delete this._sheet.cells[idx];
484
1025
  } else {
485
- return match;
1026
+ if (typeof value === "string" && value.charAt(0) === "=") {
1027
+ value = this._graph.mapFunctionBindingToId(this.mapFormulaRefsToIndices(value));
1028
+ }
1029
+ this._sheet.cells[idx] = {
1030
+ value
1031
+ };
486
1032
  }
487
- });
1033
+ }
1034
+ /**
1035
+ * Sets values from a simple map.
1036
+ */
1037
+ setValues(values) {
1038
+ Object.entries(values).forEach(([key, { value }]) => {
1039
+ this.setValue(addressFromA1Notation(key), value);
1040
+ });
1041
+ }
1042
+ /**
1043
+ * Iterate range.
1044
+ */
1045
+ _iterRange(range, cb) {
1046
+ const to = range.to ?? range.from;
1047
+ const rowRange = [
1048
+ Math.min(range.from.row, to.row),
1049
+ Math.max(range.from.row, to.row)
1050
+ ];
1051
+ const columnRange = [
1052
+ Math.min(range.from.col, to.col),
1053
+ Math.max(range.from.col, to.col)
1054
+ ];
1055
+ const rows = [];
1056
+ for (let row = rowRange[0]; row <= rowRange[1]; row++) {
1057
+ const rowCells = [];
1058
+ for (let column = columnRange[0]; column <= columnRange[1]; column++) {
1059
+ const value = cb({
1060
+ row,
1061
+ col: column
1062
+ });
1063
+ if (value !== void 0) {
1064
+ rowCells.push(value);
1065
+ }
1066
+ }
1067
+ rows.push(rowCells);
1068
+ }
1069
+ return rows;
1070
+ }
1071
+ // TODO(burdon): Delete index.
1072
+ _deleteIndices(indices, i, n) {
1073
+ throw new Error("Not implemented");
1074
+ }
1075
+ // TODO(burdon): Move. Cannot use fractional without changing. Switch back to using unique IDs?
1076
+ _moveIndices(indices, i, j, n) {
1077
+ throw new Error("Not implemented");
1078
+ }
1079
+ //
1080
+ // Indices.
1081
+ //
1082
+ /**
1083
+ * Map from A1 notation to indices.
1084
+ */
1085
+ mapFormulaRefsToIndices(formula) {
1086
+ invariant2(formula.charAt(0) === "=", void 0, {
1087
+ F: __dxlog_file2,
1088
+ L: 372,
1089
+ S: this,
1090
+ A: [
1091
+ "formula.charAt(0) === '='",
1092
+ ""
1093
+ ]
1094
+ });
1095
+ return formula.replace(/([a-zA-Z]+)([0-9]+)/g, (match) => {
1096
+ return addressToIndex(this._sheet, addressFromA1Notation(match));
1097
+ });
1098
+ }
1099
+ /**
1100
+ * Map from indices to A1 notation.
1101
+ */
1102
+ mapFormulaIndicesToRefs(formula) {
1103
+ invariant2(formula.charAt(0) === "=", void 0, {
1104
+ F: __dxlog_file2,
1105
+ L: 382,
1106
+ S: this,
1107
+ A: [
1108
+ "formula.charAt(0) === '='",
1109
+ ""
1110
+ ]
1111
+ });
1112
+ return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {
1113
+ return addressToA1Notation(addressFromIndex(this._sheet, idx));
1114
+ });
1115
+ }
1116
+ //
1117
+ // Values
1118
+ //
1119
+ /**
1120
+ * https://hyperformula.handsontable.com/guide/date-and-time-handling.html#example
1121
+ * https://hyperformula.handsontable.com/api/interfaces/configparams.html#nulldate
1122
+ * NOTE: TODAY() is number of FULL days since nullDate. It will typically be -1 days from NOW().
1123
+ */
1124
+ toLocalDate(num) {
1125
+ const { year, month, day, hours, minutes, seconds } = this.toDateTime(num);
1126
+ return new Date(year, month - 1, day, hours, minutes, seconds);
1127
+ }
1128
+ toDateTime(num) {
1129
+ invariant2(this._node, void 0, {
1130
+ F: __dxlog_file2,
1131
+ L: 403,
1132
+ S: this,
1133
+ A: [
1134
+ "this._node",
1135
+ ""
1136
+ ]
1137
+ });
1138
+ return this._node.graph.hf.numberToDateTime(num);
1139
+ }
1140
+ toDate(num) {
1141
+ invariant2(this._node, void 0, {
1142
+ F: __dxlog_file2,
1143
+ L: 408,
1144
+ S: this,
1145
+ A: [
1146
+ "this._node",
1147
+ ""
1148
+ ]
1149
+ });
1150
+ return this._node.graph.hf.numberToDate(num);
1151
+ }
1152
+ toTime(num) {
1153
+ invariant2(this._node, void 0, {
1154
+ F: __dxlog_file2,
1155
+ L: 413,
1156
+ S: this,
1157
+ A: [
1158
+ "this._node",
1159
+ ""
1160
+ ]
1161
+ });
1162
+ return this._node.graph.hf.numberToTime(num);
1163
+ }
488
1164
  };
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);
1165
+
1166
+ // packages/plugins/plugin-sheet/src/hooks/useFormattingModel.ts
1167
+ var useFormattingModel = (model) => {
1168
+ return useMemo(() => model && new FormattingModel(model), [
1169
+ model
1170
+ ]);
1171
+ };
1172
+
1173
+ // packages/plugins/plugin-sheet/src/hooks/useSheetModel.ts
1174
+ import { useEffect as useEffect2, useState as useState3 } from "react";
1175
+ var useSheetModel = (graph, sheet, { readonly } = {}) => {
1176
+ const [model, setModel] = useState3();
495
1177
  useEffect2(() => {
1178
+ if (!graph || !sheet) {
1179
+ return;
1180
+ }
496
1181
  let model2;
497
- let formatting2;
498
1182
  const t = setTimeout(async () => {
499
- model2 = new SheetModel(graph, sheet, space, {
500
- readonly,
501
- mapFormulaBindingToId,
502
- mapFormulaBindingFromId
1183
+ model2 = new SheetModel(graph, sheet, {
1184
+ readonly
503
1185
  });
504
- await model2.initialize();
505
- formatting2 = new FormattingModel(model2);
506
- setModels([
507
- model2,
508
- formatting2
509
- ]);
1186
+ await model2.open();
1187
+ setModel(model2);
510
1188
  });
511
1189
  return () => {
512
1190
  clearTimeout(t);
513
- void model2?.destroy();
1191
+ void model2?.close();
514
1192
  };
515
1193
  }, [
516
1194
  graph,
1195
+ sheet,
517
1196
  readonly
518
1197
  ]);
519
- if (!model || !formatting) {
520
- return null;
521
- }
522
- return /* @__PURE__ */ React.createElement(SheetContext.Provider, {
1198
+ return model;
1199
+ };
1200
+
1201
+ // packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx
1202
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx";
1203
+ var SheetContext = /* @__PURE__ */ createContext2(null);
1204
+ var useSheetContext = () => {
1205
+ const context = useContext2(SheetContext);
1206
+ invariant3(context, void 0, {
1207
+ F: __dxlog_file3,
1208
+ L: 43,
1209
+ S: void 0,
1210
+ A: [
1211
+ "context",
1212
+ ""
1213
+ ]
1214
+ });
1215
+ return context;
1216
+ };
1217
+ var SheetContextProvider = ({ children, graph, sheet, readonly, onInfo }) => {
1218
+ const model = useSheetModel(graph, sheet, {
1219
+ readonly
1220
+ });
1221
+ const formatting = useFormattingModel(model);
1222
+ const [cursor, setCursor] = useState4();
1223
+ const [range, setRange] = useState4();
1224
+ const [editing, setEditing] = useState4(false);
1225
+ const decorations = useMemo2(() => createDecorations(), []);
1226
+ return !model || !formatting ? null : /* @__PURE__ */ React3.createElement(SheetContext.Provider, {
523
1227
  value: {
524
1228
  model,
525
1229
  formatting,
@@ -530,11 +1234,177 @@ var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...optio
530
1234
  editing,
531
1235
  setEditing,
532
1236
  // TODO(burdon): Change to event.
533
- onInfo
1237
+ onInfo,
1238
+ decorations
534
1239
  }
535
1240
  }, children);
536
1241
  };
537
1242
 
1243
+ // packages/plugins/plugin-sheet/src/components/Sheet/threads.tsx
1244
+ import { effect } from "@preact/signals-core";
1245
+ import React4, { useCallback, useEffect as useEffect3, useMemo as useMemo3 } from "react";
1246
+ import { LayoutAction, useIntentDispatcher, useIntentResolver } from "@dxos/app-framework";
1247
+ import { debounce } from "@dxos/async";
1248
+ import { fullyQualifiedId } from "@dxos/react-client/echo";
1249
+ import { Icon, useTranslation } from "@dxos/react-ui";
1250
+ var CommentIndicator = () => {
1251
+ return /* @__PURE__ */ React4.createElement("div", {
1252
+ role: "none",
1253
+ className: "absolute top-0 right-0 w-0 h-0 border-t-8 border-l-8 border-t-cmCommentSurface border-l-transparent"
1254
+ });
1255
+ };
1256
+ var ThreadedCellWrapper = ({ children }) => {
1257
+ const dispatch = useIntentDispatcher();
1258
+ const [isHovered, setIsHovered] = React4.useState(false);
1259
+ const { t } = useTranslation(SHEET_PLUGIN);
1260
+ const handleClick = React4.useCallback((_event) => {
1261
+ void dispatch({
1262
+ action: LayoutAction.SET_LAYOUT,
1263
+ data: {
1264
+ element: "complementary",
1265
+ state: true
1266
+ }
1267
+ });
1268
+ }, [
1269
+ dispatch
1270
+ ]);
1271
+ return /* @__PURE__ */ React4.createElement("div", {
1272
+ role: "none",
1273
+ className: "relative h-full is-full",
1274
+ onMouseEnter: () => {
1275
+ setIsHovered(true);
1276
+ },
1277
+ onMouseLeave: () => {
1278
+ setIsHovered(false);
1279
+ }
1280
+ }, /* @__PURE__ */ React4.createElement(CommentIndicator, null), isHovered && /* @__PURE__ */ React4.createElement("div", {
1281
+ className: "absolute inset-0 flex items-center justify-end pr-1"
1282
+ }, /* @__PURE__ */ React4.createElement("button", {
1283
+ className: "ch-button text-xs min-bs-0 p-1",
1284
+ onClick: handleClick,
1285
+ "aria-label": t("open comment for sheet cell")
1286
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1287
+ icon: "ph--chat--regular",
1288
+ "aria-hidden": true
1289
+ }))), children);
1290
+ };
1291
+ var createThreadDecoration = (cellIndex, threadId, sheetId) => {
1292
+ return {
1293
+ type: "comment",
1294
+ cellIndex,
1295
+ decorate: (props) => /* @__PURE__ */ React4.createElement(ThreadedCellWrapper, props)
1296
+ };
1297
+ };
1298
+ var useUpdateCursorOnThreadSelection = () => {
1299
+ const { setCursor, model } = useSheetContext();
1300
+ const handleScrollIntoView = useCallback(({ action, data }) => {
1301
+ switch (action) {
1302
+ case LayoutAction.SCROLL_INTO_VIEW: {
1303
+ if (!data?.id || data?.cursor === void 0 || data?.id !== fullyQualifiedId(model.sheet)) {
1304
+ return;
1305
+ }
1306
+ const cellAddress = addressFromIndex(model.sheet, data.cursor);
1307
+ setCursor(cellAddress);
1308
+ }
1309
+ }
1310
+ }, [
1311
+ model.sheet,
1312
+ setCursor
1313
+ ]);
1314
+ useIntentResolver(SHEET_PLUGIN, handleScrollIntoView);
1315
+ };
1316
+ var useSelectThreadOnCursorChange = () => {
1317
+ const { cursor, model } = useSheetContext();
1318
+ const dispatch = useIntentDispatcher();
1319
+ const activeThreads = useMemo3(() => model.sheet.threads?.filter((thread) => !!thread && thread.status === "active") ?? [], [
1320
+ JSON.stringify(model.sheet.threads)
1321
+ ]);
1322
+ const activeThreadAddresses = useMemo3(() => activeThreads.map((thread) => thread.anchor).filter((anchor) => anchor !== void 0).map((anchor) => addressFromIndex(model.sheet, anchor)), [
1323
+ activeThreads,
1324
+ model.sheet
1325
+ ]);
1326
+ const selectClosestThread = useCallback((cellAddress) => {
1327
+ if (!cellAddress || !activeThreads) {
1328
+ return;
1329
+ }
1330
+ const closestThreadAnchor = closest(cellAddress, activeThreadAddresses);
1331
+ if (closestThreadAnchor) {
1332
+ const closestThread = activeThreads.find((thread) => thread && thread.anchor === addressToIndex(model.sheet, closestThreadAnchor));
1333
+ if (closestThread) {
1334
+ void dispatch([
1335
+ {
1336
+ action: "dxos.org/plugin/thread/action/select",
1337
+ data: {
1338
+ current: fullyQualifiedId(closestThread)
1339
+ }
1340
+ }
1341
+ ]);
1342
+ }
1343
+ }
1344
+ }, [
1345
+ dispatch,
1346
+ activeThreads,
1347
+ activeThreadAddresses,
1348
+ model.sheet
1349
+ ]);
1350
+ const debounced = useMemo3(() => {
1351
+ return debounce((cursor2) => requestAnimationFrame(() => selectClosestThread(cursor2)), 50);
1352
+ }, [
1353
+ selectClosestThread
1354
+ ]);
1355
+ useEffect3(() => {
1356
+ if (!cursor) {
1357
+ return;
1358
+ }
1359
+ debounced(cursor);
1360
+ }, [
1361
+ cursor,
1362
+ selectClosestThread
1363
+ ]);
1364
+ };
1365
+ var useThreadDecorations = () => {
1366
+ const { decorations, model } = useSheetContext();
1367
+ const sheet = useMemo3(() => model.sheet, [
1368
+ model.sheet
1369
+ ]);
1370
+ const sheetId = useMemo3(() => fullyQualifiedId(sheet), [
1371
+ sheet
1372
+ ]);
1373
+ useEffect3(() => {
1374
+ const unsubscribe = effect(() => {
1375
+ const activeThreadAnchors = /* @__PURE__ */ new Set();
1376
+ if (!sheet.threads) {
1377
+ return;
1378
+ }
1379
+ for (const thread of sheet.threads) {
1380
+ if (!thread || thread.anchor === void 0 || thread.status === "resolved") {
1381
+ continue;
1382
+ }
1383
+ activeThreadAnchors.add(thread.anchor);
1384
+ const index = thread.anchor;
1385
+ const existingDecorations = decorations.getDecorationsForCell(index);
1386
+ if (!existingDecorations || !existingDecorations.some((d) => d.type === "comment")) {
1387
+ decorations.addDecoration(index, createThreadDecoration(index, thread.id, sheetId));
1388
+ }
1389
+ }
1390
+ for (const decoration of decorations.getAllDecorations()) {
1391
+ if (decoration.type !== "comment") {
1392
+ continue;
1393
+ }
1394
+ if (!activeThreadAnchors.has(decoration.cellIndex)) {
1395
+ decorations.removeDecoration(decoration.cellIndex, "comment");
1396
+ }
1397
+ }
1398
+ });
1399
+ return () => unsubscribe();
1400
+ });
1401
+ };
1402
+ var useThreads = () => {
1403
+ useUpdateCursorOnThreadSelection();
1404
+ useSelectThreadOnCursorChange();
1405
+ useThreadDecorations();
1406
+ };
1407
+
538
1408
  // packages/plugins/plugin-sheet/src/components/Sheet/util.ts
539
1409
  var getRelativeClientRect = (root, element) => {
540
1410
  const rootRect = root.getBoundingClientRect();
@@ -570,7 +1440,7 @@ var scrollIntoView = (scrollContainer, el) => {
570
1440
 
571
1441
  // packages/plugins/plugin-sheet/src/components/CellEditor/CellEditor.tsx
572
1442
  import { EditorView, keymap } from "@codemirror/view";
573
- import React2 from "react";
1443
+ import React5 from "react";
574
1444
  import { useThemeContext } from "@dxos/react-ui";
575
1445
  import { createBasicExtensions, createThemeExtensions, preventNewline, useTextEditor } from "@dxos/react-ui-editor";
576
1446
  var editorKeys = ({ onNav, onClose }) => {
@@ -618,20 +1488,60 @@ var editorKeys = ({ onNav, onClose }) => {
618
1488
  {
619
1489
  key: "Enter",
620
1490
  run: (editor) => {
621
- onClose(editor.state.doc.toString());
1491
+ onClose(editor.state.doc.toString(), {
1492
+ key: "Enter"
1493
+ });
1494
+ return true;
1495
+ },
1496
+ shift: (editor) => {
1497
+ onClose(editor.state.doc.toString(), {
1498
+ key: "Enter",
1499
+ shift: true
1500
+ });
1501
+ return true;
1502
+ }
1503
+ },
1504
+ {
1505
+ key: "Tab",
1506
+ run: (editor) => {
1507
+ onClose(editor.state.doc.toString(), {
1508
+ key: "Tab"
1509
+ });
1510
+ return true;
1511
+ },
1512
+ shift: (editor) => {
1513
+ onClose(editor.state.doc.toString(), {
1514
+ key: "Tab",
1515
+ shift: true
1516
+ });
622
1517
  return true;
623
1518
  }
624
1519
  },
625
1520
  {
626
1521
  key: "Escape",
627
1522
  run: () => {
628
- onClose(void 0);
1523
+ onClose(void 0, {
1524
+ key: "Escape"
1525
+ });
629
1526
  return true;
630
1527
  }
631
1528
  }
632
1529
  ]);
633
1530
  };
634
- var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
1531
+ var editorVariants = {
1532
+ // TODO(thure): remove when legacy is no longer used.
1533
+ legacy: {
1534
+ root: "flex w-full",
1535
+ editor: "flex w-full [&>.cm-scroller]:scrollbar-none",
1536
+ content: "!px-2 !py-1"
1537
+ },
1538
+ grid: {
1539
+ root: "absolute z-[1]",
1540
+ editor: "[&>.cm-scroller]:scrollbar-none tabular-nums",
1541
+ content: "!border !border-transparent !p-0.5"
1542
+ }
1543
+ };
1544
+ var CellEditor = ({ value, extension, autoFocus, onBlur, variant = "legacy", box, gridId }) => {
635
1545
  const { themeMode } = useThemeContext();
636
1546
  const { parentRef } = useTextEditor(() => {
637
1547
  return {
@@ -658,31 +1568,39 @@ var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
658
1568
  themeMode,
659
1569
  slots: {
660
1570
  editor: {
661
- className: "flex w-full [&>.cm-scroller]:scrollbar-none"
1571
+ className: editorVariants[variant].editor
662
1572
  },
663
1573
  content: {
664
- className: "!px-2 !py-1"
1574
+ className: editorVariants[variant].content
665
1575
  }
666
1576
  }
667
1577
  })
668
1578
  ]
669
1579
  };
670
1580
  }, [
671
- extension
1581
+ extension,
1582
+ autoFocus,
1583
+ value,
1584
+ variant,
1585
+ onBlur
672
1586
  ]);
673
- return /* @__PURE__ */ React2.createElement("div", {
1587
+ return /* @__PURE__ */ React5.createElement("div", {
674
1588
  ref: parentRef,
675
- className: "flex w-full"
1589
+ className: editorVariants[variant].root,
1590
+ style: box,
1591
+ ...gridId && {
1592
+ "data-grid": gridId
1593
+ }
676
1594
  });
677
1595
  };
678
1596
 
679
1597
  // packages/plugins/plugin-sheet/src/components/CellEditor/extension.ts
680
1598
  import { acceptCompletion, autocompletion, completionStatus, startCompletion } from "@codemirror/autocomplete";
681
1599
  import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
682
- import { Facet } from "@codemirror/state";
683
1600
  import { ViewPlugin, keymap as keymap2 } from "@codemirror/view";
684
1601
  import { tags } from "@lezer/highlight";
685
1602
  import { spreadsheet } from "codemirror-lang-spreadsheet";
1603
+ import { singleValueFacet } from "@dxos/react-ui-editor/state";
686
1604
  import { mx } from "@dxos/react-ui-theme";
687
1605
  var highlightStyles = HighlightStyle.define([
688
1606
  // Function.
@@ -714,7 +1632,7 @@ var highlightStyles = HighlightStyle.define([
714
1632
  class: "text-unAccent"
715
1633
  }
716
1634
  ]);
717
- var languageFacet = Facet.define();
1635
+ var languageFacet = singleValueFacet();
718
1636
  var sheetExtension = ({ functions = [] }) => {
719
1637
  const { extension, language } = spreadsheet({
720
1638
  idiom: "en-US",
@@ -794,13 +1712,7 @@ var sheetExtension = ({ functions = [] }) => {
794
1712
  // NOTE: Useful for debugging.
795
1713
  closeOnBlur: false,
796
1714
  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
- )
1715
+ tooltipClass: () => mx("!-left-[1px] !top-[33px] !-m-0 border !border-t-0 [&>ul]:!min-w-[198px]", "[&>ul>li[aria-selected]]:!bg-accentSurface", "border-separator")
804
1716
  }),
805
1717
  keymap2.of([
806
1718
  {
@@ -837,7 +1749,7 @@ var rangeExtension = (onInit) => {
837
1749
  update(view2) {
838
1750
  const { anchor } = view2.state.selection.ranges[0];
839
1751
  activeRange = void 0;
840
- const [language] = view2.state.facet(languageFacet);
1752
+ const language = view2.state.facet(languageFacet);
841
1753
  const { topNode } = language.parser.parse(view2.state.doc.toString());
842
1754
  visitTree(topNode, ({ type, from, to }) => {
843
1755
  if (from <= anchor && to >= anchor) {
@@ -889,7 +1801,7 @@ var visitTree = (node, callback) => {
889
1801
  };
890
1802
 
891
1803
  // 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";
1804
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx";
893
1805
  var fragments = {
894
1806
  axis: "bg-axisSurface text-axisText text-xs select-none",
895
1807
  axisSelected: "bg-attention text-baseText",
@@ -897,25 +1809,26 @@ var fragments = {
897
1809
  cellSelected: "bg-gridCellSelected text-baseText border !border-accentSurface"
898
1810
  };
899
1811
  var SheetRoot = ({ children, ...props }) => {
900
- return /* @__PURE__ */ React3.createElement(SheetContextProvider, props, children);
1812
+ return /* @__PURE__ */ React6.createElement(SheetContextProvider, props, children);
901
1813
  };
902
- var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns }, forwardRef2) => {
1814
+ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numCols }, forwardRef2) => {
903
1815
  const { model, cursor, setCursor, setRange, setEditing } = useSheetContext();
904
1816
  const { rowsRef, columnsRef, contentRef } = useScrollHandlers();
905
- const [rows, setRows] = useState4([
1817
+ useThreads();
1818
+ const [rows, setRows] = useState5([
906
1819
  ...model.sheet.rows
907
1820
  ]);
908
- const [columns, setColumns] = useState4([
1821
+ const [columns, setColumns] = useState5([
909
1822
  ...model.sheet.columns
910
1823
  ]);
911
- useEffect3(() => {
1824
+ useEffect4(() => {
912
1825
  const rowsAccessor = createDocAccessor(model.sheet, [
913
1826
  "rows"
914
1827
  ]);
915
1828
  const columnsAccessor = createDocAccessor(model.sheet, [
916
1829
  "columns"
917
1830
  ]);
918
- const handleUpdate = debounce(() => {
1831
+ const handleUpdate = debounce2(() => {
919
1832
  setRows([
920
1833
  ...model.sheet.rows
921
1834
  ]);
@@ -933,44 +1846,44 @@ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns },
933
1846
  }, [
934
1847
  model
935
1848
  ]);
936
- useEffect3(() => {
1849
+ useEffect4(() => {
937
1850
  model.reset();
938
1851
  }, [
939
1852
  rows,
940
1853
  columns
941
1854
  ]);
942
1855
  const handleMoveRows = (from, to, num = 1) => {
943
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1856
+ const cursorIdx = cursor ? addressToIndex(model.sheet, cursor) : void 0;
944
1857
  const [rows2] = model.sheet.rows.splice(from, num);
945
1858
  model.sheet.rows.splice(to, 0, rows2);
946
1859
  if (cursorIdx) {
947
- setCursor(model.addressFromIndex(cursorIdx));
1860
+ setCursor(addressFromIndex(model.sheet, cursorIdx));
948
1861
  }
949
1862
  setRows([
950
1863
  ...model.sheet.rows
951
1864
  ]);
952
1865
  };
953
1866
  const handleMoveColumns = (from, to, num = 1) => {
954
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1867
+ const cursorIdx = cursor ? addressToIndex(model.sheet, cursor) : void 0;
955
1868
  const columns2 = model.sheet.columns.splice(from, num);
956
1869
  model.sheet.columns.splice(to, 0, ...columns2);
957
1870
  if (cursorIdx) {
958
- setCursor(model.addressFromIndex(cursorIdx));
1871
+ setCursor(addressFromIndex(model.sheet, cursorIdx));
959
1872
  }
960
1873
  setColumns([
961
1874
  ...model.sheet.columns
962
1875
  ]);
963
1876
  };
964
- const [rowSizes, setRowSizes] = useState4();
965
- const [columnSizes, setColumnSizes] = useState4();
966
- useEffect3(() => {
1877
+ const [rowSizes, setRowSizes] = useState5();
1878
+ const [columnSizes, setColumnSizes] = useState5();
1879
+ useEffect4(() => {
967
1880
  const rowAccessor = createDocAccessor(model.sheet, [
968
1881
  "rowMeta"
969
1882
  ]);
970
1883
  const columnAccessor = createDocAccessor(model.sheet, [
971
1884
  "columnMeta"
972
1885
  ]);
973
- const handleUpdate = debounce(() => {
1886
+ const handleUpdate = debounce2(() => {
974
1887
  const mapSizes = (values) => values.reduce((map, [idx, meta]) => {
975
1888
  if (meta.size) {
976
1889
  map[idx] = meta.size;
@@ -1012,54 +1925,54 @@ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns },
1012
1925
  }));
1013
1926
  }
1014
1927
  };
1015
- return /* @__PURE__ */ React3.createElement("div", {
1928
+ return /* @__PURE__ */ React6.createElement("div", {
1016
1929
  role: "none",
1017
1930
  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, {
1931
+ }, /* @__PURE__ */ React6.createElement(GridCorner, {
1019
1932
  onClick: () => {
1020
1933
  setCursor(void 0);
1021
1934
  setRange(void 0);
1022
1935
  setEditing(false);
1023
1936
  }
1024
- }), /* @__PURE__ */ React3.createElement(SheetColumns, {
1937
+ }), /* @__PURE__ */ React6.createElement(SheetColumns, {
1025
1938
  ref: columnsRef,
1026
1939
  columns,
1027
1940
  sizes: columnSizes,
1028
- selected: cursor?.column,
1029
- onSelect: (column) => setCursor(cursor?.column === column ? void 0 : {
1941
+ selected: cursor?.col,
1942
+ onSelect: (col) => setCursor(cursor?.col === col ? void 0 : {
1030
1943
  row: -1,
1031
- column
1944
+ col
1032
1945
  }),
1033
1946
  onResize: handleResizeColumn,
1034
1947
  onMove: handleMoveColumns
1035
- }), /* @__PURE__ */ React3.createElement(SheetRows, {
1948
+ }), /* @__PURE__ */ React6.createElement(SheetRows, {
1036
1949
  ref: rowsRef,
1037
1950
  rows,
1038
1951
  sizes: rowSizes,
1039
1952
  selected: cursor?.row,
1040
1953
  onSelect: (row) => setCursor(cursor?.row === row ? void 0 : {
1041
1954
  row,
1042
- column: -1
1955
+ col: -1
1043
1956
  }),
1044
1957
  onResize: handleResizeRow,
1045
1958
  onMove: handleMoveRows
1046
- }), /* @__PURE__ */ React3.createElement(SheetGrid, {
1959
+ }), /* @__PURE__ */ React6.createElement(SheetGrid, {
1047
1960
  ref: contentRef,
1048
1961
  size: {
1049
1962
  numRows: numRows ?? rows.length,
1050
- numColumns: numColumns ?? columns.length
1963
+ numCols: numCols ?? columns.length
1051
1964
  },
1052
1965
  rows,
1053
1966
  columns,
1054
1967
  rowSizes,
1055
1968
  columnSizes
1056
- }), /* @__PURE__ */ React3.createElement(GridCorner, null), /* @__PURE__ */ React3.createElement(SheetStatusBar, null));
1969
+ }), /* @__PURE__ */ React6.createElement(GridCorner, null), /* @__PURE__ */ React6.createElement(SheetStatusBar, null));
1057
1970
  });
1058
1971
  var useScrollHandlers = () => {
1059
1972
  const rowsRef = useRef(null);
1060
1973
  const columnsRef = useRef(null);
1061
1974
  const contentRef = useRef(null);
1062
- useEffect3(() => {
1975
+ useEffect4(() => {
1063
1976
  const handleRowsScroll = (ev) => {
1064
1977
  const { scrollTop } = ev.target;
1065
1978
  if (!rowsRef.current.dataset.locked) {
@@ -1096,13 +2009,13 @@ var useScrollHandlers = () => {
1096
2009
  };
1097
2010
  };
1098
2011
  var GridCorner = (props) => {
1099
- return /* @__PURE__ */ React3.createElement("div", {
2012
+ return /* @__PURE__ */ React6.createElement("div", {
1100
2013
  className: fragments.axis,
1101
2014
  ...props
1102
2015
  });
1103
2016
  };
1104
2017
  var MovingOverlay = ({ label }) => {
1105
- return /* @__PURE__ */ React3.createElement("div", {
2018
+ return /* @__PURE__ */ React6.createElement("div", {
1106
2019
  className: "flex w-full h-full justify-center items-center text-sm p-1 bg-gridOverlay cursor-pointer"
1107
2020
  }, label);
1108
2021
  };
@@ -1122,7 +2035,7 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1122
2035
  });
1123
2036
  const keyboardSensor = useSensor(KeyboardSensor, {});
1124
2037
  const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
1125
- const [active, setActive] = useState4(null);
2038
+ const [active, setActive] = useState5(null);
1126
2039
  const handleDragStart = ({ active: active2 }) => {
1127
2040
  setActive(active2);
1128
2041
  };
@@ -1146,18 +2059,18 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1146
2059
  }
1147
2060
  return transform;
1148
2061
  };
1149
- return /* @__PURE__ */ React3.createElement("div", {
2062
+ return /* @__PURE__ */ React6.createElement("div", {
1150
2063
  className: "relative flex grow overflow-hidden"
1151
- }, /* @__PURE__ */ React3.createElement("div", {
2064
+ }, /* @__PURE__ */ React6.createElement("div", {
1152
2065
  className: mx2("z-20 absolute inset-0 border-y border-gridLine pointer-events-none"),
1153
2066
  style: {
1154
2067
  width: axisWidth
1155
2068
  }
1156
- }), /* @__PURE__ */ React3.createElement("div", {
2069
+ }), /* @__PURE__ */ React6.createElement("div", {
1157
2070
  ref: forwardRef2,
1158
2071
  role: "rowheader",
1159
2072
  className: "grow overflow-y-auto scrollbar-none"
1160
- }, /* @__PURE__ */ React3.createElement(DndContext, {
2073
+ }, /* @__PURE__ */ React6.createElement(DndContext, {
1161
2074
  sensors,
1162
2075
  modifiers: [
1163
2076
  restrictToVerticalAxis,
@@ -1165,12 +2078,12 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1165
2078
  ],
1166
2079
  onDragStart: handleDragStart,
1167
2080
  onDragEnd: handleDragEnd
1168
- }, /* @__PURE__ */ React3.createElement("div", {
2081
+ }, /* @__PURE__ */ React6.createElement("div", {
1169
2082
  className: "flex flex-col",
1170
2083
  style: {
1171
2084
  width: axisWidth
1172
2085
  }
1173
- }, rows.map((idx, index) => /* @__PURE__ */ React3.createElement(GridRowCell, {
2086
+ }, rows.map((idx, index) => /* @__PURE__ */ React6.createElement(GridRowCell, {
1174
2087
  key: idx,
1175
2088
  idx,
1176
2089
  index,
@@ -1180,7 +2093,7 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1180
2093
  selected: selected === index,
1181
2094
  onResize,
1182
2095
  onSelect
1183
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(DragOverlay, null, active && /* @__PURE__ */ React3.createElement(MovingOverlay, {
2096
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement(DragOverlay, null, active && /* @__PURE__ */ React6.createElement(MovingOverlay, {
1184
2097
  label: String(active.data.current.index + 1)
1185
2098
  })), document.body))));
1186
2099
  });
@@ -1198,8 +2111,8 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1198
2111
  }
1199
2112
  });
1200
2113
  const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
1201
- const [initialSize, setInitialSize] = useState4(size);
1202
- const [resizing, setResizing] = useState4(false);
2114
+ const [initialSize, setInitialSize] = useState5(size);
2115
+ const [resizing, setResizing] = useState5(false);
1203
2116
  const scrollHandler = useRef();
1204
2117
  const handleResizeStart = (_ev, _dir, elementRef) => {
1205
2118
  const scrollContainer = elementRef.closest('[role="rowheader"]');
@@ -1221,7 +2134,7 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1221
2134
  onResize?.(idx, initialSize + height, true);
1222
2135
  setResizing(false);
1223
2136
  };
1224
- return /* @__PURE__ */ React3.createElement(Resizable, {
2137
+ return /* @__PURE__ */ React6.createElement(Resizable, {
1225
2138
  enable: {
1226
2139
  bottom: resize
1227
2140
  },
@@ -1233,17 +2146,17 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1233
2146
  onResizeStart: handleResizeStart,
1234
2147
  onResize: handleResize,
1235
2148
  onResizeStop: handleResizeStop
1236
- }, /* @__PURE__ */ React3.createElement("div", {
2149
+ }, /* @__PURE__ */ React6.createElement("div", {
1237
2150
  ref: setNodeRef,
1238
2151
  ...attributes,
1239
2152
  ...listeners,
1240
2153
  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
2154
  onClick: () => onSelect?.(index)
1242
- }, /* @__PURE__ */ React3.createElement("span", {
2155
+ }, /* @__PURE__ */ React6.createElement("span", {
1243
2156
  className: "flex w-full justify-center"
1244
- }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React3.createElement("div", {
2157
+ }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React6.createElement("div", {
1245
2158
  className: "z-20 absolute top-0 w-full min-h-[4px] border-b-4 border-accentSurface"
1246
- }), resizing && /* @__PURE__ */ React3.createElement("div", {
2159
+ }), resizing && /* @__PURE__ */ React6.createElement("div", {
1247
2160
  className: "z-20 absolute bottom-0 w-full min-h-[4px] border-b-4 border-accentSurface"
1248
2161
  })));
1249
2162
  };
@@ -1256,7 +2169,7 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1256
2169
  });
1257
2170
  const keyboardSensor = useSensor(KeyboardSensor, {});
1258
2171
  const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
1259
- const [active, setActive] = useState4(null);
2172
+ const [active, setActive] = useState5(null);
1260
2173
  const handleDragStart = ({ active: active2 }) => {
1261
2174
  setActive(active2);
1262
2175
  };
@@ -1280,18 +2193,18 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1280
2193
  }
1281
2194
  return transform;
1282
2195
  };
1283
- return /* @__PURE__ */ React3.createElement("div", {
2196
+ return /* @__PURE__ */ React6.createElement("div", {
1284
2197
  className: "relative flex grow overflow-hidden"
1285
- }, /* @__PURE__ */ React3.createElement("div", {
2198
+ }, /* @__PURE__ */ React6.createElement("div", {
1286
2199
  className: mx2("z-20 absolute inset-0 border-x border-gridLine pointer-events-none"),
1287
2200
  style: {
1288
2201
  height: axisHeight
1289
2202
  }
1290
- }), /* @__PURE__ */ React3.createElement("div", {
2203
+ }), /* @__PURE__ */ React6.createElement("div", {
1291
2204
  ref: forwardRef2,
1292
2205
  role: "columnheader",
1293
2206
  className: "grow overflow-x-auto scrollbar-none"
1294
- }, /* @__PURE__ */ React3.createElement(DndContext, {
2207
+ }, /* @__PURE__ */ React6.createElement(DndContext, {
1295
2208
  autoScroll: {
1296
2209
  enabled: true
1297
2210
  },
@@ -1302,12 +2215,12 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1302
2215
  ],
1303
2216
  onDragStart: handleDragStart,
1304
2217
  onDragEnd: handleDragEnd
1305
- }, /* @__PURE__ */ React3.createElement("div", {
2218
+ }, /* @__PURE__ */ React6.createElement("div", {
1306
2219
  className: "flex h-full",
1307
2220
  style: {
1308
2221
  height: axisHeight
1309
2222
  }
1310
- }, columns.map((idx, index) => /* @__PURE__ */ React3.createElement(GridColumnCell, {
2223
+ }, columns.map((idx, index) => /* @__PURE__ */ React6.createElement(GridColumnCell, {
1311
2224
  key: idx,
1312
2225
  idx,
1313
2226
  index,
@@ -1317,7 +2230,7 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1317
2230
  selected: selected === index,
1318
2231
  onResize,
1319
2232
  onSelect
1320
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(DragOverlay, null, active && /* @__PURE__ */ React3.createElement(MovingOverlay, {
2233
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement(DragOverlay, null, active && /* @__PURE__ */ React6.createElement(MovingOverlay, {
1321
2234
  label: columnLetter(active.data.current.index)
1322
2235
  })), document.body))));
1323
2236
  });
@@ -1335,8 +2248,8 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1335
2248
  }
1336
2249
  });
1337
2250
  const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
1338
- const [initialSize, setInitialSize] = useState4(size);
1339
- const [resizing, setResizing] = useState4(false);
2251
+ const [initialSize, setInitialSize] = useState5(size);
2252
+ const [resizing, setResizing] = useState5(false);
1340
2253
  const scrollHandler = useRef();
1341
2254
  const handleResizeStart = (_ev, _dir, elementRef) => {
1342
2255
  const scrollContainer = elementRef.closest('[role="columnheader"]');
@@ -1358,7 +2271,7 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1358
2271
  onResize?.(idx, initialSize + width, true);
1359
2272
  setResizing(false);
1360
2273
  };
1361
- return /* @__PURE__ */ React3.createElement(Resizable, {
2274
+ return /* @__PURE__ */ React6.createElement(Resizable, {
1362
2275
  enable: {
1363
2276
  right: resize
1364
2277
  },
@@ -1370,17 +2283,17 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1370
2283
  onResizeStart: handleResizeStart,
1371
2284
  onResize: handleResize,
1372
2285
  onResizeStop: handleResizeStop
1373
- }, /* @__PURE__ */ React3.createElement("div", {
2286
+ }, /* @__PURE__ */ React6.createElement("div", {
1374
2287
  ref: setNodeRef,
1375
2288
  ...attributes,
1376
2289
  ...listeners,
1377
2290
  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
2291
  onClick: () => onSelect?.(index)
1379
- }, /* @__PURE__ */ React3.createElement("span", {
2292
+ }, /* @__PURE__ */ React6.createElement("span", {
1380
2293
  className: "flex w-full justify-center"
1381
- }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React3.createElement("div", {
2294
+ }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React6.createElement("div", {
1382
2295
  className: "z-20 absolute left-0 h-full min-w-[4px] border-l-4 border-accentSurface"
1383
- }), resizing && /* @__PURE__ */ React3.createElement("div", {
2296
+ }), resizing && /* @__PURE__ */ React6.createElement("div", {
1384
2297
  className: "z-20 absolute right-0 h-full min-h-[4px] border-l-4 border-accentSurface"
1385
2298
  })));
1386
2299
  };
@@ -1393,14 +2306,14 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1393
2306
  const { model, cursor, range, editing, setCursor, setRange, setEditing, onInfo } = useSheetContext();
1394
2307
  const initialText = useRef();
1395
2308
  const quickEdit = useRef(false);
1396
- const [, forceUpdate] = useState4({});
1397
- useEffect3(() => {
2309
+ const [, forceUpdate] = useState5({});
2310
+ useEffect4(() => {
1398
2311
  const unsubscribe = model.update.on(() => {
1399
- log("updated", {
2312
+ log2("updated", {
1400
2313
  id: model.id
1401
2314
  }, {
1402
- F: __dxlog_file2,
1403
- L: 730,
2315
+ F: __dxlog_file4,
2316
+ L: 738,
1404
2317
  S: void 0,
1405
2318
  C: (f, a) => f(...a)
1406
2319
  });
@@ -1518,18 +2431,17 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1518
2431
  columnSizes
1519
2432
  });
1520
2433
  const id = fullyQualifiedId2(model.sheet);
1521
- const attendableAttrs = createAttendableAttributes(id);
1522
- const hasAttention = useHasAttention(id);
1523
- return /* @__PURE__ */ React3.createElement("div", {
2434
+ const { hasAttention } = useAttention(id);
2435
+ return /* @__PURE__ */ React6.createElement("div", {
1524
2436
  ref: containerRef,
1525
2437
  role: "grid",
1526
2438
  className: "relative flex grow overflow-hidden"
1527
- }, /* @__PURE__ */ React3.createElement("div", {
2439
+ }, /* @__PURE__ */ React6.createElement("div", {
1528
2440
  className: mx2("z-20 absolute inset-0 border border-gridLine pointer-events-none")
1529
- }), /* @__PURE__ */ React3.createElement("div", {
2441
+ }), /* @__PURE__ */ React6.createElement("div", {
1530
2442
  ref: scrollerRef,
1531
2443
  className: mx2("grow", hasAttention && "overflow-auto scrollbar-thin")
1532
- }, /* @__PURE__ */ React3.createElement("div", {
2444
+ }, /* @__PURE__ */ React6.createElement("div", {
1533
2445
  className: "relative select-none",
1534
2446
  style: {
1535
2447
  width,
@@ -1537,10 +2449,10 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1537
2449
  },
1538
2450
  onClick: () => inputRef.current?.focus(),
1539
2451
  ...handlers
1540
- }, scrollerRef.current && /* @__PURE__ */ React3.createElement(SelectionOverlay, {
2452
+ }, scrollerRef.current && /* @__PURE__ */ React6.createElement(SelectionOverlay, {
1541
2453
  root: scrollerRef.current
1542
2454
  }), rowRange.map(({ row, top, height: height2 }) => {
1543
- return columnRange.map(({ column, left, width: width2 }) => {
2455
+ return columnRange.map(({ col, left, width: width2 }) => {
1544
2456
  const style = {
1545
2457
  position: "absolute",
1546
2458
  top,
@@ -1550,10 +2462,10 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1550
2462
  };
1551
2463
  const cell = {
1552
2464
  row,
1553
- column
2465
+ col
1554
2466
  };
1555
2467
  const id2 = addressToA1Notation(cell);
1556
- const idx = model.addressToIndex(cell);
2468
+ const idx = addressToIndex(model.sheet, cell);
1557
2469
  const active = posEquals(cursor, cell);
1558
2470
  if (active && editing) {
1559
2471
  const value = initialText.current ?? model.getCellText(cell) ?? "";
@@ -1586,7 +2498,7 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1586
2498
  inputRef.current?.focus();
1587
2499
  setEditing(false);
1588
2500
  };
1589
- return /* @__PURE__ */ React3.createElement(GridCellEditor, {
2501
+ return /* @__PURE__ */ React6.createElement(GridCellEditor, {
1590
2502
  key: idx,
1591
2503
  value,
1592
2504
  style,
@@ -1594,7 +2506,7 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1594
2506
  onClose: handleClose
1595
2507
  });
1596
2508
  }
1597
- return /* @__PURE__ */ React3.createElement(SheetCell, {
2509
+ return /* @__PURE__ */ React6.createElement(SheetCell, {
1598
2510
  key: id2,
1599
2511
  id: id2,
1600
2512
  cell,
@@ -1606,13 +2518,25 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1606
2518
  }
1607
2519
  });
1608
2520
  });
1609
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement("input", {
2521
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement(SheetInput, {
1610
2522
  ref: inputRef,
1611
- autoFocus: true,
2523
+ id,
2524
+ onKeyDown: handleKeyDown
2525
+ }), document.body));
2526
+ });
2527
+ var SheetInput = /* @__PURE__ */ forwardRef(({ id, onKeyDown }, forwardedRef) => {
2528
+ const path = useAttentionPath();
2529
+ const attendableAttrs = useAttendableAttributes(id);
2530
+ return path.toReversed().reduce((acc, part) => {
2531
+ return /* @__PURE__ */ React6.createElement("div", {
2532
+ [ATTENABLE_ATTRIBUTE]: part
2533
+ }, acc);
2534
+ }, /* @__PURE__ */ React6.createElement("input", {
2535
+ ref: forwardedRef,
1612
2536
  className: "absolute w-[1px] h-[1px] bg-transparent outline-none border-none caret-transparent",
1613
- onKeyDown: handleKeyDown,
2537
+ onKeyDown,
1614
2538
  ...attendableAttrs
1615
- }), document.body));
2539
+ }));
1616
2540
  });
1617
2541
  var SelectionOverlay = ({ root }) => {
1618
2542
  const { range } = useSheetContext();
@@ -1627,20 +2551,34 @@ var SelectionOverlay = ({ root }) => {
1627
2551
  const b1 = getRelativeClientRect(root, c1);
1628
2552
  const b2 = getRelativeClientRect(root, c2);
1629
2553
  const bounds = getRectUnion(b1, b2);
1630
- return /* @__PURE__ */ React3.createElement("div", {
2554
+ return /* @__PURE__ */ React6.createElement("div", {
1631
2555
  role: "none",
1632
2556
  style: bounds,
1633
2557
  className: "z-10 absolute pointer-events-none bg-gridSelectionOverlay border border-gridOverlay"
1634
2558
  });
1635
2559
  };
1636
2560
  var SheetCell = ({ id, cell, style, active, onSelect }) => {
1637
- const { formatting, editing, setRange } = useSheetContext();
2561
+ const { formatting, editing, setRange, decorations, model: { sheet } } = useSheetContext();
1638
2562
  const { value, classNames } = formatting.getFormatting(cell);
1639
- return /* @__PURE__ */ React3.createElement("div", {
2563
+ const decorationsForCell = decorations.getDecorationsForCell(addressToIndex(sheet, cell)) ?? [];
2564
+ const decorationAddedClasses = useMemo4(() => decorationsForCell.flatMap((d) => d.classNames ?? []), [
2565
+ decorationsForCell
2566
+ ]);
2567
+ const decoratedContent = decorationsForCell.reduce((children, { decorate }) => {
2568
+ if (!decorate) {
2569
+ return children;
2570
+ }
2571
+ const DecoratorComponent = decorate;
2572
+ return /* @__PURE__ */ React6.createElement(DecoratorComponent, null, children);
2573
+ }, /* @__PURE__ */ React6.createElement("div", {
2574
+ role: "none",
2575
+ className: mx2("flex flex-grow bs-full is-full px-2 items-center truncate cursor-pointer", ...decorationAddedClasses)
2576
+ }, value));
2577
+ return /* @__PURE__ */ React6.createElement("div", {
1640
2578
  [`data-${CELL_DATA_KEY}`]: id,
1641
2579
  role: "cell",
1642
2580
  style,
1643
- className: mx2("flex w-full h-full px-2 py-1 truncate items-center border border-gridLine cursor-pointer", fragments.cell, active && [
2581
+ className: mx2("border border-gridLine cursor-pointer", fragments.cell, active && [
1644
2582
  "z-20",
1645
2583
  fragments.cellSelected
1646
2584
  ], classNames),
@@ -1654,36 +2592,36 @@ var SheetCell = ({ id, cell, style, active, onSelect }) => {
1654
2592
  }
1655
2593
  },
1656
2594
  onDoubleClick: () => onSelect?.(cell, true)
1657
- }, value);
2595
+ }, decoratedContent);
1658
2596
  };
1659
2597
  var GridCellEditor = ({ style, value, onNav, onClose }) => {
1660
2598
  const { model, range } = useSheetContext();
1661
2599
  const notifier = useRef();
1662
- useEffect3(() => {
2600
+ useEffect4(() => {
1663
2601
  if (range) {
1664
2602
  notifier.current?.(rangeToA1Notation(range));
1665
2603
  }
1666
2604
  }, [
1667
2605
  range
1668
2606
  ]);
1669
- const extension = useMemo(() => [
2607
+ const extension = useMemo4(() => [
1670
2608
  editorKeys({
1671
2609
  onNav,
1672
2610
  onClose
1673
2611
  }),
1674
2612
  sheetExtension({
1675
- functions: model.functions
2613
+ functions: model.graph.getFunctions()
1676
2614
  }),
1677
2615
  rangeExtension((fn) => notifier.current = fn)
1678
2616
  ], [
1679
2617
  model
1680
2618
  ]);
1681
- return /* @__PURE__ */ React3.createElement("div", {
2619
+ return /* @__PURE__ */ React6.createElement("div", {
1682
2620
  role: "cell",
1683
2621
  style,
1684
2622
  className: mx2("z-20 flex", fragments.cellSelected),
1685
2623
  onClick: (ev) => ev.stopPropagation()
1686
- }, /* @__PURE__ */ React3.createElement(CellEditor, {
2624
+ }, /* @__PURE__ */ React6.createElement(CellEditor, {
1687
2625
  autoFocus: true,
1688
2626
  value,
1689
2627
  extension
@@ -1696,30 +2634,30 @@ var SheetStatusBar = () => {
1696
2634
  if (cursor) {
1697
2635
  value = model.getCellValue(cursor);
1698
2636
  if (typeof value === "string" && value.charAt(0) === "=") {
1699
- value = model.mapFormulaBindingFromId(model.mapFormulaIndicesToRefs(value));
2637
+ value = model.graph.mapFunctionBindingFromId(model.mapFormulaIndicesToRefs(value));
1700
2638
  isFormula = true;
1701
2639
  } else if (value != null) {
1702
2640
  value = String(value);
1703
2641
  }
1704
2642
  }
1705
- return /* @__PURE__ */ React3.createElement("div", {
2643
+ return /* @__PURE__ */ React6.createElement("div", {
1706
2644
  className: mx2("flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x border-gridLine")
1707
- }, /* @__PURE__ */ React3.createElement("div", {
2645
+ }, /* @__PURE__ */ React6.createElement("div", {
1708
2646
  className: "flex gap-4 items-center"
1709
- }, /* @__PURE__ */ React3.createElement("div", {
2647
+ }, /* @__PURE__ */ React6.createElement("div", {
1710
2648
  className: "flex w-16 items-center font-mono"
1711
- }, range && rangeToA1Notation(range) || cursor && addressToA1Notation(cursor)), /* @__PURE__ */ React3.createElement("div", {
2649
+ }, range && rangeToA1Notation(range) || cursor && addressToA1Notation(cursor)), /* @__PURE__ */ React6.createElement("div", {
1712
2650
  className: "flex gap-2 items-center"
1713
- }, /* @__PURE__ */ React3.createElement(FunctionIcon, {
2651
+ }, /* @__PURE__ */ React6.createElement(FunctionIcon, {
1714
2652
  className: mx2("text-greenText", isFormula ? "visible" : "invisible")
1715
- }), /* @__PURE__ */ React3.createElement("span", {
2653
+ }), /* @__PURE__ */ React6.createElement("span", {
1716
2654
  className: "font-mono"
1717
2655
  }, value))));
1718
2656
  };
1719
2657
  var SheetDebug = () => {
1720
2658
  const { model, cursor, range } = useSheetContext();
1721
- const [, forceUpdate] = useState4({});
1722
- useEffect3(() => {
2659
+ const [, forceUpdate] = useState5({});
2660
+ useEffect4(() => {
1723
2661
  const accessor = createDocAccessor(model.sheet, []);
1724
2662
  const handleUpdate = () => forceUpdate({});
1725
2663
  accessor.handle.addListener("change", handleUpdate);
@@ -1730,9 +2668,9 @@ var SheetDebug = () => {
1730
2668
  }, [
1731
2669
  model
1732
2670
  ]);
1733
- return /* @__PURE__ */ React3.createElement("div", {
2671
+ return /* @__PURE__ */ React6.createElement("div", {
1734
2672
  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", {
2673
+ }, /* @__PURE__ */ React6.createElement("pre", {
1736
2674
  className: "whitespace-pre-wrap"
1737
2675
  }, JSON.stringify({
1738
2676
  cursor,
@@ -1754,19 +2692,14 @@ var Sheet = {
1754
2692
  Debug: SheetDebug
1755
2693
  };
1756
2694
 
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
2695
  export {
1770
- SheetContainer_default as default
2696
+ ComputeGraphContextProvider,
2697
+ createSheet,
2698
+ addressToIndex,
2699
+ compareIndexPositions,
2700
+ useComputeGraph,
2701
+ useSheetContext,
2702
+ Sheet,
2703
+ SheetContainer
1771
2704
  };
1772
- //# sourceMappingURL=SheetContainer-U4H5D34A.mjs.map
2705
+ //# sourceMappingURL=chunk-ZL2V5UJR.mjs.map