@dxos/plugin-sheet 0.6.11-staging.e6894a4 → 0.6.12-main.15a606f

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 (261) hide show
  1. package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs +261 -0
  2. package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-P7SSL3EG.mjs → chunk-6ZMQVB4Z.mjs} +359 -671
  4. package/dist/lib/browser/chunk-6ZMQVB4Z.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-JRL5LGCE.mjs → chunk-QILRZNE5.mjs} +2 -5
  6. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-FUAGSXA4.mjs → chunk-T3NJFTD4.mjs} +8 -15
  8. package/dist/lib/browser/chunk-T3NJFTD4.mjs.map +7 -0
  9. package/dist/lib/browser/{SheetContainer-4XOKHKKZ.mjs → chunk-U2JHW3L6.mjs} +1043 -261
  10. package/dist/lib/browser/chunk-U2JHW3L6.mjs.map +7 -0
  11. package/dist/lib/browser/graph-T27BOBOV.mjs +21 -0
  12. package/dist/lib/browser/graph-T27BOBOV.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +80 -66
  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-3ZY7MPWJ.cjs +279 -0
  19. package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs.map +7 -0
  20. package/dist/lib/node/{chunk-BJ6ZD7MN.cjs → chunk-BNARJ5GM.cjs} +5 -18
  21. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-SVAIIXWQ.cjs → chunk-DD6FIXWC.cjs} +360 -667
  23. package/dist/lib/node/chunk-DD6FIXWC.cjs.map +7 -0
  24. package/dist/lib/node/{SheetContainer-IQT6TR4Z.cjs → chunk-OTTD7FBK.cjs} +1062 -289
  25. package/dist/lib/node/chunk-OTTD7FBK.cjs.map +7 -0
  26. package/dist/lib/node/{chunk-DSYKOI4E.cjs → chunk-Q3HBHPRL.cjs} +12 -20
  27. package/dist/lib/node/chunk-Q3HBHPRL.cjs.map +7 -0
  28. package/dist/lib/node/graph-SPKGX7W4.cjs +43 -0
  29. package/dist/lib/node/graph-SPKGX7W4.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +93 -72
  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-PXSJX6XK.mjs +262 -0
  38. package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs.map +7 -0
  39. package/dist/lib/node-esm/chunk-7HVSOTGA.mjs +2553 -0
  40. package/dist/lib/node-esm/chunk-7HVSOTGA.mjs.map +7 -0
  41. package/dist/lib/node-esm/chunk-BMNA27EX.mjs +76 -0
  42. package/dist/lib/node-esm/chunk-BMNA27EX.mjs.map +7 -0
  43. package/dist/lib/node-esm/chunk-D6KU5MI7.mjs +2925 -0
  44. package/dist/lib/node-esm/chunk-D6KU5MI7.mjs.map +7 -0
  45. package/dist/lib/node-esm/chunk-IU2L277A.mjs +17 -0
  46. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +7 -0
  47. package/dist/lib/node-esm/graph-U67IO4UC.mjs +22 -0
  48. package/dist/lib/node-esm/graph-U67IO4UC.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +261 -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 +6 -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 +6 -5
  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 +5 -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 +1 -1
  109. package/dist/types/src/graph/async-function.d.ts.map +1 -0
  110. package/dist/types/src/graph/compute-graph.browser.test.d.ts +2 -0
  111. package/dist/types/src/graph/compute-graph.browser.test.d.ts.map +1 -0
  112. package/dist/types/src/graph/compute-graph.d.ts +81 -0
  113. package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
  114. package/dist/types/src/graph/compute-graph.stories.d.ts +10 -0
  115. package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
  116. package/dist/types/src/graph/compute-node.d.ts +19 -0
  117. package/dist/types/src/graph/compute-node.d.ts.map +1 -0
  118. package/dist/types/src/{components/ComputeGraph/custom.d.ts → graph/custom-function.d.ts} +1 -1
  119. package/dist/types/src/graph/custom-function.d.ts.map +1 -0
  120. package/dist/types/src/graph/edge-function.d.ts.map +1 -0
  121. package/dist/types/src/{model/functions.d.ts → graph/function-defs.d.ts} +1 -1
  122. package/dist/types/src/graph/function-defs.d.ts.map +1 -0
  123. package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
  124. package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
  125. package/dist/types/src/graph/index.d.ts +4 -0
  126. package/dist/types/src/graph/index.d.ts.map +1 -0
  127. package/dist/types/src/graph/util.d.ts +2 -0
  128. package/dist/types/src/graph/util.d.ts.map +1 -0
  129. package/dist/types/src/hooks/hooks.stories.d.ts +11 -0
  130. package/dist/types/src/hooks/hooks.stories.d.ts.map +1 -0
  131. package/dist/types/src/hooks/index.d.ts +4 -0
  132. package/dist/types/src/hooks/index.d.ts.map +1 -0
  133. package/dist/types/src/hooks/useComputeGraph.d.ts +7 -0
  134. package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -0
  135. package/dist/types/src/hooks/useFormattingModel.d.ts +3 -0
  136. package/dist/types/src/hooks/useFormattingModel.d.ts.map +1 -0
  137. package/dist/types/src/hooks/useSheetModel.d.ts +8 -0
  138. package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -0
  139. package/dist/types/src/meta.d.ts +1 -4
  140. package/dist/types/src/meta.d.ts.map +1 -1
  141. package/dist/types/src/model/formatting-model.d.ts +16 -0
  142. package/dist/types/src/model/formatting-model.d.ts.map +1 -0
  143. package/dist/types/src/model/index.d.ts +2 -3
  144. package/dist/types/src/model/index.d.ts.map +1 -1
  145. package/dist/types/src/model/{model.d.ts → sheet-model.d.ts} +9 -64
  146. package/dist/types/src/model/sheet-model.d.ts.map +1 -0
  147. package/dist/types/src/sanity.test.d.ts +2 -0
  148. package/dist/types/src/sanity.test.d.ts.map +1 -0
  149. package/dist/types/src/testing/index.d.ts +2 -0
  150. package/dist/types/src/testing/index.d.ts.map +1 -0
  151. package/dist/types/src/testing/testing.d.ts +9 -0
  152. package/dist/types/src/testing/testing.d.ts.map +1 -0
  153. package/dist/types/src/translations.d.ts +17 -12
  154. package/dist/types/src/translations.d.ts.map +1 -1
  155. package/dist/types/src/types.d.ts +83 -3
  156. package/dist/types/src/types.d.ts.map +1 -1
  157. package/dist/vendor/hyperformula.mjs +37145 -0
  158. package/package.json +48 -41
  159. package/src/SheetPlugin.tsx +51 -72
  160. package/src/components/CellEditor/CellEditor.stories.tsx +4 -3
  161. package/src/components/CellEditor/CellEditor.tsx +59 -9
  162. package/src/components/CellEditor/extension.test.ts +4 -5
  163. package/src/components/CellEditor/extension.ts +1 -3
  164. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +20 -0
  165. package/src/components/ComputeGraph/index.ts +1 -3
  166. package/src/components/GridSheet/GridSheet.stories.tsx +35 -0
  167. package/src/components/GridSheet/GridSheet.tsx +153 -0
  168. package/src/components/GridSheet/util.ts +89 -0
  169. package/src/components/Sheet/Sheet.stories.tsx +48 -87
  170. package/src/components/Sheet/Sheet.tsx +69 -39
  171. package/src/components/Sheet/decorations.ts +62 -0
  172. package/src/components/Sheet/grid.ts +3 -3
  173. package/src/components/Sheet/nav.ts +19 -19
  174. package/src/components/Sheet/sheet-context.tsx +16 -78
  175. package/src/components/Sheet/threads.tsx +205 -0
  176. package/src/components/SheetContainer.tsx +73 -21
  177. package/src/components/Toolbar/Toolbar.stories.tsx +5 -10
  178. package/src/components/Toolbar/Toolbar.tsx +53 -12
  179. package/src/components/index.ts +1 -0
  180. package/src/defs/index.ts +6 -0
  181. package/src/{model → defs}/types.test.ts +8 -9
  182. package/src/{model → defs}/types.ts +23 -14
  183. package/src/defs/util.ts +135 -0
  184. package/src/extensions/compute.stories.tsx +151 -0
  185. package/src/extensions/compute.ts +98 -0
  186. package/src/extensions/index.ts +5 -0
  187. package/src/{components/ComputeGraph → graph}/async-function.ts +3 -1
  188. package/src/graph/compute-graph.browser.test.ts +104 -0
  189. package/src/graph/compute-graph.stories.tsx +92 -0
  190. package/src/graph/compute-graph.ts +290 -0
  191. package/src/graph/compute-node.ts +51 -0
  192. package/src/{components/ComputeGraph/custom.ts → graph/custom-function.ts} +2 -6
  193. package/src/{components/ComputeGraph → graph}/edge-function.ts +2 -1
  194. package/src/graph/hyperformula.test.ts +15 -0
  195. package/src/graph/index.ts +7 -0
  196. package/src/graph/util.ts +8 -0
  197. package/src/hooks/hooks.stories.tsx +50 -0
  198. package/src/hooks/index.ts +7 -0
  199. package/src/hooks/useComputeGraph.ts +20 -0
  200. package/src/hooks/useFormattingModel.ts +11 -0
  201. package/src/hooks/useSheetModel.ts +43 -0
  202. package/src/meta.tsx +1 -5
  203. package/src/{components/Sheet/formatting.ts → model/formatting-model.ts} +20 -13
  204. package/src/model/index.ts +2 -3
  205. package/src/model/sheet-model.ts +399 -0
  206. package/src/sanity.test.ts +40 -0
  207. package/src/testing/index.ts +5 -0
  208. package/src/testing/testing.tsx +66 -0
  209. package/src/translations.ts +6 -1
  210. package/src/types.ts +30 -5
  211. package/dist/lib/browser/SheetContainer-4XOKHKKZ.mjs.map +0 -7
  212. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +0 -7
  213. package/dist/lib/browser/chunk-FWGRE3EG.mjs +0 -175
  214. package/dist/lib/browser/chunk-FWGRE3EG.mjs.map +0 -7
  215. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
  216. package/dist/lib/browser/chunk-P7SSL3EG.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-YPU3R7FA.mjs +0 -8
  218. package/dist/lib/browser/chunk-YPU3R7FA.mjs.map +0 -7
  219. package/dist/lib/browser/testing.mjs +0 -92
  220. package/dist/lib/browser/testing.mjs.map +0 -7
  221. package/dist/lib/node/SheetContainer-IQT6TR4Z.cjs.map +0 -7
  222. package/dist/lib/node/chunk-5EPCDAZC.cjs +0 -40
  223. package/dist/lib/node/chunk-5EPCDAZC.cjs.map +0 -7
  224. package/dist/lib/node/chunk-727C6YNP.cjs +0 -202
  225. package/dist/lib/node/chunk-727C6YNP.cjs.map +0 -7
  226. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
  227. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +0 -7
  228. package/dist/lib/node/chunk-SVAIIXWQ.cjs.map +0 -7
  229. package/dist/lib/node/testing.cjs +0 -111
  230. package/dist/lib/node/testing.cjs.map +0 -7
  231. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
  232. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
  233. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
  234. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
  235. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
  236. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
  237. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
  238. package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
  239. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
  240. package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
  241. package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
  242. package/dist/types/src/model/functions.d.ts.map +0 -1
  243. package/dist/types/src/model/model.browser.test.d.ts +0 -2
  244. package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
  245. package/dist/types/src/model/model.d.ts.map +0 -1
  246. package/dist/types/src/model/types.d.ts.map +0 -1
  247. package/dist/types/src/model/types.test.d.ts.map +0 -1
  248. package/dist/types/src/model/util.d.ts +0 -15
  249. package/dist/types/src/model/util.d.ts.map +0 -1
  250. package/dist/types/src/testing.d.ts +0 -9
  251. package/dist/types/src/testing.d.ts.map +0 -1
  252. package/src/components/ComputeGraph/graph-context.tsx +0 -50
  253. package/src/components/ComputeGraph/graph.browser.test.ts +0 -50
  254. package/src/components/ComputeGraph/graph.ts +0 -62
  255. package/src/model/model.browser.test.ts +0 -100
  256. package/src/model/model.ts +0 -551
  257. package/src/model/util.ts +0 -36
  258. package/src/testing.ts +0 -50
  259. /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
  260. /package/dist/types/src/{components/ComputeGraph → graph}/edge-function.d.ts +0 -0
  261. /package/src/{model/functions.ts → graph/function-defs.ts} +0 -0
@@ -1,24 +1,13 @@
1
1
  import {
2
- useComputeGraph
3
- } from "./chunk-FWGRE3EG.mjs";
2
+ SheetType,
3
+ ValueTypeEnum
4
+ } from "./chunk-T3NJFTD4.mjs";
4
5
  import {
5
- SheetModel,
6
- addressFromA1Notation,
7
- addressToA1Notation,
8
- columnLetter,
9
- defaultFunctions,
10
- inRange,
11
- posEquals,
12
- rangeToA1Notation
13
- } from "./chunk-P7SSL3EG.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-6ZMQVB4Z.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,175 @@ 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 } from "@dxos/react-ui-attention";
23
+ import { log as log2 } from "@dxos/log";
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: 39,
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 = ({ title, ...size } = {}) => {
135
+ const sheet = create(SheetType, {
136
+ title,
137
+ cells: {},
138
+ rows: [],
139
+ columns: [],
140
+ rowMeta: {},
141
+ columnMeta: {},
142
+ formatting: {}
143
+ });
144
+ initialize(sheet, size);
145
+ return sheet;
146
+ };
147
+ var addressToIndex = (sheet, cell) => {
148
+ return `${sheet.columns[cell.col]}@${sheet.rows[cell.row]}`;
149
+ };
150
+ var addressFromIndex = (sheet, idx) => {
151
+ const [column, row] = idx.split("@");
152
+ return {
153
+ col: sheet.columns.indexOf(column),
154
+ row: sheet.rows.indexOf(row)
155
+ };
156
+ };
157
+ var rangeFromIndex = (sheet, idx) => {
158
+ const [from, to] = idx.split(":").map((index) => addressFromIndex(sheet, index));
159
+ return {
160
+ from,
161
+ to
162
+ };
163
+ };
164
+ var closest = (cursor, cells) => {
165
+ let closestCell;
166
+ let closestDistance = Number.MAX_SAFE_INTEGER;
167
+ for (const cell of cells) {
168
+ const distance = Math.abs(cell.row - cursor.row) + Math.abs(cell.col - cursor.col);
169
+ if (distance < closestDistance) {
170
+ closestCell = cell;
171
+ closestDistance = distance;
172
+ }
173
+ }
174
+ return closestCell;
175
+ };
176
+ var compareIndexPositions = (sheet, indexA, indexB) => {
177
+ const { row: rowA, col: columnA } = addressFromIndex(sheet, indexA);
178
+ const { row: rowB, col: columnB } = addressFromIndex(sheet, indexB);
179
+ if (rowA !== rowB) {
180
+ return rowA - rowB;
181
+ } else {
182
+ return columnA - columnB;
183
+ }
184
+ };
185
+
186
+ // packages/plugins/plugin-sheet/src/components/Sheet/grid.ts
40
187
  var axisWidth = "calc(var(--rail-size)-2px)";
41
188
  var axisHeight = 34;
42
189
  var minWidth = 40;
@@ -78,7 +225,7 @@ var useGridLayout = ({ scroller, size, rows, columns, rowSizes, columnSizes }) =
78
225
  const left = x;
79
226
  x += width2 - 1;
80
227
  return {
81
- column: i,
228
+ col: i,
82
229
  left,
83
230
  width: width2
84
231
  };
@@ -183,14 +330,14 @@ var handleNav = (ev, cursor, range, size) => {
183
330
  break;
184
331
  }
185
332
  case "ArrowLeft": {
186
- if (opposite.column > 0) {
187
- opposite.column -= 1;
333
+ if (opposite.col > 0) {
334
+ opposite.col -= 1;
188
335
  }
189
336
  break;
190
337
  }
191
338
  case "ArrowRight": {
192
- if (opposite.column < size.numColumns - 1) {
193
- opposite.column += 1;
339
+ if (opposite.col < size.numCols - 1) {
340
+ opposite.col += 1;
194
341
  }
195
342
  break;
196
343
  }
@@ -208,18 +355,18 @@ var handleNav = (ev, cursor, range, size) => {
208
355
  cursor: next
209
356
  };
210
357
  };
211
- var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
358
+ var handleArrowNav = (ev, cursor, { numRows, numCols }) => {
212
359
  switch (ev.key) {
213
360
  case "ArrowUp":
214
361
  if (cursor === void 0) {
215
362
  return {
216
363
  row: 0,
217
- column: 0
364
+ col: 0
218
365
  };
219
366
  } else if (cursor.row > 0) {
220
367
  return {
221
368
  row: ev.metaKey ? 0 : cursor.row - 1,
222
- column: cursor.column
369
+ col: cursor.col
223
370
  };
224
371
  }
225
372
  break;
@@ -227,12 +374,12 @@ var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
227
374
  if (cursor === void 0) {
228
375
  return {
229
376
  row: 0,
230
- column: 0
377
+ col: 0
231
378
  };
232
379
  } else if (cursor.row < numRows - 1) {
233
380
  return {
234
381
  row: ev.metaKey ? numRows - 1 : cursor.row + 1,
235
- column: cursor.column
382
+ col: cursor.col
236
383
  };
237
384
  }
238
385
  break;
@@ -240,12 +387,12 @@ var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
240
387
  if (cursor === void 0) {
241
388
  return {
242
389
  row: 0,
243
- column: 0
390
+ col: 0
244
391
  };
245
- } else if (cursor.column > 0) {
392
+ } else if (cursor.col > 0) {
246
393
  return {
247
394
  row: cursor.row,
248
- column: ev.metaKey ? 0 : cursor.column - 1
395
+ col: ev.metaKey ? 0 : cursor.col - 1
249
396
  };
250
397
  }
251
398
  break;
@@ -253,24 +400,24 @@ var handleArrowNav = (ev, cursor, { numRows, numColumns }) => {
253
400
  if (cursor === void 0) {
254
401
  return {
255
402
  row: 0,
256
- column: 0
403
+ col: 0
257
404
  };
258
- } else if (cursor.column < numColumns - 1) {
405
+ } else if (cursor.col < numCols - 1) {
259
406
  return {
260
407
  row: cursor.row,
261
- column: ev.metaKey ? numColumns - 1 : cursor.column + 1
408
+ col: ev.metaKey ? numCols - 1 : cursor.col + 1
262
409
  };
263
410
  }
264
411
  break;
265
412
  case "Home":
266
413
  return {
267
414
  row: 0,
268
- column: 0
415
+ col: 0
269
416
  };
270
417
  case "End":
271
418
  return {
272
419
  row: numRows - 1,
273
- column: numColumns - 1
420
+ col: numCols - 1
274
421
  };
275
422
  }
276
423
  };
@@ -327,31 +474,103 @@ var useRangeSelect = (cb) => {
327
474
  };
328
475
 
329
476
  // 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";
477
+ import React3, { createContext as createContext2, useContext as useContext2, useMemo as useMemo2, useState as useState4 } from "react";
478
+ import { invariant as invariant3 } from "@dxos/invariant";
479
+
480
+ // packages/plugins/plugin-sheet/src/components/Sheet/decorations.ts
481
+ import { create as create2 } from "@dxos/echo-schema";
482
+ var createDecorations = () => {
483
+ const { decorations } = create2({
484
+ decorations: {}
485
+ });
486
+ const addDecoration = (cellIndex, decorator) => {
487
+ decorations[cellIndex] = [
488
+ ...decorations[cellIndex] || [],
489
+ decorator
490
+ ];
491
+ };
492
+ const removeDecoration = (cellIndex, type) => {
493
+ if (type) {
494
+ decorations[cellIndex] = (decorations[cellIndex] || []).filter((d) => d.type !== type);
495
+ } else {
496
+ delete decorations[cellIndex];
497
+ }
498
+ };
499
+ const getDecorationsForCell = (cellIndex) => {
500
+ return decorations[cellIndex];
501
+ };
502
+ const getAllDecorations = () => {
503
+ const result = [];
504
+ for (const decoratorArray of Object.values(decorations)) {
505
+ for (const decorator of decoratorArray) {
506
+ result.push(decorator);
507
+ }
508
+ }
509
+ return result;
510
+ };
511
+ return {
512
+ addDecoration,
513
+ removeDecoration,
514
+ getDecorationsForCell,
515
+ getAllDecorations
516
+ };
517
+ };
518
+
519
+ // packages/plugins/plugin-sheet/src/hooks/useComputeGraph.ts
520
+ import { useContext } from "react";
521
+ import { raise } from "@dxos/debug";
522
+ import { useAsyncState } from "@dxos/react-hooks";
523
+
524
+ // packages/plugins/plugin-sheet/src/components/index.ts
525
+ import React2 from "react";
526
+
527
+ // packages/plugins/plugin-sheet/src/components/ComputeGraph/ComputeGraphContextProvider.tsx
528
+ import React, { createContext } from "react";
529
+ var ComputeGraphContext = /* @__PURE__ */ createContext(void 0);
530
+ var ComputeGraphContextProvider = ({ registry, children }) => {
531
+ return /* @__PURE__ */ React.createElement(ComputeGraphContext.Provider, {
532
+ value: {
533
+ registry
534
+ }
535
+ }, children);
536
+ };
537
+
538
+ // packages/plugins/plugin-sheet/src/components/index.ts
539
+ var SheetContainer = React2.lazy(() => import("./SheetContainer-V4GCCZTX.mjs"));
333
540
 
334
- // packages/plugins/plugin-sheet/src/components/Sheet/formatting.ts
541
+ // packages/plugins/plugin-sheet/src/hooks/useComputeGraph.ts
542
+ var useComputeGraph = (space) => {
543
+ const { registry } = useContext(ComputeGraphContext) ?? raise(new Error("Missing ComputeGraphContext"));
544
+ return useAsyncState(async () => space && registry.getOrCreateGraph(space), [
545
+ space,
546
+ registry
547
+ ]);
548
+ };
549
+
550
+ // packages/plugins/plugin-sheet/src/hooks/useFormattingModel.ts
551
+ import { useMemo } from "react";
552
+
553
+ // packages/plugins/plugin-sheet/src/model/formatting-model.ts
335
554
  var FormattingModel = class {
336
- constructor(model) {
337
- this.model = model;
555
+ constructor(_model) {
556
+ this._model = _model;
338
557
  }
339
558
  /**
340
559
  * Get formatted string value and className for cell.
341
560
  */
342
561
  getFormatting(cell) {
343
- const value = this.model.getValue(cell);
562
+ const value = this._model.getValue(cell);
344
563
  if (value === void 0 || value === null) {
345
564
  return {};
346
565
  }
347
566
  const locales = void 0;
348
- const idx = this.model.addressToIndex(cell);
349
- let formatting = this.model.sheet.formatting?.[idx] ?? {};
567
+ const idx = addressToIndex(this._model.sheet, cell);
568
+ let formatting = this._model.sheet.formatting?.[idx] ?? {};
350
569
  const classNames = [
351
570
  ...formatting?.classNames ?? []
352
571
  ];
353
- for (const [idx2, _formatting] of Object.entries(this.model.sheet.formatting)) {
354
- const range = this.model.rangeFromIndex(idx2);
572
+ for (const [idx2, _formatting] of Object.entries(this._model.sheet.formatting)) {
573
+ const range = rangeFromIndex(this._model.sheet, idx2);
355
574
  if (inRange(range, cell)) {
356
575
  if (_formatting.classNames) {
357
576
  classNames.push(..._formatting.classNames);
@@ -362,7 +581,7 @@ var FormattingModel = class {
362
581
  }
363
582
  }
364
583
  const defaultNumber = "justify-end font-mono";
365
- const type = formatting?.type ?? this.model.getValueType(cell);
584
+ const type = formatting?.type ?? this._model.getValueType(cell);
366
585
  switch (type) {
367
586
  case ValueTypeEnum.Boolean: {
368
587
  return {
@@ -373,6 +592,9 @@ var FormattingModel = class {
373
592
  ]
374
593
  };
375
594
  }
595
+ //
596
+ // Numbers.
597
+ //
376
598
  case ValueTypeEnum.Number: {
377
599
  return {
378
600
  value: value.toLocaleString(locales),
@@ -405,22 +627,25 @@ var FormattingModel = class {
405
627
  ]
406
628
  };
407
629
  }
630
+ //
631
+ // Dates.
632
+ //
408
633
  case ValueTypeEnum.DateTime: {
409
- const date = this.model.toLocalDate(value);
634
+ const date = this._model.toLocalDate(value);
410
635
  return {
411
636
  value: date.toLocaleString(locales),
412
637
  classNames
413
638
  };
414
639
  }
415
640
  case ValueTypeEnum.Date: {
416
- const date = this.model.toLocalDate(value);
641
+ const date = this._model.toLocalDate(value);
417
642
  return {
418
643
  value: date.toLocaleDateString(locales),
419
644
  classNames
420
645
  };
421
646
  }
422
647
  case ValueTypeEnum.Time: {
423
- const date = this.model.toLocalDate(value);
648
+ const date = this._model.toLocalDate(value);
424
649
  return {
425
650
  value: date.toLocaleTimeString(locales),
426
651
  classNames
@@ -436,84 +661,428 @@ var FormattingModel = class {
436
661
  }
437
662
  };
438
663
 
439
- // packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx
440
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx";
441
- var OBJECT_ID_LENGTH = 60;
442
- var SheetContext = /* @__PURE__ */ createContext(null);
443
- var useSheetContext = () => {
444
- const context = useContext(SheetContext);
445
- invariant(context, void 0, {
446
- F: __dxlog_file,
447
- L: 45,
448
- S: void 0,
449
- A: [
450
- "context",
451
- ""
452
- ]
453
- });
454
- return context;
664
+ // packages/plugins/plugin-sheet/src/model/sheet-model.ts
665
+ import { Event } from "@dxos/async";
666
+ import { Resource } from "@dxos/context";
667
+ import { invariant as invariant2 } from "@dxos/invariant";
668
+ import { PublicKey } from "@dxos/keys";
669
+ import { log } from "@dxos/log";
670
+ import { DetailedCellError, ExportedCellChange } from "#hyperformula";
671
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/model/sheet-model.ts";
672
+ var typeMap = {
673
+ BOOLEAN: ValueTypeEnum.Boolean,
674
+ NUMBER_RAW: ValueTypeEnum.Number,
675
+ NUMBER_PERCENT: ValueTypeEnum.Percent,
676
+ NUMBER_CURRENCY: ValueTypeEnum.Currency,
677
+ NUMBER_DATETIME: ValueTypeEnum.DateTime,
678
+ NUMBER_DATE: ValueTypeEnum.Date,
679
+ NUMBER_TIME: ValueTypeEnum.Time
455
680
  };
456
- var mapFormulaBindingToId = (functions) => (formula) => {
457
- return formula.replace(/([a-zA-Z0-9]+)\((.*)\)/g, (match, binding, args) => {
458
- if (defaultFunctions.find((fn2) => fn2.name === binding) || binding === "EDGE") {
459
- return match;
681
+ var getTopLeft = (range) => {
682
+ const to = range.to ?? range.from;
683
+ return {
684
+ row: Math.min(range.from.row, to.row),
685
+ col: Math.min(range.from.col, to.col)
686
+ };
687
+ };
688
+ var toSimpleCellAddress = (sheet, cell) => ({
689
+ sheet,
690
+ row: cell.row,
691
+ col: cell.col
692
+ });
693
+ var toModelRange = (sheet, range) => ({
694
+ start: toSimpleCellAddress(sheet, range.from),
695
+ end: toSimpleCellAddress(sheet, range.to ?? range.from)
696
+ });
697
+ var SheetModel = class extends Resource {
698
+ constructor(_graph, _sheet, _options = {}) {
699
+ super();
700
+ this._graph = _graph;
701
+ this._sheet = _sheet;
702
+ this._options = _options;
703
+ this.id = `model-${PublicKey.random().truncate()}`;
704
+ this.update = new Event();
705
+ this._node = this._graph.getOrCreateNode(createSheetName(this._sheet.id));
706
+ this.reset();
707
+ }
708
+ get graph() {
709
+ return this._graph;
710
+ }
711
+ get sheet() {
712
+ return this._sheet;
713
+ }
714
+ get readonly() {
715
+ return this._options.readonly;
716
+ }
717
+ get bounds() {
718
+ return {
719
+ rows: this._sheet.rows.length,
720
+ columns: this._sheet.columns.length
721
+ };
722
+ }
723
+ /**
724
+ * Initialize sheet and engine.
725
+ */
726
+ async _open() {
727
+ log("initialize", {
728
+ id: this.id
729
+ }, {
730
+ F: __dxlog_file2,
731
+ L: 105,
732
+ S: this,
733
+ C: (f, a) => f(...a)
734
+ });
735
+ initialize(this._sheet);
736
+ this.reset();
737
+ const unsubscribe = this._graph.update.on(() => this.update.emit());
738
+ this._ctx.onDispose(unsubscribe);
739
+ }
740
+ /**
741
+ * Update engine.
742
+ * NOTE: This resets the undo history.
743
+ * @deprecated
744
+ */
745
+ reset() {
746
+ this._node.hf.clearSheet(this._node.sheetId);
747
+ Object.entries(this._sheet.cells).forEach(([key, { value }]) => {
748
+ const { col, row } = addressFromIndex(this._sheet, key);
749
+ if (typeof value === "string" && value.charAt(0) === "=") {
750
+ value = this._graph.mapFormulaToNative(this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value)));
751
+ }
752
+ this._node.hf.setCellContents({
753
+ sheet: this._node.sheetId,
754
+ row,
755
+ col
756
+ }, value);
757
+ });
758
+ }
759
+ /**
760
+ * Recalculate formulas.
761
+ * NOTE: This resets the undo history.
762
+ * https://hyperformula.handsontable.com/guide/volatile-functions.html#volatile-actions
763
+ * @deprecated
764
+ */
765
+ // TODO(burdon): Remove.
766
+ recalculate() {
767
+ this._node.hf.rebuildAndRecalculate();
768
+ }
769
+ insertRows(i, n = 1) {
770
+ insertIndices(this._sheet.rows, i, n, MAX_ROWS);
771
+ this.reset();
772
+ }
773
+ insertColumns(i, n = 1) {
774
+ insertIndices(this._sheet.columns, i, n, MAX_COLUMNS);
775
+ this.reset();
776
+ }
777
+ //
778
+ // Undoable actions.
779
+ // TODO(burdon): Group undoable methods; consistently update hf/sheet.
780
+ //
781
+ /**
782
+ * Clear range of values.
783
+ */
784
+ clear(range) {
785
+ const topLeft = getTopLeft(range);
786
+ const values = this._iterRange(range, () => null);
787
+ this._node.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);
788
+ this._iterRange(range, (cell) => {
789
+ const idx = addressToIndex(this._sheet, cell);
790
+ delete this._sheet.cells[idx];
791
+ });
792
+ }
793
+ cut(range) {
794
+ this._node.hf.cut(toModelRange(this._node.sheetId, range));
795
+ this._iterRange(range, (cell) => {
796
+ const idx = addressToIndex(this._sheet, cell);
797
+ delete this._sheet.cells[idx];
798
+ });
799
+ }
800
+ copy(range) {
801
+ this._node.hf.copy(toModelRange(this._node.sheetId, range));
802
+ }
803
+ paste(cell) {
804
+ if (!this._node.hf.isClipboardEmpty()) {
805
+ const changes = this._node.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));
806
+ for (const change of changes) {
807
+ if (change instanceof ExportedCellChange) {
808
+ const { address, newValue } = change;
809
+ const idx = addressToIndex(this._sheet, {
810
+ row: address.row,
811
+ col: address.col
812
+ });
813
+ this._sheet.cells[idx] = {
814
+ value: newValue
815
+ };
816
+ }
817
+ }
818
+ }
819
+ }
820
+ // TODO(burdon): Display undo/redo state.
821
+ undo() {
822
+ if (this._node.hf.isThereSomethingToUndo()) {
823
+ this._node.hf.undo();
824
+ this.update.emit();
825
+ }
826
+ }
827
+ redo() {
828
+ if (this._node.hf.isThereSomethingToRedo()) {
829
+ this._node.hf.redo();
830
+ this.update.emit();
460
831
  }
461
- const fn = functions.find((fn2) => fn2.binding === binding);
462
- if (fn) {
463
- return `${fullyQualifiedId(fn)}(${args})`;
832
+ }
833
+ /**
834
+ * Get value from sheet.
835
+ */
836
+ getCellValue(cell) {
837
+ const idx = addressToIndex(this._sheet, cell);
838
+ return this._sheet.cells[idx]?.value ?? null;
839
+ }
840
+ /**
841
+ * Get value as a string for editing.
842
+ */
843
+ getCellText(cell) {
844
+ const value = this.getCellValue(cell);
845
+ if (value == null) {
846
+ return void 0;
847
+ }
848
+ if (typeof value === "string" && value.charAt(0) === "=") {
849
+ return this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value));
464
850
  } else {
465
- return match;
851
+ return String(value);
466
852
  }
467
- });
468
- };
469
- var mapFormulaBindingFromId = (functions) => (formula) => {
470
- return formula.replace(/([a-zA-Z0-9]+):([a-zA-Z0-9]+)\((.*)\)/g, (match, spaceId, objectId, args) => {
471
- const id = `${spaceId}:${objectId}`;
472
- if (id.length !== OBJECT_ID_LENGTH) {
473
- return match;
853
+ }
854
+ /**
855
+ * Get array of raw values from sheet.
856
+ */
857
+ getCellValues(range) {
858
+ return this._iterRange(range, (cell) => this.getCellValue(cell));
859
+ }
860
+ /**
861
+ * Gets the regular or computed value from the engine.
862
+ */
863
+ getValue(cell) {
864
+ const value = this._node.hf.getCellValue(toSimpleCellAddress(this._node.sheetId, cell));
865
+ if (value instanceof DetailedCellError) {
866
+ return value.toString();
867
+ }
868
+ return value;
869
+ }
870
+ /**
871
+ * Get value type.
872
+ */
873
+ getValueType(cell) {
874
+ const addr = toSimpleCellAddress(this._node.sheetId, cell);
875
+ const type = this._node.hf.getCellValueDetailedType(addr);
876
+ return typeMap[type];
877
+ }
878
+ /**
879
+ * Sets the value, updating the sheet and engine.
880
+ */
881
+ setValue(cell, value) {
882
+ if (this._options.readonly) {
883
+ throw new ReadonlyException();
884
+ }
885
+ let refresh = false;
886
+ if (cell.row >= this._sheet.rows.length) {
887
+ insertIndices(this._sheet.rows, cell.row, 1, MAX_ROWS);
888
+ refresh = true;
889
+ }
890
+ if (cell.col >= this._sheet.columns.length) {
891
+ insertIndices(this._sheet.columns, cell.col, 1, MAX_COLUMNS);
892
+ refresh = true;
474
893
  }
475
- const fn = functions.find((fn2) => fullyQualifiedId(fn2) === id);
476
- if (fn?.binding) {
477
- return `${fn.binding}(${args})`;
894
+ if (refresh) {
895
+ this.reset();
896
+ }
897
+ this._node.hf.setCellContents({
898
+ sheet: this._node.sheetId,
899
+ row: cell.row,
900
+ col: cell.col
901
+ }, [
902
+ [
903
+ typeof value === "string" && value.charAt(0) === "=" ? this._graph.mapFormulaToNative(value) : value
904
+ ]
905
+ ]);
906
+ const idx = addressToIndex(this._sheet, cell);
907
+ if (value === void 0 || value === null) {
908
+ delete this._sheet.cells[idx];
478
909
  } else {
479
- return match;
910
+ if (typeof value === "string" && value.charAt(0) === "=") {
911
+ value = this._graph.mapFunctionBindingToId(this.mapFormulaRefsToIndices(value));
912
+ }
913
+ this._sheet.cells[idx] = {
914
+ value
915
+ };
480
916
  }
481
- });
917
+ }
918
+ /**
919
+ * Sets values from a simple map.
920
+ */
921
+ setValues(values) {
922
+ Object.entries(values).forEach(([key, { value }]) => {
923
+ this.setValue(addressFromA1Notation(key), value);
924
+ });
925
+ }
926
+ /**
927
+ * Iterate range.
928
+ */
929
+ _iterRange(range, cb) {
930
+ const to = range.to ?? range.from;
931
+ const rowRange = [
932
+ Math.min(range.from.row, to.row),
933
+ Math.max(range.from.row, to.row)
934
+ ];
935
+ const columnRange = [
936
+ Math.min(range.from.col, to.col),
937
+ Math.max(range.from.col, to.col)
938
+ ];
939
+ const rows = [];
940
+ for (let row = rowRange[0]; row <= rowRange[1]; row++) {
941
+ const rowCells = [];
942
+ for (let column = columnRange[0]; column <= columnRange[1]; column++) {
943
+ const value = cb({
944
+ row,
945
+ col: column
946
+ });
947
+ if (value !== void 0) {
948
+ rowCells.push(value);
949
+ }
950
+ }
951
+ rows.push(rowCells);
952
+ }
953
+ return rows;
954
+ }
955
+ // TODO(burdon): Delete index.
956
+ _deleteIndices(indices, i, n) {
957
+ throw new Error("Not implemented");
958
+ }
959
+ // TODO(burdon): Move. Cannot use fractional without changing. Switch back to using unique IDs?
960
+ _moveIndices(indices, i, j, n) {
961
+ throw new Error("Not implemented");
962
+ }
963
+ //
964
+ // Indices.
965
+ //
966
+ /**
967
+ * Map from A1 notation to indices.
968
+ */
969
+ mapFormulaRefsToIndices(formula) {
970
+ invariant2(formula.charAt(0) === "=", void 0, {
971
+ F: __dxlog_file2,
972
+ L: 358,
973
+ S: this,
974
+ A: [
975
+ "formula.charAt(0) === '='",
976
+ ""
977
+ ]
978
+ });
979
+ return formula.replace(/([a-zA-Z]+)([0-9]+)/g, (match) => {
980
+ return addressToIndex(this._sheet, addressFromA1Notation(match));
981
+ });
982
+ }
983
+ /**
984
+ * Map from indices to A1 notation.
985
+ */
986
+ mapFormulaIndicesToRefs(formula) {
987
+ invariant2(formula.charAt(0) === "=", void 0, {
988
+ F: __dxlog_file2,
989
+ L: 368,
990
+ S: this,
991
+ A: [
992
+ "formula.charAt(0) === '='",
993
+ ""
994
+ ]
995
+ });
996
+ return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {
997
+ return addressToA1Notation(addressFromIndex(this._sheet, idx));
998
+ });
999
+ }
1000
+ //
1001
+ // Values
1002
+ //
1003
+ /**
1004
+ * https://hyperformula.handsontable.com/guide/date-and-time-handling.html#example
1005
+ * https://hyperformula.handsontable.com/api/interfaces/configparams.html#nulldate
1006
+ * NOTE: TODAY() is number of FULL days since nullDate. It will typically be -1 days from NOW().
1007
+ */
1008
+ toLocalDate(num) {
1009
+ const { year, month, day, hours, minutes, seconds } = this.toDateTime(num);
1010
+ return new Date(year, month - 1, day, hours, minutes, seconds);
1011
+ }
1012
+ toDateTime(num) {
1013
+ return this._node.hf.numberToDateTime(num);
1014
+ }
1015
+ toDate(num) {
1016
+ return this._node.hf.numberToDate(num);
1017
+ }
1018
+ toTime(num) {
1019
+ return this._node.hf.numberToTime(num);
1020
+ }
482
1021
  };
483
- var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...options }) => {
484
- const graph = useComputeGraph(space, options);
485
- const [cursor, setCursor] = useState3();
486
- const [range, setRange] = useState3();
487
- const [editing, setEditing] = useState3(false);
488
- const [[model, formatting] = [], setModels] = useState3(void 0);
1022
+
1023
+ // packages/plugins/plugin-sheet/src/hooks/useFormattingModel.ts
1024
+ var useFormattingModel = (model) => {
1025
+ return useMemo(() => model && new FormattingModel(model), [
1026
+ model
1027
+ ]);
1028
+ };
1029
+
1030
+ // packages/plugins/plugin-sheet/src/hooks/useSheetModel.ts
1031
+ import { useEffect as useEffect2, useState as useState3 } from "react";
1032
+ var useSheetModel = (space, sheet, { readonly } = {}) => {
1033
+ const graph = useComputeGraph(space);
1034
+ const [model, setModel] = useState3();
489
1035
  useEffect2(() => {
1036
+ if (!space || !graph || !sheet) {
1037
+ return;
1038
+ }
490
1039
  let model2;
491
- let formatting2;
492
1040
  const t = setTimeout(async () => {
493
- model2 = new SheetModel(graph, sheet, space, {
494
- readonly,
495
- mapFormulaBindingToId,
496
- mapFormulaBindingFromId
1041
+ model2 = new SheetModel(graph, sheet, {
1042
+ readonly
497
1043
  });
498
- await model2.initialize();
499
- formatting2 = new FormattingModel(model2);
500
- setModels([
501
- model2,
502
- formatting2
503
- ]);
1044
+ await model2.open();
1045
+ setModel(model2);
504
1046
  });
505
1047
  return () => {
506
1048
  clearTimeout(t);
507
- void model2?.destroy();
1049
+ void model2?.close();
508
1050
  };
509
1051
  }, [
1052
+ space,
1053
+ sheet,
510
1054
  graph,
511
1055
  readonly
512
1056
  ]);
513
- if (!model || !formatting) {
514
- return null;
515
- }
516
- return /* @__PURE__ */ React.createElement(SheetContext.Provider, {
1057
+ return model;
1058
+ };
1059
+
1060
+ // packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx
1061
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/sheet-context.tsx";
1062
+ var SheetContext = /* @__PURE__ */ createContext2(null);
1063
+ var useSheetContext = () => {
1064
+ const context = useContext2(SheetContext);
1065
+ invariant3(context, void 0, {
1066
+ F: __dxlog_file3,
1067
+ L: 43,
1068
+ S: void 0,
1069
+ A: [
1070
+ "context",
1071
+ ""
1072
+ ]
1073
+ });
1074
+ return context;
1075
+ };
1076
+ var SheetContextProvider = ({ children, sheet, space, readonly, onInfo }) => {
1077
+ const model = useSheetModel(space, sheet, {
1078
+ readonly
1079
+ });
1080
+ const formatting = useFormattingModel(model);
1081
+ const [cursor, setCursor] = useState4();
1082
+ const [range, setRange] = useState4();
1083
+ const [editing, setEditing] = useState4(false);
1084
+ const decorations = useMemo2(() => createDecorations(), []);
1085
+ return !model || !formatting ? null : /* @__PURE__ */ React3.createElement(SheetContext.Provider, {
517
1086
  value: {
518
1087
  model,
519
1088
  formatting,
@@ -524,11 +1093,177 @@ var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...optio
524
1093
  editing,
525
1094
  setEditing,
526
1095
  // TODO(burdon): Change to event.
527
- onInfo
1096
+ onInfo,
1097
+ decorations
528
1098
  }
529
1099
  }, children);
530
1100
  };
531
1101
 
1102
+ // packages/plugins/plugin-sheet/src/components/Sheet/threads.tsx
1103
+ import { effect } from "@preact/signals-core";
1104
+ import React4, { useCallback, useEffect as useEffect3, useMemo as useMemo3 } from "react";
1105
+ import { LayoutAction, useIntentDispatcher, useIntentResolver } from "@dxos/app-framework";
1106
+ import { debounce } from "@dxos/async";
1107
+ import { fullyQualifiedId } from "@dxos/react-client/echo";
1108
+ import { Icon, useTranslation } from "@dxos/react-ui";
1109
+ var CommentIndicator = () => {
1110
+ return /* @__PURE__ */ React4.createElement("div", {
1111
+ role: "none",
1112
+ className: "absolute top-0 right-0 w-0 h-0 border-t-8 border-l-8 border-t-cmCommentSurface border-l-transparent"
1113
+ });
1114
+ };
1115
+ var ThreadedCellWrapper = ({ children }) => {
1116
+ const dispatch = useIntentDispatcher();
1117
+ const [isHovered, setIsHovered] = React4.useState(false);
1118
+ const { t } = useTranslation(SHEET_PLUGIN);
1119
+ const handleClick = React4.useCallback((_event) => {
1120
+ void dispatch({
1121
+ action: LayoutAction.SET_LAYOUT,
1122
+ data: {
1123
+ element: "complementary",
1124
+ state: true
1125
+ }
1126
+ });
1127
+ }, [
1128
+ dispatch
1129
+ ]);
1130
+ return /* @__PURE__ */ React4.createElement("div", {
1131
+ role: "none",
1132
+ className: "relative h-full is-full",
1133
+ onMouseEnter: () => {
1134
+ setIsHovered(true);
1135
+ },
1136
+ onMouseLeave: () => {
1137
+ setIsHovered(false);
1138
+ }
1139
+ }, /* @__PURE__ */ React4.createElement(CommentIndicator, null), isHovered && /* @__PURE__ */ React4.createElement("div", {
1140
+ className: "absolute inset-0 flex items-center justify-end pr-1"
1141
+ }, /* @__PURE__ */ React4.createElement("button", {
1142
+ className: "ch-button text-xs min-bs-0 p-1",
1143
+ onClick: handleClick,
1144
+ "aria-label": t("open comment for sheet cell")
1145
+ }, /* @__PURE__ */ React4.createElement(Icon, {
1146
+ icon: "ph--chat--regular",
1147
+ "aria-hidden": true
1148
+ }))), children);
1149
+ };
1150
+ var createThreadDecoration = (cellIndex, threadId, sheetId) => {
1151
+ return {
1152
+ type: "comment",
1153
+ cellIndex,
1154
+ decorate: (props) => /* @__PURE__ */ React4.createElement(ThreadedCellWrapper, props)
1155
+ };
1156
+ };
1157
+ var useUpdateCursorOnThreadSelection = () => {
1158
+ const { setCursor, model } = useSheetContext();
1159
+ const handleScrollIntoView = useCallback(({ action, data }) => {
1160
+ switch (action) {
1161
+ case LayoutAction.SCROLL_INTO_VIEW: {
1162
+ if (!data?.id || data?.cursor === void 0 || data?.id !== fullyQualifiedId(model.sheet)) {
1163
+ return;
1164
+ }
1165
+ const cellAddress = addressFromIndex(model.sheet, data.cursor);
1166
+ setCursor(cellAddress);
1167
+ }
1168
+ }
1169
+ }, [
1170
+ model.sheet,
1171
+ setCursor
1172
+ ]);
1173
+ useIntentResolver(SHEET_PLUGIN, handleScrollIntoView);
1174
+ };
1175
+ var useSelectThreadOnCursorChange = () => {
1176
+ const { cursor, model } = useSheetContext();
1177
+ const dispatch = useIntentDispatcher();
1178
+ const activeThreads = useMemo3(() => model.sheet.threads?.filter((thread) => !!thread && thread.status === "active") ?? [], [
1179
+ JSON.stringify(model.sheet.threads)
1180
+ ]);
1181
+ const activeThreadAddresses = useMemo3(() => activeThreads.map((thread) => thread.anchor).filter((anchor) => anchor !== void 0).map((anchor) => addressFromIndex(model.sheet, anchor)), [
1182
+ activeThreads,
1183
+ model.sheet
1184
+ ]);
1185
+ const selectClosestThread = useCallback((cellAddress) => {
1186
+ if (!cellAddress || !activeThreads) {
1187
+ return;
1188
+ }
1189
+ const closestThreadAnchor = closest(cellAddress, activeThreadAddresses);
1190
+ if (closestThreadAnchor) {
1191
+ const closestThread = activeThreads.find((thread) => thread && thread.anchor === addressToIndex(model.sheet, closestThreadAnchor));
1192
+ if (closestThread) {
1193
+ void dispatch([
1194
+ {
1195
+ action: "dxos.org/plugin/thread/action/select",
1196
+ data: {
1197
+ current: fullyQualifiedId(closestThread)
1198
+ }
1199
+ }
1200
+ ]);
1201
+ }
1202
+ }
1203
+ }, [
1204
+ dispatch,
1205
+ activeThreads,
1206
+ activeThreadAddresses,
1207
+ model.sheet
1208
+ ]);
1209
+ const debounced = useMemo3(() => {
1210
+ return debounce((cursor2) => requestAnimationFrame(() => selectClosestThread(cursor2)), 50);
1211
+ }, [
1212
+ selectClosestThread
1213
+ ]);
1214
+ useEffect3(() => {
1215
+ if (!cursor) {
1216
+ return;
1217
+ }
1218
+ debounced(cursor);
1219
+ }, [
1220
+ cursor,
1221
+ selectClosestThread
1222
+ ]);
1223
+ };
1224
+ var useThreadDecorations = () => {
1225
+ const { decorations, model } = useSheetContext();
1226
+ const sheet = useMemo3(() => model.sheet, [
1227
+ model.sheet
1228
+ ]);
1229
+ const sheetId = useMemo3(() => fullyQualifiedId(sheet), [
1230
+ sheet
1231
+ ]);
1232
+ useEffect3(() => {
1233
+ const unsubscribe = effect(() => {
1234
+ const activeThreadAnchors = /* @__PURE__ */ new Set();
1235
+ if (!sheet.threads) {
1236
+ return;
1237
+ }
1238
+ for (const thread of sheet.threads) {
1239
+ if (!thread || thread.anchor === void 0 || thread.status === "resolved") {
1240
+ continue;
1241
+ }
1242
+ activeThreadAnchors.add(thread.anchor);
1243
+ const index = thread.anchor;
1244
+ const existingDecorations = decorations.getDecorationsForCell(index);
1245
+ if (!existingDecorations || !existingDecorations.some((d) => d.type === "comment")) {
1246
+ decorations.addDecoration(index, createThreadDecoration(index, thread.id, sheetId));
1247
+ }
1248
+ }
1249
+ for (const decoration of decorations.getAllDecorations()) {
1250
+ if (decoration.type !== "comment") {
1251
+ continue;
1252
+ }
1253
+ if (!activeThreadAnchors.has(decoration.cellIndex)) {
1254
+ decorations.removeDecoration(decoration.cellIndex, "comment");
1255
+ }
1256
+ }
1257
+ });
1258
+ return () => unsubscribe();
1259
+ });
1260
+ };
1261
+ var useThreads = () => {
1262
+ useUpdateCursorOnThreadSelection();
1263
+ useSelectThreadOnCursorChange();
1264
+ useThreadDecorations();
1265
+ };
1266
+
532
1267
  // packages/plugins/plugin-sheet/src/components/Sheet/util.ts
533
1268
  var getRelativeClientRect = (root, element) => {
534
1269
  const rootRect = root.getBoundingClientRect();
@@ -564,7 +1299,7 @@ var scrollIntoView = (scrollContainer, el) => {
564
1299
 
565
1300
  // packages/plugins/plugin-sheet/src/components/CellEditor/CellEditor.tsx
566
1301
  import { EditorView, keymap } from "@codemirror/view";
567
- import React2 from "react";
1302
+ import React5 from "react";
568
1303
  import { useThemeContext } from "@dxos/react-ui";
569
1304
  import { createBasicExtensions, createThemeExtensions, preventNewline, useTextEditor } from "@dxos/react-ui-editor";
570
1305
  var editorKeys = ({ onNav, onClose }) => {
@@ -612,20 +1347,60 @@ var editorKeys = ({ onNav, onClose }) => {
612
1347
  {
613
1348
  key: "Enter",
614
1349
  run: (editor) => {
615
- onClose(editor.state.doc.toString());
1350
+ onClose(editor.state.doc.toString(), {
1351
+ key: "Enter"
1352
+ });
1353
+ return true;
1354
+ },
1355
+ shift: (editor) => {
1356
+ onClose(editor.state.doc.toString(), {
1357
+ key: "Enter",
1358
+ shift: true
1359
+ });
1360
+ return true;
1361
+ }
1362
+ },
1363
+ {
1364
+ key: "Tab",
1365
+ run: (editor) => {
1366
+ onClose(editor.state.doc.toString(), {
1367
+ key: "Tab"
1368
+ });
1369
+ return true;
1370
+ },
1371
+ shift: (editor) => {
1372
+ onClose(editor.state.doc.toString(), {
1373
+ key: "Tab",
1374
+ shift: true
1375
+ });
616
1376
  return true;
617
1377
  }
618
1378
  },
619
1379
  {
620
1380
  key: "Escape",
621
1381
  run: () => {
622
- onClose(void 0);
1382
+ onClose(void 0, {
1383
+ key: "Escape"
1384
+ });
623
1385
  return true;
624
1386
  }
625
1387
  }
626
1388
  ]);
627
1389
  };
628
- var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
1390
+ var editorVariants = {
1391
+ // TODO(thure): remove when legacy is no longer used.
1392
+ legacy: {
1393
+ root: "flex w-full",
1394
+ editor: "flex w-full [&>.cm-scroller]:scrollbar-none",
1395
+ content: "!px-2 !py-1"
1396
+ },
1397
+ grid: {
1398
+ root: "absolute z-[1]",
1399
+ editor: "[&>.cm-scroller]:scrollbar-none tabular-nums",
1400
+ content: "!border !border-transparent !p-0.5"
1401
+ }
1402
+ };
1403
+ var CellEditor = ({ value, extension, autoFocus, onBlur, variant = "legacy", box, gridId }) => {
629
1404
  const { themeMode } = useThemeContext();
630
1405
  const { parentRef } = useTextEditor(() => {
631
1406
  return {
@@ -652,21 +1427,29 @@ var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
652
1427
  themeMode,
653
1428
  slots: {
654
1429
  editor: {
655
- className: "flex w-full [&>.cm-scroller]:scrollbar-none"
1430
+ className: editorVariants[variant].editor
656
1431
  },
657
1432
  content: {
658
- className: "!px-2 !py-1"
1433
+ className: editorVariants[variant].content
659
1434
  }
660
1435
  }
661
1436
  })
662
1437
  ]
663
1438
  };
664
1439
  }, [
665
- extension
1440
+ extension,
1441
+ autoFocus,
1442
+ value,
1443
+ variant,
1444
+ onBlur
666
1445
  ]);
667
- return /* @__PURE__ */ React2.createElement("div", {
1446
+ return /* @__PURE__ */ React5.createElement("div", {
668
1447
  ref: parentRef,
669
- className: "flex w-full"
1448
+ className: editorVariants[variant].root,
1449
+ style: box,
1450
+ ...gridId && {
1451
+ "data-grid": gridId
1452
+ }
670
1453
  });
671
1454
  };
672
1455
 
@@ -788,13 +1571,7 @@ var sheetExtension = ({ functions = [] }) => {
788
1571
  // NOTE: Useful for debugging.
789
1572
  closeOnBlur: false,
790
1573
  icons: false,
791
- tooltipClass: () => mx(
792
- // TODO(burdon): Factor out fragments.
793
- // TODO(burdon): Size to make width same as column.
794
- "!-left-[1px] !top-[33px] !-m-0 border !border-t-0 [&>ul]:!min-w-[198px]",
795
- "[&>ul>li[aria-selected]]:!bg-accentSurface",
796
- "border-separator"
797
- )
1574
+ tooltipClass: () => mx("!-left-[1px] !top-[33px] !-m-0 border !border-t-0 [&>ul]:!min-w-[198px]", "[&>ul>li[aria-selected]]:!bg-accentSurface", "border-separator")
798
1575
  }),
799
1576
  keymap2.of([
800
1577
  {
@@ -883,34 +1660,34 @@ var visitTree = (node, callback) => {
883
1660
  };
884
1661
 
885
1662
  // packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx
886
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx";
1663
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-sheet/src/components/Sheet/Sheet.tsx";
887
1664
  var fragments = {
888
1665
  axis: "bg-axisSurface text-axisText text-xs select-none",
889
1666
  axisSelected: "bg-attention text-baseText",
890
1667
  cell: "bg-gridCell",
891
- cellSelected: "bg-gridCellSelected text-baseText border !border-accentSurface",
892
- border: "border-gridLine"
1668
+ cellSelected: "bg-gridCellSelected text-baseText border !border-accentSurface"
893
1669
  };
894
1670
  var SheetRoot = ({ children, ...props }) => {
895
- return /* @__PURE__ */ React3.createElement(SheetContextProvider, props, children);
1671
+ return /* @__PURE__ */ React6.createElement(SheetContextProvider, props, children);
896
1672
  };
897
- var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns }, forwardRef2) => {
1673
+ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numCols }, forwardRef2) => {
898
1674
  const { model, cursor, setCursor, setRange, setEditing } = useSheetContext();
899
1675
  const { rowsRef, columnsRef, contentRef } = useScrollHandlers();
900
- const [rows, setRows] = useState4([
1676
+ useThreads();
1677
+ const [rows, setRows] = useState5([
901
1678
  ...model.sheet.rows
902
1679
  ]);
903
- const [columns, setColumns] = useState4([
1680
+ const [columns, setColumns] = useState5([
904
1681
  ...model.sheet.columns
905
1682
  ]);
906
- useEffect3(() => {
1683
+ useEffect4(() => {
907
1684
  const rowsAccessor = createDocAccessor(model.sheet, [
908
1685
  "rows"
909
1686
  ]);
910
1687
  const columnsAccessor = createDocAccessor(model.sheet, [
911
1688
  "columns"
912
1689
  ]);
913
- const handleUpdate = debounce(() => {
1690
+ const handleUpdate = debounce2(() => {
914
1691
  setRows([
915
1692
  ...model.sheet.rows
916
1693
  ]);
@@ -928,44 +1705,44 @@ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns },
928
1705
  }, [
929
1706
  model
930
1707
  ]);
931
- useEffect3(() => {
1708
+ useEffect4(() => {
932
1709
  model.reset();
933
1710
  }, [
934
1711
  rows,
935
1712
  columns
936
1713
  ]);
937
1714
  const handleMoveRows = (from, to, num = 1) => {
938
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1715
+ const cursorIdx = cursor ? addressToIndex(model.sheet, cursor) : void 0;
939
1716
  const [rows2] = model.sheet.rows.splice(from, num);
940
1717
  model.sheet.rows.splice(to, 0, rows2);
941
1718
  if (cursorIdx) {
942
- setCursor(model.addressFromIndex(cursorIdx));
1719
+ setCursor(addressFromIndex(model.sheet, cursorIdx));
943
1720
  }
944
1721
  setRows([
945
1722
  ...model.sheet.rows
946
1723
  ]);
947
1724
  };
948
1725
  const handleMoveColumns = (from, to, num = 1) => {
949
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1726
+ const cursorIdx = cursor ? addressToIndex(model.sheet, cursor) : void 0;
950
1727
  const columns2 = model.sheet.columns.splice(from, num);
951
1728
  model.sheet.columns.splice(to, 0, ...columns2);
952
1729
  if (cursorIdx) {
953
- setCursor(model.addressFromIndex(cursorIdx));
1730
+ setCursor(addressFromIndex(model.sheet, cursorIdx));
954
1731
  }
955
1732
  setColumns([
956
1733
  ...model.sheet.columns
957
1734
  ]);
958
1735
  };
959
- const [rowSizes, setRowSizes] = useState4();
960
- const [columnSizes, setColumnSizes] = useState4();
961
- useEffect3(() => {
1736
+ const [rowSizes, setRowSizes] = useState5();
1737
+ const [columnSizes, setColumnSizes] = useState5();
1738
+ useEffect4(() => {
962
1739
  const rowAccessor = createDocAccessor(model.sheet, [
963
1740
  "rowMeta"
964
1741
  ]);
965
1742
  const columnAccessor = createDocAccessor(model.sheet, [
966
1743
  "columnMeta"
967
1744
  ]);
968
- const handleUpdate = debounce(() => {
1745
+ const handleUpdate = debounce2(() => {
969
1746
  const mapSizes = (values) => values.reduce((map, [idx, meta]) => {
970
1747
  if (meta.size) {
971
1748
  map[idx] = meta.size;
@@ -1007,54 +1784,54 @@ var SheetMain = /* @__PURE__ */ forwardRef(({ classNames, numRows, numColumns },
1007
1784
  }));
1008
1785
  }
1009
1786
  };
1010
- return /* @__PURE__ */ React3.createElement("div", {
1787
+ return /* @__PURE__ */ React6.createElement("div", {
1011
1788
  role: "none",
1012
- className: mx2("grid grid-cols-[calc(var(--rail-size)-2px)_1fr] grid-rows-[32px_1fr_32px] bs-full is-full overflow-hidden", fragments.border, classNames)
1013
- }, /* @__PURE__ */ React3.createElement(GridCorner, {
1789
+ className: mx2("grid grid-cols-[calc(var(--rail-size)-2px)_1fr] grid-rows-[32px_1fr_32px] bs-full is-full overflow-hidden", classNames)
1790
+ }, /* @__PURE__ */ React6.createElement(GridCorner, {
1014
1791
  onClick: () => {
1015
1792
  setCursor(void 0);
1016
1793
  setRange(void 0);
1017
1794
  setEditing(false);
1018
1795
  }
1019
- }), /* @__PURE__ */ React3.createElement(SheetColumns, {
1796
+ }), /* @__PURE__ */ React6.createElement(SheetColumns, {
1020
1797
  ref: columnsRef,
1021
1798
  columns,
1022
1799
  sizes: columnSizes,
1023
- selected: cursor?.column,
1024
- onSelect: (column) => setCursor(cursor?.column === column ? void 0 : {
1800
+ selected: cursor?.col,
1801
+ onSelect: (col) => setCursor(cursor?.col === col ? void 0 : {
1025
1802
  row: -1,
1026
- column
1803
+ col
1027
1804
  }),
1028
1805
  onResize: handleResizeColumn,
1029
1806
  onMove: handleMoveColumns
1030
- }), /* @__PURE__ */ React3.createElement(SheetRows, {
1807
+ }), /* @__PURE__ */ React6.createElement(SheetRows, {
1031
1808
  ref: rowsRef,
1032
1809
  rows,
1033
1810
  sizes: rowSizes,
1034
1811
  selected: cursor?.row,
1035
1812
  onSelect: (row) => setCursor(cursor?.row === row ? void 0 : {
1036
1813
  row,
1037
- column: -1
1814
+ col: -1
1038
1815
  }),
1039
1816
  onResize: handleResizeRow,
1040
1817
  onMove: handleMoveRows
1041
- }), /* @__PURE__ */ React3.createElement(SheetGrid, {
1818
+ }), /* @__PURE__ */ React6.createElement(SheetGrid, {
1042
1819
  ref: contentRef,
1043
1820
  size: {
1044
1821
  numRows: numRows ?? rows.length,
1045
- numColumns: numColumns ?? columns.length
1822
+ numCols: numCols ?? columns.length
1046
1823
  },
1047
1824
  rows,
1048
1825
  columns,
1049
1826
  rowSizes,
1050
1827
  columnSizes
1051
- }), /* @__PURE__ */ React3.createElement(GridCorner, null), /* @__PURE__ */ React3.createElement(SheetStatusBar, null));
1828
+ }), /* @__PURE__ */ React6.createElement(GridCorner, null), /* @__PURE__ */ React6.createElement(SheetStatusBar, null));
1052
1829
  });
1053
1830
  var useScrollHandlers = () => {
1054
1831
  const rowsRef = useRef(null);
1055
1832
  const columnsRef = useRef(null);
1056
1833
  const contentRef = useRef(null);
1057
- useEffect3(() => {
1834
+ useEffect4(() => {
1058
1835
  const handleRowsScroll = (ev) => {
1059
1836
  const { scrollTop } = ev.target;
1060
1837
  if (!rowsRef.current.dataset.locked) {
@@ -1091,13 +1868,13 @@ var useScrollHandlers = () => {
1091
1868
  };
1092
1869
  };
1093
1870
  var GridCorner = (props) => {
1094
- return /* @__PURE__ */ React3.createElement("div", {
1871
+ return /* @__PURE__ */ React6.createElement("div", {
1095
1872
  className: fragments.axis,
1096
1873
  ...props
1097
1874
  });
1098
1875
  };
1099
1876
  var MovingOverlay = ({ label }) => {
1100
- return /* @__PURE__ */ React3.createElement("div", {
1877
+ return /* @__PURE__ */ React6.createElement("div", {
1101
1878
  className: "flex w-full h-full justify-center items-center text-sm p-1 bg-gridOverlay cursor-pointer"
1102
1879
  }, label);
1103
1880
  };
@@ -1117,7 +1894,7 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1117
1894
  });
1118
1895
  const keyboardSensor = useSensor(KeyboardSensor, {});
1119
1896
  const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
1120
- const [active, setActive] = useState4(null);
1897
+ const [active, setActive] = useState5(null);
1121
1898
  const handleDragStart = ({ active: active2 }) => {
1122
1899
  setActive(active2);
1123
1900
  };
@@ -1141,18 +1918,18 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1141
1918
  }
1142
1919
  return transform;
1143
1920
  };
1144
- return /* @__PURE__ */ React3.createElement("div", {
1921
+ return /* @__PURE__ */ React6.createElement("div", {
1145
1922
  className: "relative flex grow overflow-hidden"
1146
- }, /* @__PURE__ */ React3.createElement("div", {
1147
- className: mx2("z-20 absolute inset-0 border-y pointer-events-none", fragments.border),
1923
+ }, /* @__PURE__ */ React6.createElement("div", {
1924
+ className: mx2("z-20 absolute inset-0 border-y border-gridLine pointer-events-none"),
1148
1925
  style: {
1149
1926
  width: axisWidth
1150
1927
  }
1151
- }), /* @__PURE__ */ React3.createElement("div", {
1928
+ }), /* @__PURE__ */ React6.createElement("div", {
1152
1929
  ref: forwardRef2,
1153
1930
  role: "rowheader",
1154
1931
  className: "grow overflow-y-auto scrollbar-none"
1155
- }, /* @__PURE__ */ React3.createElement(DndContext, {
1932
+ }, /* @__PURE__ */ React6.createElement(DndContext, {
1156
1933
  sensors,
1157
1934
  modifiers: [
1158
1935
  restrictToVerticalAxis,
@@ -1160,12 +1937,12 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1160
1937
  ],
1161
1938
  onDragStart: handleDragStart,
1162
1939
  onDragEnd: handleDragEnd
1163
- }, /* @__PURE__ */ React3.createElement("div", {
1940
+ }, /* @__PURE__ */ React6.createElement("div", {
1164
1941
  className: "flex flex-col",
1165
1942
  style: {
1166
1943
  width: axisWidth
1167
1944
  }
1168
- }, rows.map((idx, index) => /* @__PURE__ */ React3.createElement(GridRowCell, {
1945
+ }, rows.map((idx, index) => /* @__PURE__ */ React6.createElement(GridRowCell, {
1169
1946
  key: idx,
1170
1947
  idx,
1171
1948
  index,
@@ -1175,7 +1952,7 @@ var SheetRows = /* @__PURE__ */ forwardRef(({ rows, sizes, selected, onSelect, o
1175
1952
  selected: selected === index,
1176
1953
  onResize,
1177
1954
  onSelect
1178
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(DragOverlay, null, active && /* @__PURE__ */ React3.createElement(MovingOverlay, {
1955
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement(DragOverlay, null, active && /* @__PURE__ */ React6.createElement(MovingOverlay, {
1179
1956
  label: String(active.data.current.index + 1)
1180
1957
  })), document.body))));
1181
1958
  });
@@ -1193,8 +1970,8 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1193
1970
  }
1194
1971
  });
1195
1972
  const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
1196
- const [initialSize, setInitialSize] = useState4(size);
1197
- const [resizing, setResizing] = useState4(false);
1973
+ const [initialSize, setInitialSize] = useState5(size);
1974
+ const [resizing, setResizing] = useState5(false);
1198
1975
  const scrollHandler = useRef();
1199
1976
  const handleResizeStart = (_ev, _dir, elementRef) => {
1200
1977
  const scrollContainer = elementRef.closest('[role="rowheader"]');
@@ -1216,7 +1993,7 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1216
1993
  onResize?.(idx, initialSize + height, true);
1217
1994
  setResizing(false);
1218
1995
  };
1219
- return /* @__PURE__ */ React3.createElement(Resizable, {
1996
+ return /* @__PURE__ */ React6.createElement(Resizable, {
1220
1997
  enable: {
1221
1998
  bottom: resize
1222
1999
  },
@@ -1228,17 +2005,17 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1228
2005
  onResizeStart: handleResizeStart,
1229
2006
  onResize: handleResize,
1230
2007
  onResizeStop: handleResizeStop
1231
- }, /* @__PURE__ */ React3.createElement("div", {
2008
+ }, /* @__PURE__ */ React6.createElement("div", {
1232
2009
  ref: setNodeRef,
1233
2010
  ...attributes,
1234
2011
  ...listeners,
1235
- className: mx2("flex h-full items-center justify-center cursor-pointer", "border-t focus-visible:outline-none", fragments.border, fragments.axis, selected && fragments.axisSelected, isDragging && fragments.axisSelected),
2012
+ 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),
1236
2013
  onClick: () => onSelect?.(index)
1237
- }, /* @__PURE__ */ React3.createElement("span", {
2014
+ }, /* @__PURE__ */ React6.createElement("span", {
1238
2015
  className: "flex w-full justify-center"
1239
- }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React3.createElement("div", {
2016
+ }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React6.createElement("div", {
1240
2017
  className: "z-20 absolute top-0 w-full min-h-[4px] border-b-4 border-accentSurface"
1241
- }), resizing && /* @__PURE__ */ React3.createElement("div", {
2018
+ }), resizing && /* @__PURE__ */ React6.createElement("div", {
1242
2019
  className: "z-20 absolute bottom-0 w-full min-h-[4px] border-b-4 border-accentSurface"
1243
2020
  })));
1244
2021
  };
@@ -1251,7 +2028,7 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1251
2028
  });
1252
2029
  const keyboardSensor = useSensor(KeyboardSensor, {});
1253
2030
  const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
1254
- const [active, setActive] = useState4(null);
2031
+ const [active, setActive] = useState5(null);
1255
2032
  const handleDragStart = ({ active: active2 }) => {
1256
2033
  setActive(active2);
1257
2034
  };
@@ -1275,18 +2052,18 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1275
2052
  }
1276
2053
  return transform;
1277
2054
  };
1278
- return /* @__PURE__ */ React3.createElement("div", {
2055
+ return /* @__PURE__ */ React6.createElement("div", {
1279
2056
  className: "relative flex grow overflow-hidden"
1280
- }, /* @__PURE__ */ React3.createElement("div", {
1281
- className: mx2("z-20 absolute inset-0 border-x pointer-events-none", fragments.border),
2057
+ }, /* @__PURE__ */ React6.createElement("div", {
2058
+ className: mx2("z-20 absolute inset-0 border-x border-gridLine pointer-events-none"),
1282
2059
  style: {
1283
2060
  height: axisHeight
1284
2061
  }
1285
- }), /* @__PURE__ */ React3.createElement("div", {
2062
+ }), /* @__PURE__ */ React6.createElement("div", {
1286
2063
  ref: forwardRef2,
1287
2064
  role: "columnheader",
1288
2065
  className: "grow overflow-x-auto scrollbar-none"
1289
- }, /* @__PURE__ */ React3.createElement(DndContext, {
2066
+ }, /* @__PURE__ */ React6.createElement(DndContext, {
1290
2067
  autoScroll: {
1291
2068
  enabled: true
1292
2069
  },
@@ -1297,12 +2074,12 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1297
2074
  ],
1298
2075
  onDragStart: handleDragStart,
1299
2076
  onDragEnd: handleDragEnd
1300
- }, /* @__PURE__ */ React3.createElement("div", {
2077
+ }, /* @__PURE__ */ React6.createElement("div", {
1301
2078
  className: "flex h-full",
1302
2079
  style: {
1303
2080
  height: axisHeight
1304
2081
  }
1305
- }, columns.map((idx, index) => /* @__PURE__ */ React3.createElement(GridColumnCell, {
2082
+ }, columns.map((idx, index) => /* @__PURE__ */ React6.createElement(GridColumnCell, {
1306
2083
  key: idx,
1307
2084
  idx,
1308
2085
  index,
@@ -1312,7 +2089,7 @@ var SheetColumns = /* @__PURE__ */ forwardRef(({ columns, sizes, selected, onSel
1312
2089
  selected: selected === index,
1313
2090
  onResize,
1314
2091
  onSelect
1315
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(DragOverlay, null, active && /* @__PURE__ */ React3.createElement(MovingOverlay, {
2092
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement(DragOverlay, null, active && /* @__PURE__ */ React6.createElement(MovingOverlay, {
1316
2093
  label: columnLetter(active.data.current.index)
1317
2094
  })), document.body))));
1318
2095
  });
@@ -1330,8 +2107,8 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1330
2107
  }
1331
2108
  });
1332
2109
  const setNodeRef = useCombinedRefs(setDroppableNodeRef, setDraggableNodeRef);
1333
- const [initialSize, setInitialSize] = useState4(size);
1334
- const [resizing, setResizing] = useState4(false);
2110
+ const [initialSize, setInitialSize] = useState5(size);
2111
+ const [resizing, setResizing] = useState5(false);
1335
2112
  const scrollHandler = useRef();
1336
2113
  const handleResizeStart = (_ev, _dir, elementRef) => {
1337
2114
  const scrollContainer = elementRef.closest('[role="columnheader"]');
@@ -1353,7 +2130,7 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1353
2130
  onResize?.(idx, initialSize + width, true);
1354
2131
  setResizing(false);
1355
2132
  };
1356
- return /* @__PURE__ */ React3.createElement(Resizable, {
2133
+ return /* @__PURE__ */ React6.createElement(Resizable, {
1357
2134
  enable: {
1358
2135
  right: resize
1359
2136
  },
@@ -1365,17 +2142,17 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1365
2142
  onResizeStart: handleResizeStart,
1366
2143
  onResize: handleResize,
1367
2144
  onResizeStop: handleResizeStop
1368
- }, /* @__PURE__ */ React3.createElement("div", {
2145
+ }, /* @__PURE__ */ React6.createElement("div", {
1369
2146
  ref: setNodeRef,
1370
2147
  ...attributes,
1371
2148
  ...listeners,
1372
- className: mx2("flex h-full items-center justify-center cursor-pointer", "border-l focus-visible:outline-none", fragments.border, fragments.axis, selected && fragments.axisSelected, isDragging && fragments.axisSelected),
2149
+ 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),
1373
2150
  onClick: () => onSelect?.(index)
1374
- }, /* @__PURE__ */ React3.createElement("span", {
2151
+ }, /* @__PURE__ */ React6.createElement("span", {
1375
2152
  className: "flex w-full justify-center"
1376
- }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React3.createElement("div", {
2153
+ }, label), over?.id === idx && !isDragging && /* @__PURE__ */ React6.createElement("div", {
1377
2154
  className: "z-20 absolute left-0 h-full min-w-[4px] border-l-4 border-accentSurface"
1378
- }), resizing && /* @__PURE__ */ React3.createElement("div", {
2155
+ }), resizing && /* @__PURE__ */ React6.createElement("div", {
1379
2156
  className: "z-20 absolute right-0 h-full min-h-[4px] border-l-4 border-accentSurface"
1380
2157
  })));
1381
2158
  };
@@ -1388,14 +2165,14 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1388
2165
  const { model, cursor, range, editing, setCursor, setRange, setEditing, onInfo } = useSheetContext();
1389
2166
  const initialText = useRef();
1390
2167
  const quickEdit = useRef(false);
1391
- const [, forceUpdate] = useState4({});
1392
- useEffect3(() => {
2168
+ const [, forceUpdate] = useState5({});
2169
+ useEffect4(() => {
1393
2170
  const unsubscribe = model.update.on(() => {
1394
- log("updated", {
2171
+ log2("updated", {
1395
2172
  id: model.id
1396
2173
  }, {
1397
- F: __dxlog_file2,
1398
- L: 735,
2174
+ F: __dxlog_file4,
2175
+ L: 737,
1399
2176
  S: void 0,
1400
2177
  C: (f, a) => f(...a)
1401
2178
  });
@@ -1512,19 +2289,19 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1512
2289
  rowSizes,
1513
2290
  columnSizes
1514
2291
  });
1515
- const qualifiedSubjectId = fullyQualifiedId2(model.sheet);
1516
- const attendableAttrs = createAttendableAttributes(qualifiedSubjectId);
1517
- const attended = true;
1518
- return /* @__PURE__ */ React3.createElement("div", {
2292
+ const id = fullyQualifiedId2(model.sheet);
2293
+ const attendableAttrs = createAttendableAttributes(id);
2294
+ const hasAttention = useHasAttention(id);
2295
+ return /* @__PURE__ */ React6.createElement("div", {
1519
2296
  ref: containerRef,
1520
2297
  role: "grid",
1521
2298
  className: "relative flex grow overflow-hidden"
1522
- }, /* @__PURE__ */ React3.createElement("div", {
1523
- className: mx2("z-20 absolute inset-0 border pointer-events-none", fragments.border)
1524
- }), /* @__PURE__ */ React3.createElement("div", {
2299
+ }, /* @__PURE__ */ React6.createElement("div", {
2300
+ className: mx2("z-20 absolute inset-0 border border-gridLine pointer-events-none")
2301
+ }), /* @__PURE__ */ React6.createElement("div", {
1525
2302
  ref: scrollerRef,
1526
- className: mx2("grow", attended && "overflow-auto scrollbar-thin")
1527
- }, /* @__PURE__ */ React3.createElement("div", {
2303
+ className: mx2("grow", hasAttention && "overflow-auto scrollbar-thin")
2304
+ }, /* @__PURE__ */ React6.createElement("div", {
1528
2305
  className: "relative select-none",
1529
2306
  style: {
1530
2307
  width,
@@ -1532,10 +2309,10 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1532
2309
  },
1533
2310
  onClick: () => inputRef.current?.focus(),
1534
2311
  ...handlers
1535
- }, scrollerRef.current && /* @__PURE__ */ React3.createElement(SelectionOverlay, {
2312
+ }, scrollerRef.current && /* @__PURE__ */ React6.createElement(SelectionOverlay, {
1536
2313
  root: scrollerRef.current
1537
2314
  }), rowRange.map(({ row, top, height: height2 }) => {
1538
- return columnRange.map(({ column, left, width: width2 }) => {
2315
+ return columnRange.map(({ col, left, width: width2 }) => {
1539
2316
  const style = {
1540
2317
  position: "absolute",
1541
2318
  top,
@@ -1545,10 +2322,10 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1545
2322
  };
1546
2323
  const cell = {
1547
2324
  row,
1548
- column
2325
+ col
1549
2326
  };
1550
- const id = addressToA1Notation(cell);
1551
- const idx = model.addressToIndex(cell);
2327
+ const id2 = addressToA1Notation(cell);
2328
+ const idx = addressToIndex(model.sheet, cell);
1552
2329
  const active = posEquals(cursor, cell);
1553
2330
  if (active && editing) {
1554
2331
  const value = initialText.current ?? model.getCellText(cell) ?? "";
@@ -1581,7 +2358,7 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1581
2358
  inputRef.current?.focus();
1582
2359
  setEditing(false);
1583
2360
  };
1584
- return /* @__PURE__ */ React3.createElement(GridCellEditor, {
2361
+ return /* @__PURE__ */ React6.createElement(GridCellEditor, {
1585
2362
  key: idx,
1586
2363
  value,
1587
2364
  style,
@@ -1589,9 +2366,9 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1589
2366
  onClose: handleClose
1590
2367
  });
1591
2368
  }
1592
- return /* @__PURE__ */ React3.createElement(SheetCell, {
1593
- key: id,
1594
- id,
2369
+ return /* @__PURE__ */ React6.createElement(SheetCell, {
2370
+ key: id2,
2371
+ id: id2,
1595
2372
  cell,
1596
2373
  active,
1597
2374
  style,
@@ -1601,7 +2378,7 @@ var SheetGrid = /* @__PURE__ */ forwardRef(({ size, rows, columns, rowSizes, col
1601
2378
  }
1602
2379
  });
1603
2380
  });
1604
- }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement("input", {
2381
+ }))), /* @__PURE__ */ createPortal(/* @__PURE__ */ React6.createElement("input", {
1605
2382
  ref: inputRef,
1606
2383
  autoFocus: true,
1607
2384
  className: "absolute w-[1px] h-[1px] bg-transparent outline-none border-none caret-transparent",
@@ -1622,20 +2399,34 @@ var SelectionOverlay = ({ root }) => {
1622
2399
  const b1 = getRelativeClientRect(root, c1);
1623
2400
  const b2 = getRelativeClientRect(root, c2);
1624
2401
  const bounds = getRectUnion(b1, b2);
1625
- return /* @__PURE__ */ React3.createElement("div", {
2402
+ return /* @__PURE__ */ React6.createElement("div", {
1626
2403
  role: "none",
1627
2404
  style: bounds,
1628
2405
  className: "z-10 absolute pointer-events-none bg-gridSelectionOverlay border border-gridOverlay"
1629
2406
  });
1630
2407
  };
1631
2408
  var SheetCell = ({ id, cell, style, active, onSelect }) => {
1632
- const { formatting, editing, setRange } = useSheetContext();
2409
+ const { formatting, editing, setRange, decorations, model: { sheet } } = useSheetContext();
1633
2410
  const { value, classNames } = formatting.getFormatting(cell);
1634
- return /* @__PURE__ */ React3.createElement("div", {
2411
+ const decorationsForCell = decorations.getDecorationsForCell(addressToIndex(sheet, cell)) ?? [];
2412
+ const decorationAddedClasses = useMemo4(() => decorationsForCell.flatMap((d) => d.classNames ?? []), [
2413
+ decorationsForCell
2414
+ ]);
2415
+ const decoratedContent = decorationsForCell.reduce((children, { decorate }) => {
2416
+ if (!decorate) {
2417
+ return children;
2418
+ }
2419
+ const DecoratorComponent = decorate;
2420
+ return /* @__PURE__ */ React6.createElement(DecoratorComponent, null, children);
2421
+ }, /* @__PURE__ */ React6.createElement("div", {
2422
+ role: "none",
2423
+ className: mx2("flex flex-grow bs-full is-full px-2 items-center truncate cursor-pointer", ...decorationAddedClasses)
2424
+ }, value));
2425
+ return /* @__PURE__ */ React6.createElement("div", {
1635
2426
  [`data-${CELL_DATA_KEY}`]: id,
1636
2427
  role: "cell",
1637
2428
  style,
1638
- className: mx2("flex w-full h-full truncate items-center border cursor-pointer", "px-2 py-1", fragments.cell, fragments.border, active && [
2429
+ className: mx2("border border-gridLine cursor-pointer", fragments.cell, active && [
1639
2430
  "z-20",
1640
2431
  fragments.cellSelected
1641
2432
  ], classNames),
@@ -1649,36 +2440,36 @@ var SheetCell = ({ id, cell, style, active, onSelect }) => {
1649
2440
  }
1650
2441
  },
1651
2442
  onDoubleClick: () => onSelect?.(cell, true)
1652
- }, value);
2443
+ }, decoratedContent);
1653
2444
  };
1654
2445
  var GridCellEditor = ({ style, value, onNav, onClose }) => {
1655
2446
  const { model, range } = useSheetContext();
1656
2447
  const notifier = useRef();
1657
- useEffect3(() => {
2448
+ useEffect4(() => {
1658
2449
  if (range) {
1659
2450
  notifier.current?.(rangeToA1Notation(range));
1660
2451
  }
1661
2452
  }, [
1662
2453
  range
1663
2454
  ]);
1664
- const extension = useMemo(() => [
2455
+ const extension = useMemo4(() => [
1665
2456
  editorKeys({
1666
2457
  onNav,
1667
2458
  onClose
1668
2459
  }),
1669
2460
  sheetExtension({
1670
- functions: model.functions
2461
+ functions: model.graph.getFunctions()
1671
2462
  }),
1672
2463
  rangeExtension((fn) => notifier.current = fn)
1673
2464
  ], [
1674
2465
  model
1675
2466
  ]);
1676
- return /* @__PURE__ */ React3.createElement("div", {
2467
+ return /* @__PURE__ */ React6.createElement("div", {
1677
2468
  role: "cell",
1678
2469
  style,
1679
2470
  className: mx2("z-20 flex", fragments.cellSelected),
1680
2471
  onClick: (ev) => ev.stopPropagation()
1681
- }, /* @__PURE__ */ React3.createElement(CellEditor, {
2472
+ }, /* @__PURE__ */ React6.createElement(CellEditor, {
1682
2473
  autoFocus: true,
1683
2474
  value,
1684
2475
  extension
@@ -1691,30 +2482,30 @@ var SheetStatusBar = () => {
1691
2482
  if (cursor) {
1692
2483
  value = model.getCellValue(cursor);
1693
2484
  if (typeof value === "string" && value.charAt(0) === "=") {
1694
- value = model.mapFormulaBindingFromId(model.mapFormulaIndicesToRefs(value));
2485
+ value = model.graph.mapFunctionBindingFromId(model.mapFormulaIndicesToRefs(value));
1695
2486
  isFormula = true;
1696
2487
  } else if (value != null) {
1697
2488
  value = String(value);
1698
2489
  }
1699
2490
  }
1700
- return /* @__PURE__ */ React3.createElement("div", {
1701
- className: mx2("flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x", fragments.border)
1702
- }, /* @__PURE__ */ React3.createElement("div", {
2491
+ return /* @__PURE__ */ React6.createElement("div", {
2492
+ className: mx2("flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x border-gridLine")
2493
+ }, /* @__PURE__ */ React6.createElement("div", {
1703
2494
  className: "flex gap-4 items-center"
1704
- }, /* @__PURE__ */ React3.createElement("div", {
2495
+ }, /* @__PURE__ */ React6.createElement("div", {
1705
2496
  className: "flex w-16 items-center font-mono"
1706
- }, range && rangeToA1Notation(range) || cursor && addressToA1Notation(cursor)), /* @__PURE__ */ React3.createElement("div", {
2497
+ }, range && rangeToA1Notation(range) || cursor && addressToA1Notation(cursor)), /* @__PURE__ */ React6.createElement("div", {
1707
2498
  className: "flex gap-2 items-center"
1708
- }, /* @__PURE__ */ React3.createElement(FunctionIcon, {
2499
+ }, /* @__PURE__ */ React6.createElement(FunctionIcon, {
1709
2500
  className: mx2("text-greenText", isFormula ? "visible" : "invisible")
1710
- }), /* @__PURE__ */ React3.createElement("span", {
2501
+ }), /* @__PURE__ */ React6.createElement("span", {
1711
2502
  className: "font-mono"
1712
2503
  }, value))));
1713
2504
  };
1714
2505
  var SheetDebug = () => {
1715
2506
  const { model, cursor, range } = useSheetContext();
1716
- const [, forceUpdate] = useState4({});
1717
- useEffect3(() => {
2507
+ const [, forceUpdate] = useState5({});
2508
+ useEffect4(() => {
1718
2509
  const accessor = createDocAccessor(model.sheet, []);
1719
2510
  const handleUpdate = () => forceUpdate({});
1720
2511
  accessor.handle.addListener("change", handleUpdate);
@@ -1725,9 +2516,9 @@ var SheetDebug = () => {
1725
2516
  }, [
1726
2517
  model
1727
2518
  ]);
1728
- return /* @__PURE__ */ React3.createElement("div", {
1729
- className: mx2("z-20 absolute right-0 top-20 bottom-20 w-[30rem] overflow-auto scrollbar-thin", "border text-xs bg-neutral-50 dark:bg-black text-cyan-500 font-mono p-1 opacity-80", fragments.border)
1730
- }, /* @__PURE__ */ React3.createElement("pre", {
2519
+ return /* @__PURE__ */ React6.createElement("div", {
2520
+ 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")
2521
+ }, /* @__PURE__ */ React6.createElement("pre", {
1731
2522
  className: "whitespace-pre-wrap"
1732
2523
  }, JSON.stringify({
1733
2524
  cursor,
@@ -1749,22 +2540,13 @@ var Sheet = {
1749
2540
  Debug: SheetDebug
1750
2541
  };
1751
2542
 
1752
- // packages/plugins/plugin-sheet/src/components/SheetContainer.tsx
1753
- var SheetContainer = ({ sheet, space, role, coordinate = {
1754
- part: "main",
1755
- entryId: ""
1756
- }, remoteFunctionUrl }) => {
1757
- return /* @__PURE__ */ React4.createElement("div", {
1758
- role: "none",
1759
- className: mx3("flex", role === "article" && "row-span-2", role === "section" && "aspect-square border-y border-is border-separator", coordinate.part !== "solo" && "border-is border-separator")
1760
- }, /* @__PURE__ */ React4.createElement(Sheet.Root, {
1761
- sheet,
1762
- space,
1763
- remoteFunctionUrl
1764
- }, /* @__PURE__ */ React4.createElement(Sheet.Main, null)));
1765
- };
1766
- var SheetContainer_default = SheetContainer;
1767
2543
  export {
1768
- SheetContainer_default as default
2544
+ ComputeGraphContextProvider,
2545
+ createSheet,
2546
+ addressToIndex,
2547
+ compareIndexPositions,
2548
+ useSheetContext,
2549
+ Sheet,
2550
+ SheetContainer
1769
2551
  };
1770
- //# sourceMappingURL=SheetContainer-4XOKHKKZ.mjs.map
2552
+ //# sourceMappingURL=chunk-U2JHW3L6.mjs.map