@dxos/plugin-sheet 0.10.0 → 0.11.1

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 (227) hide show
  1. package/dist/lib/SheetPlugin.mjs +32 -0
  2. package/dist/lib/SheetPlugin.mjs.map +1 -0
  3. package/dist/lib/SheetPlugin.node.mjs +11 -0
  4. package/dist/lib/SheetPlugin.node.mjs.map +1 -0
  5. package/dist/lib/SheetPlugin.workerd.mjs +11 -0
  6. package/dist/lib/SheetPlugin.workerd.mjs.map +1 -0
  7. package/dist/lib/capabilities/node.mjs +10 -0
  8. package/dist/lib/capabilities/node.mjs.map +1 -0
  9. package/dist/lib/capabilities.mjs +16 -0
  10. package/dist/lib/capabilities.mjs.map +1 -0
  11. package/dist/lib/chunk-RangeList.mjs +47 -0
  12. package/dist/lib/chunk-RangeList.mjs.map +1 -0
  13. package/dist/lib/chunk-SheetArticle.mjs +58 -0
  14. package/dist/lib/chunk-SheetArticle.mjs.map +1 -0
  15. package/dist/lib/chunk-anchor-sort.mjs +18 -0
  16. package/dist/lib/chunk-anchor-sort.mjs.map +1 -0
  17. package/dist/lib/chunk-comment-config.mjs +18 -0
  18. package/dist/lib/chunk-comment-config.mjs.map +1 -0
  19. package/dist/lib/chunk-compute-graph-registry.mjs +24 -0
  20. package/dist/lib/chunk-compute-graph-registry.mjs.map +1 -0
  21. package/dist/lib/chunk-create-object.mjs +24 -0
  22. package/dist/lib/chunk-create-object.mjs.map +1 -0
  23. package/dist/lib/chunk-create.mjs +20 -0
  24. package/dist/lib/chunk-create.mjs.map +1 -0
  25. package/dist/lib/chunk-drop-axis.mjs +18 -0
  26. package/dist/lib/chunk-drop-axis.mjs.map +1 -0
  27. package/dist/lib/chunk-extensions.mjs +246 -0
  28. package/dist/lib/chunk-extensions.mjs.map +1 -0
  29. package/dist/lib/chunk-get-values.mjs +73 -0
  30. package/dist/lib/chunk-get-values.mjs.map +1 -0
  31. package/dist/lib/chunk-insert-axis.mjs +11 -0
  32. package/dist/lib/chunk-insert-axis.mjs.map +1 -0
  33. package/dist/lib/chunk-markdown-extension.mjs +22 -0
  34. package/dist/lib/chunk-markdown-extension.mjs.map +1 -0
  35. package/dist/lib/{neutral/chunk-WTSCOM64.mjs → chunk-meta.mjs} +20 -28
  36. package/dist/lib/chunk-meta.mjs.map +1 -0
  37. package/dist/lib/chunk-operation-handler.mjs +11 -0
  38. package/dist/lib/chunk-operation-handler.mjs.map +1 -0
  39. package/dist/lib/chunk-react-surface.mjs +27 -0
  40. package/dist/lib/chunk-react-surface.mjs.map +1 -0
  41. package/dist/lib/chunk-restore-axis.mjs +11 -0
  42. package/dist/lib/chunk-restore-axis.mjs.map +1 -0
  43. package/dist/lib/chunk-scroll-to-anchor.mjs +20 -0
  44. package/dist/lib/chunk-scroll-to-anchor.mjs.map +1 -0
  45. package/dist/lib/chunk-set-values.mjs +20 -0
  46. package/dist/lib/chunk-set-values.mjs.map +1 -0
  47. package/dist/lib/{neutral/skill-definition-U3KQCFOI.mjs → chunk-skill-definition.mjs} +6 -8
  48. package/dist/lib/chunk-skill-definition.mjs.map +1 -0
  49. package/dist/lib/chunk-state.mjs +27 -0
  50. package/dist/lib/chunk-state.mjs.map +1 -0
  51. package/dist/lib/chunk-thread-ranges.mjs +59 -0
  52. package/dist/lib/chunk-thread-ranges.mjs.map +1 -0
  53. package/dist/lib/chunk-types.mjs +355 -0
  54. package/dist/lib/chunk-types.mjs.map +1 -0
  55. package/dist/lib/chunk-undo-mappings.mjs +22 -0
  56. package/dist/lib/chunk-undo-mappings.mjs.map +1 -0
  57. package/dist/lib/components.mjs +1377 -0
  58. package/dist/lib/components.mjs.map +1 -0
  59. package/dist/lib/containers.mjs +8 -0
  60. package/dist/lib/containers.mjs.map +1 -0
  61. package/dist/lib/index.mjs +4 -0
  62. package/dist/lib/meta.mjs +2 -0
  63. package/dist/lib/operations/node.mjs +7 -0
  64. package/dist/lib/operations/node.mjs.map +1 -0
  65. package/dist/lib/operations.mjs +7 -0
  66. package/dist/lib/operations.mjs.map +1 -0
  67. package/dist/lib/plugin.mjs +9 -0
  68. package/dist/lib/plugin.mjs.map +1 -0
  69. package/dist/lib/skills.mjs +42 -0
  70. package/dist/lib/skills.mjs.map +1 -0
  71. package/dist/lib/testing.mjs +59 -0
  72. package/dist/lib/testing.mjs.map +1 -0
  73. package/dist/lib/translations.mjs +50 -0
  74. package/dist/lib/translations.mjs.map +1 -0
  75. package/dist/lib/types.mjs +2 -0
  76. package/dist/types/src/capabilities/anchor-sort.d.ts +1 -1
  77. package/dist/types/src/capabilities/compute-graph-registry.d.ts +1 -1
  78. package/dist/types/src/capabilities/create-object.d.ts +1 -1
  79. package/dist/types/src/capabilities/markdown-extension.d.ts +1 -1
  80. package/dist/types/src/capabilities/node.d.ts +7 -0
  81. package/dist/types/src/capabilities/node.d.ts.map +1 -0
  82. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  83. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  84. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  85. package/dist/types/src/capabilities/skill-definition.d.ts +1 -1
  86. package/dist/types/src/capabilities/state.d.ts +1 -1
  87. package/dist/types/src/capabilities/undo-mappings.d.ts +1 -1
  88. package/dist/types/src/components/ComputeGraph/ComputeGraphContext.d.ts +11 -0
  89. package/dist/types/src/components/ComputeGraph/ComputeGraphContext.d.ts.map +1 -0
  90. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +1 -10
  91. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -1
  92. package/dist/types/src/components/ComputeGraph/index.d.ts +1 -0
  93. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  94. package/dist/types/src/components/Sheet/Sheet.d.ts +4 -4
  95. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  96. package/dist/types/src/components/SheetContent/SheetContent.d.ts +1 -1
  97. package/dist/types/src/components/SheetContent/SheetContent.d.ts.map +1 -1
  98. package/dist/types/src/components/SheetContent/SheetContent.stories.d.ts +1 -1
  99. package/dist/types/src/components/SheetRoot/SheetContext.d.ts +4 -0
  100. package/dist/types/src/components/SheetRoot/SheetContext.d.ts.map +1 -0
  101. package/dist/types/src/components/SheetRoot/SheetRoot.d.ts +0 -1
  102. package/dist/types/src/components/SheetRoot/SheetRoot.d.ts.map +1 -1
  103. package/dist/types/src/components/SheetRoot/index.d.ts +1 -0
  104. package/dist/types/src/components/SheetRoot/index.d.ts.map +1 -1
  105. package/dist/types/src/components/SheetStatusbar/SheetStatusbar.d.ts +1 -1
  106. package/dist/types/src/components/SheetStatusbar/SheetStatusbar.d.ts.map +1 -1
  107. package/dist/types/src/components/SheetToolbar/SheetToolbar.d.ts +1 -1
  108. package/dist/types/src/components/SheetToolbar/SheetToolbar.d.ts.map +1 -1
  109. package/dist/types/src/components/index.d.ts +1 -0
  110. package/dist/types/src/components/index.d.ts.map +1 -1
  111. package/dist/types/src/containers/RangeList/RangeList.d.ts +4 -1
  112. package/dist/types/src/containers/RangeList/RangeList.d.ts.map +1 -1
  113. package/dist/types/src/containers/SheetArticle/SheetArticle.d.ts +4 -5
  114. package/dist/types/src/containers/SheetArticle/SheetArticle.d.ts.map +1 -1
  115. package/dist/types/src/containers/SheetArticle/SheetArticle.stories.d.ts +4 -1
  116. package/dist/types/src/containers/SheetArticle/SheetArticle.stories.d.ts.map +1 -1
  117. package/dist/types/src/extensions/editor/sheet-extension.d.ts.map +1 -1
  118. package/dist/types/src/operations/node.d.ts +3 -0
  119. package/dist/types/src/operations/node.d.ts.map +1 -0
  120. package/dist/types/src/operations/scroll-to-anchor.d.ts.map +1 -1
  121. package/dist/types/src/plugin.d.ts +1 -1
  122. package/dist/types/src/plugin.d.ts.map +1 -1
  123. package/dist/types/src/testing/testing.d.ts +8 -2
  124. package/dist/types/src/testing/testing.d.ts.map +1 -1
  125. package/dist/types/src/types/SheetOperation.d.ts +1 -1
  126. package/dist/types/src/types/SheetOperation.d.ts.map +1 -1
  127. package/dist/types/tsconfig.tsbuildinfo +1 -1
  128. package/dx.config.ts +1 -0
  129. package/package.json +75 -67
  130. package/src/capabilities/node.ts +18 -0
  131. package/src/capabilities/{react-surface.tsx → react-surface.ts} +6 -18
  132. package/src/components/ComputeGraph/ComputeGraphContext.ts +35 -0
  133. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +2 -27
  134. package/src/components/ComputeGraph/compute-graph.stories.tsx +1 -1
  135. package/src/components/ComputeGraph/index.ts +2 -0
  136. package/src/components/Sheet/Sheet.tsx +1 -1
  137. package/src/components/SheetRoot/SheetContext.ts +19 -0
  138. package/src/components/SheetRoot/SheetRoot.tsx +2 -9
  139. package/src/components/SheetRoot/index.ts +2 -0
  140. package/src/components/SheetStatusbar/SheetStatusbar.tsx +1 -1
  141. package/src/components/SheetToolbar/SheetToolbar.tsx +9 -9
  142. package/src/components/index.ts +1 -0
  143. package/src/containers/RangeList/RangeList.tsx +2 -0
  144. package/src/containers/SheetArticle/SheetArticle.stories.tsx +15 -24
  145. package/src/containers/SheetArticle/SheetArticle.tsx +23 -11
  146. package/src/extensions/editor/sheet-extension.ts +61 -2
  147. package/src/integrations/thread-ranges.ts +4 -4
  148. package/src/operations/node.ts +18 -0
  149. package/src/operations/scroll-to-anchor.ts +3 -2
  150. package/src/plugin.ts +1 -1
  151. package/src/testing/testing.tsx +11 -5
  152. package/src/types/SheetOperation.ts +6 -2
  153. package/dist/lib/neutral/RangeList-EIJTFS7P.mjs +0 -53
  154. package/dist/lib/neutral/RangeList-EIJTFS7P.mjs.map +0 -7
  155. package/dist/lib/neutral/SheetArticle-IUPQYGUU.mjs +0 -34
  156. package/dist/lib/neutral/SheetArticle-IUPQYGUU.mjs.map +0 -7
  157. package/dist/lib/neutral/SheetPlugin.mjs +0 -61
  158. package/dist/lib/neutral/SheetPlugin.mjs.map +0 -7
  159. package/dist/lib/neutral/SheetPlugin.node.mjs +0 -27
  160. package/dist/lib/neutral/SheetPlugin.node.mjs.map +0 -7
  161. package/dist/lib/neutral/SheetPlugin.workerd.mjs +0 -21
  162. package/dist/lib/neutral/SheetPlugin.workerd.mjs.map +0 -7
  163. package/dist/lib/neutral/anchor-sort-2POWTKTD.mjs +0 -22
  164. package/dist/lib/neutral/anchor-sort-2POWTKTD.mjs.map +0 -7
  165. package/dist/lib/neutral/capabilities/index.mjs +0 -27
  166. package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
  167. package/dist/lib/neutral/chunk-ERHMBRSU.mjs +0 -234
  168. package/dist/lib/neutral/chunk-ERHMBRSU.mjs.map +0 -7
  169. package/dist/lib/neutral/chunk-HEN74ZWI.mjs +0 -83
  170. package/dist/lib/neutral/chunk-HEN74ZWI.mjs.map +0 -7
  171. package/dist/lib/neutral/chunk-HY4DM35G.mjs +0 -466
  172. package/dist/lib/neutral/chunk-HY4DM35G.mjs.map +0 -7
  173. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
  174. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
  175. package/dist/lib/neutral/chunk-TDGEOMRG.mjs +0 -8
  176. package/dist/lib/neutral/chunk-TDGEOMRG.mjs.map +0 -7
  177. package/dist/lib/neutral/chunk-WTSCOM64.mjs.map +0 -7
  178. package/dist/lib/neutral/comment-config-4CIQFYM2.mjs +0 -22
  179. package/dist/lib/neutral/comment-config-4CIQFYM2.mjs.map +0 -7
  180. package/dist/lib/neutral/components/index.mjs +0 -1552
  181. package/dist/lib/neutral/components/index.mjs.map +0 -7
  182. package/dist/lib/neutral/compute-graph-registry-YYINTFC2.mjs +0 -26
  183. package/dist/lib/neutral/compute-graph-registry-YYINTFC2.mjs.map +0 -7
  184. package/dist/lib/neutral/containers/index.mjs +0 -11
  185. package/dist/lib/neutral/containers/index.mjs.map +0 -7
  186. package/dist/lib/neutral/create-I3TKMPQO.mjs +0 -30
  187. package/dist/lib/neutral/create-I3TKMPQO.mjs.map +0 -7
  188. package/dist/lib/neutral/create-object-5WEY5XZJ.mjs +0 -27
  189. package/dist/lib/neutral/create-object-5WEY5XZJ.mjs.map +0 -7
  190. package/dist/lib/neutral/drop-axis-JPFU5CJO.mjs +0 -23
  191. package/dist/lib/neutral/drop-axis-JPFU5CJO.mjs.map +0 -7
  192. package/dist/lib/neutral/get-values-7YWQTH65.mjs +0 -92
  193. package/dist/lib/neutral/get-values-7YWQTH65.mjs.map +0 -7
  194. package/dist/lib/neutral/index.mjs +0 -66
  195. package/dist/lib/neutral/index.mjs.map +0 -7
  196. package/dist/lib/neutral/insert-axis-WD6ZC3UA.mjs +0 -16
  197. package/dist/lib/neutral/insert-axis-WD6ZC3UA.mjs.map +0 -7
  198. package/dist/lib/neutral/markdown-extension-HTJDICGT.mjs +0 -28
  199. package/dist/lib/neutral/markdown-extension-HTJDICGT.mjs.map +0 -7
  200. package/dist/lib/neutral/meta.json +0 -1
  201. package/dist/lib/neutral/meta.mjs +0 -8
  202. package/dist/lib/neutral/meta.mjs.map +0 -7
  203. package/dist/lib/neutral/operation-handler-TB6LFV2H.mjs +0 -13
  204. package/dist/lib/neutral/operation-handler-TB6LFV2H.mjs.map +0 -7
  205. package/dist/lib/neutral/operations/index.mjs +0 -8
  206. package/dist/lib/neutral/operations/index.mjs.map +0 -7
  207. package/dist/lib/neutral/plugin.mjs +0 -16
  208. package/dist/lib/neutral/plugin.mjs.map +0 -7
  209. package/dist/lib/neutral/react-surface-TJT6F2E4.mjs +0 -40
  210. package/dist/lib/neutral/react-surface-TJT6F2E4.mjs.map +0 -7
  211. package/dist/lib/neutral/restore-axis-RLPX7P3G.mjs +0 -16
  212. package/dist/lib/neutral/restore-axis-RLPX7P3G.mjs.map +0 -7
  213. package/dist/lib/neutral/scroll-to-anchor-6FJJQWZC.mjs +0 -33
  214. package/dist/lib/neutral/scroll-to-anchor-6FJJQWZC.mjs.map +0 -7
  215. package/dist/lib/neutral/set-values-5DVOVLJH.mjs +0 -30
  216. package/dist/lib/neutral/set-values-5DVOVLJH.mjs.map +0 -7
  217. package/dist/lib/neutral/skill-definition-U3KQCFOI.mjs.map +0 -7
  218. package/dist/lib/neutral/state-HPA27MX2.mjs +0 -29
  219. package/dist/lib/neutral/state-HPA27MX2.mjs.map +0 -7
  220. package/dist/lib/neutral/testing/index.mjs +0 -103
  221. package/dist/lib/neutral/testing/index.mjs.map +0 -7
  222. package/dist/lib/neutral/translations.mjs +0 -56
  223. package/dist/lib/neutral/translations.mjs.map +0 -7
  224. package/dist/lib/neutral/types/index.mjs +0 -58
  225. package/dist/lib/neutral/types/index.mjs.map +0 -7
  226. package/dist/lib/neutral/undo-mappings-O75AYIRG.mjs +0 -31
  227. package/dist/lib/neutral/undo-mappings-O75AYIRG.mjs.map +0 -7
@@ -0,0 +1,1377 @@
1
+ import { n as sheetExtension, t as rangeExtension } from "./chunk-extensions.mjs";
2
+ import { n as useSelectThreadOnCellFocus } from "./chunk-thread-ranges.mjs";
3
+ import { DetailedCellError, ExportedCellChange, addressFromA1Notation, addressToA1Notation, createSheetName, inRange, isFormula, rangeToA1Notation } from "@dxos/compute-hyperformula";
4
+ import { Obj } from "@dxos/echo";
5
+ import { assertArgument, invariant } from "@dxos/invariant";
6
+ import { meta } from "#meta";
7
+ import { PublicKey } from "@dxos/keys";
8
+ import { DEFAULT_COLS, DEFAULT_ROWS, MAX_COLS, MAX_ROWS, ReadonlyException, SheetCapabilities, SheetOperation, addressFromIndex, addressToIndex, alignKey, cellClassNameForRange, initialize, insertIndices, mapFormulaIndicesToRefs, mapFormulaRefsToIndices, rangeFromIndex, rangeToIndex } from "#types";
9
+ import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
10
+ import { raise } from "@dxos/debug";
11
+ import { useAsyncState } from "@dxos/react-hooks";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ import { Grid, GridCellEditor, closestCell, colToA1Notation, editorKeys, parseCellIndex, rowToA1Notation, useGridContext } from "@dxos/react-ui-grid";
14
+ import { Event } from "@dxos/async";
15
+ import { Resource } from "@dxos/context";
16
+ import { Format, TypeEnum } from "@dxos/echo/Format";
17
+ import { log } from "@dxos/log";
18
+ import { useCapabilities, useOperationInvoker } from "@dxos/app-framework/ui";
19
+ import { defaultColSize, defaultRowSize } from "@dxos/lit-grid";
20
+ import { DropdownMenu, Icon, composable, composableProps, useTranslation } from "@dxos/react-ui";
21
+ import { useAttention } from "@dxos/react-ui-attention";
22
+ import { mx } from "@dxos/ui-theme";
23
+ import { Doc } from "@dxos/echo-doc";
24
+ import { cellClassesForFieldType, parseValue } from "@dxos/react-ui-form";
25
+ import { Atom, RegistryContext } from "@effect-atom/atom-react";
26
+ import { useAppGraph } from "@dxos/app-toolkit/ui";
27
+ import { Menu, createGapSeparator, createMenuAction, createMenuItemGroup, graphActions, isToolbarAction, useMenuActions } from "@dxos/react-ui-menu";
28
+ //#region src/components/ComputeGraph/ComputeGraphContext.ts
29
+ /**
30
+ * The compute graph context manages a ComputeGraph for each space.
31
+ */
32
+ var ComputeGraphContext = createContext(void 0);
33
+ var useComputeGraph = (space) => {
34
+ const { registry } = useContext(ComputeGraphContext) ?? raise(/* @__PURE__ */ new Error("Missing ComputeGraphContext"));
35
+ const [graph] = useAsyncState(async () => {
36
+ if (space) {
37
+ const graph = registry.getOrCreateGraph(space);
38
+ await graph.open();
39
+ return graph;
40
+ }
41
+ }, [space, registry]);
42
+ return graph;
43
+ };
44
+ //#endregion
45
+ //#region src/components/ComputeGraph/ComputeGraphContextProvider.tsx
46
+ var ComputeGraphContextProvider = ({ registry, children }) => {
47
+ return /* @__PURE__ */ jsx(ComputeGraphContext.Provider, {
48
+ value: { registry },
49
+ children
50
+ });
51
+ };
52
+ //#endregion
53
+ //#region src/components/SheetRoot/SheetContext.ts
54
+ var SheetContext = createContext(void 0);
55
+ var useSheetContext = () => {
56
+ return useContext(SheetContext) ?? raise(/* @__PURE__ */ new Error("Missing SheetContext"));
57
+ };
58
+ //#endregion
59
+ //#region src/model/sheet-model.ts
60
+ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-sheet/src/model/sheet-model.ts";
61
+ var typeMap = {
62
+ BOOLEAN: { type: TypeEnum.Boolean },
63
+ NUMBER_RAW: { type: TypeEnum.Number },
64
+ NUMBER_PERCENT: {
65
+ type: TypeEnum.Number,
66
+ format: Format.TypeFormat.Percent
67
+ },
68
+ NUMBER_CURRENCY: {
69
+ type: TypeEnum.Number,
70
+ format: Format.TypeFormat.Currency
71
+ },
72
+ NUMBER_DATETIME: {
73
+ type: TypeEnum.String,
74
+ format: Format.TypeFormat.DateTime
75
+ },
76
+ NUMBER_DATE: {
77
+ type: TypeEnum.String,
78
+ format: Format.TypeFormat.Date
79
+ },
80
+ NUMBER_TIME: {
81
+ type: TypeEnum.String,
82
+ format: Format.TypeFormat.Time
83
+ }
84
+ };
85
+ var getTopLeft = (range) => {
86
+ const to = range.to ?? range.from;
87
+ return {
88
+ row: Math.min(range.from.row, to.row),
89
+ col: Math.min(range.from.col, to.col)
90
+ };
91
+ };
92
+ var toSimpleCellAddress = (sheet, cell) => ({
93
+ sheet,
94
+ row: cell.row,
95
+ col: cell.col
96
+ });
97
+ var toModelRange = (sheet, range) => ({
98
+ start: toSimpleCellAddress(sheet, range.from),
99
+ end: toSimpleCellAddress(sheet, range.to ?? range.from)
100
+ });
101
+ /**
102
+ * Spreadsheet data model.
103
+ *
104
+ * [ComputeGraphContext] > [SheetContext]:[SheetModel] > [Sheet.Root]
105
+ */
106
+ var SheetModel = class extends Resource {
107
+ _graph;
108
+ _sheet;
109
+ _options;
110
+ id = `model-${PublicKey.random().truncate()}`;
111
+ update = new Event();
112
+ _node;
113
+ constructor(_graph, _sheet, _options = {}) {
114
+ super();
115
+ this._graph = _graph;
116
+ this._sheet = _sheet;
117
+ this._options = _options;
118
+ }
119
+ get graph() {
120
+ return this._graph;
121
+ }
122
+ get sheet() {
123
+ return this._sheet;
124
+ }
125
+ get readonly() {
126
+ return this._options.readonly;
127
+ }
128
+ get bounds() {
129
+ return {
130
+ rows: this._sheet.rows.length,
131
+ columns: this._sheet.columns.length
132
+ };
133
+ }
134
+ /**
135
+ * Initialize sheet and engine.
136
+ */
137
+ async _open() {
138
+ log("initialize", { id: this.id }, {
139
+ "~LogMeta": "~LogMeta",
140
+ F: __dxlog_file,
141
+ L: 124,
142
+ S: this
143
+ });
144
+ Obj.update(this._sheet, (obj) => {
145
+ initialize(obj);
146
+ });
147
+ this._graph.update.on((event) => {
148
+ if (event.type === "functionsUpdated") this.reset();
149
+ });
150
+ this._node = this._graph.getOrCreateNode(createSheetName({
151
+ type: Obj.getTypename(this._sheet),
152
+ id: this._sheet.id
153
+ }));
154
+ await this._node.open();
155
+ const unsubscribe = this._node.update.on((event) => this.update.emit(event));
156
+ this._ctx.onDispose(unsubscribe);
157
+ this.reset();
158
+ }
159
+ /**
160
+ * Update engine.
161
+ * NOTE: This resets the undo history.
162
+ * @deprecated
163
+ */
164
+ reset() {
165
+ invariant(this._node, void 0, {
166
+ "~LogMeta": "~LogMeta",
167
+ F: __dxlog_file,
168
+ L: 154,
169
+ S: this,
170
+ A: ["this._node", ""]
171
+ });
172
+ this._node.graph.hf.clearSheet(this._node.sheetId);
173
+ Object.entries(this._sheet.cells).forEach(([key, { value }]) => {
174
+ invariant(this._node, void 0, {
175
+ "~LogMeta": "~LogMeta",
176
+ F: __dxlog_file,
177
+ L: 157,
178
+ S: this,
179
+ A: ["this._node", ""]
180
+ });
181
+ const { col, row } = addressFromIndex(this._sheet, key);
182
+ if (isFormula(value)) {
183
+ const binding = this._graph.mapFunctionBindingFromId(mapFormulaIndicesToRefs(this._sheet, value));
184
+ if (binding) value = this._graph.mapFormulaToNative(binding);
185
+ else value = "";
186
+ }
187
+ this._node.graph.hf.setCellContents({
188
+ sheet: this._node.sheetId,
189
+ row,
190
+ col
191
+ }, value);
192
+ });
193
+ }
194
+ /**
195
+ * Recalculate formulas.
196
+ * NOTE: This resets the undo history.
197
+ * https://hyperformula.handsontable.com/guide/volatile-functions.html#volatile-actions
198
+ * @deprecated
199
+ */
200
+ recalculate() {
201
+ this._node?.graph.hf.rebuildAndRecalculate();
202
+ }
203
+ insertRows(i, n = 1) {
204
+ let idx = [];
205
+ Obj.update(this._sheet, (obj) => {
206
+ idx = insertIndices(obj.rows, i, n, MAX_ROWS);
207
+ });
208
+ this.reset();
209
+ return idx;
210
+ }
211
+ insertColumns(i, n = 1) {
212
+ let idx = [];
213
+ Obj.update(this._sheet, (obj) => {
214
+ idx = insertIndices(obj.columns, i, n, MAX_COLS);
215
+ });
216
+ this.reset();
217
+ return idx;
218
+ }
219
+ dropRow(rowIndex) {
220
+ const range = {
221
+ from: addressFromIndex(this._sheet, `${this._sheet.columns[0]}@${rowIndex}`),
222
+ to: addressFromIndex(this._sheet, `${this._sheet.columns[this._sheet.columns.length - 1]}@${rowIndex}`)
223
+ };
224
+ const values = this.getCellValues(range).flat();
225
+ const index = this._sheet.rows.indexOf(rowIndex);
226
+ this.clear(range);
227
+ Obj.update(this._sheet, (obj) => {
228
+ obj.rows.splice(index, 1);
229
+ delete obj.rowMeta[rowIndex];
230
+ });
231
+ this.reset();
232
+ return {
233
+ axis: "row",
234
+ index,
235
+ axisIndex: rowIndex,
236
+ axisMeta: this._sheet.rowMeta[rowIndex],
237
+ values
238
+ };
239
+ }
240
+ dropColumn(colIndex) {
241
+ const range = {
242
+ from: addressFromIndex(this._sheet, `${colIndex}@${this._sheet.rows[0]}`),
243
+ to: addressFromIndex(this._sheet, `${colIndex}@${this._sheet.rows[this._sheet.rows.length - 1]}`)
244
+ };
245
+ const values = this.getCellValues(range).flat();
246
+ const index = this._sheet.columns.indexOf(colIndex);
247
+ this.clear(range);
248
+ Obj.update(this._sheet, (obj) => {
249
+ obj.columns.splice(index, 1);
250
+ delete obj.columnMeta[colIndex];
251
+ });
252
+ this.reset();
253
+ return {
254
+ axis: "col",
255
+ index,
256
+ axisIndex: colIndex,
257
+ axisMeta: this._sheet.rowMeta[colIndex],
258
+ values
259
+ };
260
+ }
261
+ restoreRow({ index, axisIndex, axisMeta, values }) {
262
+ Obj.update(this._sheet, (obj) => {
263
+ obj.rows.splice(index, 0, axisIndex);
264
+ values.forEach((value, col) => {
265
+ if (value) obj.cells[`${obj.columns[col]}@${axisIndex}`] = { value };
266
+ });
267
+ if (axisMeta) obj.rowMeta[axisIndex] = axisMeta;
268
+ });
269
+ this.reset();
270
+ }
271
+ restoreColumn({ index, axisIndex, axisMeta, values }) {
272
+ Obj.update(this._sheet, (obj) => {
273
+ obj.columns.splice(index, 0, axisIndex);
274
+ values.forEach((value, row) => {
275
+ if (value) obj.cells[`${axisIndex}@${obj.rows[row]}`] = { value };
276
+ });
277
+ if (axisMeta) obj.columnMeta[axisIndex] = axisMeta;
278
+ });
279
+ this.reset();
280
+ }
281
+ /**
282
+ * Clear range of values.
283
+ */
284
+ clear(range) {
285
+ invariant(this._node, void 0, {
286
+ "~LogMeta": "~LogMeta",
287
+ F: __dxlog_file,
288
+ L: 276,
289
+ S: this,
290
+ A: ["this._node", ""]
291
+ });
292
+ const topLeft = getTopLeft(range);
293
+ const values = this._iterRange(range, () => null);
294
+ this._node.graph.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);
295
+ Obj.update(this._sheet, (obj) => {
296
+ this._iterRange(range, (cell) => {
297
+ const idx = addressToIndex(this._sheet, cell);
298
+ delete obj.cells[idx];
299
+ });
300
+ });
301
+ }
302
+ cut(range) {
303
+ invariant(this._node, void 0, {
304
+ "~LogMeta": "~LogMeta",
305
+ F: __dxlog_file,
306
+ L: 289,
307
+ S: this,
308
+ A: ["this._node", ""]
309
+ });
310
+ this._node.graph.hf.cut(toModelRange(this._node.sheetId, range));
311
+ Obj.update(this._sheet, (obj) => {
312
+ this._iterRange(range, (cell) => {
313
+ const idx = addressToIndex(this._sheet, cell);
314
+ delete obj.cells[idx];
315
+ });
316
+ });
317
+ }
318
+ copy(range) {
319
+ invariant(this._node, void 0, {
320
+ "~LogMeta": "~LogMeta",
321
+ F: __dxlog_file,
322
+ L: 300,
323
+ S: this,
324
+ A: ["this._node", ""]
325
+ });
326
+ this._node.graph.hf.copy(toModelRange(this._node.sheetId, range));
327
+ }
328
+ paste(cell) {
329
+ invariant(this._node, void 0, {
330
+ "~LogMeta": "~LogMeta",
331
+ F: __dxlog_file,
332
+ L: 305,
333
+ S: this,
334
+ A: ["this._node", ""]
335
+ });
336
+ if (!this._node.graph.hf.isClipboardEmpty()) {
337
+ const changes = this._node.graph.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));
338
+ Obj.update(this._sheet, (obj) => {
339
+ for (const change of changes) if (change instanceof ExportedCellChange) {
340
+ const { address, newValue } = change;
341
+ const idx = addressToIndex(this._sheet, {
342
+ row: address.row,
343
+ col: address.col
344
+ });
345
+ obj.cells[idx] = { value: newValue };
346
+ }
347
+ });
348
+ }
349
+ }
350
+ undo() {
351
+ invariant(this._node, void 0, {
352
+ "~LogMeta": "~LogMeta",
353
+ F: __dxlog_file,
354
+ L: 322,
355
+ S: this,
356
+ A: ["this._node", ""]
357
+ });
358
+ if (this._node.graph.hf.isThereSomethingToUndo()) this._node.graph.hf.undo();
359
+ }
360
+ redo() {
361
+ invariant(this._node, void 0, {
362
+ "~LogMeta": "~LogMeta",
363
+ F: __dxlog_file,
364
+ L: 330,
365
+ S: this,
366
+ A: ["this._node", ""]
367
+ });
368
+ if (this._node.graph.hf.isThereSomethingToRedo()) this._node.graph.hf.redo();
369
+ }
370
+ /**
371
+ * Get value from sheet.
372
+ */
373
+ getCellValue(cell) {
374
+ const idx = addressToIndex(this._sheet, cell);
375
+ return this._sheet.cells[idx]?.value ?? null;
376
+ }
377
+ /**
378
+ * Get value as a string for editing.
379
+ */
380
+ getCellText(cell) {
381
+ const value = this.getCellValue(cell);
382
+ if (value == null) return;
383
+ if (isFormula(value)) return this._graph.mapFunctionBindingFromId(mapFormulaIndicesToRefs(this._sheet, value));
384
+ else return String(value);
385
+ }
386
+ /**
387
+ * Get array of raw values from sheet.
388
+ */
389
+ getCellValues(range) {
390
+ return this._iterRange(range, (cell) => this.getCellValue(cell));
391
+ }
392
+ /**
393
+ * Gets the regular or computed value from the engine.
394
+ */
395
+ getValue(cell) {
396
+ invariant(this._node, void 0, {
397
+ "~LogMeta": "~LogMeta",
398
+ F: __dxlog_file,
399
+ L: 373,
400
+ S: this,
401
+ A: ["this._node", ""]
402
+ });
403
+ const address = toSimpleCellAddress(this._node.sheetId, cell);
404
+ const value = this._node.graph.hf.getCellValue(address);
405
+ if (value instanceof DetailedCellError) {
406
+ log.warn("cell error", {
407
+ cell,
408
+ error: value
409
+ }, {
410
+ "~LogMeta": "~LogMeta",
411
+ F: __dxlog_file,
412
+ L: 378,
413
+ S: this
414
+ });
415
+ return value.toString();
416
+ }
417
+ return value;
418
+ }
419
+ /**
420
+ * Get value type.
421
+ */
422
+ getValueDescription(cell) {
423
+ invariant(this._node, void 0, {
424
+ "~LogMeta": "~LogMeta",
425
+ F: __dxlog_file,
426
+ L: 389,
427
+ S: this,
428
+ A: ["this._node", ""]
429
+ });
430
+ const addr = toSimpleCellAddress(this._node.sheetId, cell);
431
+ return typeMap[this._node.graph.hf.getCellValueDetailedType(addr)];
432
+ }
433
+ /**
434
+ * Sets the value, updating the sheet and engine.
435
+ */
436
+ setValue(cell, value) {
437
+ invariant(this._node, void 0, {
438
+ "~LogMeta": "~LogMeta",
439
+ F: __dxlog_file,
440
+ L: 399,
441
+ S: this,
442
+ A: ["this._node", ""]
443
+ });
444
+ if (this._options.readonly) throw new ReadonlyException();
445
+ let refresh = false;
446
+ if (cell.row >= this._sheet.rows.length) {
447
+ Obj.update(this._sheet, (obj) => {
448
+ insertIndices(obj.rows, cell.row, 1, MAX_ROWS);
449
+ });
450
+ refresh = true;
451
+ }
452
+ if (cell.col >= this._sheet.columns.length) {
453
+ Obj.update(this._sheet, (obj) => {
454
+ insertIndices(obj.columns, cell.col, 1, MAX_COLS);
455
+ });
456
+ refresh = true;
457
+ }
458
+ if (refresh) this.reset();
459
+ this._node.graph.hf.setCellContents({
460
+ sheet: this._node.sheetId,
461
+ row: cell.row,
462
+ col: cell.col
463
+ }, [[isFormula(value) ? this._graph.mapFormulaToNative(value) : value]]);
464
+ const idx = addressToIndex(this._sheet, cell);
465
+ if (value === void 0 || value === null) Obj.update(this._sheet, (obj) => {
466
+ delete obj.cells[idx];
467
+ });
468
+ else {
469
+ if (isFormula(value)) value = this._graph.mapFunctionBindingToId(mapFormulaRefsToIndices(this._sheet, value));
470
+ Obj.update(this._sheet, (obj) => {
471
+ obj.cells[idx] = { value };
472
+ });
473
+ }
474
+ }
475
+ /**
476
+ * Sets values from a simple map.
477
+ */
478
+ setValues(values) {
479
+ Object.entries(values).forEach(([key, { value }]) => {
480
+ this.setValue(addressFromA1Notation(key), value);
481
+ });
482
+ }
483
+ /**
484
+ * Iterate range.
485
+ */
486
+ _iterRange(range, cb) {
487
+ const to = range.to ?? range.from;
488
+ const rowRange = [Math.min(range.from.row, to.row), Math.max(range.from.row, to.row)];
489
+ const columnRange = [Math.min(range.from.col, to.col), Math.max(range.from.col, to.col)];
490
+ const rows = [];
491
+ for (let row = rowRange[0]; row <= rowRange[1]; row++) {
492
+ const rowCells = [];
493
+ for (let column = columnRange[0]; column <= columnRange[1]; column++) {
494
+ const value = cb({
495
+ row,
496
+ col: column
497
+ });
498
+ if (value !== void 0) rowCells.push(value);
499
+ }
500
+ rows.push(rowCells);
501
+ }
502
+ return rows;
503
+ }
504
+ _deleteIndices(indices, i, n) {
505
+ throw new Error("Not implemented");
506
+ }
507
+ _moveIndices(indices, i, j, n) {
508
+ throw new Error("Not implemented");
509
+ }
510
+ /**
511
+ * Map from indices to A1 notation.
512
+ */
513
+ mapFormulaIndicesToRefs(formula) {
514
+ assertArgument(isFormula(formula), "formula");
515
+ return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {
516
+ return addressToA1Notation(addressFromIndex(this._sheet, idx));
517
+ });
518
+ }
519
+ /**
520
+ * https://hyperformula.handsontable.com/guide/date-and-time-handling.html#example
521
+ * https://hyperformula.handsontable.com/api/interfaces/configparams.html#nulldate
522
+ * NOTE: TODAY() is number of FULL days since nullDate. It will typically be -1 days from NOW().
523
+ */
524
+ toLocalDate(num) {
525
+ const { year, month, day, hours, minutes, seconds } = this.toDateTime(num);
526
+ return new Date(year, month - 1, day, hours, minutes, seconds);
527
+ }
528
+ toDateTime(num) {
529
+ invariant(this._node, void 0, {
530
+ "~LogMeta": "~LogMeta",
531
+ F: __dxlog_file,
532
+ L: 513,
533
+ S: this,
534
+ A: ["this._node", ""]
535
+ });
536
+ return this._node.graph.hf.numberToDateTime(num);
537
+ }
538
+ toDate(num) {
539
+ invariant(this._node, void 0, {
540
+ "~LogMeta": "~LogMeta",
541
+ F: __dxlog_file,
542
+ L: 518,
543
+ S: this,
544
+ A: ["this._node", ""]
545
+ });
546
+ return this._node.graph.hf.numberToDate(num);
547
+ }
548
+ toTime(num) {
549
+ invariant(this._node, void 0, {
550
+ "~LogMeta": "~LogMeta",
551
+ F: __dxlog_file,
552
+ L: 523,
553
+ S: this,
554
+ A: ["this._node", ""]
555
+ });
556
+ return this._node.graph.hf.numberToTime(num);
557
+ }
558
+ };
559
+ //#endregion
560
+ //#region src/model/useSheetModel.ts
561
+ var useSheetModel = (graph, sheet, { readonly } = {}) => {
562
+ const [model, setModel] = useState();
563
+ useEffect(() => {
564
+ if (!graph || !sheet) return;
565
+ let model;
566
+ const t = setTimeout(async () => {
567
+ model = new SheetModel(graph, sheet, { readonly });
568
+ await model.open();
569
+ setModel(model);
570
+ });
571
+ return () => {
572
+ clearTimeout(t);
573
+ model?.close();
574
+ };
575
+ }, [
576
+ graph,
577
+ sheet,
578
+ readonly
579
+ ]);
580
+ return model;
581
+ };
582
+ //#endregion
583
+ //#region src/components/SheetRoot/SheetRoot.tsx
584
+ var SheetRoot = ({ children, graph, sheet, attendableId, readonly, ignoreAttention, onInfo }) => {
585
+ const model = useSheetModel(graph, sheet, { readonly });
586
+ if (!model) return null;
587
+ return /* @__PURE__ */ jsx(Grid.Root, {
588
+ id: attendableId,
589
+ children: /* @__PURE__ */ jsx(SheetProviderImpl, {
590
+ model,
591
+ attendableId,
592
+ onInfo,
593
+ ignoreAttention,
594
+ children
595
+ })
596
+ });
597
+ };
598
+ var SheetProviderImpl = ({ __gridScope, children, attendableId, ignoreAttention, model, onInfo }) => {
599
+ const { id, editing, setEditing } = useGridContext("SheetProvider", __gridScope);
600
+ const [cursor, setCursorInternal] = useState();
601
+ const [range, setRangeInternal] = useState();
602
+ const [cursorFallbackRange, setCursorFallbackRange] = useState();
603
+ const [activeRefs, setActiveRefs] = useState("");
604
+ const setCursor = useCallback((nextCursor) => {
605
+ setCursorInternal(nextCursor);
606
+ setCursorFallbackRange(range?.to ? range : nextCursor ? {
607
+ from: nextCursor,
608
+ to: nextCursor
609
+ } : void 0);
610
+ }, [range]);
611
+ const setRange = useCallback((nextRange) => {
612
+ setRangeInternal(nextRange);
613
+ setCursorFallbackRange(nextRange?.to ? nextRange : cursor ? {
614
+ from: cursor,
615
+ to: cursor
616
+ } : void 0);
617
+ }, [cursor]);
618
+ return /* @__PURE__ */ jsx(SheetContext.Provider, {
619
+ value: {
620
+ id,
621
+ attendableId,
622
+ model,
623
+ editing,
624
+ setEditing,
625
+ cursor,
626
+ setCursor,
627
+ range,
628
+ setRange,
629
+ cursorFallbackRange,
630
+ activeRefs,
631
+ setActiveRefs,
632
+ ignoreAttention,
633
+ onInfo
634
+ },
635
+ children
636
+ });
637
+ };
638
+ //#endregion
639
+ //#region src/components/SheetContent/util.ts
640
+ var createDxGridColumns = (model) => {
641
+ return model.sheet.columns.reduce((acc, columnId, numericIndex) => {
642
+ if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) acc.grid[numericIndex] = {
643
+ size: model.sheet.columnMeta[columnId].size,
644
+ resizeable: true
645
+ };
646
+ return acc;
647
+ }, { grid: {} });
648
+ };
649
+ var createDxGridRows = (model) => {
650
+ return model.sheet.rows.reduce((acc, rowId, numericIndex) => {
651
+ if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) acc.grid[numericIndex] = {
652
+ size: model.sheet.rowMeta[rowId].size,
653
+ resizeable: true
654
+ };
655
+ return acc;
656
+ }, { grid: {} });
657
+ };
658
+ var projectCellProps = (model, col, row) => {
659
+ const address = {
660
+ col,
661
+ row
662
+ };
663
+ const rawValue = model.getValue(address);
664
+ const ranges = model.sheet.ranges?.filter(({ range }) => inRange(rangeFromIndex(model.sheet, range), address));
665
+ const threadRefs = void 0;
666
+ const description = model.getValueDescription(address);
667
+ const type = description?.type;
668
+ const format = description?.format;
669
+ const classNames = ranges?.map(cellClassNameForRange).reverse();
670
+ return {
671
+ value: parseValue({
672
+ type,
673
+ format,
674
+ value: rawValue
675
+ }),
676
+ className: mx(cellClassesForFieldType({
677
+ type,
678
+ format
679
+ }), threadRefs, classNames),
680
+ dataRefs: threadRefs
681
+ };
682
+ };
683
+ var gridCellGetter = (model) => {
684
+ const cachedGridCells = {};
685
+ return (nextBounds) => {
686
+ [...Array(nextBounds.end.col - nextBounds.start.col)].forEach((_, c0) => {
687
+ return [...Array(nextBounds.end.row - nextBounds.start.row)].forEach((_, r0) => {
688
+ const col = nextBounds.start.col + c0;
689
+ const row = nextBounds.start.row + r0;
690
+ cachedGridCells[`${col},${row}`] = projectCellProps(model, col, row);
691
+ });
692
+ });
693
+ return cachedGridCells;
694
+ };
695
+ };
696
+ var rowLabelCell = (row) => ({
697
+ value: rowToA1Notation(row),
698
+ className: "bg-axis-surface! text-axis-text text-end pe-1",
699
+ resizeHandle: "row"
700
+ });
701
+ var colLabelCell = (col) => ({
702
+ value: colToA1Notation(col),
703
+ className: "bg-axis-surface! text-axis-text",
704
+ resizeHandle: "col"
705
+ });
706
+ var cellGetter = (model) => {
707
+ const getGridCells = gridCellGetter(model);
708
+ return (nextBounds, plane) => {
709
+ switch (plane) {
710
+ case "grid": return getGridCells(nextBounds);
711
+ case "fixedStartStart": return { "0,0": { className: "bg-axis-surface!" } };
712
+ case "frozenColsStart": return [...Array(nextBounds.end.row - nextBounds.start.row)].reduce((acc, _, r0) => {
713
+ const r = nextBounds.start.row + r0;
714
+ acc[`0,${r}`] = rowLabelCell(r);
715
+ return acc;
716
+ }, {});
717
+ case "frozenRowsStart": return [...Array(nextBounds.end.col - nextBounds.start.col)].reduce((acc, _, c0) => {
718
+ const c = nextBounds.start.col + c0;
719
+ acc[`${c},0`] = colLabelCell(c);
720
+ return acc;
721
+ }, {});
722
+ default: return {};
723
+ }
724
+ };
725
+ };
726
+ var useSheetModelDxGridProps = (dxGrid, model) => {
727
+ const [columns, setColumns] = useState(createDxGridColumns(model));
728
+ const [rows, setRows] = useState(createDxGridRows(model));
729
+ useEffect(() => {
730
+ const cellsAccessor = Doc.createAccessor(model.sheet, ["cells"]);
731
+ if (dxGrid) dxGrid.getCells = cellGetter(model);
732
+ const handleCellsUpdate = () => {
733
+ dxGrid?.requestUpdate("initialCells");
734
+ };
735
+ cellsAccessor.handle.addListener("change", handleCellsUpdate);
736
+ const unsubscribe = model.graph.update.on(handleCellsUpdate);
737
+ return () => {
738
+ cellsAccessor.handle.removeListener("change", handleCellsUpdate);
739
+ unsubscribe();
740
+ };
741
+ }, [model, dxGrid]);
742
+ useEffect(() => {
743
+ const columnMetaAccessor = Doc.createAccessor(model.sheet, ["columnMeta"]);
744
+ const rowMetaAccessor = Doc.createAccessor(model.sheet, ["rowMeta"]);
745
+ const handleColumnMetaUpdate = () => {
746
+ setColumns(createDxGridColumns(model));
747
+ };
748
+ const handleRowMetaUpdate = () => {
749
+ setRows(createDxGridRows(model));
750
+ };
751
+ columnMetaAccessor.handle.addListener("change", handleColumnMetaUpdate);
752
+ rowMetaAccessor.handle.addListener("change", handleRowMetaUpdate);
753
+ return () => {
754
+ columnMetaAccessor.handle.removeListener("change", handleColumnMetaUpdate);
755
+ rowMetaAccessor.handle.removeListener("change", handleRowMetaUpdate);
756
+ };
757
+ }, [model, dxGrid]);
758
+ return {
759
+ columns,
760
+ rows
761
+ };
762
+ };
763
+ //#endregion
764
+ //#region src/components/SheetContent/SheetContent.tsx
765
+ var inertPosition = {
766
+ plane: "grid",
767
+ col: 0,
768
+ row: 0
769
+ };
770
+ var initialCells = {
771
+ grid: {},
772
+ frozenColsStart: [...Array(64)].reduce((acc, _, i) => {
773
+ acc[`0,${i}`] = rowLabelCell(i);
774
+ return acc;
775
+ }, {}),
776
+ frozenRowsStart: [...Array(12)].reduce((acc, _, i) => {
777
+ acc[`${i},0`] = colLabelCell(i);
778
+ return acc;
779
+ }, {})
780
+ };
781
+ var frozen = {
782
+ frozenColsStart: 1,
783
+ frozenRowsStart: 1
784
+ };
785
+ var sheetColDefault = {
786
+ frozenColsStart: {
787
+ size: 48,
788
+ readonly: true,
789
+ focusUnfurl: false
790
+ },
791
+ grid: {
792
+ size: defaultColSize,
793
+ resizeable: true
794
+ }
795
+ };
796
+ var sheetRowDefault = {
797
+ frozenRowsStart: {
798
+ size: defaultRowSize,
799
+ readonly: true,
800
+ focusUnfurl: false
801
+ },
802
+ grid: {
803
+ size: defaultRowSize,
804
+ resizeable: true
805
+ }
806
+ };
807
+ var SheetContent = composable((props, forwardedRef) => {
808
+ const { t } = useTranslation(meta.profile.key);
809
+ const { id, attendableId, model, editing, setCursor, setRange, cursor, cursorFallbackRange, activeRefs, setActiveRefs, ignoreAttention } = useSheetContext();
810
+ const [dxGrid, setDxGrid] = useState(null);
811
+ const [extraplanarFocus, setExtraplanarFocus] = useState(null);
812
+ const { invokePromise } = useOperationInvoker();
813
+ const rangeController = useRef(null);
814
+ const { hasAttention } = useAttention(id);
815
+ const handleFocus = useCallback((event) => {
816
+ if (!editing) {
817
+ const cell = closestCell(event.target);
818
+ if (cell) if (cell.plane === "grid") {
819
+ setCursor({
820
+ col: cell.col,
821
+ row: cell.row
822
+ });
823
+ setExtraplanarFocus(null);
824
+ } else setExtraplanarFocus(cell);
825
+ else setExtraplanarFocus(null);
826
+ }
827
+ }, [editing]);
828
+ const handleClose = useCallback((_value, event) => {
829
+ if (event) {
830
+ const { key, shift } = event;
831
+ const axis = [
832
+ "Enter",
833
+ "ArrowUp",
834
+ "ArrowDown"
835
+ ].includes(key) ? "row" : [
836
+ "Tab",
837
+ "ArrowLeft",
838
+ "ArrowRight"
839
+ ].includes(key) ? "col" : void 0;
840
+ const delta = key.startsWith("Arrow") ? ["ArrowUp", "ArrowLeft"].includes(key) ? -1 : 1 : shift ? -1 : 1;
841
+ dxGrid?.refocus(axis, delta);
842
+ }
843
+ }, [
844
+ model,
845
+ editing,
846
+ dxGrid
847
+ ]);
848
+ const handleBlur = useCallback((value) => {
849
+ if (value !== void 0) model.setValue(parseCellIndex(editing.index), value);
850
+ }, [model, editing]);
851
+ const handleAxisResize = useCallback(({ axis, size, index: numericIndex }) => {
852
+ Obj.update(model.sheet, (sheet) => {
853
+ if (axis === "row") {
854
+ const rowId = sheet.rows[parseInt(numericIndex)];
855
+ sheet.rowMeta[rowId] ??= {};
856
+ sheet.rowMeta[rowId].size = size;
857
+ } else {
858
+ const columnId = sheet.columns[parseInt(numericIndex)];
859
+ sheet.columnMeta[columnId] ??= {};
860
+ sheet.columnMeta[columnId].size = size;
861
+ }
862
+ });
863
+ }, [model]);
864
+ const handleSelect = useCallback(({ minCol, maxCol, minRow, maxRow }) => {
865
+ const range = { from: {
866
+ col: minCol,
867
+ row: minRow
868
+ } };
869
+ if (minCol !== maxCol || minRow !== maxRow) range.to = {
870
+ col: maxCol,
871
+ row: maxRow
872
+ };
873
+ if (editing) rangeController.current?.setRange(rangeToA1Notation(range));
874
+ else setRange(range.to ? range : void 0);
875
+ }, [editing]);
876
+ const handleWheel = useCallback((event) => {
877
+ if (!ignoreAttention && !hasAttention) event.stopPropagation();
878
+ }, [hasAttention, ignoreAttention]);
879
+ const selectEntireAxis = useCallback((pos) => {
880
+ switch (pos.plane) {
881
+ case "frozenRowsStart": return dxGrid?.setSelection({
882
+ start: {
883
+ col: pos.col,
884
+ row: 0,
885
+ plane: "grid"
886
+ },
887
+ end: {
888
+ col: pos.col,
889
+ row: model.sheet.rows.length - 1,
890
+ plane: "grid"
891
+ }
892
+ });
893
+ case "frozenColsStart": return dxGrid?.setSelection({
894
+ start: {
895
+ row: pos.row,
896
+ col: 0,
897
+ plane: "grid"
898
+ },
899
+ end: {
900
+ row: pos.row,
901
+ col: model.sheet.columns.length - 1,
902
+ plane: "grid"
903
+ }
904
+ });
905
+ }
906
+ }, [dxGrid, model.sheet]);
907
+ const handleClick = useCallback((event) => {
908
+ const cell = closestCell(event.target);
909
+ if (cell) selectEntireAxis(cell);
910
+ }, [selectEntireAxis]);
911
+ const handleKeyDown = useCallback((event) => {
912
+ switch (event.key) {
913
+ case "Backspace":
914
+ case "Delete":
915
+ event.preventDefault();
916
+ return cursorFallbackRange && model.clear(cursorFallbackRange);
917
+ case "Enter":
918
+ case "Space": if (dxGrid && extraplanarFocus) switch (extraplanarFocus.plane) {
919
+ case "frozenRowsStart":
920
+ case "frozenColsStart":
921
+ event.preventDefault();
922
+ return selectEntireAxis(extraplanarFocus);
923
+ }
924
+ }
925
+ if (event.metaKey || event.ctrlKey) switch (event.key) {
926
+ case "x":
927
+ case "X":
928
+ event.preventDefault();
929
+ return cursorFallbackRange && model.cut(cursorFallbackRange);
930
+ case "c":
931
+ case "C":
932
+ event.preventDefault();
933
+ return cursorFallbackRange && model.copy(cursorFallbackRange);
934
+ case "v":
935
+ case "V":
936
+ event.preventDefault();
937
+ return cursor && model.paste(cursor);
938
+ case "z":
939
+ event.preventDefault();
940
+ return event.shiftKey ? model.redo() : model.undo();
941
+ case "Z":
942
+ case "y":
943
+ event.preventDefault();
944
+ return model.redo();
945
+ }
946
+ }, [
947
+ cursorFallbackRange,
948
+ model,
949
+ cursor,
950
+ extraplanarFocus,
951
+ selectEntireAxis
952
+ ]);
953
+ const contextMenuAnchorRef = useRef(null);
954
+ const [contextMenuOpen, setContextMenuOpen] = useState(null);
955
+ const contextMenuAxis = contextMenuOpen?.plane.startsWith("frozenRows") ? "col" : "row";
956
+ const handleContextMenu = useCallback((event) => {
957
+ const cell = closestCell(event.target);
958
+ if (cell && cell.plane.startsWith("frozen")) {
959
+ event.preventDefault();
960
+ contextMenuAnchorRef.current = event.target;
961
+ setContextMenuOpen(cell);
962
+ }
963
+ }, []);
964
+ const handleAxisMenuAction = useCallback((operation) => {
965
+ switch (operation) {
966
+ case "insert-before":
967
+ case "insert-after": return invokePromise(SheetOperation.InsertAxis, {
968
+ model,
969
+ axis: contextMenuAxis,
970
+ index: contextMenuOpen[contextMenuAxis] + (operation === "insert-before" ? 0 : 1)
971
+ });
972
+ case "drop": return invokePromise(SheetOperation.DropAxis, {
973
+ model,
974
+ axis: contextMenuAxis,
975
+ axisIndex: model.sheet[contextMenuAxis === "row" ? "rows" : "columns"][contextMenuOpen[contextMenuAxis]]
976
+ });
977
+ }
978
+ }, [
979
+ contextMenuAxis,
980
+ contextMenuOpen,
981
+ model,
982
+ invokePromise
983
+ ]);
984
+ const { columns, rows } = useSheetModelDxGridProps(dxGrid, model);
985
+ const extensions = useMemo(() => [
986
+ editorKeys({
987
+ onClose: handleClose,
988
+ ...editing?.initialContent && { onNav: handleClose }
989
+ }),
990
+ sheetExtension({ functions: model.graph.getFunctions() }),
991
+ rangeExtension({
992
+ onInit: (fn) => rangeController.current = fn,
993
+ onStateChange: (state) => {
994
+ if (dxGrid) dxGrid.mode = typeof state.activeRange === "undefined" ? "edit" : "edit-select";
995
+ }
996
+ })
997
+ ], [
998
+ model,
999
+ handleClose,
1000
+ editing
1001
+ ]);
1002
+ const getCellContent = useCallback((index) => {
1003
+ return model.getCellText(parseCellIndex(index));
1004
+ }, [model]);
1005
+ const [gridInstances] = useCapabilities(SheetCapabilities.GridInstances);
1006
+ useEffect(() => {
1007
+ if (dxGrid && gridInstances) {
1008
+ gridInstances.register(attendableId, dxGrid, setActiveRefs);
1009
+ return () => gridInstances.unregister(attendableId);
1010
+ }
1011
+ }, [
1012
+ dxGrid,
1013
+ gridInstances,
1014
+ attendableId,
1015
+ setActiveRefs
1016
+ ]);
1017
+ useSelectThreadOnCellFocus();
1018
+ return /* @__PURE__ */ jsxs("div", {
1019
+ ref: forwardedRef,
1020
+ ...composableProps(props, { classNames: "relative min-h-0" }),
1021
+ children: [
1022
+ /* @__PURE__ */ jsx(GridCellEditor, {
1023
+ getCellContent,
1024
+ extensions,
1025
+ onBlur: handleBlur
1026
+ }),
1027
+ /* @__PURE__ */ jsx(Grid.Content, {
1028
+ className: "[--dx-grid-base:var(--base-surface)] [&_.dx-grid]:absolute [&_.dx-grid]:inset-0",
1029
+ initialCells,
1030
+ limitColumns: DEFAULT_COLS,
1031
+ limitRows: DEFAULT_ROWS,
1032
+ columns,
1033
+ rows,
1034
+ columnDefault: sheetColDefault,
1035
+ rowDefault: sheetRowDefault,
1036
+ activeRefs,
1037
+ frozen,
1038
+ overscroll: "trap",
1039
+ onAxisResize: handleAxisResize,
1040
+ onSelect: handleSelect,
1041
+ onFocus: handleFocus,
1042
+ onWheelCapture: handleWheel,
1043
+ onKeyDown: handleKeyDown,
1044
+ onContextMenu: handleContextMenu,
1045
+ onClick: handleClick,
1046
+ ref: setDxGrid
1047
+ }),
1048
+ /* @__PURE__ */ jsxs(DropdownMenu.Root, {
1049
+ modal: false,
1050
+ open: !!contextMenuOpen,
1051
+ onOpenChange: (nextOpen) => setContextMenuOpen(nextOpen ? inertPosition : null),
1052
+ children: [/* @__PURE__ */ jsx(DropdownMenu.VirtualTrigger, { virtualRef: contextMenuAnchorRef }), /* @__PURE__ */ jsxs(DropdownMenu.Content, {
1053
+ side: contextMenuAxis === "col" ? "bottom" : "right",
1054
+ sideOffset: 4,
1055
+ collisionPadding: 8,
1056
+ children: [/* @__PURE__ */ jsxs(DropdownMenu.Viewport, { children: [
1057
+ /* @__PURE__ */ jsxs(DropdownMenu.Item, {
1058
+ onClick: () => handleAxisMenuAction("insert-before"),
1059
+ "data-testid": `grid.${contextMenuAxis}.insert-before`,
1060
+ children: [/* @__PURE__ */ jsx(Icon, { icon: contextMenuAxis === "col" ? "ph--columns-plus-left--regular" : "ph--rows-plus-top--regular" }), /* @__PURE__ */ jsx("span", { children: t(`add-${contextMenuAxis}-before.label`) })]
1061
+ }),
1062
+ /* @__PURE__ */ jsxs(DropdownMenu.Item, {
1063
+ onClick: () => handleAxisMenuAction("insert-after"),
1064
+ "data-testid": `grid.${contextMenuAxis}.insert-after`,
1065
+ children: [/* @__PURE__ */ jsx(Icon, { icon: contextMenuAxis === "col" ? "ph--columns-plus-right--regular" : "ph--rows-plus-bottom--regular" }), /* @__PURE__ */ jsx("span", { children: t(`add-${contextMenuAxis}-after.label`) })]
1066
+ }),
1067
+ /* @__PURE__ */ jsxs(DropdownMenu.Item, {
1068
+ onClick: () => handleAxisMenuAction("drop"),
1069
+ "data-testid": `grid.${contextMenuAxis}.drop`,
1070
+ children: [/* @__PURE__ */ jsx(Icon, { icon: "ph--backspace--regular" }), /* @__PURE__ */ jsx("span", { children: t(`delete-${contextMenuAxis}.label`) })]
1071
+ })
1072
+ ] }), /* @__PURE__ */ jsx(DropdownMenu.Arrow, {})]
1073
+ })]
1074
+ })
1075
+ ]
1076
+ });
1077
+ });
1078
+ //#endregion
1079
+ //#region src/components/SheetStatusbar/SheetStatusbar.tsx
1080
+ var SheetStatusbar = composable((props, forwardedRef) => {
1081
+ const { className, ...rest } = composableProps(props);
1082
+ const { model, cursor, range } = useSheetContext();
1083
+ let value;
1084
+ let formula = false;
1085
+ if (cursor) {
1086
+ value = model.getCellValue(cursor);
1087
+ if (isFormula(value)) {
1088
+ value = model.graph.mapFunctionBindingFromId(mapFormulaIndicesToRefs(model.sheet, value));
1089
+ formula = true;
1090
+ } else if (value != null) value = String(value);
1091
+ }
1092
+ return /* @__PURE__ */ jsx("div", {
1093
+ ref: forwardedRef,
1094
+ ...rest,
1095
+ className: mx("flex shrink-0 justify-between items-center px-4 py-1 text-sm dx-toolbar-surface border-y !border-subdued-separator", className),
1096
+ children: /* @__PURE__ */ jsxs("div", {
1097
+ className: "flex gap-4 items-center",
1098
+ children: [/* @__PURE__ */ jsx("div", {
1099
+ className: "flex w-16 items-center font-mono",
1100
+ children: range && rangeToA1Notation(range) || cursor && addressToA1Notation(cursor)
1101
+ }), /* @__PURE__ */ jsxs("div", {
1102
+ className: "flex gap-2 items-center",
1103
+ children: [/* @__PURE__ */ jsx(Icon, {
1104
+ icon: "ph--function--regular",
1105
+ classNames: ["text-green-text", formula ? "visible" : "invisible"]
1106
+ }), /* @__PURE__ */ jsx("span", {
1107
+ className: "font-mono",
1108
+ children: value
1109
+ })]
1110
+ })]
1111
+ })
1112
+ });
1113
+ });
1114
+ //#endregion
1115
+ //#region src/components/SheetToolbar/align.ts
1116
+ var aligns = {
1117
+ start: "ph--text-align-left--regular",
1118
+ center: "ph--text-align-center--regular",
1119
+ end: "ph--text-align-right--regular"
1120
+ };
1121
+ var useAlignState = (stateAtom) => {
1122
+ const registry = useContext(RegistryContext);
1123
+ const { cursor, model } = useSheetContext();
1124
+ useEffect(() => {
1125
+ const alignValue = cursor ? model.sheet.ranges?.findLast(({ range, key }) => key === alignKey && inRange(rangeFromIndex(model.sheet, range), cursor))?.value : void 0;
1126
+ const prev = registry.get(stateAtom);
1127
+ registry.set(stateAtom, {
1128
+ ...prev,
1129
+ [alignKey]: alignValue
1130
+ });
1131
+ }, [
1132
+ cursor,
1133
+ model.sheet,
1134
+ registry,
1135
+ stateAtom
1136
+ ]);
1137
+ };
1138
+ var createAlignGroupAction = (value) => createMenuItemGroup("align", {
1139
+ label: ["align.label", { ns: meta.profile.key }],
1140
+ variant: "toggleGroup",
1141
+ selectCardinality: "single",
1142
+ value: `${alignKey}--${value}`
1143
+ });
1144
+ var createAlignActions = ({ model, state, stateAtom, registry, cursorFallbackRange }) => Object.entries(aligns).map(([alignValue, icon]) => {
1145
+ return createMenuAction(`${alignKey}--${alignValue}`, () => {
1146
+ if (!cursorFallbackRange) return;
1147
+ const index = model.sheet.ranges?.findIndex((range) => range.key === alignKey && inRange(rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from)) ?? -1;
1148
+ const nextRangeEntity = {
1149
+ range: rangeToIndex(model.sheet, cursorFallbackRange),
1150
+ key: alignKey,
1151
+ value: alignValue
1152
+ };
1153
+ const currentState = registry.get(stateAtom);
1154
+ if (index < 0) {
1155
+ Obj.update(model.sheet, (obj) => {
1156
+ obj.ranges?.push(nextRangeEntity);
1157
+ });
1158
+ registry.set(stateAtom, {
1159
+ ...currentState,
1160
+ [alignKey]: nextRangeEntity.value
1161
+ });
1162
+ } else if (model.sheet.ranges[index].value === nextRangeEntity.value) {
1163
+ Obj.update(model.sheet, (obj) => {
1164
+ obj.ranges?.splice(index, 1);
1165
+ });
1166
+ registry.set(stateAtom, {
1167
+ ...currentState,
1168
+ [alignKey]: void 0
1169
+ });
1170
+ } else {
1171
+ Obj.update(model.sheet, (obj) => {
1172
+ obj.ranges?.splice(index, 1, nextRangeEntity);
1173
+ });
1174
+ registry.set(stateAtom, {
1175
+ ...currentState,
1176
+ [alignKey]: nextRangeEntity.value
1177
+ });
1178
+ }
1179
+ }, {
1180
+ key: alignKey,
1181
+ value: alignValue,
1182
+ checked: state[alignKey] === alignValue,
1183
+ label: [`range-value.${alignValue}.label`, { ns: meta.profile.key }],
1184
+ icon,
1185
+ testId: `grid.toolbar.${alignKey}.${alignValue}`
1186
+ });
1187
+ });
1188
+ var createAlign = (context) => {
1189
+ const alignGroup = createAlignGroupAction(context.state[alignKey]);
1190
+ const alignActions = createAlignActions(context);
1191
+ return {
1192
+ nodes: [alignGroup, ...alignActions],
1193
+ edges: [{
1194
+ source: "root",
1195
+ target: "align",
1196
+ relation: "child"
1197
+ }, ...alignActions.map(({ id }) => ({
1198
+ source: alignGroup.id,
1199
+ target: id,
1200
+ relation: "child"
1201
+ }))]
1202
+ };
1203
+ };
1204
+ //#endregion
1205
+ //#region src/components/SheetToolbar/style.ts
1206
+ var styles = {
1207
+ highlight: "ph--highlighter--regular",
1208
+ softwrap: "ph--paragraph--regular"
1209
+ };
1210
+ var useStyleState = (stateAtom) => {
1211
+ const registry = useContext(RegistryContext);
1212
+ const { cursorFallbackRange, model } = useSheetContext();
1213
+ useEffect(() => {
1214
+ let highlight = false;
1215
+ let softwrap = false;
1216
+ if (cursorFallbackRange && model.sheet.ranges) model.sheet.ranges.filter(({ range, key }) => key === "style" && inRange(rangeFromIndex(model.sheet, range), cursorFallbackRange.from)).forEach(({ value }) => {
1217
+ if (value === "highlight") highlight = true;
1218
+ if (value === "softwrap") softwrap = true;
1219
+ });
1220
+ const prev = registry.get(stateAtom);
1221
+ registry.set(stateAtom, {
1222
+ ...prev,
1223
+ highlight,
1224
+ softwrap
1225
+ });
1226
+ }, [
1227
+ cursorFallbackRange,
1228
+ model.sheet,
1229
+ registry,
1230
+ stateAtom
1231
+ ]);
1232
+ };
1233
+ var createStyleGroup = (state) => {
1234
+ return createMenuItemGroup("style", {
1235
+ variant: "toggleGroup",
1236
+ selectCardinality: "multiple",
1237
+ value: Object.keys(styles).filter((key) => !!state[key]).map((styleValue) => `style--${styleValue}`)
1238
+ });
1239
+ };
1240
+ var createStyleActions = ({ model, state, stateAtom, registry, cursorFallbackRange }) => Object.entries(styles).map(([styleValue, icon]) => {
1241
+ return createMenuAction(`style--${styleValue}`, () => {
1242
+ if (!cursorFallbackRange) return;
1243
+ const index = model.sheet.ranges?.findIndex((range) => range.key === "style" && inRange(rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from)) ?? -1;
1244
+ const nextRangeEntity = {
1245
+ range: rangeToIndex(model.sheet, cursorFallbackRange),
1246
+ key: "style",
1247
+ value: styleValue
1248
+ };
1249
+ const currentState = registry.get(stateAtom);
1250
+ if (model.sheet.ranges.filter(({ range, key: rangeKey }) => rangeKey === "style" && inRange(rangeFromIndex(model.sheet, range), cursorFallbackRange.from)).some(({ value: rangeValue }) => rangeValue === styleValue)) {
1251
+ if (index >= 0) Obj.update(model.sheet, (obj) => {
1252
+ obj.ranges?.splice(index, 1);
1253
+ });
1254
+ registry.set(stateAtom, {
1255
+ ...currentState,
1256
+ [nextRangeEntity.value]: false
1257
+ });
1258
+ } else {
1259
+ Obj.update(model.sheet, (obj) => {
1260
+ obj.ranges?.push(nextRangeEntity);
1261
+ });
1262
+ registry.set(stateAtom, {
1263
+ ...currentState,
1264
+ [nextRangeEntity.value]: true
1265
+ });
1266
+ }
1267
+ }, {
1268
+ key: "style",
1269
+ value: styleValue,
1270
+ icon,
1271
+ label: [`range-value.${styleValue}.label`, { ns: meta.profile.key }],
1272
+ checked: !!state[styleValue]
1273
+ });
1274
+ });
1275
+ var createStyle = (context) => {
1276
+ const styleGroupAction = createStyleGroup(context.state);
1277
+ const styleActions = createStyleActions(context);
1278
+ return {
1279
+ nodes: [styleGroupAction, ...styleActions],
1280
+ edges: [{
1281
+ source: "root",
1282
+ target: "style",
1283
+ relation: "child"
1284
+ }, ...styleActions.map(({ id }) => ({
1285
+ source: styleGroupAction.id,
1286
+ target: id,
1287
+ relation: "child"
1288
+ }))]
1289
+ };
1290
+ };
1291
+ //#endregion
1292
+ //#region src/components/SheetToolbar/useToolbarState.ts
1293
+ /**
1294
+ * Creates a reactive toolbar state Atom.
1295
+ */
1296
+ var useToolbarState = (initialState = {}) => {
1297
+ return useMemo(() => Atom.make(initialState).pipe(Atom.keepAlive), []);
1298
+ };
1299
+ //#endregion
1300
+ //#region src/components/SheetToolbar/SheetToolbar.tsx
1301
+ var createToolbarActions = ({ model, stateAtom, registry, cursorFallbackRange, customActions }) => {
1302
+ return Atom.make((get) => {
1303
+ const context = {
1304
+ model,
1305
+ state: get(stateAtom),
1306
+ stateAtom,
1307
+ registry,
1308
+ cursorFallbackRange
1309
+ };
1310
+ const align = createAlign(context);
1311
+ const style = createStyle(context);
1312
+ const gap = createGapSeparator();
1313
+ const graph = {
1314
+ nodes: [
1315
+ ...align.nodes,
1316
+ ...style.nodes,
1317
+ ...gap.nodes
1318
+ ],
1319
+ edges: [
1320
+ ...align.edges,
1321
+ ...style.edges,
1322
+ ...gap.edges
1323
+ ]
1324
+ };
1325
+ if (customActions) {
1326
+ const custom = get(customActions);
1327
+ graph.nodes.push(...custom.nodes);
1328
+ graph.edges.push(...custom.edges);
1329
+ }
1330
+ return graph;
1331
+ });
1332
+ };
1333
+ var SheetToolbar = composable((props, forwardedRef) => {
1334
+ const { attendableId, model, cursorFallbackRange } = useSheetContext();
1335
+ const stateAtom = useToolbarState({});
1336
+ const registry = useContext(RegistryContext);
1337
+ useAlignState(stateAtom);
1338
+ useStyleState(stateAtom);
1339
+ const { graph } = useAppGraph();
1340
+ const customActions = useMemo(() => {
1341
+ return Atom.make((get) => graphActions(graph, get, attendableId, { filter: isToolbarAction }));
1342
+ }, [graph, attendableId]);
1343
+ const menuActions = useMenuActions(useMemo(() => createToolbarActions({
1344
+ model,
1345
+ stateAtom,
1346
+ registry,
1347
+ cursorFallbackRange,
1348
+ customActions
1349
+ }), [
1350
+ model,
1351
+ stateAtom,
1352
+ registry,
1353
+ cursorFallbackRange,
1354
+ customActions
1355
+ ]));
1356
+ return /* @__PURE__ */ jsx(Menu.Root, {
1357
+ ...menuActions,
1358
+ attendableId,
1359
+ children: /* @__PURE__ */ jsx(Menu.Toolbar, {
1360
+ ...composableProps(props),
1361
+ ref: forwardedRef
1362
+ })
1363
+ });
1364
+ });
1365
+ SheetToolbar.displayName = "SheetToolbar";
1366
+ //#endregion
1367
+ //#region src/components/Sheet/Sheet.tsx
1368
+ var Sheet = {
1369
+ Root: SheetRoot,
1370
+ Toolbar: SheetToolbar,
1371
+ Content: SheetContent,
1372
+ Statusbar: SheetStatusbar
1373
+ };
1374
+ //#endregion
1375
+ export { ComputeGraphContextProvider, Sheet, useComputeGraph, useSheetContext };
1376
+
1377
+ //# sourceMappingURL=components.mjs.map