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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/dist/lib/browser/SheetContainer-VISF3VUB.mjs +261 -0
  2. package/dist/lib/browser/SheetContainer-VISF3VUB.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-JRL5LGCE.mjs → chunk-QILRZNE5.mjs} +2 -5
  4. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-FUAGSXA4.mjs → chunk-WZMOZKQZ.mjs} +9 -16
  6. package/dist/lib/browser/chunk-WZMOZKQZ.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-D5AGLXJP.mjs → chunk-Z2XOOC2R.mjs} +385 -678
  8. package/dist/lib/browser/chunk-Z2XOOC2R.mjs.map +7 -0
  9. package/dist/lib/browser/{SheetContainer-U4H5D34A.mjs → chunk-ZLJ2GRE2.mjs} +1151 -240
  10. package/dist/lib/browser/chunk-ZLJ2GRE2.mjs.map +7 -0
  11. package/dist/lib/browser/graph-4XFKIHRL.mjs +21 -0
  12. package/dist/lib/browser/graph-4XFKIHRL.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +74 -60
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/meta.mjs +1 -1
  17. package/dist/lib/browser/types.mjs +4 -6
  18. package/dist/lib/node/SheetContainer-2MEALQWW.cjs +279 -0
  19. package/dist/lib/node/SheetContainer-2MEALQWW.cjs.map +7 -0
  20. package/dist/lib/node/{SheetContainer-AXQV3ZT5.cjs → chunk-6DQABRGJ.cjs} +1182 -279
  21. package/dist/lib/node/chunk-6DQABRGJ.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-DSYKOI4E.cjs → chunk-AOP42UAA.cjs} +13 -21
  23. package/dist/lib/node/chunk-AOP42UAA.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-BJ6ZD7MN.cjs → chunk-BNARJ5GM.cjs} +5 -18
  25. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +7 -0
  26. package/dist/lib/node/{chunk-5KKJ4NPP.cjs → chunk-P5QYYEHQ.cjs} +388 -676
  27. package/dist/lib/node/chunk-P5QYYEHQ.cjs.map +7 -0
  28. package/dist/lib/node/graph-2LRDUXBZ.cjs +43 -0
  29. package/dist/lib/node/graph-2LRDUXBZ.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +86 -66
  31. package/dist/lib/node/index.cjs.map +3 -3
  32. package/dist/lib/node/meta.cjs +3 -3
  33. package/dist/lib/node/meta.cjs.map +1 -1
  34. package/dist/lib/node/meta.json +1 -1
  35. package/dist/lib/node/types.cjs +10 -12
  36. package/dist/lib/node/types.cjs.map +2 -2
  37. package/dist/lib/node-esm/SheetContainer-RPSUSXWS.mjs +262 -0
  38. package/dist/lib/node-esm/SheetContainer-RPSUSXWS.mjs.map +7 -0
  39. package/dist/lib/node-esm/chunk-4MM7THJW.mjs +2944 -0
  40. package/dist/lib/node-esm/chunk-4MM7THJW.mjs.map +7 -0
  41. package/dist/lib/node-esm/chunk-5RLTCIE2.mjs +2684 -0
  42. package/dist/lib/node-esm/chunk-5RLTCIE2.mjs.map +7 -0
  43. package/dist/lib/node-esm/chunk-IU2L277A.mjs +17 -0
  44. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +7 -0
  45. package/dist/lib/node-esm/chunk-RR2AO4SM.mjs +76 -0
  46. package/dist/lib/node-esm/chunk-RR2AO4SM.mjs.map +7 -0
  47. package/dist/lib/node-esm/graph-WG5EKOMO.mjs +22 -0
  48. package/dist/lib/node-esm/graph-WG5EKOMO.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +263 -0
  50. package/dist/lib/node-esm/index.mjs.map +7 -0
  51. package/dist/lib/node-esm/meta.json +1 -0
  52. package/dist/lib/node-esm/meta.mjs +10 -0
  53. package/dist/lib/node-esm/meta.mjs.map +7 -0
  54. package/dist/lib/node-esm/types.mjs +21 -0
  55. package/dist/lib/node-esm/types.mjs.map +7 -0
  56. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  57. package/dist/types/src/components/CellEditor/CellEditor.d.ts +23 -3
  58. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -1
  59. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts +2 -2
  60. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -1
  61. package/dist/types/src/components/CellEditor/extension.d.ts +1 -1
  62. package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
  63. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +11 -0
  64. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -0
  65. package/dist/types/src/components/ComputeGraph/index.d.ts +1 -3
  66. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  67. package/dist/types/src/components/GridSheet/GridSheet.d.ts +10 -0
  68. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -0
  69. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +9 -0
  70. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -0
  71. package/dist/types/src/components/GridSheet/util.d.ts +7 -0
  72. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -0
  73. package/dist/types/src/components/Sheet/Sheet.d.ts +1 -1
  74. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  75. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +5 -6
  76. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/Sheet/decorations.d.ts +24 -0
  78. package/dist/types/src/components/Sheet/decorations.d.ts.map +1 -0
  79. package/dist/types/src/components/Sheet/grid.d.ts +2 -2
  80. package/dist/types/src/components/Sheet/grid.d.ts.map +1 -1
  81. package/dist/types/src/components/Sheet/nav.d.ts +3 -3
  82. package/dist/types/src/components/Sheet/nav.d.ts.map +1 -1
  83. package/dist/types/src/components/Sheet/sheet-context.d.ts +8 -7
  84. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
  85. package/dist/types/src/components/Sheet/threads.d.ts +2 -0
  86. package/dist/types/src/components/Sheet/threads.d.ts.map +1 -0
  87. package/dist/types/src/components/SheetContainer.d.ts +2 -3
  88. package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
  89. package/dist/types/src/components/Toolbar/Toolbar.d.ts +19 -3
  90. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  91. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +18 -13
  92. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/index.d.ts +2 -2
  94. package/dist/types/src/components/index.d.ts.map +1 -1
  95. package/dist/types/src/defs/index.d.ts +3 -0
  96. package/dist/types/src/defs/index.d.ts.map +1 -0
  97. package/dist/types/src/{model → defs}/types.d.ts +8 -3
  98. package/dist/types/src/defs/types.d.ts.map +1 -0
  99. package/dist/types/src/defs/types.test.d.ts.map +1 -0
  100. package/dist/types/src/defs/util.d.ts +43 -0
  101. package/dist/types/src/defs/util.d.ts.map +1 -0
  102. package/dist/types/src/extensions/compute.d.ts +9 -0
  103. package/dist/types/src/extensions/compute.d.ts.map +1 -0
  104. package/dist/types/src/extensions/compute.stories.d.ts +26 -0
  105. package/dist/types/src/extensions/compute.stories.d.ts.map +1 -0
  106. package/dist/types/src/extensions/index.d.ts +2 -0
  107. package/dist/types/src/extensions/index.d.ts.map +1 -0
  108. package/dist/types/src/{components/ComputeGraph → graph}/async-function.d.ts +8 -2
  109. package/dist/types/src/graph/async-function.d.ts.map +1 -0
  110. package/dist/types/src/graph/compute-graph.d.ts +84 -0
  111. package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
  112. package/dist/types/src/graph/compute-graph.stories.d.ts +10 -0
  113. package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
  114. package/dist/types/src/graph/compute-graph.test.d.ts +2 -0
  115. package/dist/types/src/graph/compute-graph.test.d.ts.map +1 -0
  116. package/dist/types/src/graph/compute-node.d.ts +26 -0
  117. package/dist/types/src/graph/compute-node.d.ts.map +1 -0
  118. package/dist/types/src/graph/edge-function.d.ts.map +1 -0
  119. package/dist/types/src/{model/functions.d.ts → graph/function-defs.d.ts} +1 -1
  120. package/dist/types/src/graph/function-defs.d.ts.map +1 -0
  121. package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
  122. package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
  123. package/dist/types/src/graph/index.d.ts +4 -0
  124. package/dist/types/src/graph/index.d.ts.map +1 -0
  125. package/dist/types/src/{components/ComputeGraph/custom.d.ts → graph/testing/custom-function.d.ts} +4 -2
  126. package/dist/types/src/graph/testing/custom-function.d.ts.map +1 -0
  127. package/dist/types/src/graph/testing/index.d.ts +2 -0
  128. package/dist/types/src/graph/testing/index.d.ts.map +1 -0
  129. package/dist/types/src/graph/util.d.ts +2 -0
  130. package/dist/types/src/graph/util.d.ts.map +1 -0
  131. package/dist/types/src/hooks/hooks.stories.d.ts +11 -0
  132. package/dist/types/src/hooks/hooks.stories.d.ts.map +1 -0
  133. package/dist/types/src/hooks/index.d.ts +4 -0
  134. package/dist/types/src/hooks/index.d.ts.map +1 -0
  135. package/dist/types/src/hooks/useComputeGraph.d.ts +7 -0
  136. package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -0
  137. package/dist/types/src/hooks/useFormattingModel.d.ts +3 -0
  138. package/dist/types/src/hooks/useFormattingModel.d.ts.map +1 -0
  139. package/dist/types/src/hooks/useSheetModel.d.ts +8 -0
  140. package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -0
  141. package/dist/types/src/meta.d.ts +1 -4
  142. package/dist/types/src/meta.d.ts.map +1 -1
  143. package/dist/types/src/model/formatting-model.d.ts +16 -0
  144. package/dist/types/src/model/formatting-model.d.ts.map +1 -0
  145. package/dist/types/src/model/index.d.ts +2 -3
  146. package/dist/types/src/model/index.d.ts.map +1 -1
  147. package/dist/types/src/model/{model.d.ts → sheet-model.d.ts} +10 -65
  148. package/dist/types/src/model/sheet-model.d.ts.map +1 -0
  149. package/dist/types/src/sanity.test.d.ts +2 -0
  150. package/dist/types/src/sanity.test.d.ts.map +1 -0
  151. package/dist/types/src/testing/index.d.ts +2 -0
  152. package/dist/types/src/testing/index.d.ts.map +1 -0
  153. package/dist/types/src/testing/testing.d.ts +8 -0
  154. package/dist/types/src/testing/testing.d.ts.map +1 -0
  155. package/dist/types/src/translations.d.ts +17 -12
  156. package/dist/types/src/translations.d.ts.map +1 -1
  157. package/dist/types/src/types.d.ts +86 -5
  158. package/dist/types/src/types.d.ts.map +1 -1
  159. package/dist/vendor/hyperformula.mjs +37145 -0
  160. package/package.json +48 -41
  161. package/src/SheetPlugin.tsx +48 -73
  162. package/src/components/CellEditor/CellEditor.stories.tsx +5 -4
  163. package/src/components/CellEditor/CellEditor.tsx +59 -9
  164. package/src/components/CellEditor/extension.test.ts +4 -5
  165. package/src/components/CellEditor/extension.ts +1 -3
  166. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +20 -0
  167. package/src/components/ComputeGraph/index.ts +1 -3
  168. package/src/components/GridSheet/GridSheet.stories.tsx +36 -0
  169. package/src/components/GridSheet/GridSheet.tsx +153 -0
  170. package/src/components/GridSheet/util.ts +108 -0
  171. package/src/components/Sheet/Sheet.stories.tsx +52 -88
  172. package/src/components/Sheet/Sheet.tsx +57 -18
  173. package/src/components/Sheet/decorations.ts +62 -0
  174. package/src/components/Sheet/grid.ts +3 -3
  175. package/src/components/Sheet/nav.ts +19 -19
  176. package/src/components/Sheet/sheet-context.tsx +18 -80
  177. package/src/components/Sheet/threads.tsx +205 -0
  178. package/src/components/SheetContainer.tsx +73 -19
  179. package/src/components/Toolbar/Toolbar.tsx +53 -12
  180. package/src/components/index.ts +1 -0
  181. package/src/defs/index.ts +6 -0
  182. package/src/{model → defs}/types.test.ts +8 -9
  183. package/src/{model → defs}/types.ts +24 -14
  184. package/src/defs/util.ts +151 -0
  185. package/src/extensions/compute.stories.tsx +153 -0
  186. package/src/extensions/compute.ts +131 -0
  187. package/src/extensions/index.ts +5 -0
  188. package/src/{components/ComputeGraph → graph}/async-function.ts +15 -6
  189. package/src/graph/compute-graph.stories.tsx +93 -0
  190. package/src/graph/compute-graph.test.ts +127 -0
  191. package/src/graph/compute-graph.ts +313 -0
  192. package/src/graph/compute-node.ts +62 -0
  193. package/src/{components/ComputeGraph → graph}/edge-function.ts +3 -3
  194. package/src/graph/hyperformula.test.ts +15 -0
  195. package/src/graph/index.ts +7 -0
  196. package/src/{components/ComputeGraph/custom.ts → graph/testing/custom-function.ts} +11 -7
  197. package/src/graph/testing/index.ts +5 -0
  198. package/src/graph/util.ts +8 -0
  199. package/src/hooks/hooks.stories.tsx +50 -0
  200. package/src/hooks/index.ts +7 -0
  201. package/src/hooks/useComputeGraph.ts +21 -0
  202. package/src/hooks/useFormattingModel.ts +11 -0
  203. package/src/hooks/useSheetModel.ts +40 -0
  204. package/src/meta.tsx +1 -5
  205. package/src/{components/Sheet/formatting.ts → model/formatting-model.ts} +20 -13
  206. package/src/model/index.ts +2 -3
  207. package/src/model/sheet-model.ts +414 -0
  208. package/src/sanity.test.ts +40 -0
  209. package/src/testing/index.ts +5 -0
  210. package/src/testing/testing.tsx +68 -0
  211. package/src/translations.ts +6 -1
  212. package/src/types.ts +31 -6
  213. package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +0 -7
  214. package/dist/lib/browser/chunk-APHOLYUB.mjs +0 -175
  215. package/dist/lib/browser/chunk-APHOLYUB.mjs.map +0 -7
  216. package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +0 -7
  218. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
  219. package/dist/lib/browser/chunk-NU4PBN33.mjs +0 -8
  220. package/dist/lib/browser/chunk-NU4PBN33.mjs.map +0 -7
  221. package/dist/lib/browser/testing.mjs +0 -92
  222. package/dist/lib/browser/testing.mjs.map +0 -7
  223. package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +0 -7
  224. package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +0 -7
  225. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
  226. package/dist/lib/node/chunk-CN3RPESU.cjs +0 -202
  227. package/dist/lib/node/chunk-CN3RPESU.cjs.map +0 -7
  228. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +0 -7
  229. package/dist/lib/node/chunk-PYXHNAAK.cjs +0 -40
  230. package/dist/lib/node/chunk-PYXHNAAK.cjs.map +0 -7
  231. package/dist/lib/node/testing.cjs +0 -111
  232. package/dist/lib/node/testing.cjs.map +0 -7
  233. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
  234. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
  235. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
  236. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
  237. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
  238. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
  239. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
  240. package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
  241. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
  242. package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
  243. package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
  244. package/dist/types/src/model/functions.d.ts.map +0 -1
  245. package/dist/types/src/model/model.browser.test.d.ts +0 -2
  246. package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
  247. package/dist/types/src/model/model.d.ts.map +0 -1
  248. package/dist/types/src/model/types.d.ts.map +0 -1
  249. package/dist/types/src/model/types.test.d.ts.map +0 -1
  250. package/dist/types/src/model/util.d.ts +0 -15
  251. package/dist/types/src/model/util.d.ts.map +0 -1
  252. package/dist/types/src/testing.d.ts +0 -9
  253. package/dist/types/src/testing.d.ts.map +0 -1
  254. package/src/components/ComputeGraph/graph-context.tsx +0 -50
  255. package/src/components/ComputeGraph/graph.browser.test.ts +0 -50
  256. package/src/components/ComputeGraph/graph.ts +0 -62
  257. package/src/model/model.browser.test.ts +0 -100
  258. package/src/model/model.ts +0 -550
  259. package/src/model/util.ts +0 -36
  260. package/src/testing.ts +0 -50
  261. /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
  262. /package/dist/types/src/{components/ComputeGraph → graph}/edge-function.d.ts +0 -0
  263. /package/src/{model/functions.ts → graph/function-defs.ts} +0 -0
@@ -1,24 +1,13 @@
1
1
  import {
2
- useComputeGraph
3
- } from "./chunk-APHOLYUB.mjs";
2
+ SheetType,
3
+ ValueTypeEnum
4
+ } from "./chunk-WZMOZKQZ.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-Z2XOOC2R.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";
23
+ import { log as log2 } from "@dxos/log";
35
24
  import { createAttendableAttributes, useHasAttention } 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,104 @@ 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-VISF3VUB.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 () => space && registry.getOrCreateGraph(space), [
553
+ space,
554
+ registry
555
+ ]);
556
+ return graph;
557
+ };
333
558
 
334
- // packages/plugins/plugin-sheet/src/components/Sheet/formatting.ts
559
+ // packages/plugins/plugin-sheet/src/hooks/useFormattingModel.ts
560
+ import { useMemo } from "react";
561
+
562
+ // packages/plugins/plugin-sheet/src/model/formatting-model.ts
335
563
  var FormattingModel = class {
336
- constructor(model) {
337
- this.model = model;
564
+ constructor(_model) {
565
+ this._model = _model;
338
566
  }
339
567
  /**
340
568
  * Get formatted string value and className for cell.
341
569
  */
342
570
  getFormatting(cell) {
343
- const value = this.model.getValue(cell);
571
+ const value = this._model.getValue(cell);
344
572
  if (value === void 0 || value === null) {
345
573
  return {};
346
574
  }
347
575
  const locales = void 0;
348
- const idx = this.model.addressToIndex(cell);
349
- let formatting = this.model.sheet.formatting?.[idx] ?? {};
576
+ const idx = addressToIndex(this._model.sheet, cell);
577
+ let formatting = this._model.sheet.formatting?.[idx] ?? {};
350
578
  const classNames = [
351
579
  ...formatting?.classNames ?? []
352
580
  ];
353
- for (const [idx2, _formatting] of Object.entries(this.model.sheet.formatting)) {
354
- const range = this.model.rangeFromIndex(idx2);
581
+ for (const [idx2, _formatting] of Object.entries(this._model.sheet.formatting)) {
582
+ const range = rangeFromIndex(this._model.sheet, idx2);
355
583
  if (inRange(range, cell)) {
356
584
  if (_formatting.classNames) {
357
585
  classNames.push(..._formatting.classNames);
@@ -362,7 +590,7 @@ var FormattingModel = class {
362
590
  }
363
591
  }
364
592
  const defaultNumber = "justify-end font-mono";
365
- const type = formatting?.type ?? this.model.getValueType(cell);
593
+ const type = formatting?.type ?? this._model.getValueType(cell);
366
594
  switch (type) {
367
595
  case ValueTypeEnum.Boolean: {
368
596
  return {
@@ -412,21 +640,21 @@ var FormattingModel = class {
412
640
  // Dates.
413
641
  //
414
642
  case ValueTypeEnum.DateTime: {
415
- const date = this.model.toLocalDate(value);
643
+ const date = this._model.toLocalDate(value);
416
644
  return {
417
645
  value: date.toLocaleString(locales),
418
646
  classNames
419
647
  };
420
648
  }
421
649
  case ValueTypeEnum.Date: {
422
- const date = this.model.toLocalDate(value);
650
+ const date = this._model.toLocalDate(value);
423
651
  return {
424
652
  value: date.toLocaleDateString(locales),
425
653
  classNames
426
654
  };
427
655
  }
428
656
  case ValueTypeEnum.Time: {
429
- const date = this.model.toLocalDate(value);
657
+ const date = this._model.toLocalDate(value);
430
658
  return {
431
659
  value: date.toLocaleTimeString(locales),
432
660
  classNames
@@ -442,84 +670,549 @@ var FormattingModel = class {
442
670
  }
443
671
  };
444
672
 
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;
673
+ // packages/plugins/plugin-sheet/src/model/sheet-model.ts
674
+ import { Event } from "@dxos/async";
675
+ import { Resource } from "@dxos/context";
676
+ import { invariant as invariant2 } from "@dxos/invariant";
677
+ import { PublicKey } from "@dxos/keys";
678
+ import { log } from "@dxos/log";
679
+ import { DetailedCellError, ExportedCellChange } from "#hyperformula";
680
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/model/sheet-model.ts";
681
+ var typeMap = {
682
+ BOOLEAN: ValueTypeEnum.Boolean,
683
+ NUMBER_RAW: ValueTypeEnum.Number,
684
+ NUMBER_PERCENT: ValueTypeEnum.Percent,
685
+ NUMBER_CURRENCY: ValueTypeEnum.Currency,
686
+ NUMBER_DATETIME: ValueTypeEnum.DateTime,
687
+ NUMBER_DATE: ValueTypeEnum.Date,
688
+ NUMBER_TIME: ValueTypeEnum.Time
461
689
  };
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;
690
+ var getTopLeft = (range) => {
691
+ const to = range.to ?? range.from;
692
+ return {
693
+ row: Math.min(range.from.row, to.row),
694
+ col: Math.min(range.from.col, to.col)
695
+ };
696
+ };
697
+ var toSimpleCellAddress = (sheet, cell) => ({
698
+ sheet,
699
+ row: cell.row,
700
+ col: cell.col
701
+ });
702
+ var toModelRange = (sheet, range) => ({
703
+ start: toSimpleCellAddress(sheet, range.from),
704
+ end: toSimpleCellAddress(sheet, range.to ?? range.from)
705
+ });
706
+ var SheetModel = class extends Resource {
707
+ constructor(_graph, _sheet, _options = {}) {
708
+ super();
709
+ this._graph = _graph;
710
+ this._sheet = _sheet;
711
+ this._options = _options;
712
+ this.id = `model-${PublicKey.random().truncate()}`;
713
+ this.update = new Event();
714
+ }
715
+ get graph() {
716
+ return this._graph;
717
+ }
718
+ get sheet() {
719
+ return this._sheet;
720
+ }
721
+ get readonly() {
722
+ return this._options.readonly;
723
+ }
724
+ get bounds() {
725
+ return {
726
+ rows: this._sheet.rows.length,
727
+ columns: this._sheet.columns.length
728
+ };
729
+ }
730
+ /**
731
+ * Initialize sheet and engine.
732
+ */
733
+ async _open() {
734
+ log("initialize", {
735
+ id: this.id
736
+ }, {
737
+ F: __dxlog_file2,
738
+ L: 103,
739
+ S: this,
740
+ C: (f, a) => f(...a)
741
+ });
742
+ initialize(this._sheet);
743
+ this._node = await this._graph.getOrCreateNode(createSheetName(this._sheet.id));
744
+ const unsubscribe = this._node.update.on((event) => this.update.emit(event));
745
+ this._ctx.onDispose(unsubscribe);
746
+ this.reset();
747
+ }
748
+ /**
749
+ * Update engine.
750
+ * NOTE: This resets the undo history.
751
+ * @deprecated
752
+ */
753
+ reset() {
754
+ invariant2(this._node, void 0, {
755
+ F: __dxlog_file2,
756
+ L: 122,
757
+ S: this,
758
+ A: [
759
+ "this._node",
760
+ ""
761
+ ]
762
+ });
763
+ this._node.graph.hf.clearSheet(this._node.sheetId);
764
+ Object.entries(this._sheet.cells).forEach(([key, { value }]) => {
765
+ invariant2(this._node, void 0, {
766
+ F: __dxlog_file2,
767
+ L: 125,
768
+ S: this,
769
+ A: [
770
+ "this._node",
771
+ ""
772
+ ]
773
+ });
774
+ const { col, row } = addressFromIndex(this._sheet, key);
775
+ if (typeof value === "string" && value.charAt(0) === "=") {
776
+ value = this._graph.mapFormulaToNative(this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value)));
777
+ }
778
+ this._node.graph.hf.setCellContents({
779
+ sheet: this._node.sheetId,
780
+ row,
781
+ col
782
+ }, value);
783
+ });
784
+ }
785
+ /**
786
+ * Recalculate formulas.
787
+ * NOTE: This resets the undo history.
788
+ * https://hyperformula.handsontable.com/guide/volatile-functions.html#volatile-actions
789
+ * @deprecated
790
+ */
791
+ // TODO(burdon): Remove.
792
+ recalculate() {
793
+ this._node?.graph.hf.rebuildAndRecalculate();
794
+ }
795
+ insertRows(i, n = 1) {
796
+ insertIndices(this._sheet.rows, i, n, MAX_ROWS);
797
+ this.reset();
798
+ }
799
+ insertColumns(i, n = 1) {
800
+ insertIndices(this._sheet.columns, i, n, MAX_COLUMNS);
801
+ this.reset();
802
+ }
803
+ //
804
+ // Undoable actions.
805
+ // TODO(burdon): Group undoable methods; consistently update hf/sheet.
806
+ //
807
+ /**
808
+ * Clear range of values.
809
+ */
810
+ clear(range) {
811
+ invariant2(this._node, void 0, {
812
+ F: __dxlog_file2,
813
+ L: 167,
814
+ S: this,
815
+ A: [
816
+ "this._node",
817
+ ""
818
+ ]
819
+ });
820
+ const topLeft = getTopLeft(range);
821
+ const values = this._iterRange(range, () => null);
822
+ this._node.graph.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);
823
+ this._iterRange(range, (cell) => {
824
+ const idx = addressToIndex(this._sheet, cell);
825
+ delete this._sheet.cells[idx];
826
+ });
827
+ }
828
+ cut(range) {
829
+ invariant2(this._node, void 0, {
830
+ F: __dxlog_file2,
831
+ L: 178,
832
+ S: this,
833
+ A: [
834
+ "this._node",
835
+ ""
836
+ ]
837
+ });
838
+ this._node.graph.hf.cut(toModelRange(this._node.sheetId, range));
839
+ this._iterRange(range, (cell) => {
840
+ const idx = addressToIndex(this._sheet, cell);
841
+ delete this._sheet.cells[idx];
842
+ });
843
+ }
844
+ copy(range) {
845
+ invariant2(this._node, void 0, {
846
+ F: __dxlog_file2,
847
+ L: 187,
848
+ S: this,
849
+ A: [
850
+ "this._node",
851
+ ""
852
+ ]
853
+ });
854
+ this._node.graph.hf.copy(toModelRange(this._node.sheetId, range));
855
+ }
856
+ paste(cell) {
857
+ invariant2(this._node, void 0, {
858
+ F: __dxlog_file2,
859
+ L: 192,
860
+ S: this,
861
+ A: [
862
+ "this._node",
863
+ ""
864
+ ]
865
+ });
866
+ if (!this._node.graph.hf.isClipboardEmpty()) {
867
+ const changes = this._node.graph.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));
868
+ for (const change of changes) {
869
+ if (change instanceof ExportedCellChange) {
870
+ const { address, newValue } = change;
871
+ const idx = addressToIndex(this._sheet, {
872
+ row: address.row,
873
+ col: address.col
874
+ });
875
+ this._sheet.cells[idx] = {
876
+ value: newValue
877
+ };
878
+ }
879
+ }
466
880
  }
467
- const fn = functions.find((fn2) => fn2.binding === binding);
468
- if (fn) {
469
- return `${fullyQualifiedId(fn)}(${args})`;
881
+ }
882
+ // TODO(burdon): Display undo/redo state.
883
+ undo() {
884
+ invariant2(this._node, void 0, {
885
+ F: __dxlog_file2,
886
+ L: 207,
887
+ S: this,
888
+ A: [
889
+ "this._node",
890
+ ""
891
+ ]
892
+ });
893
+ if (this._node.graph.hf.isThereSomethingToUndo()) {
894
+ this._node.graph.hf.undo();
895
+ }
896
+ }
897
+ redo() {
898
+ invariant2(this._node, void 0, {
899
+ F: __dxlog_file2,
900
+ L: 215,
901
+ S: this,
902
+ A: [
903
+ "this._node",
904
+ ""
905
+ ]
906
+ });
907
+ if (this._node.graph.hf.isThereSomethingToRedo()) {
908
+ this._node.graph.hf.redo();
909
+ }
910
+ }
911
+ /**
912
+ * Get value from sheet.
913
+ */
914
+ getCellValue(cell) {
915
+ const idx = addressToIndex(this._sheet, cell);
916
+ return this._sheet.cells[idx]?.value ?? null;
917
+ }
918
+ /**
919
+ * Get value as a string for editing.
920
+ */
921
+ getCellText(cell) {
922
+ const value = this.getCellValue(cell);
923
+ if (value == null) {
924
+ return void 0;
925
+ }
926
+ if (typeof value === "string" && value.charAt(0) === "=") {
927
+ return this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value));
470
928
  } else {
471
- return match;
929
+ return String(value);
472
930
  }
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;
931
+ }
932
+ /**
933
+ * Get array of raw values from sheet.
934
+ */
935
+ getCellValues(range) {
936
+ return this._iterRange(range, (cell) => this.getCellValue(cell));
937
+ }
938
+ /**
939
+ * Gets the regular or computed value from the engine.
940
+ */
941
+ getValue(cell) {
942
+ invariant2(this._node, void 0, {
943
+ F: __dxlog_file2,
944
+ L: 258,
945
+ S: this,
946
+ A: [
947
+ "this._node",
948
+ ""
949
+ ]
950
+ });
951
+ const value = this._node.graph.hf.getCellValue(toSimpleCellAddress(this._node.sheetId, cell));
952
+ if (value instanceof DetailedCellError) {
953
+ return value.toString();
954
+ }
955
+ return value;
956
+ }
957
+ /**
958
+ * Get value type.
959
+ */
960
+ getValueType(cell) {
961
+ invariant2(this._node, void 0, {
962
+ F: __dxlog_file2,
963
+ L: 271,
964
+ S: this,
965
+ A: [
966
+ "this._node",
967
+ ""
968
+ ]
969
+ });
970
+ const addr = toSimpleCellAddress(this._node.sheetId, cell);
971
+ const type = this._node.graph.hf.getCellValueDetailedType(addr);
972
+ return typeMap[type];
973
+ }
974
+ /**
975
+ * Sets the value, updating the sheet and engine.
976
+ */
977
+ setValue(cell, value) {
978
+ invariant2(this._node, void 0, {
979
+ F: __dxlog_file2,
980
+ L: 281,
981
+ S: this,
982
+ A: [
983
+ "this._node",
984
+ ""
985
+ ]
986
+ });
987
+ if (this._options.readonly) {
988
+ throw new ReadonlyException();
989
+ }
990
+ let refresh = false;
991
+ if (cell.row >= this._sheet.rows.length) {
992
+ insertIndices(this._sheet.rows, cell.row, 1, MAX_ROWS);
993
+ refresh = true;
480
994
  }
481
- const fn = functions.find((fn2) => fullyQualifiedId(fn2) === id);
482
- if (fn?.binding) {
483
- return `${fn.binding}(${args})`;
995
+ if (cell.col >= this._sheet.columns.length) {
996
+ insertIndices(this._sheet.columns, cell.col, 1, MAX_COLUMNS);
997
+ refresh = true;
998
+ }
999
+ if (refresh) {
1000
+ this.reset();
1001
+ }
1002
+ this._node.graph.hf.setCellContents({
1003
+ sheet: this._node.sheetId,
1004
+ row: cell.row,
1005
+ col: cell.col
1006
+ }, [
1007
+ [
1008
+ typeof value === "string" && value.charAt(0) === "=" ? this._graph.mapFormulaToNative(value) : value
1009
+ ]
1010
+ ]);
1011
+ const idx = addressToIndex(this._sheet, cell);
1012
+ if (value === void 0 || value === null) {
1013
+ delete this._sheet.cells[idx];
484
1014
  } else {
485
- return match;
1015
+ if (typeof value === "string" && value.charAt(0) === "=") {
1016
+ value = this._graph.mapFunctionBindingToId(this.mapFormulaRefsToIndices(value));
1017
+ }
1018
+ this._sheet.cells[idx] = {
1019
+ value
1020
+ };
486
1021
  }
487
- });
1022
+ }
1023
+ /**
1024
+ * Sets values from a simple map.
1025
+ */
1026
+ setValues(values) {
1027
+ Object.entries(values).forEach(([key, { value }]) => {
1028
+ this.setValue(addressFromA1Notation(key), value);
1029
+ });
1030
+ }
1031
+ /**
1032
+ * Iterate range.
1033
+ */
1034
+ _iterRange(range, cb) {
1035
+ const to = range.to ?? range.from;
1036
+ const rowRange = [
1037
+ Math.min(range.from.row, to.row),
1038
+ Math.max(range.from.row, to.row)
1039
+ ];
1040
+ const columnRange = [
1041
+ Math.min(range.from.col, to.col),
1042
+ Math.max(range.from.col, to.col)
1043
+ ];
1044
+ const rows = [];
1045
+ for (let row = rowRange[0]; row <= rowRange[1]; row++) {
1046
+ const rowCells = [];
1047
+ for (let column = columnRange[0]; column <= columnRange[1]; column++) {
1048
+ const value = cb({
1049
+ row,
1050
+ col: column
1051
+ });
1052
+ if (value !== void 0) {
1053
+ rowCells.push(value);
1054
+ }
1055
+ }
1056
+ rows.push(rowCells);
1057
+ }
1058
+ return rows;
1059
+ }
1060
+ // TODO(burdon): Delete index.
1061
+ _deleteIndices(indices, i, n) {
1062
+ throw new Error("Not implemented");
1063
+ }
1064
+ // TODO(burdon): Move. Cannot use fractional without changing. Switch back to using unique IDs?
1065
+ _moveIndices(indices, i, j, n) {
1066
+ throw new Error("Not implemented");
1067
+ }
1068
+ //
1069
+ // Indices.
1070
+ //
1071
+ /**
1072
+ * Map from A1 notation to indices.
1073
+ */
1074
+ mapFormulaRefsToIndices(formula) {
1075
+ invariant2(formula.charAt(0) === "=", void 0, {
1076
+ F: __dxlog_file2,
1077
+ L: 370,
1078
+ S: this,
1079
+ A: [
1080
+ "formula.charAt(0) === '='",
1081
+ ""
1082
+ ]
1083
+ });
1084
+ return formula.replace(/([a-zA-Z]+)([0-9]+)/g, (match) => {
1085
+ return addressToIndex(this._sheet, addressFromA1Notation(match));
1086
+ });
1087
+ }
1088
+ /**
1089
+ * Map from indices to A1 notation.
1090
+ */
1091
+ mapFormulaIndicesToRefs(formula) {
1092
+ invariant2(formula.charAt(0) === "=", void 0, {
1093
+ F: __dxlog_file2,
1094
+ L: 380,
1095
+ S: this,
1096
+ A: [
1097
+ "formula.charAt(0) === '='",
1098
+ ""
1099
+ ]
1100
+ });
1101
+ return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {
1102
+ return addressToA1Notation(addressFromIndex(this._sheet, idx));
1103
+ });
1104
+ }
1105
+ //
1106
+ // Values
1107
+ //
1108
+ /**
1109
+ * https://hyperformula.handsontable.com/guide/date-and-time-handling.html#example
1110
+ * https://hyperformula.handsontable.com/api/interfaces/configparams.html#nulldate
1111
+ * NOTE: TODAY() is number of FULL days since nullDate. It will typically be -1 days from NOW().
1112
+ */
1113
+ toLocalDate(num) {
1114
+ const { year, month, day, hours, minutes, seconds } = this.toDateTime(num);
1115
+ return new Date(year, month - 1, day, hours, minutes, seconds);
1116
+ }
1117
+ toDateTime(num) {
1118
+ invariant2(this._node, void 0, {
1119
+ F: __dxlog_file2,
1120
+ L: 401,
1121
+ S: this,
1122
+ A: [
1123
+ "this._node",
1124
+ ""
1125
+ ]
1126
+ });
1127
+ return this._node.graph.hf.numberToDateTime(num);
1128
+ }
1129
+ toDate(num) {
1130
+ invariant2(this._node, void 0, {
1131
+ F: __dxlog_file2,
1132
+ L: 406,
1133
+ S: this,
1134
+ A: [
1135
+ "this._node",
1136
+ ""
1137
+ ]
1138
+ });
1139
+ return this._node.graph.hf.numberToDate(num);
1140
+ }
1141
+ toTime(num) {
1142
+ invariant2(this._node, void 0, {
1143
+ F: __dxlog_file2,
1144
+ L: 411,
1145
+ S: this,
1146
+ A: [
1147
+ "this._node",
1148
+ ""
1149
+ ]
1150
+ });
1151
+ return this._node.graph.hf.numberToTime(num);
1152
+ }
488
1153
  };
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);
1154
+
1155
+ // packages/plugins/plugin-sheet/src/hooks/useFormattingModel.ts
1156
+ var useFormattingModel = (model) => {
1157
+ return useMemo(() => model && new FormattingModel(model), [
1158
+ model
1159
+ ]);
1160
+ };
1161
+
1162
+ // packages/plugins/plugin-sheet/src/hooks/useSheetModel.ts
1163
+ import { useEffect as useEffect2, useState as useState3 } from "react";
1164
+ var useSheetModel = (graph, sheet, { readonly } = {}) => {
1165
+ const [model, setModel] = useState3();
495
1166
  useEffect2(() => {
1167
+ if (!graph || !sheet) {
1168
+ return;
1169
+ }
496
1170
  let model2;
497
- let formatting2;
498
1171
  const t = setTimeout(async () => {
499
- model2 = new SheetModel(graph, sheet, space, {
500
- readonly,
501
- mapFormulaBindingToId,
502
- mapFormulaBindingFromId
1172
+ model2 = new SheetModel(graph, sheet, {
1173
+ readonly
503
1174
  });
504
- await model2.initialize();
505
- formatting2 = new FormattingModel(model2);
506
- setModels([
507
- model2,
508
- formatting2
509
- ]);
1175
+ await model2.open();
1176
+ setModel(model2);
510
1177
  });
511
1178
  return () => {
512
1179
  clearTimeout(t);
513
- void model2?.destroy();
1180
+ void model2?.close();
514
1181
  };
515
1182
  }, [
516
1183
  graph,
1184
+ sheet,
517
1185
  readonly
518
1186
  ]);
519
- if (!model || !formatting) {
520
- return null;
521
- }
522
- return /* @__PURE__ */ React.createElement(SheetContext.Provider, {
1187
+ return model;
1188
+ };
1189
+
1190
+ // packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx
1191
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx";
1192
+ var SheetContext = /* @__PURE__ */ createContext2(null);
1193
+ var useSheetContext = () => {
1194
+ const context = useContext2(SheetContext);
1195
+ invariant3(context, void 0, {
1196
+ F: __dxlog_file3,
1197
+ L: 43,
1198
+ S: void 0,
1199
+ A: [
1200
+ "context",
1201
+ ""
1202
+ ]
1203
+ });
1204
+ return context;
1205
+ };
1206
+ var SheetContextProvider = ({ children, graph, sheet, readonly, onInfo }) => {
1207
+ const model = useSheetModel(graph, sheet, {
1208
+ readonly
1209
+ });
1210
+ const formatting = useFormattingModel(model);
1211
+ const [cursor, setCursor] = useState4();
1212
+ const [range, setRange] = useState4();
1213
+ const [editing, setEditing] = useState4(false);
1214
+ const decorations = useMemo2(() => createDecorations(), []);
1215
+ return !model || !formatting ? null : /* @__PURE__ */ React3.createElement(SheetContext.Provider, {
523
1216
  value: {
524
1217
  model,
525
1218
  formatting,
@@ -530,11 +1223,177 @@ var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...optio
530
1223
  editing,
531
1224
  setEditing,
532
1225
  // TODO(burdon): Change to event.
533
- onInfo
1226
+ onInfo,
1227
+ decorations
534
1228
  }
535
1229
  }, children);
536
1230
  };
537
1231
 
1232
+ // packages/plugins/plugin-sheet/src/components/Sheet/threads.tsx
1233
+ import { effect } from "@preact/signals-core";
1234
+ import React4, { useCallback, useEffect as useEffect3, useMemo as useMemo3 } from "react";
1235
+ import { LayoutAction, useIntentDispatcher, useIntentResolver } from "@dxos/app-framework";
1236
+ import { debounce } from "@dxos/async";
1237
+ import { fullyQualifiedId } from "@dxos/react-client/echo";
1238
+ import { Icon, useTranslation } from "@dxos/react-ui";
1239
+ var CommentIndicator = () => {
1240
+ return /* @__PURE__ */ React4.createElement("div", {
1241
+ role: "none",
1242
+ className: "absolute top-0 right-0 w-0 h-0 border-t-8 border-l-8 border-t-cmCommentSurface border-l-transparent"
1243
+ });
1244
+ };
1245
+ var ThreadedCellWrapper = ({ children }) => {
1246
+ const dispatch = useIntentDispatcher();
1247
+ const [isHovered, setIsHovered] = React4.useState(false);
1248
+ const { t } = useTranslation(SHEET_PLUGIN);
1249
+ const handleClick = React4.useCallback((_event) => {
1250
+ void dispatch({
1251
+ action: LayoutAction.SET_LAYOUT,
1252
+ data: {
1253
+ element: "complementary",
1254
+ state: true
1255
+ }
1256
+ });
1257
+ }, [
1258
+ dispatch
1259
+ ]);
1260
+ return /* @__PURE__ */ React4.createElement("div", {
1261
+ role: "none",
1262
+ className: "relative h-full is-full",
1263
+ onMouseEnter: () => {
1264
+ setIsHovered(true);
1265
+ },
1266
+ onMouseLeave: () => {
1267
+ setIsHovered(false);
1268
+ }
1269
+ }, /* @__PURE__ */ React4.createElement(CommentIndicator, null), isHovered && /* @__PURE__ */ React4.createElement("div", {
1270
+ className: "absolute inset-0 flex items-center justify-end pr-1"
1271
+ }, /* @__PURE__ */ React4.createElement("button", {
1272
+ className: "ch-button text-xs min-bs-0 p-1",
1273
+ onClick: handleClick,
1274
+ "aria-label": t("open comment for sheet cell")
1275
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1276
+ icon: "ph--chat--regular",
1277
+ "aria-hidden": true
1278
+ }))), children);
1279
+ };
1280
+ var createThreadDecoration = (cellIndex, threadId, sheetId) => {
1281
+ return {
1282
+ type: "comment",
1283
+ cellIndex,
1284
+ decorate: (props) => /* @__PURE__ */ React4.createElement(ThreadedCellWrapper, props)
1285
+ };
1286
+ };
1287
+ var useUpdateCursorOnThreadSelection = () => {
1288
+ const { setCursor, model } = useSheetContext();
1289
+ const handleScrollIntoView = useCallback(({ action, data }) => {
1290
+ switch (action) {
1291
+ case LayoutAction.SCROLL_INTO_VIEW: {
1292
+ if (!data?.id || data?.cursor === void 0 || data?.id !== fullyQualifiedId(model.sheet)) {
1293
+ return;
1294
+ }
1295
+ const cellAddress = addressFromIndex(model.sheet, data.cursor);
1296
+ setCursor(cellAddress);
1297
+ }
1298
+ }
1299
+ }, [
1300
+ model.sheet,
1301
+ setCursor
1302
+ ]);
1303
+ useIntentResolver(SHEET_PLUGIN, handleScrollIntoView);
1304
+ };
1305
+ var useSelectThreadOnCursorChange = () => {
1306
+ const { cursor, model } = useSheetContext();
1307
+ const dispatch = useIntentDispatcher();
1308
+ const activeThreads = useMemo3(() => model.sheet.threads?.filter((thread) => !!thread && thread.status === "active") ?? [], [
1309
+ JSON.stringify(model.sheet.threads)
1310
+ ]);
1311
+ const activeThreadAddresses = useMemo3(() => activeThreads.map((thread) => thread.anchor).filter((anchor) => anchor !== void 0).map((anchor) => addressFromIndex(model.sheet, anchor)), [
1312
+ activeThreads,
1313
+ model.sheet
1314
+ ]);
1315
+ const selectClosestThread = useCallback((cellAddress) => {
1316
+ if (!cellAddress || !activeThreads) {
1317
+ return;
1318
+ }
1319
+ const closestThreadAnchor = closest(cellAddress, activeThreadAddresses);
1320
+ if (closestThreadAnchor) {
1321
+ const closestThread = activeThreads.find((thread) => thread && thread.anchor === addressToIndex(model.sheet, closestThreadAnchor));
1322
+ if (closestThread) {
1323
+ void dispatch([
1324
+ {
1325
+ action: "dxos.org/plugin/thread/action/select",
1326
+ data: {
1327
+ current: fullyQualifiedId(closestThread)
1328
+ }
1329
+ }
1330
+ ]);
1331
+ }
1332
+ }
1333
+ }, [
1334
+ dispatch,
1335
+ activeThreads,
1336
+ activeThreadAddresses,
1337
+ model.sheet
1338
+ ]);
1339
+ const debounced = useMemo3(() => {
1340
+ return debounce((cursor2) => requestAnimationFrame(() => selectClosestThread(cursor2)), 50);
1341
+ }, [
1342
+ selectClosestThread
1343
+ ]);
1344
+ useEffect3(() => {
1345
+ if (!cursor) {
1346
+ return;
1347
+ }
1348
+ debounced(cursor);
1349
+ }, [
1350
+ cursor,
1351
+ selectClosestThread
1352
+ ]);
1353
+ };
1354
+ var useThreadDecorations = () => {
1355
+ const { decorations, model } = useSheetContext();
1356
+ const sheet = useMemo3(() => model.sheet, [
1357
+ model.sheet
1358
+ ]);
1359
+ const sheetId = useMemo3(() => fullyQualifiedId(sheet), [
1360
+ sheet
1361
+ ]);
1362
+ useEffect3(() => {
1363
+ const unsubscribe = effect(() => {
1364
+ const activeThreadAnchors = /* @__PURE__ */ new Set();
1365
+ if (!sheet.threads) {
1366
+ return;
1367
+ }
1368
+ for (const thread of sheet.threads) {
1369
+ if (!thread || thread.anchor === void 0 || thread.status === "resolved") {
1370
+ continue;
1371
+ }
1372
+ activeThreadAnchors.add(thread.anchor);
1373
+ const index = thread.anchor;
1374
+ const existingDecorations = decorations.getDecorationsForCell(index);
1375
+ if (!existingDecorations || !existingDecorations.some((d) => d.type === "comment")) {
1376
+ decorations.addDecoration(index, createThreadDecoration(index, thread.id, sheetId));
1377
+ }
1378
+ }
1379
+ for (const decoration of decorations.getAllDecorations()) {
1380
+ if (decoration.type !== "comment") {
1381
+ continue;
1382
+ }
1383
+ if (!activeThreadAnchors.has(decoration.cellIndex)) {
1384
+ decorations.removeDecoration(decoration.cellIndex, "comment");
1385
+ }
1386
+ }
1387
+ });
1388
+ return () => unsubscribe();
1389
+ });
1390
+ };
1391
+ var useThreads = () => {
1392
+ useUpdateCursorOnThreadSelection();
1393
+ useSelectThreadOnCursorChange();
1394
+ useThreadDecorations();
1395
+ };
1396
+
538
1397
  // packages/plugins/plugin-sheet/src/components/Sheet/util.ts
539
1398
  var getRelativeClientRect = (root, element) => {
540
1399
  const rootRect = root.getBoundingClientRect();
@@ -570,7 +1429,7 @@ var scrollIntoView = (scrollContainer, el) => {
570
1429
 
571
1430
  // packages/plugins/plugin-sheet/src/components/CellEditor/CellEditor.tsx
572
1431
  import { EditorView, keymap } from "@codemirror/view";
573
- import React2 from "react";
1432
+ import React5 from "react";
574
1433
  import { useThemeContext } from "@dxos/react-ui";
575
1434
  import { createBasicExtensions, createThemeExtensions, preventNewline, useTextEditor } from "@dxos/react-ui-editor";
576
1435
  var editorKeys = ({ onNav, onClose }) => {
@@ -618,20 +1477,60 @@ var editorKeys = ({ onNav, onClose }) => {
618
1477
  {
619
1478
  key: "Enter",
620
1479
  run: (editor) => {
621
- onClose(editor.state.doc.toString());
1480
+ onClose(editor.state.doc.toString(), {
1481
+ key: "Enter"
1482
+ });
1483
+ return true;
1484
+ },
1485
+ shift: (editor) => {
1486
+ onClose(editor.state.doc.toString(), {
1487
+ key: "Enter",
1488
+ shift: true
1489
+ });
1490
+ return true;
1491
+ }
1492
+ },
1493
+ {
1494
+ key: "Tab",
1495
+ run: (editor) => {
1496
+ onClose(editor.state.doc.toString(), {
1497
+ key: "Tab"
1498
+ });
1499
+ return true;
1500
+ },
1501
+ shift: (editor) => {
1502
+ onClose(editor.state.doc.toString(), {
1503
+ key: "Tab",
1504
+ shift: true
1505
+ });
622
1506
  return true;
623
1507
  }
624
1508
  },
625
1509
  {
626
1510
  key: "Escape",
627
1511
  run: () => {
628
- onClose(void 0);
1512
+ onClose(void 0, {
1513
+ key: "Escape"
1514
+ });
629
1515
  return true;
630
1516
  }
631
1517
  }
632
1518
  ]);
633
1519
  };
634
- var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
1520
+ var editorVariants = {
1521
+ // TODO(thure): remove when legacy is no longer used.
1522
+ legacy: {
1523
+ root: "flex w-full",
1524
+ editor: "flex w-full [&>.cm-scroller]:scrollbar-none",
1525
+ content: "!px-2 !py-1"
1526
+ },
1527
+ grid: {
1528
+ root: "absolute z-[1]",
1529
+ editor: "[&>.cm-scroller]:scrollbar-none tabular-nums",
1530
+ content: "!border !border-transparent !p-0.5"
1531
+ }
1532
+ };
1533
+ var CellEditor = ({ value, extension, autoFocus, onBlur, variant = "legacy", box, gridId }) => {
635
1534
  const { themeMode } = useThemeContext();
636
1535
  const { parentRef } = useTextEditor(() => {
637
1536
  return {
@@ -658,21 +1557,29 @@ var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
658
1557
  themeMode,
659
1558
  slots: {
660
1559
  editor: {
661
- className: "flex w-full [&>.cm-scroller]:scrollbar-none"
1560
+ className: editorVariants[variant].editor
662
1561
  },
663
1562
  content: {
664
- className: "!px-2 !py-1"
1563
+ className: editorVariants[variant].content
665
1564
  }
666
1565
  }
667
1566
  })
668
1567
  ]
669
1568
  };
670
1569
  }, [
671
- extension
1570
+ extension,
1571
+ autoFocus,
1572
+ value,
1573
+ variant,
1574
+ onBlur
672
1575
  ]);
673
- return /* @__PURE__ */ React2.createElement("div", {
1576
+ return /* @__PURE__ */ React5.createElement("div", {
674
1577
  ref: parentRef,
675
- className: "flex w-full"
1578
+ className: editorVariants[variant].root,
1579
+ style: box,
1580
+ ...gridId && {
1581
+ "data-grid": gridId
1582
+ }
676
1583
  });
677
1584
  };
678
1585
 
@@ -794,13 +1701,7 @@ var sheetExtension = ({ functions = [] }) => {
794
1701
  // NOTE: Useful for debugging.
795
1702
  closeOnBlur: false,
796
1703
  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
- )
1704
+ 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
1705
  }),
805
1706
  keymap2.of([
806
1707
  {
@@ -889,7 +1790,7 @@ var visitTree = (node, callback) => {
889
1790
  };
890
1791
 
891
1792
  // 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";
1793
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx";
893
1794
  var fragments = {
894
1795
  axis: "bg-axisSurface text-axisText text-xs select-none",
895
1796
  axisSelected: "bg-attention text-baseText",
@@ -897,25 +1798,26 @@ var fragments = {
897
1798
  cellSelected: "bg-gridCellSelected text-baseText border !border-accentSurface"
898
1799
  };
899
1800
  var SheetRoot = ({ children, ...props }) => {
900
- return /* @__PURE__ */ React3.createElement(SheetContextProvider, props, children);
1801
+ return /* @__PURE__ */ React6.createElement(SheetContextProvider, props, children);
901
1802
  };
902
- var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns }, forwardRef2) => {
1803
+ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numCols }, forwardRef2) => {
903
1804
  const { model, cursor, setCursor, setRange, setEditing } = useSheetContext();
904
1805
  const { rowsRef, columnsRef, contentRef } = useScrollHandlers();
905
- const [rows, setRows] = useState4([
1806
+ useThreads();
1807
+ const [rows, setRows] = useState5([
906
1808
  ...model.sheet.rows
907
1809
  ]);
908
- const [columns, setColumns] = useState4([
1810
+ const [columns, setColumns] = useState5([
909
1811
  ...model.sheet.columns
910
1812
  ]);
911
- useEffect3(() => {
1813
+ useEffect4(() => {
912
1814
  const rowsAccessor = createDocAccessor(model.sheet, [
913
1815
  "rows"
914
1816
  ]);
915
1817
  const columnsAccessor = createDocAccessor(model.sheet, [
916
1818
  "columns"
917
1819
  ]);
918
- const handleUpdate = debounce(() => {
1820
+ const handleUpdate = debounce2(() => {
919
1821
  setRows([
920
1822
  ...model.sheet.rows
921
1823
  ]);
@@ -933,44 +1835,44 @@ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns },
933
1835
  }, [
934
1836
  model
935
1837
  ]);
936
- useEffect3(() => {
1838
+ useEffect4(() => {
937
1839
  model.reset();
938
1840
  }, [
939
1841
  rows,
940
1842
  columns
941
1843
  ]);
942
1844
  const handleMoveRows = (from, to, num = 1) => {
943
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1845
+ const cursorIdx = cursor ? addressToIndex(model.sheet, cursor) : void 0;
944
1846
  const [rows2] = model.sheet.rows.splice(from, num);
945
1847
  model.sheet.rows.splice(to, 0, rows2);
946
1848
  if (cursorIdx) {
947
- setCursor(model.addressFromIndex(cursorIdx));
1849
+ setCursor(addressFromIndex(model.sheet, cursorIdx));
948
1850
  }
949
1851
  setRows([
950
1852
  ...model.sheet.rows
951
1853
  ]);
952
1854
  };
953
1855
  const handleMoveColumns = (from, to, num = 1) => {
954
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1856
+ const cursorIdx = cursor ? addressToIndex(model.sheet, cursor) : void 0;
955
1857
  const columns2 = model.sheet.columns.splice(from, num);
956
1858
  model.sheet.columns.splice(to, 0, ...columns2);
957
1859
  if (cursorIdx) {
958
- setCursor(model.addressFromIndex(cursorIdx));
1860
+ setCursor(addressFromIndex(model.sheet, cursorIdx));
959
1861
  }
960
1862
  setColumns([
961
1863
  ...model.sheet.columns
962
1864
  ]);
963
1865
  };
964
- const [rowSizes, setRowSizes] = useState4();
965
- const [columnSizes, setColumnSizes] = useState4();
966
- useEffect3(() => {
1866
+ const [rowSizes, setRowSizes] = useState5();
1867
+ const [columnSizes, setColumnSizes] = useState5();
1868
+ useEffect4(() => {
967
1869
  const rowAccessor = createDocAccessor(model.sheet, [
968
1870
  "rowMeta"
969
1871
  ]);
970
1872
  const columnAccessor = createDocAccessor(model.sheet, [
971
1873
  "columnMeta"
972
1874
  ]);
973
- const handleUpdate = debounce(() => {
1875
+ const handleUpdate = debounce2(() => {
974
1876
  const mapSizes = (values) => values.reduce((map, [idx, meta]) => {
975
1877
  if (meta.size) {
976
1878
  map[idx] = meta.size;
@@ -1012,54 +1914,54 @@ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns },
1012
1914
  }));
1013
1915
  }
1014
1916
  };
1015
- return /* @__PURE__ */ React3.createElement("div", {
1917
+ return /* @__PURE__ */ React6.createElement("div", {
1016
1918
  role: "none",
1017
1919
  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, {
1920
+ }, /* @__PURE__ */ React6.createElement(GridCorner, {
1019
1921
  onClick: () => {
1020
1922
  setCursor(void 0);
1021
1923
  setRange(void 0);
1022
1924
  setEditing(false);
1023
1925
  }
1024
- }), /* @__PURE__ */ React3.createElement(SheetColumns, {
1926
+ }), /* @__PURE__ */ React6.createElement(SheetColumns, {
1025
1927
  ref: columnsRef,
1026
1928
  columns,
1027
1929
  sizes: columnSizes,
1028
- selected: cursor?.column,
1029
- onSelect: (column) => setCursor(cursor?.column === column ? void 0 : {
1930
+ selected: cursor?.col,
1931
+ onSelect: (col) => setCursor(cursor?.col === col ? void 0 : {
1030
1932
  row: -1,
1031
- column
1933
+ col
1032
1934
  }),
1033
1935
  onResize: handleResizeColumn,
1034
1936
  onMove: handleMoveColumns
1035
- }), /* @__PURE__ */ React3.createElement(SheetRows, {
1937
+ }), /* @__PURE__ */ React6.createElement(SheetRows, {
1036
1938
  ref: rowsRef,
1037
1939
  rows,
1038
1940
  sizes: rowSizes,
1039
1941
  selected: cursor?.row,
1040
1942
  onSelect: (row) => setCursor(cursor?.row === row ? void 0 : {
1041
1943
  row,
1042
- column: -1
1944
+ col: -1
1043
1945
  }),
1044
1946
  onResize: handleResizeRow,
1045
1947
  onMove: handleMoveRows
1046
- }), /* @__PURE__ */ React3.createElement(SheetGrid, {
1948
+ }), /* @__PURE__ */ React6.createElement(SheetGrid, {
1047
1949
  ref: contentRef,
1048
1950
  size: {
1049
1951
  numRows: numRows ?? rows.length,
1050
- numColumns: numColumns ?? columns.length
1952
+ numCols: numCols ?? columns.length
1051
1953
  },
1052
1954
  rows,
1053
1955
  columns,
1054
1956
  rowSizes,
1055
1957
  columnSizes
1056
- }), /* @__PURE__ */ React3.createElement(GridCorner, null), /* @__PURE__ */ React3.createElement(SheetStatusBar, null));
1958
+ }), /* @__PURE__ */ React6.createElement(GridCorner, null), /* @__PURE__ */ React6.createElement(SheetStatusBar, null));
1057
1959
  });
1058
1960
  var useScrollHandlers = () => {
1059
1961
  const rowsRef = useRef(null);
1060
1962
  const columnsRef = useRef(null);
1061
1963
  const contentRef = useRef(null);
1062
- useEffect3(() => {
1964
+ useEffect4(() => {
1063
1965
  const handleRowsScroll = (ev) => {
1064
1966
  const { scrollTop } = ev.target;
1065
1967
  if (!rowsRef.current.dataset.locked) {
@@ -1096,13 +1998,13 @@ var useScrollHandlers = () => {
1096
1998
  };
1097
1999
  };
1098
2000
  var GridCorner = (props) => {
1099
- return /* @__PURE__ */ React3.createElement("div", {
2001
+ return /* @__PURE__ */ React6.createElement("div", {
1100
2002
  className: fragments.axis,
1101
2003
  ...props
1102
2004
  });
1103
2005
  };
1104
2006
  var MovingOverlay = ({ label }) => {
1105
- return /* @__PURE__ */ React3.createElement("div", {
2007
+ return /* @__PURE__ */ React6.createElement("div", {
1106
2008
  className: "flex w-full h-full justify-center items-center text-sm p-1 bg-gridOverlay cursor-pointer"
1107
2009
  }, label);
1108
2010
  };
@@ -1122,7 +2024,7 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1122
2024
  });
1123
2025
  const keyboardSensor = useSensor(KeyboardSensor, {});
1124
2026
  const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
1125
- const [active, setActive] = useState4(null);
2027
+ const [active, setActive] = useState5(null);
1126
2028
  const handleDragStart = ({ active: active2 }) => {
1127
2029
  setActive(active2);
1128
2030
  };
@@ -1146,18 +2048,18 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1146
2048
  }
1147
2049
  return transform;
1148
2050
  };
1149
- return /* @__PURE__ */ React3.createElement("div", {
2051
+ return /* @__PURE__ */ React6.createElement("div", {
1150
2052
  className: "relative flex grow overflow-hidden"
1151
- }, /* @__PURE__ */ React3.createElement("div", {
2053
+ }, /* @__PURE__ */ React6.createElement("div", {
1152
2054
  className: mx2("z-20 absolute inset-0 border-y border-gridLine pointer-events-none"),
1153
2055
  style: {
1154
2056
  width: axisWidth
1155
2057
  }
1156
- }), /* @__PURE__ */ React3.createElement("div", {
2058
+ }), /* @__PURE__ */ React6.createElement("div", {
1157
2059
  ref: forwardRef2,
1158
2060
  role: "rowheader",
1159
2061
  className: "grow overflow-y-auto scrollbar-none"
1160
- }, /* @__PURE__ */ React3.createElement(DndContext, {
2062
+ }, /* @__PURE__ */ React6.createElement(DndContext, {
1161
2063
  sensors,
1162
2064
  modifiers: [
1163
2065
  restrictToVerticalAxis,
@@ -1165,12 +2067,12 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1165
2067
  ],
1166
2068
  onDragStart: handleDragStart,
1167
2069
  onDragEnd: handleDragEnd
1168
- }, /* @__PURE__ */ React3.createElement("div", {
2070
+ }, /* @__PURE__ */ React6.createElement("div", {
1169
2071
  className: "flex flex-col",
1170
2072
  style: {
1171
2073
  width: axisWidth
1172
2074
  }
1173
- }, rows.map((idx, index) => /* @__PURE__ */ React3.createElement(GridRowCell, {
2075
+ }, rows.map((idx, index) => /* @__PURE__ */ React6.createElement(GridRowCell, {
1174
2076
  key: idx,
1175
2077
  idx,
1176
2078
  index,
@@ -1180,7 +2082,7 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1180
2082
  selected: selected === index,
1181
2083
  onResize,
1182
2084
  onSelect
1183
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(DragOverlay, null, active && /* @__PURE__ */ React3.createElement(MovingOverlay, {
2085
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement(DragOverlay, null, active && /* @__PURE__ */ React6.createElement(MovingOverlay, {
1184
2086
  label: String(active.data.current.index + 1)
1185
2087
  })), document.body))));
1186
2088
  });
@@ -1198,8 +2100,8 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1198
2100
  }
1199
2101
  });
1200
2102
  const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
1201
- const [initialSize, setInitialSize] = useState4(size);
1202
- const [resizing, setResizing] = useState4(false);
2103
+ const [initialSize, setInitialSize] = useState5(size);
2104
+ const [resizing, setResizing] = useState5(false);
1203
2105
  const scrollHandler = useRef();
1204
2106
  const handleResizeStart = (_ev, _dir, elementRef) => {
1205
2107
  const scrollContainer = elementRef.closest('[role="rowheader"]');
@@ -1221,7 +2123,7 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1221
2123
  onResize?.(idx, initialSize + height, true);
1222
2124
  setResizing(false);
1223
2125
  };
1224
- return /* @__PURE__ */ React3.createElement(Resizable, {
2126
+ return /* @__PURE__ */ React6.createElement(Resizable, {
1225
2127
  enable: {
1226
2128
  bottom: resize
1227
2129
  },
@@ -1233,17 +2135,17 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1233
2135
  onResizeStart: handleResizeStart,
1234
2136
  onResize: handleResize,
1235
2137
  onResizeStop: handleResizeStop
1236
- }, /* @__PURE__ */ React3.createElement("div", {
2138
+ }, /* @__PURE__ */ React6.createElement("div", {
1237
2139
  ref: setNodeRef,
1238
2140
  ...attributes,
1239
2141
  ...listeners,
1240
2142
  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
2143
  onClick: () => onSelect?.(index)
1242
- }, /* @__PURE__ */ React3.createElement("span", {
2144
+ }, /* @__PURE__ */ React6.createElement("span", {
1243
2145
  className: "flex w-full justify-center"
1244
- }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React3.createElement("div", {
2146
+ }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React6.createElement("div", {
1245
2147
  className: "z-20 absolute top-0 w-full min-h-[4px] border-b-4 border-accentSurface"
1246
- }), resizing && /* @__PURE__ */ React3.createElement("div", {
2148
+ }), resizing && /* @__PURE__ */ React6.createElement("div", {
1247
2149
  className: "z-20 absolute bottom-0 w-full min-h-[4px] border-b-4 border-accentSurface"
1248
2150
  })));
1249
2151
  };
@@ -1256,7 +2158,7 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1256
2158
  });
1257
2159
  const keyboardSensor = useSensor(KeyboardSensor, {});
1258
2160
  const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
1259
- const [active, setActive] = useState4(null);
2161
+ const [active, setActive] = useState5(null);
1260
2162
  const handleDragStart = ({ active: active2 }) => {
1261
2163
  setActive(active2);
1262
2164
  };
@@ -1280,18 +2182,18 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1280
2182
  }
1281
2183
  return transform;
1282
2184
  };
1283
- return /* @__PURE__ */ React3.createElement("div", {
2185
+ return /* @__PURE__ */ React6.createElement("div", {
1284
2186
  className: "relative flex grow overflow-hidden"
1285
- }, /* @__PURE__ */ React3.createElement("div", {
2187
+ }, /* @__PURE__ */ React6.createElement("div", {
1286
2188
  className: mx2("z-20 absolute inset-0 border-x border-gridLine pointer-events-none"),
1287
2189
  style: {
1288
2190
  height: axisHeight
1289
2191
  }
1290
- }), /* @__PURE__ */ React3.createElement("div", {
2192
+ }), /* @__PURE__ */ React6.createElement("div", {
1291
2193
  ref: forwardRef2,
1292
2194
  role: "columnheader",
1293
2195
  className: "grow overflow-x-auto scrollbar-none"
1294
- }, /* @__PURE__ */ React3.createElement(DndContext, {
2196
+ }, /* @__PURE__ */ React6.createElement(DndContext, {
1295
2197
  autoScroll: {
1296
2198
  enabled: true
1297
2199
  },
@@ -1302,12 +2204,12 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1302
2204
  ],
1303
2205
  onDragStart: handleDragStart,
1304
2206
  onDragEnd: handleDragEnd
1305
- }, /* @__PURE__ */ React3.createElement("div", {
2207
+ }, /* @__PURE__ */ React6.createElement("div", {
1306
2208
  className: "flex h-full",
1307
2209
  style: {
1308
2210
  height: axisHeight
1309
2211
  }
1310
- }, columns.map((idx, index) => /* @__PURE__ */ React3.createElement(GridColumnCell, {
2212
+ }, columns.map((idx, index) => /* @__PURE__ */ React6.createElement(GridColumnCell, {
1311
2213
  key: idx,
1312
2214
  idx,
1313
2215
  index,
@@ -1317,7 +2219,7 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1317
2219
  selected: selected === index,
1318
2220
  onResize,
1319
2221
  onSelect
1320
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(DragOverlay, null, active && /* @__PURE__ */ React3.createElement(MovingOverlay, {
2222
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement(DragOverlay, null, active && /* @__PURE__ */ React6.createElement(MovingOverlay, {
1321
2223
  label: columnLetter(active.data.current.index)
1322
2224
  })), document.body))));
1323
2225
  });
@@ -1335,8 +2237,8 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1335
2237
  }
1336
2238
  });
1337
2239
  const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
1338
- const [initialSize, setInitialSize] = useState4(size);
1339
- const [resizing, setResizing] = useState4(false);
2240
+ const [initialSize, setInitialSize] = useState5(size);
2241
+ const [resizing, setResizing] = useState5(false);
1340
2242
  const scrollHandler = useRef();
1341
2243
  const handleResizeStart = (_ev, _dir, elementRef) => {
1342
2244
  const scrollContainer = elementRef.closest('[role="columnheader"]');
@@ -1358,7 +2260,7 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1358
2260
  onResize?.(idx, initialSize + width, true);
1359
2261
  setResizing(false);
1360
2262
  };
1361
- return /* @__PURE__ */ React3.createElement(Resizable, {
2263
+ return /* @__PURE__ */ React6.createElement(Resizable, {
1362
2264
  enable: {
1363
2265
  right: resize
1364
2266
  },
@@ -1370,17 +2272,17 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1370
2272
  onResizeStart: handleResizeStart,
1371
2273
  onResize: handleResize,
1372
2274
  onResizeStop: handleResizeStop
1373
- }, /* @__PURE__ */ React3.createElement("div", {
2275
+ }, /* @__PURE__ */ React6.createElement("div", {
1374
2276
  ref: setNodeRef,
1375
2277
  ...attributes,
1376
2278
  ...listeners,
1377
2279
  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
2280
  onClick: () => onSelect?.(index)
1379
- }, /* @__PURE__ */ React3.createElement("span", {
2281
+ }, /* @__PURE__ */ React6.createElement("span", {
1380
2282
  className: "flex w-full justify-center"
1381
- }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React3.createElement("div", {
2283
+ }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React6.createElement("div", {
1382
2284
  className: "z-20 absolute left-0 h-full min-w-[4px] border-l-4 border-accentSurface"
1383
- }), resizing && /* @__PURE__ */ React3.createElement("div", {
2285
+ }), resizing && /* @__PURE__ */ React6.createElement("div", {
1384
2286
  className: "z-20 absolute right-0 h-full min-h-[4px] border-l-4 border-accentSurface"
1385
2287
  })));
1386
2288
  };
@@ -1393,14 +2295,14 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1393
2295
  const { model, cursor, range, editing, setCursor, setRange, setEditing, onInfo } = useSheetContext();
1394
2296
  const initialText = useRef();
1395
2297
  const quickEdit = useRef(false);
1396
- const [, forceUpdate] = useState4({});
1397
- useEffect3(() => {
2298
+ const [, forceUpdate] = useState5({});
2299
+ useEffect4(() => {
1398
2300
  const unsubscribe = model.update.on(() => {
1399
- log("updated", {
2301
+ log2("updated", {
1400
2302
  id: model.id
1401
2303
  }, {
1402
- F: __dxlog_file2,
1403
- L: 730,
2304
+ F: __dxlog_file4,
2305
+ L: 737,
1404
2306
  S: void 0,
1405
2307
  C: (f, a) => f(...a)
1406
2308
  });
@@ -1520,16 +2422,16 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1520
2422
  const id = fullyQualifiedId2(model.sheet);
1521
2423
  const attendableAttrs = createAttendableAttributes(id);
1522
2424
  const hasAttention = useHasAttention(id);
1523
- return /* @__PURE__ */ React3.createElement("div", {
2425
+ return /* @__PURE__ */ React6.createElement("div", {
1524
2426
  ref: containerRef,
1525
2427
  role: "grid",
1526
2428
  className: "relative flex grow overflow-hidden"
1527
- }, /* @__PURE__ */ React3.createElement("div", {
2429
+ }, /* @__PURE__ */ React6.createElement("div", {
1528
2430
  className: mx2("z-20 absolute inset-0 border border-gridLine pointer-events-none")
1529
- }), /* @__PURE__ */ React3.createElement("div", {
2431
+ }), /* @__PURE__ */ React6.createElement("div", {
1530
2432
  ref: scrollerRef,
1531
2433
  className: mx2("grow", hasAttention && "overflow-auto scrollbar-thin")
1532
- }, /* @__PURE__ */ React3.createElement("div", {
2434
+ }, /* @__PURE__ */ React6.createElement("div", {
1533
2435
  className: "relative select-none",
1534
2436
  style: {
1535
2437
  width,
@@ -1537,10 +2439,10 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1537
2439
  },
1538
2440
  onClick: () => inputRef.current?.focus(),
1539
2441
  ...handlers
1540
- }, scrollerRef.current && /* @__PURE__ */ React3.createElement(SelectionOverlay, {
2442
+ }, scrollerRef.current && /* @__PURE__ */ React6.createElement(SelectionOverlay, {
1541
2443
  root: scrollerRef.current
1542
2444
  }), rowRange.map(({ row, top, height: height2 }) => {
1543
- return columnRange.map(({ column, left, width: width2 }) => {
2445
+ return columnRange.map(({ col, left, width: width2 }) => {
1544
2446
  const style = {
1545
2447
  position: "absolute",
1546
2448
  top,
@@ -1550,10 +2452,10 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1550
2452
  };
1551
2453
  const cell = {
1552
2454
  row,
1553
- column
2455
+ col
1554
2456
  };
1555
2457
  const id2 = addressToA1Notation(cell);
1556
- const idx = model.addressToIndex(cell);
2458
+ const idx = addressToIndex(model.sheet, cell);
1557
2459
  const active = posEquals(cursor, cell);
1558
2460
  if (active && editing) {
1559
2461
  const value = initialText.current ?? model.getCellText(cell) ?? "";
@@ -1586,7 +2488,7 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1586
2488
  inputRef.current?.focus();
1587
2489
  setEditing(false);
1588
2490
  };
1589
- return /* @__PURE__ */ React3.createElement(GridCellEditor, {
2491
+ return /* @__PURE__ */ React6.createElement(GridCellEditor, {
1590
2492
  key: idx,
1591
2493
  value,
1592
2494
  style,
@@ -1594,7 +2496,7 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1594
2496
  onClose: handleClose
1595
2497
  });
1596
2498
  }
1597
- return /* @__PURE__ */ React3.createElement(SheetCell, {
2499
+ return /* @__PURE__ */ React6.createElement(SheetCell, {
1598
2500
  key: id2,
1599
2501
  id: id2,
1600
2502
  cell,
@@ -1606,7 +2508,7 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1606
2508
  }
1607
2509
  });
1608
2510
  });
1609
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement("input", {
2511
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement("input", {
1610
2512
  ref: inputRef,
1611
2513
  autoFocus: true,
1612
2514
  className: "absolute w-[1px] h-[1px] bg-transparent outline-none border-none caret-transparent",
@@ -1627,20 +2529,34 @@ var SelectionOverlay = ({ root }) => {
1627
2529
  const b1 = getRelativeClientRect(root, c1);
1628
2530
  const b2 = getRelativeClientRect(root, c2);
1629
2531
  const bounds = getRectUnion(b1, b2);
1630
- return /* @__PURE__ */ React3.createElement("div", {
2532
+ return /* @__PURE__ */ React6.createElement("div", {
1631
2533
  role: "none",
1632
2534
  style: bounds,
1633
2535
  className: "z-10 absolute pointer-events-none bg-gridSelectionOverlay border border-gridOverlay"
1634
2536
  });
1635
2537
  };
1636
2538
  var SheetCell = ({ id, cell, style, active, onSelect }) => {
1637
- const { formatting, editing, setRange } = useSheetContext();
2539
+ const { formatting, editing, setRange, decorations, model: { sheet } } = useSheetContext();
1638
2540
  const { value, classNames } = formatting.getFormatting(cell);
1639
- return /* @__PURE__ */ React3.createElement("div", {
2541
+ const decorationsForCell = decorations.getDecorationsForCell(addressToIndex(sheet, cell)) ?? [];
2542
+ const decorationAddedClasses = useMemo4(() => decorationsForCell.flatMap((d) => d.classNames ?? []), [
2543
+ decorationsForCell
2544
+ ]);
2545
+ const decoratedContent = decorationsForCell.reduce((children, { decorate }) => {
2546
+ if (!decorate) {
2547
+ return children;
2548
+ }
2549
+ const DecoratorComponent = decorate;
2550
+ return /* @__PURE__ */ React6.createElement(DecoratorComponent, null, children);
2551
+ }, /* @__PURE__ */ React6.createElement("div", {
2552
+ role: "none",
2553
+ className: mx2("flex flex-grow bs-full is-full px-2 items-center truncate cursor-pointer", ...decorationAddedClasses)
2554
+ }, value));
2555
+ return /* @__PURE__ */ React6.createElement("div", {
1640
2556
  [`data-${CELL_DATA_KEY}`]: id,
1641
2557
  role: "cell",
1642
2558
  style,
1643
- className: mx2("flex w-full h-full px-2 py-1 truncate items-center border border-gridLine cursor-pointer", fragments.cell, active && [
2559
+ className: mx2("border border-gridLine cursor-pointer", fragments.cell, active && [
1644
2560
  "z-20",
1645
2561
  fragments.cellSelected
1646
2562
  ], classNames),
@@ -1654,36 +2570,36 @@ var SheetCell = ({ id, cell, style, active, onSelect }) => {
1654
2570
  }
1655
2571
  },
1656
2572
  onDoubleClick: () => onSelect?.(cell, true)
1657
- }, value);
2573
+ }, decoratedContent);
1658
2574
  };
1659
2575
  var GridCellEditor = ({ style, value, onNav, onClose }) => {
1660
2576
  const { model, range } = useSheetContext();
1661
2577
  const notifier = useRef();
1662
- useEffect3(() => {
2578
+ useEffect4(() => {
1663
2579
  if (range) {
1664
2580
  notifier.current?.(rangeToA1Notation(range));
1665
2581
  }
1666
2582
  }, [
1667
2583
  range
1668
2584
  ]);
1669
- const extension = useMemo(() => [
2585
+ const extension = useMemo4(() => [
1670
2586
  editorKeys({
1671
2587
  onNav,
1672
2588
  onClose
1673
2589
  }),
1674
2590
  sheetExtension({
1675
- functions: model.functions
2591
+ functions: model.graph.getFunctions()
1676
2592
  }),
1677
2593
  rangeExtension((fn) => notifier.current = fn)
1678
2594
  ], [
1679
2595
  model
1680
2596
  ]);
1681
- return /* @__PURE__ */ React3.createElement("div", {
2597
+ return /* @__PURE__ */ React6.createElement("div", {
1682
2598
  role: "cell",
1683
2599
  style,
1684
2600
  className: mx2("z-20 flex", fragments.cellSelected),
1685
2601
  onClick: (ev) => ev.stopPropagation()
1686
- }, /* @__PURE__ */ React3.createElement(CellEditor, {
2602
+ }, /* @__PURE__ */ React6.createElement(CellEditor, {
1687
2603
  autoFocus: true,
1688
2604
  value,
1689
2605
  extension
@@ -1696,30 +2612,30 @@ var SheetStatusBar = () => {
1696
2612
  if (cursor) {
1697
2613
  value = model.getCellValue(cursor);
1698
2614
  if (typeof value === "string" && value.charAt(0) === "=") {
1699
- value = model.mapFormulaBindingFromId(model.mapFormulaIndicesToRefs(value));
2615
+ value = model.graph.mapFunctionBindingFromId(model.mapFormulaIndicesToRefs(value));
1700
2616
  isFormula = true;
1701
2617
  } else if (value != null) {
1702
2618
  value = String(value);
1703
2619
  }
1704
2620
  }
1705
- return /* @__PURE__ */ React3.createElement("div", {
2621
+ return /* @__PURE__ */ React6.createElement("div", {
1706
2622
  className: mx2("flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x border-gridLine")
1707
- }, /* @__PURE__ */ React3.createElement("div", {
2623
+ }, /* @__PURE__ */ React6.createElement("div", {
1708
2624
  className: "flex gap-4 items-center"
1709
- }, /* @__PURE__ */ React3.createElement("div", {
2625
+ }, /* @__PURE__ */ React6.createElement("div", {
1710
2626
  className: "flex w-16 items-center font-mono"
1711
- }, range && rangeToA1Notation(range) || cursor && addressToA1Notation(cursor)), /* @__PURE__ */ React3.createElement("div", {
2627
+ }, range && rangeToA1Notation(range) || cursor && addressToA1Notation(cursor)), /* @__PURE__ */ React6.createElement("div", {
1712
2628
  className: "flex gap-2 items-center"
1713
- }, /* @__PURE__ */ React3.createElement(FunctionIcon, {
2629
+ }, /* @__PURE__ */ React6.createElement(FunctionIcon, {
1714
2630
  className: mx2("text-greenText", isFormula ? "visible" : "invisible")
1715
- }), /* @__PURE__ */ React3.createElement("span", {
2631
+ }), /* @__PURE__ */ React6.createElement("span", {
1716
2632
  className: "font-mono"
1717
2633
  }, value))));
1718
2634
  };
1719
2635
  var SheetDebug = () => {
1720
2636
  const { model, cursor, range } = useSheetContext();
1721
- const [, forceUpdate] = useState4({});
1722
- useEffect3(() => {
2637
+ const [, forceUpdate] = useState5({});
2638
+ useEffect4(() => {
1723
2639
  const accessor = createDocAccessor(model.sheet, []);
1724
2640
  const handleUpdate = () => forceUpdate({});
1725
2641
  accessor.handle.addListener("change", handleUpdate);
@@ -1730,9 +2646,9 @@ var SheetDebug = () => {
1730
2646
  }, [
1731
2647
  model
1732
2648
  ]);
1733
- return /* @__PURE__ */ React3.createElement("div", {
2649
+ return /* @__PURE__ */ React6.createElement("div", {
1734
2650
  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", {
2651
+ }, /* @__PURE__ */ React6.createElement("pre", {
1736
2652
  className: "whitespace-pre-wrap"
1737
2653
  }, JSON.stringify({
1738
2654
  cursor,
@@ -1754,19 +2670,14 @@ var Sheet = {
1754
2670
  Debug: SheetDebug
1755
2671
  };
1756
2672
 
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
2673
  export {
1770
- SheetContainer_default as default
2674
+ ComputeGraphContextProvider,
2675
+ createSheet,
2676
+ addressToIndex,
2677
+ compareIndexPositions,
2678
+ useComputeGraph,
2679
+ useSheetContext,
2680
+ Sheet,
2681
+ SheetContainer
1771
2682
  };
1772
- //# sourceMappingURL=SheetContainer-U4H5D34A.mjs.map
2683
+ //# sourceMappingURL=chunk-ZLJ2GRE2.mjs.map