@dxos/react-ui-editor 0.7.5-main.9d26e3a → 0.7.5-main.e9bb01b

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 (78) hide show
  1. package/dist/lib/browser/index.mjs +1110 -1127
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +1133 -1164
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +1110 -1127
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/InputMode.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +4 -0
  12. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -0
  13. package/dist/types/src/components/EditorToolbar/blocks.d.ts +18 -0
  14. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -0
  15. package/dist/types/src/components/EditorToolbar/comment.d.ts +17 -0
  16. package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -0
  17. package/dist/types/src/components/EditorToolbar/formatting.d.ts +18 -0
  18. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -0
  19. package/dist/types/src/components/EditorToolbar/headings.d.ts +18 -0
  20. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -0
  21. package/dist/types/src/components/EditorToolbar/index.d.ts +3 -0
  22. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -0
  23. package/dist/types/src/components/EditorToolbar/lists.d.ts +18 -0
  24. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
  25. package/dist/types/src/components/EditorToolbar/util.d.ts +58 -0
  26. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -0
  27. package/dist/types/src/components/EditorToolbar/viewMode.d.ts +18 -0
  28. package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +1 -0
  29. package/dist/types/src/components/index.d.ts +1 -1
  30. package/dist/types/src/components/index.d.ts.map +1 -1
  31. package/dist/types/src/extensions/comments.d.ts +3 -4
  32. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  33. package/dist/types/src/extensions/markdown/editorAction.d.ts +12 -0
  34. package/dist/types/src/extensions/markdown/editorAction.d.ts.map +1 -0
  35. package/dist/types/src/extensions/markdown/formatting.d.ts +14 -12
  36. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  37. package/dist/types/src/extensions/markdown/index.d.ts +1 -1
  38. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  39. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  40. package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
  41. package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
  42. package/dist/types/src/index.d.ts +1 -0
  43. package/dist/types/src/index.d.ts.map +1 -1
  44. package/dist/types/src/styles/stack-item-content-class-names.d.ts +3 -0
  45. package/dist/types/src/styles/stack-item-content-class-names.d.ts.map +1 -0
  46. package/dist/types/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +30 -29
  48. package/src/InputMode.stories.tsx +7 -10
  49. package/src/components/EditorToolbar/EditorToolbar.tsx +106 -0
  50. package/src/components/EditorToolbar/blocks.ts +41 -0
  51. package/src/components/EditorToolbar/comment.ts +23 -0
  52. package/src/components/EditorToolbar/formatting.ts +41 -0
  53. package/src/components/EditorToolbar/headings.ts +59 -0
  54. package/src/components/EditorToolbar/index.ts +6 -0
  55. package/src/components/EditorToolbar/lists.ts +40 -0
  56. package/src/components/EditorToolbar/util.ts +65 -0
  57. package/src/components/EditorToolbar/viewMode.ts +48 -0
  58. package/src/components/index.ts +1 -1
  59. package/src/extensions/comments.ts +8 -15
  60. package/src/extensions/markdown/decorate.ts +1 -1
  61. package/src/extensions/markdown/{action.ts → editorAction.ts} +22 -20
  62. package/src/extensions/markdown/formatting.test.ts +7 -6
  63. package/src/extensions/markdown/formatting.ts +20 -24
  64. package/src/extensions/markdown/index.ts +1 -1
  65. package/src/extensions/markdown/styles.ts +21 -0
  66. package/src/hooks/useActionHandler.ts +4 -4
  67. package/src/index.ts +4 -0
  68. package/src/styles/markdown.ts +1 -1
  69. package/src/styles/stack-item-content-class-names.ts +17 -0
  70. package/src/styles/theme.ts +1 -1
  71. package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -34
  72. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
  73. package/dist/types/src/components/Toolbar/index.d.ts +0 -2
  74. package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
  75. package/dist/types/src/extensions/markdown/action.d.ts +0 -9
  76. package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
  77. package/src/components/Toolbar/Toolbar.tsx +0 -522
  78. package/src/components/Toolbar/index.ts +0 -5
@@ -32,6 +32,7 @@ __export(node_exports, {
32
32
  EditorInputMode: () => EditorInputMode,
33
33
  EditorInputModes: () => EditorInputModes,
34
34
  EditorState: () => import_state.EditorState,
35
+ EditorToolbar: () => EditorToolbar,
35
36
  EditorView: () => import_view.EditorView,
36
37
  EditorViewMode: () => EditorViewMode,
37
38
  EditorViewModes: () => EditorViewModes,
@@ -41,7 +42,6 @@ __export(node_exports, {
41
42
  RemoteSelectionsDecorator: () => RemoteSelectionsDecorator,
42
43
  SpaceAwarenessProvider: () => SpaceAwarenessProvider,
43
44
  TextKind: () => import_text.TextKind,
44
- Toolbar: () => Toolbar,
45
45
  addBlockquote: () => addBlockquote,
46
46
  addCodeblock: () => addCodeblock,
47
47
  addLink: () => addLink,
@@ -60,8 +60,10 @@ __export(node_exports, {
60
60
  commentsState: () => commentsState,
61
61
  convertTreeToJson: () => convertTreeToJson,
62
62
  createBasicExtensions: () => createBasicExtensions,
63
- createComment: () => createComment,
63
+ createComment: () => createComment2,
64
64
  createDataExtensions: () => createDataExtensions,
65
+ createEditorAction: () => createEditorAction,
66
+ createEditorActionGroup: () => createEditorActionGroup,
65
67
  createEditorStateStore: () => createEditorStateStore,
66
68
  createEditorStateTransaction: () => createEditorStateTransaction,
67
69
  createElement: () => createElement,
@@ -100,7 +102,7 @@ __export(node_exports, {
100
102
  mention: () => mention,
101
103
  overlap: () => overlap,
102
104
  preventNewline: () => preventNewline,
103
- processAction: () => processAction,
105
+ processEditorPayload: () => processEditorPayload,
104
106
  removeBlockquote: () => removeBlockquote,
105
107
  removeCodeblock: () => removeCodeblock,
106
108
  removeLink: () => removeLink,
@@ -116,6 +118,8 @@ __export(node_exports, {
116
118
  setSelection: () => setSelection,
117
119
  setStyle: () => setStyle,
118
120
  singleValueFacet: () => singleValueFacet,
121
+ stackItemContentEditorClassNames: () => stackItemContentEditorClassNames,
122
+ stackItemContentToolbarClassNames: () => stackItemContentToolbarClassNames,
119
123
  table: () => table,
120
124
  tags: () => import_highlight.tags,
121
125
  textRange: () => textRange,
@@ -133,9 +137,9 @@ __export(node_exports, {
133
137
  useCommentClickListener: () => useCommentClickListener,
134
138
  useCommentState: () => useCommentState,
135
139
  useComments: () => useComments,
140
+ useEditorToolbarState: () => useEditorToolbarState,
136
141
  useFormattingState: () => useFormattingState,
137
142
  useTextEditor: () => useTextEditor,
138
- useToolbarContext: () => useToolbarContext,
139
143
  wrapWithCatch: () => wrapWithCatch
140
144
  });
141
145
  module.exports = __toCommonJS(node_exports);
@@ -143,26 +147,33 @@ var import_state = require("@codemirror/state");
143
147
  var import_view = require("@codemirror/view");
144
148
  var import_highlight = require("@lezer/highlight");
145
149
  var import_text = require("@dxos/protocols/proto/dxos/echo/model/text");
146
- var import_react = require("@phosphor-icons/react");
147
- var import_react_context = require("@radix-ui/react-context");
148
- var import_react2 = __toESM(require("react"));
149
- var import_react_dropzone = require("react-dropzone");
150
+ var import_react = __toESM(require("react"));
150
151
  var import_react_ui = require("@dxos/react-ui");
152
+ var import_react_ui_menu = require("@dxos/react-ui-menu");
151
153
  var import_react_ui_theme = require("@dxos/react-ui-theme");
152
- var import_state2 = require("@codemirror/state");
154
+ var import_react2 = require("react");
155
+ var import_live_object = require("@dxos/live-object");
156
+ var import_react_ui_menu2 = require("@dxos/react-ui-menu");
157
+ var import_react_ui_theme2 = require("@dxos/react-ui-theme");
153
158
  var import_view2 = require("@codemirror/view");
159
+ var import_react_ui_theme3 = require("@dxos/react-ui-theme");
160
+ var import_react_ui_theme4 = require("@dxos/react-ui-theme");
161
+ var import_lodash = __toESM(require("lodash.get"));
162
+ var import_react_ui_theme5 = require("@dxos/react-ui-theme");
163
+ var import_state2 = require("@codemirror/state");
164
+ var import_view3 = require("@codemirror/view");
154
165
  var import_util = require("@dxos/util");
155
166
  var import_state3 = require("@codemirror/state");
156
167
  var import_log = require("@dxos/log");
157
168
  var import_react3 = __toESM(require("react"));
158
169
  var import_client = require("react-dom/client");
159
170
  var import_react_ui2 = require("@dxos/react-ui");
160
- var import_react_ui_theme2 = require("@dxos/react-ui-theme");
171
+ var import_react_ui_theme6 = require("@dxos/react-ui-theme");
161
172
  var import_autocomplete = require("@codemirror/autocomplete");
162
173
  var import_lang_markdown = require("@codemirror/lang-markdown");
163
- var import_view3 = require("@codemirror/view");
164
- var import_state4 = require("@codemirror/state");
165
174
  var import_view4 = require("@codemirror/view");
175
+ var import_state4 = require("@codemirror/state");
176
+ var import_view5 = require("@codemirror/view");
166
177
  var import_automerge = require("@dxos/automerge/automerge");
167
178
  var import_log2 = require("@dxos/log");
168
179
  var import_echo = require("@dxos/react-client/echo");
@@ -171,64 +182,61 @@ var import_automerge2 = require("@dxos/automerge/automerge");
171
182
  var import_automerge3 = require("@dxos/automerge/automerge");
172
183
  var import_state6 = require("@codemirror/state");
173
184
  var import_state7 = require("@codemirror/state");
174
- var import_view5 = require("@codemirror/view");
185
+ var import_view6 = require("@codemirror/view");
175
186
  var import_async = require("@dxos/async");
176
187
  var import_context = require("@dxos/context");
177
188
  var import_async2 = require("@dxos/async");
178
189
  var import_context2 = require("@dxos/context");
179
190
  var import_invariant = require("@dxos/invariant");
180
191
  var import_log3 = require("@dxos/log");
181
- var import_view6 = require("@codemirror/view");
182
- var import_lodash = __toESM(require("lodash.defaultsdeep"));
183
- var import_invariant2 = require("@dxos/invariant");
184
192
  var import_view7 = require("@codemirror/view");
185
- var import_state8 = require("@codemirror/state");
193
+ var import_lodash2 = __toESM(require("lodash.defaultsdeep"));
194
+ var import_invariant2 = require("@dxos/invariant");
186
195
  var import_view8 = require("@codemirror/view");
187
- var import_state9 = require("@codemirror/state");
196
+ var import_state8 = require("@codemirror/state");
188
197
  var import_view9 = require("@codemirror/view");
198
+ var import_state9 = require("@codemirror/state");
199
+ var import_view10 = require("@codemirror/view");
189
200
  var import_commands = require("@codemirror/commands");
190
201
  var import_state10 = require("@codemirror/state");
191
- var import_view10 = require("@codemirror/view");
192
- var import_lodash2 = __toESM(require("lodash.sortby"));
202
+ var import_view11 = require("@codemirror/view");
203
+ var import_lodash3 = __toESM(require("lodash.sortby"));
193
204
  var import_react4 = require("react");
194
205
  var import_async3 = require("@dxos/async");
195
206
  var import_log4 = require("@dxos/log");
196
207
  var import_util2 = require("@dxos/util");
197
208
  var import_state11 = require("@codemirror/state");
198
- var import_view11 = require("@codemirror/view");
209
+ var import_view12 = require("@codemirror/view");
199
210
  var import_async4 = require("@dxos/async");
200
211
  var import_invariant3 = require("@dxos/invariant");
201
212
  var import_util3 = require("@dxos/util");
202
213
  var import_language = require("@codemirror/language");
203
214
  var import_state12 = require("@codemirror/state");
204
- var import_view12 = require("@codemirror/view");
215
+ var import_view13 = require("@codemirror/view");
205
216
  var import_autocomplete2 = require("@codemirror/autocomplete");
206
217
  var import_commands2 = require("@codemirror/commands");
207
218
  var import_language2 = require("@codemirror/language");
208
219
  var import_search = require("@codemirror/search");
209
220
  var import_state13 = require("@codemirror/state");
210
221
  var import_theme_one_dark = require("@codemirror/theme-one-dark");
211
- var import_view13 = require("@codemirror/view");
212
- var import_lodash3 = __toESM(require("lodash.defaultsdeep"));
213
- var import_lodash4 = __toESM(require("lodash.merge"));
222
+ var import_view14 = require("@codemirror/view");
223
+ var import_lodash4 = __toESM(require("lodash.defaultsdeep"));
224
+ var import_lodash5 = __toESM(require("lodash.merge"));
214
225
  var import_display_name = require("@dxos/display-name");
215
226
  var import_log5 = require("@dxos/log");
216
- var import_react_ui_theme3 = require("@dxos/react-ui-theme");
227
+ var import_react_ui_theme7 = require("@dxos/react-ui-theme");
217
228
  var import_util4 = require("@dxos/util");
218
229
  var import_state14 = require("@codemirror/state");
219
- var import_view14 = require("@codemirror/view");
220
- var import_react_ui_theme4 = require("@dxos/react-ui-theme");
221
- var import_lodash5 = __toESM(require("lodash.get"));
222
- var import_react_ui_theme5 = require("@dxos/react-ui-theme");
223
- var import_language3 = require("@codemirror/language");
224
230
  var import_view15 = require("@codemirror/view");
231
+ var import_language3 = require("@codemirror/language");
232
+ var import_view16 = require("@codemirror/view");
225
233
  var import_react5 = __toESM(require("react"));
226
234
  var import_react_ui3 = require("@dxos/react-ui");
227
- var import_view16 = require("@codemirror/view");
235
+ var import_view17 = require("@codemirror/view");
228
236
  var import_autocomplete3 = require("@codemirror/autocomplete");
229
237
  var import_language4 = require("@codemirror/language");
230
238
  var import_state15 = require("@codemirror/state");
231
- var import_view17 = require("@codemirror/view");
239
+ var import_view18 = require("@codemirror/view");
232
240
  var import_react6 = require("react");
233
241
  var import_autocomplete4 = require("@codemirror/autocomplete");
234
242
  var import_commands3 = require("@codemirror/commands");
@@ -236,7 +244,7 @@ var import_lang_markdown2 = require("@codemirror/lang-markdown");
236
244
  var import_language5 = require("@codemirror/language");
237
245
  var import_language_data = require("@codemirror/language-data");
238
246
  var import_lint = require("@codemirror/lint");
239
- var import_view18 = require("@codemirror/view");
247
+ var import_view19 = require("@codemirror/view");
240
248
  var import_lang_markdown3 = require("@codemirror/lang-markdown");
241
249
  var import_language6 = require("@codemirror/language");
242
250
  var import_highlight2 = require("@lezer/highlight");
@@ -245,35 +253,34 @@ var import_language7 = require("@codemirror/language");
245
253
  var import_state16 = require("@codemirror/state");
246
254
  var import_language8 = require("@codemirror/language");
247
255
  var import_state17 = require("@codemirror/state");
248
- var import_view19 = require("@codemirror/view");
256
+ var import_view20 = require("@codemirror/view");
249
257
  var import_invariant4 = require("@dxos/invariant");
250
- var import_react_ui_theme6 = require("@dxos/react-ui-theme");
258
+ var import_react_ui_theme8 = require("@dxos/react-ui-theme");
251
259
  var import_language9 = require("@codemirror/language");
252
260
  var import_state18 = require("@codemirror/state");
253
- var import_view20 = require("@codemirror/view");
261
+ var import_view21 = require("@codemirror/view");
254
262
  var import_language10 = require("@codemirror/language");
255
263
  var import_state19 = require("@codemirror/state");
256
- var import_view21 = require("@codemirror/view");
257
264
  var import_view22 = require("@codemirror/view");
265
+ var import_view23 = require("@codemirror/view");
258
266
  var import_language11 = require("@codemirror/language");
259
267
  var import_state20 = require("@codemirror/state");
260
- var import_view23 = require("@codemirror/view");
261
- var import_language12 = require("@codemirror/language");
262
268
  var import_view24 = require("@codemirror/view");
263
- var import_react_ui_theme7 = require("@dxos/react-ui-theme");
269
+ var import_language12 = require("@codemirror/language");
270
+ var import_view25 = require("@codemirror/view");
271
+ var import_react_ui_theme9 = require("@dxos/react-ui-theme");
264
272
  var import_autocomplete5 = require("@codemirror/autocomplete");
265
273
  var import_log6 = require("@dxos/log");
266
- var import_view25 = require("@codemirror/view");
274
+ var import_view26 = require("@codemirror/view");
267
275
  var import_codemirror_vim = require("@replit/codemirror-vim");
268
276
  var import_codemirror_vscode_keymap = require("@replit/codemirror-vscode-keymap");
269
277
  var import_echo_schema = require("@dxos/echo-schema");
270
- var import_view26 = require("@codemirror/view");
271
278
  var import_view27 = require("@codemirror/view");
272
- var import_react_ui_theme8 = require("@dxos/react-ui-theme");
279
+ var import_react7 = require("react");
273
280
  var import_state21 = require("@codemirror/state");
274
281
  var import_view28 = require("@codemirror/view");
275
282
  var import_react_tabster = require("@fluentui/react-tabster");
276
- var import_react7 = require("react");
283
+ var import_react8 = require("react");
277
284
  var import_log7 = require("@dxos/log");
278
285
  var import_util5 = require("@dxos/util");
279
286
  var translationKey = "react-ui-editor";
@@ -309,211 +316,778 @@ var translations_default = [
309
316
  }
310
317
  }
311
318
  ];
312
- var singleValueFacet = (defaultValue) => import_state3.Facet.define({
313
- // Called immediately.
314
- combine: (providers) => {
315
- return providers[0] ?? defaultValue;
319
+ var useEditorToolbarState = (initialState = {}) => {
320
+ return (0, import_react2.useMemo)(() => (0, import_live_object.create)(initialState), []);
321
+ };
322
+ var createEditorAction = (payload, icon, label = [
323
+ `${payload.type} label`,
324
+ {
325
+ ns: translationKey
316
326
  }
327
+ ], id = payload.type) => (0, import_react_ui_menu2.createMenuAction)(id, {
328
+ icon,
329
+ label,
330
+ ...payload
317
331
  });
318
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
319
- var defaultCursorConverter = {
320
- toCursor: (position) => position.toString(),
321
- fromCursor: (cursor) => parseInt(cursor)
332
+ var createEditorActionGroup = (id, props, icon) => (0, import_react_ui_menu2.createMenuItemGroup)(id, {
333
+ icon,
334
+ iconOnly: true,
335
+ ...props
336
+ });
337
+ var editorToolbarSearch = createEditorAction({
338
+ type: "search"
339
+ }, "ph--magnifying-glass--regular");
340
+ var createBlockGroupAction = (value) => createEditorActionGroup("block", {
341
+ variant: "toggleGroup",
342
+ selectCardinality: "single",
343
+ value
344
+ });
345
+ var createBlockActions = (value, blankLine) => Object.entries({
346
+ blockquote: "ph--quotes--regular",
347
+ codeblock: "ph--code-block--regular",
348
+ table: "ph--table--regular"
349
+ }).map(([type, icon]) => {
350
+ return createEditorAction({
351
+ type,
352
+ checked: type === value,
353
+ ...type === "table" && {
354
+ disabled: !!blankLine
355
+ }
356
+ }, icon);
357
+ });
358
+ var createBlocks = (state) => {
359
+ const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
360
+ const blockGroupAction = createBlockGroupAction(value);
361
+ const blockActions = createBlockActions(value, state.blankLine);
362
+ return {
363
+ nodes: [
364
+ blockGroupAction,
365
+ ...blockActions
366
+ ],
367
+ edges: [
368
+ {
369
+ source: "root",
370
+ target: "block"
371
+ },
372
+ ...blockActions.map(({ id }) => ({
373
+ source: blockGroupAction.id,
374
+ target: id
375
+ }))
376
+ ]
377
+ };
322
378
  };
323
- var Cursor = class _Cursor {
324
- static {
325
- this.converter = singleValueFacet(defaultCursorConverter);
326
- }
327
- static {
328
- this.getCursorFromRange = (state, range) => {
329
- const cursorConverter2 = state.facet(_Cursor.converter);
330
- const from = cursorConverter2.toCursor(range.from);
331
- const to = cursorConverter2.toCursor(range.to, -1);
332
- return [
333
- from,
334
- to
335
- ].join(":");
336
- };
337
- }
338
- static {
339
- this.getRangeFromCursor = (state, cursor) => {
340
- const cursorConverter2 = state.facet(_Cursor.converter);
341
- const parts = cursor.split(":");
342
- const from = cursorConverter2.fromCursor(parts[0]);
343
- const to = cursorConverter2.fromCursor(parts[1]);
344
- return from !== void 0 && to !== void 0 ? {
345
- from,
346
- to
347
- } : void 0;
348
- };
349
- }
379
+ var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
380
+ var createCommentAction = (label) => createEditorAction({
381
+ type: "comment",
382
+ testId: "editor.toolbar.comment"
383
+ }, "ph--chat-text--regular", label);
384
+ var createComment = (state) => ({
385
+ nodes: [
386
+ createCommentAction([
387
+ commentLabel(state.comment, state.selection),
388
+ {
389
+ ns: translationKey
390
+ }
391
+ ])
392
+ ],
393
+ edges: [
394
+ {
395
+ source: "root",
396
+ target: "comment"
397
+ }
398
+ ]
399
+ });
400
+ var formats = {
401
+ strong: "ph--text-b--regular",
402
+ emphasis: "ph--text-italic--regular",
403
+ strikethrough: "ph--text-strikethrough--regular",
404
+ code: "ph--code--regular",
405
+ link: "ph--link--regular"
406
+ };
407
+ var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
408
+ variant: "toggleGroup",
409
+ selectCardinality: "multiple",
410
+ value: Object.keys(formats).filter((key) => !!formatting[key])
411
+ });
412
+ var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
413
+ type,
414
+ checked: !!formatting[type]
415
+ }, icon));
416
+ var createFormatting = (state) => {
417
+ const formattingGroupAction = createFormattingGroup(state);
418
+ const formattingActions = createFormattingActions(state);
419
+ return {
420
+ nodes: [
421
+ formattingGroupAction,
422
+ ...formattingActions
423
+ ],
424
+ edges: [
425
+ {
426
+ source: "root",
427
+ target: "formatting"
428
+ },
429
+ ...formattingActions.map(({ id }) => ({
430
+ source: formattingGroupAction.id,
431
+ target: id
432
+ }))
433
+ ]
434
+ };
350
435
  };
351
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
352
- var wrapWithCatch = (fn) => {
353
- return (...args) => {
354
- try {
355
- return fn(...args);
356
- } catch (err) {
357
- import_log.log.catch(err, void 0, {
358
- F: __dxlog_file,
359
- L: 15,
360
- S: void 0,
361
- C: (f, a) => f(...a)
362
- });
436
+ var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
437
+ variant: "dropdownMenu",
438
+ applyActive: true,
439
+ selectCardinality: "single",
440
+ value
441
+ }, "ph--text-h--regular");
442
+ var createHeadingActions = (value) => Object.entries({
443
+ "0": "ph--paragraph--regular",
444
+ "1": "ph--text-h-one--regular",
445
+ "2": "ph--text-h-two--regular",
446
+ "3": "ph--text-h-three--regular",
447
+ "4": "ph--text-h-four--regular",
448
+ "5": "ph--text-h-five--regular",
449
+ "6": "ph--text-h-six--regular"
450
+ }).map(([levelStr, icon]) => {
451
+ const level = parseInt(levelStr);
452
+ return createEditorAction({
453
+ type: "heading",
454
+ data: level,
455
+ checked: value === levelStr
456
+ }, icon, [
457
+ "heading level label",
458
+ {
459
+ count: level,
460
+ ns: translationKey
363
461
  }
462
+ ], `heading--${levelStr}`);
463
+ });
464
+ var computeHeadingValue = (state) => {
465
+ const blockType = state ? state.blockType : "paragraph";
466
+ const header = blockType && /heading(\d)/.exec(blockType);
467
+ return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
468
+ };
469
+ var createHeadings = (state) => {
470
+ const headingValue = computeHeadingValue(state);
471
+ const headingGroupAction = createHeadingGroupAction(headingValue);
472
+ const headingActions = createHeadingActions(headingValue);
473
+ return {
474
+ nodes: [
475
+ headingGroupAction,
476
+ ...headingActions
477
+ ],
478
+ edges: [
479
+ {
480
+ source: "root",
481
+ target: "heading"
482
+ },
483
+ ...headingActions.map(({ id }) => ({
484
+ source: headingGroupAction.id,
485
+ target: id
486
+ }))
487
+ ]
364
488
  };
365
489
  };
366
- var callbackWrapper = (fn) => (...args) => {
367
- try {
368
- return fn(...args);
369
- } catch (err) {
370
- import_log.log.catch(err, void 0, {
371
- F: __dxlog_file,
372
- L: 29,
373
- S: void 0,
374
- C: (f, a) => f(...a)
375
- });
376
- }
490
+ var listStyles = {
491
+ bullet: "ph--list-bullets--regular",
492
+ ordered: "ph--list-numbers--regular",
493
+ task: "ph--list-checks--regular"
377
494
  };
378
- var debugDispatcher = (trs, view) => {
379
- logChanges(trs);
380
- view.update(trs);
495
+ var createListGroupAction = (value) => createEditorActionGroup("list", {
496
+ variant: "toggleGroup",
497
+ selectCardinality: "single",
498
+ value
499
+ });
500
+ var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
501
+ type: `list-${listStyle}`,
502
+ checked: value === listStyle
503
+ }, icon));
504
+ var createLists = (state) => {
505
+ const value = state.listStyle ?? "";
506
+ const listGroupAction = createListGroupAction(value);
507
+ const listActionsMap = createListActions(value);
508
+ return {
509
+ nodes: [
510
+ listGroupAction,
511
+ ...listActionsMap
512
+ ],
513
+ edges: [
514
+ {
515
+ source: "root",
516
+ target: "list"
517
+ },
518
+ ...listActionsMap.map(({ id }) => ({
519
+ source: listGroupAction.id,
520
+ target: id
521
+ }))
522
+ ]
523
+ };
381
524
  };
382
- var logChanges = (trs) => {
383
- const changes = trs.flatMap((tr) => {
384
- if (tr.changes.empty) {
385
- return void 0;
525
+ var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
526
+ variant: "dropdownMenu",
527
+ applyActive: true,
528
+ selectCardinality: "single",
529
+ value
530
+ }, "ph--eye--regular");
531
+ var createViewModeActions = (value) => Object.entries({
532
+ preview: "ph--eye--regular",
533
+ source: "ph--pencil-simple--regular",
534
+ readonly: "ph--pencil-slash--regular"
535
+ }).map(([viewMode, icon]) => {
536
+ return createEditorAction({
537
+ type: "view-mode",
538
+ data: viewMode,
539
+ checked: viewMode === value
540
+ }, icon, [
541
+ `${viewMode} mode label`,
542
+ {
543
+ ns: translationKey
386
544
  }
387
- const changes2 = [];
388
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
389
- fromA,
390
- toA,
391
- fromB,
392
- toB,
393
- inserted: inserted.toString()
394
- })));
395
- return changes2;
396
- }).filter(Boolean);
397
- if (changes.length) {
398
- import_log.log.info("changes", {
399
- changes
400
- }, {
401
- F: __dxlog_file,
402
- L: 62,
403
- S: void 0,
404
- C: (f, a) => f(...a)
545
+ ], `view-mode--${viewMode}`);
546
+ });
547
+ var createViewMode = (state) => {
548
+ const value = state.viewMode ?? "source";
549
+ const viewModeGroupAction = createViewModeGroupAction(value);
550
+ const viewModeActions = createViewModeActions(value);
551
+ return {
552
+ nodes: [
553
+ viewModeGroupAction,
554
+ ...viewModeActions
555
+ ],
556
+ edges: [
557
+ {
558
+ source: "root",
559
+ target: "viewMode"
560
+ },
561
+ ...viewModeActions.map(({ id }) => ({
562
+ source: viewModeGroupAction.id,
563
+ target: id
564
+ }))
565
+ ]
566
+ };
567
+ };
568
+ var stackItemContentEditorClassNames = (role) => (0, import_react_ui_theme2.mx)("dx-focus-ring-inset data-[toolbar=disabled]:pbs-2 attention-surface", role === "article" ? "min-bs-0" : "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24");
569
+ var stackItemContentToolbarClassNames = (role) => (0, import_react_ui_theme2.mx)("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
570
+ var createToolbar = ({ state, customActions, ...features }) => {
571
+ const nodes = [];
572
+ const edges = [];
573
+ if (features.headings ?? true) {
574
+ const headings2 = createHeadings(state);
575
+ nodes.push(...headings2.nodes);
576
+ edges.push(...headings2.edges);
577
+ }
578
+ if (features.formatting ?? true) {
579
+ const formatting = createFormatting(state);
580
+ nodes.push(...formatting.nodes);
581
+ edges.push(...formatting.edges);
582
+ }
583
+ if (features.lists ?? true) {
584
+ const lists = createLists(state);
585
+ nodes.push(...lists.nodes);
586
+ edges.push(...lists.edges);
587
+ }
588
+ if (features.blocks ?? true) {
589
+ const blocks = createBlocks(state);
590
+ nodes.push(...blocks.nodes);
591
+ edges.push(...blocks.edges);
592
+ }
593
+ if (customActions) {
594
+ const custom = customActions();
595
+ nodes.push(...custom.nodes);
596
+ edges.push(...custom.edges);
597
+ }
598
+ const editorToolbarGap = (0, import_react_ui_menu.createGapSeparator)();
599
+ nodes.push(...editorToolbarGap.nodes);
600
+ edges.push(...editorToolbarGap.edges);
601
+ if (features.comment ?? true) {
602
+ const comment = createComment(state);
603
+ nodes.push(...comment.nodes);
604
+ edges.push(...comment.edges);
605
+ }
606
+ if (features.search ?? true) {
607
+ nodes.push(editorToolbarSearch);
608
+ edges.push({
609
+ source: "root",
610
+ target: editorToolbarSearch.id
405
611
  });
406
612
  }
613
+ if (features.viewMode ?? true) {
614
+ const viewMode = createViewMode(state);
615
+ nodes.push(...viewMode.nodes);
616
+ edges.push(...viewMode.edges);
617
+ }
618
+ return {
619
+ nodes,
620
+ edges
621
+ };
407
622
  };
408
- var flattenRect = (rect, left) => {
409
- const x = left ? rect.left : rect.right;
623
+ var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
624
+ const menuCreator = (0, import_react.useCallback)(() => createToolbar(props), [
625
+ props
626
+ ]);
627
+ const { resolveGroupItems } = (0, import_react_ui_menu.useMenuActions)(menuCreator);
410
628
  return {
411
- left: x,
412
- right: x,
413
- top: rect.top,
414
- bottom: rect.bottom
629
+ resolveGroupItems,
630
+ onAction
415
631
  };
416
632
  };
417
- var scratchRange;
418
- var textRange = (node, from, to = from) => {
419
- const range = scratchRange || (scratchRange = document.createRange());
420
- range.setEnd(node, to);
421
- range.setStart(node, from);
422
- return range;
633
+ var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
634
+ const menuProps = useEditorToolbarActionGraph(props);
635
+ return /* @__PURE__ */ import_react.default.createElement("div", {
636
+ role: "none",
637
+ className: stackItemContentToolbarClassNames(role)
638
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.ElevationProvider, {
639
+ elevation: role === "section" ? "positioned" : "base"
640
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.MenuProvider, {
641
+ ...menuProps,
642
+ attendableId
643
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.ToolbarMenu, {
644
+ classNames: [
645
+ import_react_ui_theme.textBlockWidth,
646
+ "!bg-transparent",
647
+ classNames
648
+ ]
649
+ }))));
423
650
  };
424
- var clientRectsFor = (dom) => {
425
- if (dom.nodeType === 3) {
426
- return textRange(dom, 0, dom.nodeValue.length).getClientRects();
427
- } else if (dom.nodeType === 1) {
428
- return dom.getClientRects();
429
- } else {
430
- return [];
431
- }
651
+ var headings = {
652
+ 1: "text-4xl",
653
+ 2: "text-3xl",
654
+ 3: "text-2xl",
655
+ 4: "text-xl",
656
+ 5: "text-lg",
657
+ 6: ""
432
658
  };
433
- var createElement = (tag, options, children) => {
434
- const el = document.createElement(tag);
435
- if (options?.className) {
436
- el.className = options.className;
437
- }
438
- if (children) {
439
- el.append(...Array.isArray(children) ? children : [
440
- children
441
- ]);
659
+ var theme = {
660
+ code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
661
+ codeMark: "font-mono text-primary-500",
662
+ mark: "opacity-50",
663
+ heading: (level) => {
664
+ return (0, import_react_ui_theme4.mx)(headings[level], "dark:text-primary-400");
442
665
  }
443
- return el;
444
666
  };
445
- var renderRoot = (root, node) => {
446
- (0, import_client.createRoot)(root).render(/* @__PURE__ */ import_react3.default.createElement(import_react_ui2.ThemeProvider, {
447
- tx: import_react_ui_theme2.defaultTx
448
- }, node));
449
- return root;
667
+ var getToken = (path, defaultValue) => {
668
+ const value = (0, import_lodash.default)(import_react_ui_theme5.tokens, path, defaultValue);
669
+ return value?.toString() ?? "";
450
670
  };
451
- var annotationMark = import_view2.Decoration.mark({
452
- class: "cm-annotation"
453
- });
454
- var annotations = (options = {}) => {
455
- const match = (state) => {
456
- const annotations2 = [];
457
- const text = state.doc.toString();
458
- if (options.match) {
459
- const matches = text.matchAll(options.match);
460
- for (const match2 of matches) {
461
- const from = match2.index;
462
- const to = from + match2[0].length;
463
- const cursor = Cursor.getCursorFromRange(state, {
464
- from,
465
- to
466
- });
467
- annotations2.push({
468
- cursor
469
- });
470
- }
471
- }
472
- return annotations2;
473
- };
474
- const annotationsState = import_state2.StateField.define({
475
- create: (state) => {
476
- return match(state);
671
+ var fontBody = getToken("fontFamily.body");
672
+ var fontMono = getToken("fontFamily.mono");
673
+ var defaultTheme = {
674
+ "&": {},
675
+ "&.cm-focused": {
676
+ outline: "none"
677
+ },
678
+ /**
679
+ * Scroller
680
+ */
681
+ ".cm-scroller": {
682
+ overflowY: "auto"
683
+ },
684
+ /**
685
+ * Content
686
+ * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
687
+ */
688
+ ".cm-content": {
689
+ padding: "unset",
690
+ fontFamily: fontBody,
691
+ // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
692
+ fontSize: "16px",
693
+ lineHeight: 1.5,
694
+ color: "unset"
695
+ },
696
+ /**
697
+ * Gutters
698
+ * NOTE: Gutters should have the same top margin as the content.
699
+ * NOTE: They can't be transparent since the content needs to scroll below.
700
+ */
701
+ ".cm-gutters": {
702
+ background: "var(--surface-bg)",
703
+ borderRight: "none"
704
+ },
705
+ ".cm-gutter": {},
706
+ ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
707
+ minWidth: "40px",
708
+ alignContent: "center"
709
+ },
710
+ /**
711
+ * Height is set to match the corresponding line.
712
+ */
713
+ ".cm-gutterElement": {
714
+ alignItems: "center",
715
+ fontSize: "16px"
716
+ },
717
+ /**
718
+ * Line.
719
+ */
720
+ ".cm-line": {
721
+ paddingInline: 0
722
+ },
723
+ ".cm-activeLine": {
724
+ background: "var(--dx-cmActiveLine)"
725
+ },
726
+ /**
727
+ * Cursor (layer).
728
+ */
729
+ ".cm-cursor, .cm-dropCursor": {
730
+ borderLeft: "2px solid var(--dx-cmCursor)"
731
+ },
732
+ ".cm-placeholder": {
733
+ color: "var(--dx-subdued)"
734
+ },
735
+ /**
736
+ * Selection (layer).
737
+ */
738
+ ".cm-selectionBackground": {
739
+ background: "var(--dx-cmSelection)"
740
+ },
741
+ /**
742
+ * Search.
743
+ * NOTE: Matches comment.
744
+ */
745
+ ".cm-searchMatch": {
746
+ margin: "0 -3px",
747
+ padding: "3px",
748
+ borderRadius: "3px",
749
+ background: "var(--dx-cmHighlightSurface)",
750
+ color: "var(--dx-cmHighlight)"
751
+ },
752
+ ".cm-searchMatch-selected": {
753
+ textDecoration: "underline"
754
+ },
755
+ /**
756
+ * Link.
757
+ */
758
+ ".cm-link": {
759
+ textDecorationLine: "underline",
760
+ textDecorationThickness: "1px",
761
+ textUnderlineOffset: "2px",
762
+ borderRadius: ".125rem"
763
+ },
764
+ ".cm-link > span": {
765
+ color: "var(--dx-accentText)"
766
+ },
767
+ /**
768
+ * Tooltip.
769
+ */
770
+ ".cm-tooltip": {
771
+ background: "var(--dx-baseSurface)"
772
+ },
773
+ ".cm-tooltip-below": {},
774
+ /**
775
+ * Autocomplete.
776
+ * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
777
+ */
778
+ ".cm-tooltip.cm-tooltip-autocomplete": {
779
+ marginTop: "4px",
780
+ marginLeft: "-3px"
781
+ },
782
+ ".cm-tooltip.cm-tooltip-autocomplete > ul": {
783
+ maxHeight: "20em"
784
+ },
785
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
786
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
787
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
788
+ paddingLeft: "4px !important",
789
+ borderBottom: "none !important",
790
+ color: "var(--dx-accentText)"
791
+ },
792
+ ".cm-tooltip.cm-completionInfo": {
793
+ width: "360px !important",
794
+ margin: "-10px 1px 0 1px",
795
+ padding: "8px !important",
796
+ borderColor: "var(--dx-separator)"
797
+ },
798
+ ".cm-completionIcon": {
799
+ display: "none"
800
+ },
801
+ ".cm-completionLabel": {
802
+ fontFamily: fontBody
803
+ },
804
+ ".cm-completionMatchedText": {
805
+ textDecoration: "none !important",
806
+ opacity: 0.5
807
+ },
808
+ /**
809
+ * Panels
810
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
811
+ *
812
+ * Find/replace panel.
813
+ * <div class="cm-announced">...</div>
814
+ * <div class="cm-scroller">...</div>
815
+ * <div class="cm-panels cm-panels-bottom">
816
+ * <div class="cm-search cm-panel">
817
+ * <input class="cm-textfield" />
818
+ * <button class="cm-button">...</button>
819
+ * <label><input type="checkbox" />...</label>
820
+ * </div>
821
+ * </div
822
+ */
823
+ // TODO(burdon): Implement custom panel (with icon buttons).
824
+ ".cm-panels": {},
825
+ ".cm-panel": {
826
+ fontFamily: fontBody,
827
+ backgroundColor: "var(--surface-bg)"
828
+ },
829
+ ".cm-panel input, .cm-panel button, .cm-panel label": {
830
+ color: "var(--dx-subdued)",
831
+ fontFamily: fontBody,
832
+ fontSize: "14px",
833
+ all: "unset",
834
+ margin: "3px !important",
835
+ padding: "2px 6px !important",
836
+ outline: "1px solid transparent"
837
+ },
838
+ ".cm-panel input, .cm-panel button": {
839
+ backgroundColor: "var(--dx-input)"
840
+ },
841
+ ".cm-panel input:focus, .cm-panel button:focus": {
842
+ outline: "1px solid var(--dx-accentFocusIndicator)"
843
+ },
844
+ ".cm-panel label": {
845
+ display: "inline-flex",
846
+ alignItems: "center",
847
+ cursor: "pointer"
848
+ },
849
+ ".cm-panel input.cm-textfield": {},
850
+ ".cm-panel input[type=checkbox]": {
851
+ width: "8px",
852
+ height: "8px",
853
+ marginRight: "6px !important",
854
+ padding: "2px !important",
855
+ color: "var(--dx-accentFocusIndicator)"
856
+ },
857
+ ".cm-panel button": {
858
+ "&:hover": {
859
+ backgroundColor: "var(--dx-accentSurfaceHover) !important"
477
860
  },
478
- update: (value, tr) => {
479
- if (!tr.changes.empty) {
480
- return match(tr.state);
481
- }
482
- return value;
861
+ "&:active": {
862
+ backgroundColor: "var(--dx-accentSurfaceHover)"
483
863
  }
484
- });
485
- return [
486
- annotationsState,
487
- import_view2.EditorView.decorations.compute([
488
- annotationsState
489
- ], (state) => {
490
- const annotations2 = state.field(annotationsState);
491
- const decorations = annotations2.map((annotation) => {
492
- const range = Cursor.getRangeFromCursor(state, annotation.cursor);
493
- return range && annotationMark.range(range.from, range.to);
494
- }).filter(import_util.isNotFalsy);
495
- return import_view2.Decoration.set(decorations);
496
- }),
497
- styles
498
- ];
864
+ },
865
+ ".cm-panel.cm-search": {
866
+ padding: "4px",
867
+ borderTop: "1px solid var(--dx-separator)"
868
+ }
499
869
  };
500
- var styles = import_view2.EditorView.theme({
501
- ".cm-annotation": {
502
- textDecoration: "underline",
503
- textDecorationStyle: "wavy",
504
- textDecorationColor: "var(--dx-error)"
870
+ var margin = "!mt-[1rem]";
871
+ var editorContent = (0, import_react_ui_theme3.mx)(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
872
+ var editorFullWidth = (0, import_react_ui_theme3.mx)(margin);
873
+ var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
874
+ var editorGutter = import_view2.EditorView.theme({
875
+ // Match margin from content.
876
+ ".cm-gutters": {
877
+ marginTop: "16px",
878
+ paddingRight: "1rem"
505
879
  }
506
880
  });
507
- var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
508
- const extensions = [
509
- // https://codemirror.net/docs/ref/#view.keymap
510
- // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
511
- // TODO(burdon): Set custom keymap.
512
- import_view3.keymap.of(import_autocomplete.completionKeymap),
513
- // https://codemirror.net/examples/autocompletion
514
- // https://codemirror.net/docs/ref/#autocomplete.autocompletion
515
- (0, import_autocomplete.autocompletion)({
516
- activateOnTyping,
881
+ var editorMonospace = import_view2.EditorView.theme({
882
+ ".cm-content": {
883
+ fontFamily: fontMono
884
+ }
885
+ });
886
+ var singleValueFacet = (defaultValue) => import_state3.Facet.define({
887
+ // Called immediately.
888
+ combine: (providers) => {
889
+ return providers[0] ?? defaultValue;
890
+ }
891
+ });
892
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
893
+ var defaultCursorConverter = {
894
+ toCursor: (position) => position.toString(),
895
+ fromCursor: (cursor) => parseInt(cursor)
896
+ };
897
+ var Cursor = class _Cursor {
898
+ static {
899
+ this.converter = singleValueFacet(defaultCursorConverter);
900
+ }
901
+ static {
902
+ this.getCursorFromRange = (state, range) => {
903
+ const cursorConverter2 = state.facet(_Cursor.converter);
904
+ const from = cursorConverter2.toCursor(range.from);
905
+ const to = cursorConverter2.toCursor(range.to, -1);
906
+ return [
907
+ from,
908
+ to
909
+ ].join(":");
910
+ };
911
+ }
912
+ static {
913
+ this.getRangeFromCursor = (state, cursor) => {
914
+ const cursorConverter2 = state.facet(_Cursor.converter);
915
+ const parts = cursor.split(":");
916
+ const from = cursorConverter2.fromCursor(parts[0]);
917
+ const to = cursorConverter2.fromCursor(parts[1]);
918
+ return from !== void 0 && to !== void 0 ? {
919
+ from,
920
+ to
921
+ } : void 0;
922
+ };
923
+ }
924
+ };
925
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
926
+ var wrapWithCatch = (fn) => {
927
+ return (...args) => {
928
+ try {
929
+ return fn(...args);
930
+ } catch (err) {
931
+ import_log.log.catch(err, void 0, {
932
+ F: __dxlog_file,
933
+ L: 15,
934
+ S: void 0,
935
+ C: (f, a) => f(...a)
936
+ });
937
+ }
938
+ };
939
+ };
940
+ var callbackWrapper = (fn) => (...args) => {
941
+ try {
942
+ return fn(...args);
943
+ } catch (err) {
944
+ import_log.log.catch(err, void 0, {
945
+ F: __dxlog_file,
946
+ L: 29,
947
+ S: void 0,
948
+ C: (f, a) => f(...a)
949
+ });
950
+ }
951
+ };
952
+ var debugDispatcher = (trs, view) => {
953
+ logChanges(trs);
954
+ view.update(trs);
955
+ };
956
+ var logChanges = (trs) => {
957
+ const changes = trs.flatMap((tr) => {
958
+ if (tr.changes.empty) {
959
+ return void 0;
960
+ }
961
+ const changes2 = [];
962
+ tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
963
+ fromA,
964
+ toA,
965
+ fromB,
966
+ toB,
967
+ inserted: inserted.toString()
968
+ })));
969
+ return changes2;
970
+ }).filter(Boolean);
971
+ if (changes.length) {
972
+ import_log.log.info("changes", {
973
+ changes
974
+ }, {
975
+ F: __dxlog_file,
976
+ L: 62,
977
+ S: void 0,
978
+ C: (f, a) => f(...a)
979
+ });
980
+ }
981
+ };
982
+ var flattenRect = (rect, left) => {
983
+ const x = left ? rect.left : rect.right;
984
+ return {
985
+ left: x,
986
+ right: x,
987
+ top: rect.top,
988
+ bottom: rect.bottom
989
+ };
990
+ };
991
+ var scratchRange;
992
+ var textRange = (node, from, to = from) => {
993
+ const range = scratchRange || (scratchRange = document.createRange());
994
+ range.setEnd(node, to);
995
+ range.setStart(node, from);
996
+ return range;
997
+ };
998
+ var clientRectsFor = (dom) => {
999
+ if (dom.nodeType === 3) {
1000
+ return textRange(dom, 0, dom.nodeValue.length).getClientRects();
1001
+ } else if (dom.nodeType === 1) {
1002
+ return dom.getClientRects();
1003
+ } else {
1004
+ return [];
1005
+ }
1006
+ };
1007
+ var createElement = (tag, options, children) => {
1008
+ const el = document.createElement(tag);
1009
+ if (options?.className) {
1010
+ el.className = options.className;
1011
+ }
1012
+ if (children) {
1013
+ el.append(...Array.isArray(children) ? children : [
1014
+ children
1015
+ ]);
1016
+ }
1017
+ return el;
1018
+ };
1019
+ var renderRoot = (root, node) => {
1020
+ (0, import_client.createRoot)(root).render(/* @__PURE__ */ import_react3.default.createElement(import_react_ui2.ThemeProvider, {
1021
+ tx: import_react_ui_theme6.defaultTx
1022
+ }, node));
1023
+ return root;
1024
+ };
1025
+ var annotationMark = import_view3.Decoration.mark({
1026
+ class: "cm-annotation"
1027
+ });
1028
+ var annotations = (options = {}) => {
1029
+ const match = (state) => {
1030
+ const annotations2 = [];
1031
+ const text = state.doc.toString();
1032
+ if (options.match) {
1033
+ const matches = text.matchAll(options.match);
1034
+ for (const match2 of matches) {
1035
+ const from = match2.index;
1036
+ const to = from + match2[0].length;
1037
+ const cursor = Cursor.getCursorFromRange(state, {
1038
+ from,
1039
+ to
1040
+ });
1041
+ annotations2.push({
1042
+ cursor
1043
+ });
1044
+ }
1045
+ }
1046
+ return annotations2;
1047
+ };
1048
+ const annotationsState = import_state2.StateField.define({
1049
+ create: (state) => {
1050
+ return match(state);
1051
+ },
1052
+ update: (value, tr) => {
1053
+ if (!tr.changes.empty) {
1054
+ return match(tr.state);
1055
+ }
1056
+ return value;
1057
+ }
1058
+ });
1059
+ return [
1060
+ annotationsState,
1061
+ import_view3.EditorView.decorations.compute([
1062
+ annotationsState
1063
+ ], (state) => {
1064
+ const annotations2 = state.field(annotationsState);
1065
+ const decorations = annotations2.map((annotation) => {
1066
+ const range = Cursor.getRangeFromCursor(state, annotation.cursor);
1067
+ return range && annotationMark.range(range.from, range.to);
1068
+ }).filter(import_util.isNotFalsy);
1069
+ return import_view3.Decoration.set(decorations);
1070
+ }),
1071
+ styles
1072
+ ];
1073
+ };
1074
+ var styles = import_view3.EditorView.theme({
1075
+ ".cm-annotation": {
1076
+ textDecoration: "underline",
1077
+ textDecorationStyle: "wavy",
1078
+ textDecorationColor: "var(--dx-error)"
1079
+ }
1080
+ });
1081
+ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
1082
+ const extensions = [
1083
+ // https://codemirror.net/docs/ref/#view.keymap
1084
+ // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
1085
+ // TODO(burdon): Set custom keymap.
1086
+ import_view4.keymap.of(import_autocomplete.completionKeymap),
1087
+ // https://codemirror.net/examples/autocompletion
1088
+ // https://codemirror.net/docs/ref/#autocomplete.autocompletion
1089
+ (0, import_autocomplete.autocompletion)({
1090
+ activateOnTyping,
517
1091
  override,
518
1092
  closeOnBlur: !debug,
519
1093
  tooltipClass: () => "shadow rounded"
@@ -787,7 +1361,7 @@ var automerge = (accessor) => {
787
1361
  // Track heads.
788
1362
  syncState,
789
1363
  // Reconcile external updates.
790
- import_view4.ViewPlugin.fromClass(class {
1364
+ import_view5.ViewPlugin.fromClass(class {
791
1365
  constructor(_view) {
792
1366
  this._view = _view;
793
1367
  this._handleChange = () => {
@@ -800,7 +1374,7 @@ var automerge = (accessor) => {
800
1374
  }
801
1375
  }),
802
1376
  // Reconcile local updates.
803
- import_view4.EditorView.updateListener.of(({ view, changes }) => {
1377
+ import_view5.EditorView.updateListener.of(({ view, changes }) => {
804
1378
  if (!changes.empty) {
805
1379
  syncer.reconcile(view, true);
806
1380
  }
@@ -823,7 +1397,7 @@ var RemoteSelectionChangedAnnotation = import_state7.Annotation.define();
823
1397
  var awareness = (provider = dummyProvider) => {
824
1398
  return [
825
1399
  awarenessProvider.of(provider),
826
- import_view5.ViewPlugin.fromClass(RemoteSelectionsDecorator, {
1400
+ import_view6.ViewPlugin.fromClass(RemoteSelectionsDecorator, {
827
1401
  decorations: (value) => value.decorations
828
1402
  }),
829
1403
  styles2
@@ -887,7 +1461,7 @@ var RemoteSelectionsDecorator = class {
887
1461
  decorations.push({
888
1462
  from: start,
889
1463
  to: end,
890
- value: import_view5.Decoration.mark({
1464
+ value: import_view6.Decoration.mark({
891
1465
  attributes: {
892
1466
  style: `background-color: ${lightColor}`
893
1467
  },
@@ -898,7 +1472,7 @@ var RemoteSelectionsDecorator = class {
898
1472
  decorations.push({
899
1473
  from: start,
900
1474
  to: startLine.from + startLine.length,
901
- value: import_view5.Decoration.mark({
1475
+ value: import_view6.Decoration.mark({
902
1476
  attributes: {
903
1477
  style: `background-color: ${lightColor}`
904
1478
  },
@@ -908,7 +1482,7 @@ var RemoteSelectionsDecorator = class {
908
1482
  decorations.push({
909
1483
  from: endLine.from,
910
1484
  to: end,
911
- value: import_view5.Decoration.mark({
1485
+ value: import_view6.Decoration.mark({
912
1486
  attributes: {
913
1487
  style: `background-color: ${lightColor}`
914
1488
  },
@@ -920,7 +1494,7 @@ var RemoteSelectionsDecorator = class {
920
1494
  decorations.push({
921
1495
  from: linePos,
922
1496
  to: linePos,
923
- value: import_view5.Decoration.line({
1497
+ value: import_view6.Decoration.line({
924
1498
  attributes: {
925
1499
  style: `background-color: ${lightColor}`,
926
1500
  class: "cm-collab-selectionLine"
@@ -932,17 +1506,17 @@ var RemoteSelectionsDecorator = class {
932
1506
  decorations.push({
933
1507
  from: head,
934
1508
  to: head,
935
- value: import_view5.Decoration.widget({
1509
+ value: import_view6.Decoration.widget({
936
1510
  side: head - anchor > 0 ? -1 : 1,
937
1511
  block: false,
938
1512
  widget: new RemoteCaretWidget(state.info.displayName ?? "Anonymous", darkColor)
939
1513
  })
940
1514
  });
941
1515
  }
942
- this.decorations = import_view5.Decoration.set(decorations, true);
1516
+ this.decorations = import_view6.Decoration.set(decorations, true);
943
1517
  }
944
1518
  };
945
- var RemoteCaretWidget = class extends import_view5.WidgetType {
1519
+ var RemoteCaretWidget = class extends import_view6.WidgetType {
946
1520
  constructor(_name, _color) {
947
1521
  super();
948
1522
  this._name = _name;
@@ -978,7 +1552,7 @@ var RemoteCaretWidget = class extends import_view5.WidgetType {
978
1552
  return true;
979
1553
  }
980
1554
  };
981
- var styles2 = import_view5.EditorView.theme({
1555
+ var styles2 = import_view6.EditorView.theme({
982
1556
  ".cm-collab-selection": {},
983
1557
  ".cm-collab-selectionLine": {
984
1558
  padding: 0,
@@ -1181,12 +1755,12 @@ var blast = (options = defaultOptions) => {
1181
1755
  };
1182
1756
  return [
1183
1757
  // Cursor moved.
1184
- import_view6.EditorView.updateListener.of((update2) => {
1758
+ import_view7.EditorView.updateListener.of((update2) => {
1185
1759
  if (blaster?.node !== update2.view.scrollDOM) {
1186
1760
  if (blaster) {
1187
1761
  blaster.destroy();
1188
1762
  }
1189
- blaster = new Blaster(update2.view.scrollDOM, (0, import_lodash.default)({
1763
+ blaster = new Blaster(update2.view.scrollDOM, (0, import_lodash2.default)({
1190
1764
  particleGravity: 0.2,
1191
1765
  particleShrinkRate: 0.995,
1192
1766
  color: () => [
@@ -1212,7 +1786,7 @@ var blast = (options = defaultOptions) => {
1212
1786
  }
1213
1787
  }
1214
1788
  }),
1215
- import_view6.keymap.of([
1789
+ import_view7.keymap.of([
1216
1790
  {
1217
1791
  any: (_, event) => {
1218
1792
  if (blaster) {
@@ -1498,7 +2072,7 @@ var commandState = import_state9.StateField.define({
1498
2072
  return state;
1499
2073
  },
1500
2074
  provide: (field) => [
1501
- import_view9.showTooltip.from(field, (value) => value.tooltip ?? null)
2075
+ import_view10.showTooltip.from(field, (value) => value.tooltip ?? null)
1502
2076
  ]
1503
2077
  });
1504
2078
  var openEffect = import_state9.StateEffect.define();
@@ -1538,7 +2112,7 @@ var commandKeyBindings = [
1538
2112
  run: closeCommand
1539
2113
  }
1540
2114
  ];
1541
- var CommandHint = class extends import_view8.WidgetType {
2115
+ var CommandHint = class extends import_view9.WidgetType {
1542
2116
  constructor(content) {
1543
2117
  super();
1544
2118
  this.content = content;
@@ -1577,9 +2151,9 @@ var CommandHint = class extends import_view8.WidgetType {
1577
2151
  return false;
1578
2152
  }
1579
2153
  };
1580
- var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
2154
+ var hintViewPlugin = ({ onHint }) => import_view9.ViewPlugin.fromClass(class {
1581
2155
  constructor() {
1582
- this.deco = import_view8.Decoration.none;
2156
+ this.deco = import_view9.Decoration.none;
1583
2157
  }
1584
2158
  update(update2) {
1585
2159
  const builder = new import_state8.RangeSetBuilder();
@@ -1590,7 +2164,7 @@ var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
1590
2164
  if (selection.from === selection.to && line.from === line.to) {
1591
2165
  const hint = onHint();
1592
2166
  if (hint) {
1593
- builder.add(selection.from, selection.to, import_view8.Decoration.widget({
2167
+ builder.add(selection.from, selection.to, import_view9.Decoration.widget({
1594
2168
  widget: new CommandHint(hint)
1595
2169
  }));
1596
2170
  }
@@ -1600,16 +2174,16 @@ var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
1600
2174
  }
1601
2175
  }, {
1602
2176
  provide: (plugin) => [
1603
- import_view8.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view8.Decoration.none)
2177
+ import_view9.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view9.Decoration.none)
1604
2178
  ]
1605
2179
  });
1606
2180
  var command = (options) => {
1607
2181
  return [
1608
2182
  commandConfig.of(options),
1609
2183
  commandState,
1610
- import_view7.keymap.of(commandKeyBindings),
2184
+ import_view8.keymap.of(commandKeyBindings),
1611
2185
  hintViewPlugin(options),
1612
- import_view7.EditorView.focusChangeEffect.of((_, focusing) => {
2186
+ import_view8.EditorView.focusChangeEffect.of((_, focusing) => {
1613
2187
  return focusing ? closeEffect.of(null) : null;
1614
2188
  })
1615
2189
  ];
@@ -1621,7 +2195,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1621
2195
  return {
1622
2196
  selection,
1623
2197
  scrollIntoView: !scrollTo,
1624
- effects: scrollTo ? import_view11.EditorView.scrollIntoView(scrollTo, {
2198
+ effects: scrollTo ? import_view12.EditorView.scrollIntoView(scrollTo, {
1625
2199
  yMargin: 96
1626
2200
  }) : void 0,
1627
2201
  annotations: import_state11.Transaction.userEvent.of(stateRestoreAnnotation)
@@ -1663,7 +2237,7 @@ var selectionState = ({ getState, setState } = {}) => {
1663
2237
  // setStateDebounced(id, {});
1664
2238
  // },
1665
2239
  // }),
1666
- import_view11.EditorView.updateListener.of(({ view, transactions }) => {
2240
+ import_view12.EditorView.updateListener.of(({ view, transactions }) => {
1667
2241
  const id = view.state.facet(documentId);
1668
2242
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1669
2243
  return;
@@ -1686,7 +2260,7 @@ var selectionState = ({ getState, setState } = {}) => {
1686
2260
  }
1687
2261
  }
1688
2262
  }),
1689
- getState && import_view11.keymap.of([
2263
+ getState && import_view12.keymap.of([
1690
2264
  {
1691
2265
  key: "ctrl-r",
1692
2266
  run: (view) => {
@@ -1742,7 +2316,7 @@ var commentsState = import_state10.StateField.define({
1742
2316
  return value;
1743
2317
  }
1744
2318
  });
1745
- var styles3 = import_view10.EditorView.theme({
2319
+ var styles3 = import_view11.EditorView.theme({
1746
2320
  ".cm-comment, .cm-comment-current": {
1747
2321
  margin: "0 -3px",
1748
2322
  padding: "3px",
@@ -1755,23 +2329,23 @@ var styles3 = import_view10.EditorView.theme({
1755
2329
  textDecoration: "underline"
1756
2330
  }
1757
2331
  });
1758
- var createCommentMark = (id, isCurrent) => import_view10.Decoration.mark({
2332
+ var createCommentMark = (id, isCurrent) => import_view11.Decoration.mark({
1759
2333
  class: isCurrent ? "cm-comment-current" : "cm-comment",
1760
2334
  attributes: {
1761
2335
  "data-testid": "cm-comment",
1762
2336
  "data-comment-id": id
1763
2337
  }
1764
2338
  });
1765
- var commentsDecorations = import_view10.EditorView.decorations.compute([
2339
+ var commentsDecorations = import_view11.EditorView.decorations.compute([
1766
2340
  commentsState
1767
2341
  ], (state) => {
1768
2342
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
1769
- const decorations = (0, import_lodash2.default)(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
2343
+ const decorations = (0, import_lodash3.default)(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
1770
2344
  const range = comment.range;
1771
2345
  if (!range) {
1772
2346
  import_log4.log.warn("Invalid range:", range, {
1773
2347
  F: __dxlog_file7,
1774
- L: 142,
2348
+ L: 144,
1775
2349
  S: void 0,
1776
2350
  C: (f, a) => f(...a)
1777
2351
  });
@@ -1782,10 +2356,10 @@ var commentsDecorations = import_view10.EditorView.decorations.compute([
1782
2356
  const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
1783
2357
  return mark.range(range.from, range.to);
1784
2358
  }).filter(import_util2.nonNullable);
1785
- return import_view10.Decoration.set(decorations);
2359
+ return import_view11.Decoration.set(decorations);
1786
2360
  });
1787
2361
  var commentClickedEffect = import_state10.StateEffect.define();
1788
- var handleCommentClick = import_view10.EditorView.domEventHandlers({
2362
+ var handleCommentClick = import_view11.EditorView.domEventHandlers({
1789
2363
  click: (event, view) => {
1790
2364
  let target = event.target;
1791
2365
  const editorRoot = view.dom;
@@ -1824,7 +2398,7 @@ var trackPastedComments = (onUpdate) => {
1824
2398
  }
1825
2399
  };
1826
2400
  return [
1827
- import_view10.EditorView.domEventHandlers({
2401
+ import_view11.EditorView.domEventHandlers({
1828
2402
  cut: handleTrack,
1829
2403
  copy: handleTrack
1830
2404
  }),
@@ -1846,7 +2420,7 @@ var trackPastedComments = (onUpdate) => {
1846
2420
  return effects;
1847
2421
  }),
1848
2422
  // Handle paste or the undo of comment deletion.
1849
- import_view10.EditorView.updateListener.of((update2) => {
2423
+ import_view11.EditorView.updateListener.of((update2) => {
1850
2424
  const restore = [];
1851
2425
  for (let i = 0; i < update2.transactions.length; i++) {
1852
2426
  const tr = update2.transactions[i];
@@ -1905,7 +2479,7 @@ var mapTrackedComment = (comment, changes) => ({
1905
2479
  var restoreCommentEffect = import_state10.StateEffect.define({
1906
2480
  map: mapTrackedComment
1907
2481
  });
1908
- var createComment = (view) => {
2482
+ var createComment2 = (view) => {
1909
2483
  const options = view.state.facet(optionsFacet);
1910
2484
  const { from, to } = view.state.selection.main;
1911
2485
  if (from === to) {
@@ -1947,17 +2521,17 @@ var comments = (options = {}) => {
1947
2521
  //
1948
2522
  // Keymap.
1949
2523
  //
1950
- options.onCreate && import_view10.keymap.of([
2524
+ options.onCreate && import_view11.keymap.of([
1951
2525
  {
1952
2526
  key: shortcut,
1953
- run: callbackWrapper(createComment)
2527
+ run: callbackWrapper(createComment2)
1954
2528
  }
1955
2529
  ]),
1956
2530
  //
1957
2531
  // Hover tooltip (for key shortcut hints, etc.)
1958
2532
  // TODO(burdon): Factor out to generic hints extension for current selection/line.
1959
2533
  //
1960
- options.onHover && (0, import_view10.hoverTooltip)((view, pos) => {
2534
+ options.onHover && (0, import_view11.hoverTooltip)((view, pos) => {
1961
2535
  const selection = view.state.selection.main;
1962
2536
  if (selection && pos >= selection.from && pos <= selection.to) {
1963
2537
  return {
@@ -1986,7 +2560,7 @@ var comments = (options = {}) => {
1986
2560
  //
1987
2561
  // Track deleted ranges and update ranges for decorations.
1988
2562
  //
1989
- import_view10.EditorView.updateListener.of(({ view, state, changes }) => {
2563
+ import_view11.EditorView.updateListener.of(({ view, state, changes }) => {
1990
2564
  let mod = false;
1991
2565
  const { comments: comments2, ...value } = state.field(commentsState);
1992
2566
  changes.iterChanges((from, to, from2, to2) => {
@@ -2018,7 +2592,7 @@ var comments = (options = {}) => {
2018
2592
  //
2019
2593
  // Track selection/proximity.
2020
2594
  //
2021
- import_view10.EditorView.updateListener.of(({ view, state }) => {
2595
+ import_view11.EditorView.updateListener.of(({ view, state }) => {
2022
2596
  let min = Infinity;
2023
2597
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2024
2598
  const { head } = state.selection.main;
@@ -2048,414 +2622,187 @@ var comments = (options = {}) => {
2048
2622
  range,
2049
2623
  location: view.coordsAtPos(range.from)
2050
2624
  }))
2051
- });
2052
- }
2053
- }),
2054
- options.onUpdate && trackPastedComments(options.onUpdate)
2055
- ].filter(import_util2.nonNullable);
2056
- };
2057
- var scrollThreadIntoView = (view, id, center = true) => {
2058
- const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
2059
- if (!comment?.comment.cursor) {
2060
- return;
2061
- }
2062
- const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
2063
- if (range) {
2064
- const currentSelection = view.state.selection.main;
2065
- const currentScrollPosition = view.scrollDOM.scrollTop;
2066
- const targetScrollPosition = view.coordsAtPos(range.from)?.top;
2067
- const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
2068
- const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
2069
- if (needsScroll || needsSelectionUpdate) {
2070
- view.dispatch({
2071
- selection: needsSelectionUpdate ? {
2072
- anchor: range.from
2073
- } : void 0,
2074
- effects: [
2075
- needsScroll ? import_view10.EditorView.scrollIntoView(range.from, center ? {
2076
- y: "center"
2077
- } : void 0) : [],
2078
- needsSelectionUpdate ? setSelection.of({
2079
- current: id
2080
- }) : []
2081
- ].flat()
2082
- });
2083
- }
2084
- }
2085
- };
2086
- var selectionOverlapsComment = (state) => {
2087
- const commentState = state.field(commentsState, false);
2088
- if (commentState === void 0) {
2089
- return false;
2090
- }
2091
- const { selection } = state;
2092
- for (const range of selection.ranges) {
2093
- if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
2094
- return true;
2095
- }
2096
- }
2097
- return false;
2098
- };
2099
- var hasActiveSelection = (state) => {
2100
- return state.selection.ranges.some((range) => !range.empty);
2101
- };
2102
- var ExternalCommentSync = class {
2103
- constructor(view, id, subscribe, getComments) {
2104
- this.destroy = () => {
2105
- this.unsubscribe();
2106
- };
2107
- const updateComments = () => {
2108
- const comments2 = getComments();
2109
- if (id === view.state.facet(documentId)) {
2110
- queueMicrotask(() => view.dispatch({
2111
- effects: setComments.of({
2112
- id,
2113
- comments: comments2
2114
- })
2115
- }));
2116
- }
2117
- };
2118
- this.unsubscribe = subscribe(updateComments);
2119
- }
2120
- };
2121
- var createExternalCommentSync = (id, subscribe, getComments) => import_view10.ViewPlugin.fromClass(class {
2122
- constructor(view) {
2123
- return new ExternalCommentSync(view, id, subscribe, getComments);
2124
- }
2125
- });
2126
- var useCommentState = () => {
2127
- const [state, setState] = (0, import_react4.useState)({
2128
- comment: false,
2129
- selection: false
2130
- });
2131
- const observer = (0, import_react4.useMemo)(() => import_view10.EditorView.updateListener.of((update2) => {
2132
- if (update2.docChanged || update2.selectionSet) {
2133
- setState({
2134
- comment: selectionOverlapsComment(update2.state),
2135
- selection: hasActiveSelection(update2.state)
2136
- });
2137
- }
2138
- }), []);
2139
- return [
2140
- state,
2141
- observer
2142
- ];
2143
- };
2144
- var useComments = (view, id, comments2) => {
2145
- (0, import_react4.useEffect)(() => {
2146
- if (view) {
2147
- if (id === view.state.facet(documentId)) {
2148
- view.dispatch({
2149
- effects: setComments.of({
2150
- id,
2151
- comments: comments2 ?? []
2152
- })
2153
- });
2154
- }
2155
- }
2156
- });
2157
- };
2158
- var useCommentClickListener = (onCommentClick) => {
2159
- return (0, import_react4.useMemo)(() => import_view10.EditorView.updateListener.of((update2) => {
2160
- update2.transactions.forEach((transaction) => {
2161
- transaction.effects.forEach((effect) => {
2162
- if (effect.is(commentClickedEffect)) {
2163
- onCommentClick(effect.value);
2164
- }
2165
- });
2166
- });
2167
- }), [
2168
- onCommentClick
2169
- ]);
2170
- };
2171
- var debugNodeLogger = (log8 = console.log) => {
2172
- const logTokens = (state) => (0, import_language.syntaxTree)(state).iterate({
2173
- enter: (node) => log8(node.type)
2174
- });
2175
- return import_state12.StateField.define({
2176
- create: (state) => logTokens(state),
2177
- update: (_, tr) => logTokens(tr.state)
2178
- });
2179
- };
2180
- var styles4 = import_view12.EditorView.theme({
2181
- ".cm-dropCursor": {
2182
- borderLeft: "2px solid var(--dx-accentText)",
2183
- color: "var(--dx-accentText)",
2184
- padding: "0 4px"
2185
- },
2186
- ".cm-dropCursor:after": {
2187
- content: '"\u2190"'
2188
- }
2189
- });
2190
- var dropFile = (options = {}) => {
2191
- return [
2192
- styles4,
2193
- (0, import_view12.dropCursor)(),
2194
- import_view12.EditorView.domEventHandlers({
2195
- drop: (event, view) => {
2196
- event.preventDefault();
2197
- const files = event.dataTransfer?.files;
2198
- const pos = view.posAtCoords(event);
2199
- if (files?.length && pos !== null) {
2200
- view.dispatch({
2201
- selection: {
2202
- anchor: pos
2203
- }
2204
- });
2205
- options.onDrop?.(view, {
2206
- files
2207
- });
2208
- }
2209
- }
2210
- })
2211
- ];
2212
- };
2213
- var focusEffect = import_state14.StateEffect.define();
2214
- var focusField = import_state14.StateField.define({
2215
- create: () => false,
2216
- update: (value, tr) => {
2217
- for (const effect of tr.effects) {
2218
- if (effect.is(focusEffect)) {
2219
- return effect.value;
2220
- }
2221
- }
2222
- return value;
2223
- }
2224
- });
2225
- var focus = [
2226
- focusField,
2227
- import_view14.EditorView.domEventHandlers({
2228
- focus: (event, view) => {
2229
- setTimeout(() => view.dispatch({
2230
- effects: focusEffect.of(true)
2231
- }));
2232
- },
2233
- blur: (event, view) => {
2234
- setTimeout(() => view.dispatch({
2235
- effects: focusEffect.of(false)
2236
- }));
2237
- }
2238
- })
2239
- ];
2240
- var headings = {
2241
- 1: "text-4xl",
2242
- 2: "text-3xl",
2243
- 3: "text-2xl",
2244
- 4: "text-xl",
2245
- 5: "text-lg",
2246
- 6: "text-md"
2247
- };
2248
- var theme = {
2249
- code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
2250
- codeMark: "font-mono text-primary-500",
2251
- mark: "opacity-50",
2252
- heading: (level) => {
2253
- return (0, import_react_ui_theme4.mx)(headings[level], "dark:text-primary-400");
2254
- }
2255
- };
2256
- var getToken = (path, defaultValue) => {
2257
- const value = (0, import_lodash5.default)(import_react_ui_theme5.tokens, path, defaultValue);
2258
- return value?.toString() ?? "";
2259
- };
2260
- var fontBody = getToken("fontFamily.body");
2261
- var fontMono = getToken("fontFamily.mono");
2262
- var defaultTheme = {
2263
- "&": {},
2264
- "&.cm-focused": {
2265
- outline: "none"
2266
- },
2267
- /**
2268
- * Scroller
2269
- */
2270
- ".cm-scroller": {
2271
- overflowY: "auto"
2272
- },
2273
- /**
2274
- * Content
2275
- * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
2276
- */
2277
- ".cm-content": {
2278
- padding: "unset",
2279
- fontFamily: fontBody,
2280
- // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
2281
- fontSize: "16px",
2282
- lineHeight: 1.5,
2283
- color: "unset"
2284
- },
2285
- /**
2286
- * Gutters
2287
- * NOTE: Gutters should have the same top margin as the content.
2288
- * NOTE: They can't be transparent since the content needs to scroll below.
2289
- */
2290
- ".cm-gutters": {
2291
- background: "var(--surface-bg)",
2292
- borderRight: "none"
2293
- },
2294
- ".cm-gutter": {},
2295
- ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2296
- minWidth: "40px",
2297
- alignContent: "center"
2298
- },
2299
- /**
2300
- * Height is set to match the corresponding line.
2301
- */
2302
- ".cm-gutterElement": {
2303
- alignItems: "center",
2304
- fontSize: "16px"
2305
- },
2306
- /**
2307
- * Line.
2308
- */
2309
- ".cm-line": {
2310
- paddingInline: 0
2311
- },
2312
- ".cm-activeLine": {
2313
- background: "var(--dx-cmActiveLine)"
2314
- },
2315
- /**
2316
- * Cursor (layer).
2317
- */
2318
- ".cm-cursor, .cm-dropCursor": {
2319
- borderLeft: "2px solid var(--dx-cmCursor)"
2320
- },
2321
- ".cm-placeholder": {
2322
- color: "var(--dx-subdued)"
2323
- },
2324
- /**
2325
- * Selection (layer).
2326
- */
2327
- ".cm-selectionBackground": {
2328
- background: "var(--dx-cmSelection)"
2329
- },
2330
- /**
2331
- * Search.
2332
- * NOTE: Matches comment.
2333
- */
2334
- ".cm-searchMatch": {
2335
- margin: "0 -3px",
2336
- padding: "3px",
2337
- borderRadius: "3px",
2338
- background: "var(--dx-cmHighlightSurface)",
2339
- color: "var(--dx-cmHighlight)"
2340
- },
2341
- ".cm-searchMatch-selected": {
2342
- textDecoration: "underline"
2343
- },
2344
- /**
2345
- * Link.
2346
- */
2347
- ".cm-link": {
2348
- textDecorationLine: "underline",
2349
- textDecorationThickness: "1px",
2350
- textUnderlineOffset: "2px",
2351
- borderRadius: ".125rem"
2352
- },
2353
- ".cm-link > span": {
2354
- color: "var(--dx-accentText)"
2355
- },
2356
- /**
2357
- * Tooltip.
2358
- */
2359
- ".cm-tooltip": {
2360
- background: "var(--dx-base)"
2361
- },
2362
- ".cm-tooltip-below": {},
2363
- /**
2364
- * Autocomplete.
2365
- * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
2366
- */
2367
- ".cm-tooltip.cm-tooltip-autocomplete": {
2368
- marginTop: "4px",
2369
- marginLeft: "-3px"
2370
- },
2371
- ".cm-tooltip.cm-tooltip-autocomplete > ul": {
2372
- maxHeight: "20em"
2373
- },
2374
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
2375
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
2376
- ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2377
- paddingLeft: "4px !important",
2378
- borderBottom: "none !important",
2379
- color: "var(--dx-accentText)"
2380
- },
2381
- ".cm-tooltip.cm-completionInfo": {
2382
- width: "360px !important",
2383
- margin: "-10px 1px 0 1px",
2384
- padding: "8px !important",
2385
- borderColor: "var(--dx-separator)"
2386
- },
2387
- ".cm-completionIcon": {
2388
- display: "none"
2389
- },
2390
- ".cm-completionLabel": {
2391
- fontFamily: fontBody
2392
- },
2393
- ".cm-completionMatchedText": {
2394
- textDecoration: "none !important",
2395
- opacity: 0.5
2396
- },
2397
- /**
2398
- * Panels
2399
- * https://github.com/codemirror/search/blob/main/src/search.ts#L745
2400
- *
2401
- * Find/replace panel.
2402
- * <div class="cm-announced">...</div>
2403
- * <div class="cm-scroller">...</div>
2404
- * <div class="cm-panels cm-panels-bottom">
2405
- * <div class="cm-search cm-panel">
2406
- * <input class="cm-textfield" />
2407
- * <button class="cm-button">...</button>
2408
- * <label><input type="checkbox" />...</label>
2409
- * </div>
2410
- * </div
2411
- */
2412
- // TODO(burdon): Implement custom panel (with icon buttons).
2413
- ".cm-panels": {},
2414
- ".cm-panel": {
2415
- fontFamily: fontBody,
2416
- backgroundColor: "var(--surface-bg)"
2417
- },
2418
- ".cm-panel input, .cm-panel button, .cm-panel label": {
2419
- color: "var(--dx-subdued)",
2420
- fontFamily: fontBody,
2421
- fontSize: "14px",
2422
- all: "unset",
2423
- margin: "3px !important",
2424
- padding: "2px 6px !important",
2425
- outline: "1px solid transparent"
2426
- },
2427
- ".cm-panel input, .cm-panel button": {
2428
- backgroundColor: "var(--dx-input)"
2429
- },
2430
- ".cm-panel input:focus, .cm-panel button:focus": {
2431
- outline: "1px solid var(--dx-accentFocusIndicator)"
2432
- },
2433
- ".cm-panel label": {
2434
- display: "inline-flex",
2435
- alignItems: "center",
2436
- cursor: "pointer"
2437
- },
2438
- ".cm-panel input.cm-textfield": {},
2439
- ".cm-panel input[type=checkbox]": {
2440
- width: "8px",
2441
- height: "8px",
2442
- marginRight: "6px !important",
2443
- padding: "2px !important",
2444
- color: "var(--dx-accentFocusIndicator)"
2445
- },
2446
- ".cm-panel button": {
2447
- "&:hover": {
2448
- backgroundColor: "var(--dx-accentSurfaceHover) !important"
2449
- },
2450
- "&:active": {
2451
- backgroundColor: "var(--dx-accentSurfaceHover)"
2625
+ });
2626
+ }
2627
+ }),
2628
+ options.onUpdate && trackPastedComments(options.onUpdate)
2629
+ ].filter(import_util2.nonNullable);
2630
+ };
2631
+ var scrollThreadIntoView = (view, id, center = true) => {
2632
+ const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
2633
+ if (!comment?.comment.cursor) {
2634
+ return;
2635
+ }
2636
+ const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
2637
+ if (range) {
2638
+ const currentSelection = view.state.selection.main;
2639
+ const currentScrollPosition = view.scrollDOM.scrollTop;
2640
+ const targetScrollPosition = view.coordsAtPos(range.from)?.top;
2641
+ const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
2642
+ const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
2643
+ if (needsScroll || needsSelectionUpdate) {
2644
+ view.dispatch({
2645
+ selection: needsSelectionUpdate ? {
2646
+ anchor: range.from
2647
+ } : void 0,
2648
+ effects: [
2649
+ needsScroll ? import_view11.EditorView.scrollIntoView(range.from, center ? {
2650
+ y: "center"
2651
+ } : void 0) : [],
2652
+ needsSelectionUpdate ? setSelection.of({
2653
+ current: id
2654
+ }) : []
2655
+ ].flat()
2656
+ });
2657
+ }
2658
+ }
2659
+ };
2660
+ var selectionOverlapsComment = (state) => {
2661
+ const commentState = state.field(commentsState, false);
2662
+ if (commentState === void 0) {
2663
+ return false;
2664
+ }
2665
+ const { selection } = state;
2666
+ for (const range of selection.ranges) {
2667
+ if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
2668
+ return true;
2669
+ }
2670
+ }
2671
+ return false;
2672
+ };
2673
+ var hasActiveSelection = (state) => {
2674
+ return state.selection.ranges.some((range) => !range.empty);
2675
+ };
2676
+ var ExternalCommentSync = class {
2677
+ constructor(view, id, subscribe, getComments) {
2678
+ this.destroy = () => {
2679
+ this.unsubscribe();
2680
+ };
2681
+ const updateComments = () => {
2682
+ const comments2 = getComments();
2683
+ if (id === view.state.facet(documentId)) {
2684
+ queueMicrotask(() => view.dispatch({
2685
+ effects: setComments.of({
2686
+ id,
2687
+ comments: comments2
2688
+ })
2689
+ }));
2690
+ }
2691
+ };
2692
+ this.unsubscribe = subscribe(updateComments);
2693
+ }
2694
+ };
2695
+ var createExternalCommentSync = (id, subscribe, getComments) => import_view11.ViewPlugin.fromClass(class {
2696
+ constructor(view) {
2697
+ return new ExternalCommentSync(view, id, subscribe, getComments);
2698
+ }
2699
+ });
2700
+ var useCommentState = (state) => {
2701
+ return (0, import_react4.useMemo)(() => import_view11.EditorView.updateListener.of((update2) => {
2702
+ if (update2.docChanged || update2.selectionSet) {
2703
+ state.comment = selectionOverlapsComment(update2.state);
2704
+ state.selection = hasActiveSelection(update2.state);
2705
+ }
2706
+ }), [
2707
+ state
2708
+ ]);
2709
+ };
2710
+ var useComments = (view, id, comments2) => {
2711
+ (0, import_react4.useEffect)(() => {
2712
+ if (view) {
2713
+ if (id === view.state.facet(documentId)) {
2714
+ view.dispatch({
2715
+ effects: setComments.of({
2716
+ id,
2717
+ comments: comments2 ?? []
2718
+ })
2719
+ });
2720
+ }
2452
2721
  }
2722
+ });
2723
+ };
2724
+ var useCommentClickListener = (onCommentClick) => {
2725
+ return (0, import_react4.useMemo)(() => import_view11.EditorView.updateListener.of((update2) => {
2726
+ update2.transactions.forEach((transaction) => {
2727
+ transaction.effects.forEach((effect) => {
2728
+ if (effect.is(commentClickedEffect)) {
2729
+ onCommentClick(effect.value);
2730
+ }
2731
+ });
2732
+ });
2733
+ }), [
2734
+ onCommentClick
2735
+ ]);
2736
+ };
2737
+ var debugNodeLogger = (log8 = console.log) => {
2738
+ const logTokens = (state) => (0, import_language.syntaxTree)(state).iterate({
2739
+ enter: (node) => log8(node.type)
2740
+ });
2741
+ return import_state12.StateField.define({
2742
+ create: (state) => logTokens(state),
2743
+ update: (_, tr) => logTokens(tr.state)
2744
+ });
2745
+ };
2746
+ var styles4 = import_view13.EditorView.theme({
2747
+ ".cm-dropCursor": {
2748
+ borderLeft: "2px solid var(--dx-accentText)",
2749
+ color: "var(--dx-accentText)",
2750
+ padding: "0 4px"
2453
2751
  },
2454
- ".cm-panel.cm-search": {
2455
- padding: "4px",
2456
- borderTop: "1px solid var(--dx-separator)"
2752
+ ".cm-dropCursor:after": {
2753
+ content: '"\u2190"'
2457
2754
  }
2755
+ });
2756
+ var dropFile = (options = {}) => {
2757
+ return [
2758
+ styles4,
2759
+ (0, import_view13.dropCursor)(),
2760
+ import_view13.EditorView.domEventHandlers({
2761
+ drop: (event, view) => {
2762
+ event.preventDefault();
2763
+ const files = event.dataTransfer?.files;
2764
+ const pos = view.posAtCoords(event);
2765
+ if (files?.length && pos !== null) {
2766
+ view.dispatch({
2767
+ selection: {
2768
+ anchor: pos
2769
+ }
2770
+ });
2771
+ options.onDrop?.(view, {
2772
+ files
2773
+ });
2774
+ }
2775
+ }
2776
+ })
2777
+ ];
2458
2778
  };
2779
+ var focusEffect = import_state14.StateEffect.define();
2780
+ var focusField = import_state14.StateField.define({
2781
+ create: () => false,
2782
+ update: (value, tr) => {
2783
+ for (const effect of tr.effects) {
2784
+ if (effect.is(focusEffect)) {
2785
+ return effect.value;
2786
+ }
2787
+ }
2788
+ return value;
2789
+ }
2790
+ });
2791
+ var focus = [
2792
+ focusField,
2793
+ import_view15.EditorView.domEventHandlers({
2794
+ focus: (event, view) => {
2795
+ setTimeout(() => view.dispatch({
2796
+ effects: focusEffect.of(true)
2797
+ }));
2798
+ },
2799
+ blur: (event, view) => {
2800
+ setTimeout(() => view.dispatch({
2801
+ effects: focusEffect.of(false)
2802
+ }));
2803
+ }
2804
+ })
2805
+ ];
2459
2806
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2460
2807
  var preventNewline = import_state13.EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
2461
2808
  var defaultBasicOptions = {
@@ -2477,10 +2824,10 @@ var keymaps = {
2477
2824
  default: import_commands2.defaultKeymap
2478
2825
  };
2479
2826
  var createBasicExtensions = (_props) => {
2480
- const props = (0, import_lodash3.default)({}, _props, defaultBasicOptions);
2827
+ const props = (0, import_lodash4.default)({}, _props, defaultBasicOptions);
2481
2828
  return [
2482
2829
  // NOTE: Doesn't catch errors in keymap functions.
2483
- import_view13.EditorView.exceptionSink.of((err) => {
2830
+ import_view14.EditorView.exceptionSink.of((err) => {
2484
2831
  import_log5.log.catch(err, void 0, {
2485
2832
  F: __dxlog_file8,
2486
2833
  L: 96,
@@ -2491,24 +2838,24 @@ var createBasicExtensions = (_props) => {
2491
2838
  props.allowMultipleSelections && import_state13.EditorState.allowMultipleSelections.of(true),
2492
2839
  props.bracketMatching && (0, import_language2.bracketMatching)(),
2493
2840
  props.closeBrackets && (0, import_autocomplete2.closeBrackets)(),
2494
- props.dropCursor && (0, import_view13.dropCursor)(),
2495
- props.drawSelection && (0, import_view13.drawSelection)({
2841
+ props.dropCursor && (0, import_view14.dropCursor)(),
2842
+ props.drawSelection && (0, import_view14.drawSelection)({
2496
2843
  cursorBlinkRate: 1200
2497
2844
  }),
2498
2845
  props.focus && focus,
2499
- props.highlightActiveLine && (0, import_view13.highlightActiveLine)(),
2846
+ props.highlightActiveLine && (0, import_view14.highlightActiveLine)(),
2500
2847
  props.history && (0, import_commands2.history)(),
2501
- props.lineNumbers && (0, import_view13.lineNumbers)(),
2502
- props.lineWrapping && import_view13.EditorView.lineWrapping,
2503
- props.placeholder && (0, import_view13.placeholder)(props.placeholder),
2848
+ props.lineNumbers && (0, import_view14.lineNumbers)(),
2849
+ props.lineWrapping && import_view14.EditorView.lineWrapping,
2850
+ props.placeholder && (0, import_view14.placeholder)(props.placeholder),
2504
2851
  props.readonly && [
2505
2852
  import_state13.EditorState.readOnly.of(true),
2506
- import_view13.EditorView.editable.of(false)
2853
+ import_view14.EditorView.editable.of(false)
2507
2854
  ],
2508
- props.scrollPastEnd && (0, import_view13.scrollPastEnd)(),
2855
+ props.scrollPastEnd && (0, import_view14.scrollPastEnd)(),
2509
2856
  props.tabSize && import_state13.EditorState.tabSize.of(props.tabSize),
2510
2857
  // https://codemirror.net/docs/ref/#view.KeyBinding
2511
- import_view13.keymap.of([
2858
+ import_view14.keymap.of([
2512
2859
  ...(props.keymap && keymaps[props.keymap]) ?? [],
2513
2860
  // NOTE: Tabs are also configured by markdown extension.
2514
2861
  // https://codemirror.net/docs/ref/#commands.indentWithTab
@@ -2530,16 +2877,16 @@ var defaultThemeSlots = {
2530
2877
  }
2531
2878
  };
2532
2879
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2533
- const slots = (0, import_lodash3.default)({}, _slots, defaultThemeSlots);
2880
+ const slots = (0, import_lodash4.default)({}, _slots, defaultThemeSlots);
2534
2881
  return [
2535
- import_view13.EditorView.darkTheme.of(themeMode === "dark"),
2536
- import_view13.EditorView.baseTheme(styles5 ? (0, import_lodash4.default)({}, defaultTheme, styles5) : defaultTheme),
2882
+ import_view14.EditorView.darkTheme.of(themeMode === "dark"),
2883
+ import_view14.EditorView.baseTheme(styles5 ? (0, import_lodash5.default)({}, defaultTheme, styles5) : defaultTheme),
2537
2884
  // https://github.com/codemirror/theme-one-dark
2538
2885
  _syntaxHighlighting && (themeMode === "dark" ? (0, import_language2.syntaxHighlighting)(import_theme_one_dark.oneDarkHighlightStyle) : (0, import_language2.syntaxHighlighting)(import_language2.defaultHighlightStyle)),
2539
- slots.editor?.className && import_view13.EditorView.editorAttributes.of({
2886
+ slots.editor?.className && import_view14.EditorView.editorAttributes.of({
2540
2887
  class: slots.editor.className
2541
2888
  }),
2542
- slots.content?.className && import_view13.EditorView.contentAttributes.of({
2889
+ slots.content?.className && import_view14.EditorView.contentAttributes.of({
2543
2890
  class: slots.content.className
2544
2891
  })
2545
2892
  ].filter(import_util4.isNotFalsy);
@@ -2551,7 +2898,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2551
2898
  }
2552
2899
  if (space && identity) {
2553
2900
  const peerId = identity?.identityKey.toHex();
2554
- const { cursorLightValue, cursorDarkValue } = import_react_ui_theme3.hueTokens[identity?.profile?.data?.hue ?? (0, import_util4.hexToHue)(peerId ?? "0")];
2901
+ const { cursorLightValue, cursorDarkValue } = import_react_ui_theme7.hueTokens[identity?.profile?.data?.hue ?? (0, import_util4.hexToHue)(peerId ?? "0")];
2555
2902
  extensions.push(awareness(new SpaceAwarenessProvider({
2556
2903
  space,
2557
2904
  channel: `awareness.${id}`,
@@ -2586,7 +2933,7 @@ var folding = (_props = {}) => [
2586
2933
  }));
2587
2934
  }
2588
2935
  }),
2589
- import_view15.EditorView.theme({
2936
+ import_view16.EditorView.theme({
2590
2937
  ".cm-foldGutter": {
2591
2938
  opacity: 0.3,
2592
2939
  transition: "opacity 0.3s",
@@ -2599,11 +2946,11 @@ var folding = (_props = {}) => [
2599
2946
  ];
2600
2947
  var listener = ({ onFocus, onChange }) => {
2601
2948
  const extensions = [];
2602
- onFocus && extensions.push(import_view16.EditorView.focusChangeEffect.of((_, focusing) => {
2949
+ onFocus && extensions.push(import_view17.EditorView.focusChangeEffect.of((_, focusing) => {
2603
2950
  onFocus(focusing);
2604
2951
  return null;
2605
2952
  }));
2606
- onChange && extensions.push(import_view16.EditorView.updateListener.of((update2) => {
2953
+ onChange && extensions.push(import_view17.EditorView.updateListener.of((update2) => {
2607
2954
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
2608
2955
  }));
2609
2956
  return extensions;
@@ -3494,7 +3841,7 @@ var toggleCodeblock = (target) => {
3494
3841
  };
3495
3842
  var formattingKeymap = (_options = {}) => {
3496
3843
  return [
3497
- import_view17.keymap.of([
3844
+ import_view18.keymap.of([
3498
3845
  {
3499
3846
  key: "meta-b",
3500
3847
  run: toggleStrong
@@ -3694,63 +4041,54 @@ var getFormatting = (state) => {
3694
4041
  listStyle: listStyle || null
3695
4042
  };
3696
4043
  };
3697
- var useFormattingState = () => {
3698
- const [state, setState] = (0, import_react6.useState)();
3699
- const observer = (0, import_react6.useMemo)(() => import_view17.EditorView.updateListener.of((update2) => {
4044
+ var useFormattingState = (state) => {
4045
+ return (0, import_react6.useMemo)(() => import_view18.EditorView.updateListener.of((update2) => {
3700
4046
  if (update2.docChanged || update2.selectionSet) {
3701
- setState((prevState) => {
3702
- const newState = getFormatting(update2.state);
3703
- if (!prevState || !formattingEquals(prevState, newState)) {
3704
- return newState;
3705
- }
3706
- return prevState;
4047
+ Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
4048
+ state[key] = active;
3707
4049
  });
3708
4050
  }
3709
4051
  }), []);
3710
- return [
3711
- state,
3712
- observer
3713
- ];
3714
4052
  };
3715
- var processAction = (view, action) => {
4053
+ var processEditorPayload = (view, { type, data }) => {
3716
4054
  let inlineType, listType;
3717
- switch (action.type) {
4055
+ switch (type) {
3718
4056
  case "heading":
3719
- setHeading(parseInt(action.data))(view);
4057
+ setHeading(parseInt(data))(view);
3720
4058
  break;
3721
4059
  case "strong":
3722
4060
  case "emphasis":
3723
4061
  case "strikethrough":
3724
4062
  case "code":
3725
- inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
3726
- (typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
4063
+ inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
4064
+ (typeof data === "boolean" ? setStyle(inlineType, data) : toggleStyle(inlineType))(view);
3727
4065
  break;
3728
4066
  case "list-ordered":
3729
4067
  case "list-bullet":
3730
4068
  case "list-task":
3731
- listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
3732
- (action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
4069
+ listType = type === "list-ordered" ? List.Ordered : type === "list-bullet" ? List.Bullet : List.Task;
4070
+ (data === false ? removeList(listType) : data === true ? addList(listType) : toggleList(listType))(view);
3733
4071
  break;
3734
4072
  case "blockquote":
3735
- (action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
4073
+ (data === false ? removeBlockquote : data === true ? addBlockquote : toggleBlockquote)(view);
3736
4074
  break;
3737
4075
  case "codeblock":
3738
- (action.data === false ? removeCodeblock : addCodeblock)(view);
4076
+ (data === false ? removeCodeblock : addCodeblock)(view);
3739
4077
  break;
3740
4078
  case "table":
3741
4079
  insertTable(view);
3742
4080
  break;
3743
4081
  case "link":
3744
- (action.data === false ? removeLink : addLink())(view);
4082
+ (data === false ? removeLink : addLink())(view);
3745
4083
  break;
3746
4084
  case "image":
3747
4085
  addLink({
3748
- url: action.data,
4086
+ url: data,
3749
4087
  image: true
3750
4088
  })(view);
3751
4089
  break;
3752
4090
  case "comment":
3753
- createComment(view);
4091
+ createComment2(view);
3754
4092
  break;
3755
4093
  }
3756
4094
  requestAnimationFrame(() => {
@@ -3956,7 +4294,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3956
4294
  }),
3957
4295
  // Custom styles.
3958
4296
  (0, import_language5.syntaxHighlighting)(markdownHighlightStyle()),
3959
- import_view18.keymap.of([
4297
+ import_view19.keymap.of([
3960
4298
  // https://codemirror.net/docs/ref/#commands.indentWithTab
3961
4299
  import_commands3.indentWithTab,
3962
4300
  // https://codemirror.net/docs/ref/#commands.defaultKeymap
@@ -3990,7 +4328,7 @@ var convertTreeToJson = (state) => {
3990
4328
  return treeToJson((0, import_language7.syntaxTree)(state).cursor());
3991
4329
  };
3992
4330
  var adjustChanges = () => {
3993
- return import_view20.ViewPlugin.fromClass(class {
4331
+ return import_view21.ViewPlugin.fromClass(class {
3994
4332
  update(update2) {
3995
4333
  const tree = (0, import_language9.syntaxTree)(update2.state);
3996
4334
  const adjustments = [];
@@ -4132,7 +4470,7 @@ var image = (_options = {}) => {
4132
4470
  return [
4133
4471
  import_state19.StateField.define({
4134
4472
  create: (state) => {
4135
- return import_view21.Decoration.set(buildDecorations(0, state.doc.length, state));
4473
+ return import_view22.Decoration.set(buildDecorations(0, state.doc.length, state));
4136
4474
  },
4137
4475
  update: (value, tr) => {
4138
4476
  if (!tr.docChanged && !tr.selection) {
@@ -4155,7 +4493,7 @@ var image = (_options = {}) => {
4155
4493
  add: buildDecorations(from, to, tr.state)
4156
4494
  });
4157
4495
  },
4158
- provide: (field) => import_view21.EditorView.decorations.from(field)
4496
+ provide: (field) => import_view22.EditorView.decorations.from(field)
4159
4497
  })
4160
4498
  ];
4161
4499
  };
@@ -4181,7 +4519,7 @@ var buildDecorations = (from, to, state) => {
4181
4519
  return;
4182
4520
  }
4183
4521
  preloadImage(url);
4184
- decorations.push(import_view21.Decoration.replace({
4522
+ decorations.push(import_view22.Decoration.replace({
4185
4523
  block: true,
4186
4524
  widget: new ImageWidget(url)
4187
4525
  }).range(hide2 ? node.from : node.to, node.to));
@@ -4193,7 +4531,7 @@ var buildDecorations = (from, to, state) => {
4193
4531
  });
4194
4532
  return decorations;
4195
4533
  };
4196
- var ImageWidget = class extends import_view21.WidgetType {
4534
+ var ImageWidget = class extends import_view22.WidgetType {
4197
4535
  constructor(_url) {
4198
4536
  super();
4199
4537
  this._url = _url;
@@ -4215,7 +4553,7 @@ var ImageWidget = class extends import_view21.WidgetType {
4215
4553
  };
4216
4554
  var bulletListIndentationWidth = 24;
4217
4555
  var orderedListIndentationWidth = 36;
4218
- var formattingStyles = import_view22.EditorView.theme({
4556
+ var formattingStyles = import_view23.EditorView.theme({
4219
4557
  /**
4220
4558
  * Horizontal rule.
4221
4559
  */
@@ -4309,13 +4647,34 @@ var formattingStyles = import_view22.EditorView.theme({
4309
4647
  height: "auto",
4310
4648
  borderTop: "0.5rem solid transparent",
4311
4649
  borderBottom: "0.5rem solid transparent"
4650
+ },
4651
+ ".cm-image-with-loader": {
4652
+ display: "block",
4653
+ opacity: "0",
4654
+ transitionDuration: "350ms",
4655
+ transitionProperty: "opacity"
4656
+ },
4657
+ ".cm-image-with-loader.cm-loaded-image": {
4658
+ opacity: "1"
4659
+ },
4660
+ ".cm-image-wrapper": {
4661
+ "grid-template-columns": "1fr",
4662
+ display: "grid",
4663
+ margin: "0.5rem 0",
4664
+ overflow: "hidden",
4665
+ transitionDuration: "350ms",
4666
+ transitionProperty: "height",
4667
+ "& > *": {
4668
+ "grid-row-start": 1,
4669
+ "grid-column-start": 1
4670
+ }
4312
4671
  }
4313
4672
  });
4314
4673
  var table = (options = {}) => {
4315
4674
  return import_state20.StateField.define({
4316
4675
  create: (state) => update(state, options),
4317
4676
  update: (_, tr) => update(tr.state, options),
4318
- provide: (field) => import_view23.EditorView.decorations.from(field)
4677
+ provide: (field) => import_view24.EditorView.decorations.from(field)
4319
4678
  });
4320
4679
  };
4321
4680
  var update = (state, _options) => {
@@ -4360,19 +4719,19 @@ var update = (state, _options) => {
4360
4719
  tables.forEach((table2) => {
4361
4720
  const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4362
4721
  if (replace) {
4363
- builder.add(table2.from, table2.to, import_view23.Decoration.replace({
4722
+ builder.add(table2.from, table2.to, import_view24.Decoration.replace({
4364
4723
  block: true,
4365
4724
  widget: new TableWidget(table2)
4366
4725
  }));
4367
4726
  } else {
4368
- builder.add(table2.from, table2.to, import_view23.Decoration.mark({
4727
+ builder.add(table2.from, table2.to, import_view24.Decoration.mark({
4369
4728
  class: "cm-table"
4370
4729
  }));
4371
4730
  }
4372
4731
  });
4373
4732
  return builder.finish();
4374
4733
  };
4375
- var TableWidget = class extends import_view23.WidgetType {
4734
+ var TableWidget = class extends import_view24.WidgetType {
4376
4735
  constructor(_table) {
4377
4736
  super();
4378
4737
  this._table = _table;
@@ -4412,14 +4771,14 @@ var Unicode = {
4412
4771
  bulletSmall: "\u2219",
4413
4772
  bulletSquare: "\u2B1D"
4414
4773
  };
4415
- var HorizontalRuleWidget = class extends import_view19.WidgetType {
4774
+ var HorizontalRuleWidget = class extends import_view20.WidgetType {
4416
4775
  toDOM() {
4417
4776
  const el = document.createElement("span");
4418
4777
  el.className = "cm-hr";
4419
4778
  return el;
4420
4779
  }
4421
4780
  };
4422
- var LinkButton = class extends import_view19.WidgetType {
4781
+ var LinkButton = class extends import_view20.WidgetType {
4423
4782
  constructor(url, render) {
4424
4783
  super();
4425
4784
  this.url = url;
@@ -4435,7 +4794,7 @@ var LinkButton = class extends import_view19.WidgetType {
4435
4794
  return el;
4436
4795
  }
4437
4796
  };
4438
- var CheckboxWidget = class extends import_view19.WidgetType {
4797
+ var CheckboxWidget = class extends import_view20.WidgetType {
4439
4798
  constructor(_checked) {
4440
4799
  super();
4441
4800
  this._checked = _checked;
@@ -4445,7 +4804,7 @@ var CheckboxWidget = class extends import_view19.WidgetType {
4445
4804
  }
4446
4805
  toDOM(view) {
4447
4806
  const input = document.createElement("input");
4448
- input.className = "cm-task-checkbox ch-checkbox";
4807
+ input.className = "cm-task-checkbox dx-checkbox";
4449
4808
  input.type = "checkbox";
4450
4809
  input.tabIndex = -1;
4451
4810
  input.checked = this._checked;
@@ -4480,7 +4839,7 @@ var CheckboxWidget = class extends import_view19.WidgetType {
4480
4839
  return false;
4481
4840
  }
4482
4841
  };
4483
- var TextWidget = class extends import_view19.WidgetType {
4842
+ var TextWidget = class extends import_view20.WidgetType {
4484
4843
  constructor(text, className) {
4485
4844
  super();
4486
4845
  this.text = text;
@@ -4495,29 +4854,29 @@ var TextWidget = class extends import_view19.WidgetType {
4495
4854
  return el;
4496
4855
  }
4497
4856
  };
4498
- var hide = import_view19.Decoration.replace({});
4499
- var blockQuote = import_view19.Decoration.line({
4500
- class: (0, import_react_ui_theme6.mx)("cm-blockquote")
4857
+ var hide = import_view20.Decoration.replace({});
4858
+ var blockQuote = import_view20.Decoration.line({
4859
+ class: (0, import_react_ui_theme8.mx)("cm-blockquote")
4501
4860
  });
4502
- var fencedCodeLine = import_view19.Decoration.line({
4503
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line")
4861
+ var fencedCodeLine = import_view20.Decoration.line({
4862
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line")
4504
4863
  });
4505
- var fencedCodeLineFirst = import_view19.Decoration.line({
4506
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line", "cm-codeblock-first")
4864
+ var fencedCodeLineFirst = import_view20.Decoration.line({
4865
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line", "cm-codeblock-first")
4507
4866
  });
4508
- var fencedCodeLineLast = import_view19.Decoration.line({
4509
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line", "cm-codeblock-last")
4867
+ var fencedCodeLineLast = import_view20.Decoration.line({
4868
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line", "cm-codeblock-last")
4510
4869
  });
4511
4870
  var commentBlockLine = fencedCodeLine;
4512
4871
  var commentBlockLineFirst = fencedCodeLineFirst;
4513
4872
  var commentBlockLineLast = fencedCodeLineLast;
4514
- var horizontalRule = import_view19.Decoration.replace({
4873
+ var horizontalRule = import_view20.Decoration.replace({
4515
4874
  widget: new HorizontalRuleWidget()
4516
4875
  });
4517
- var checkedTask = import_view19.Decoration.replace({
4876
+ var checkedTask = import_view20.Decoration.replace({
4518
4877
  widget: new CheckboxWidget(true)
4519
4878
  });
4520
- var uncheckedTask = import_view19.Decoration.replace({
4879
+ var uncheckedTask = import_view20.Decoration.replace({
4521
4880
  widget: new CheckboxWidget(false)
4522
4881
  });
4523
4882
  var editingRange = (state, range, focus2) => {
@@ -4618,7 +4977,7 @@ var buildDecorations2 = (view, options, focus2) => {
4618
4977
  } else {
4619
4978
  const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
4620
4979
  if (num.length) {
4621
- atomicDeco.add(mark.from, mark.from + len, import_view19.Decoration.replace({
4980
+ atomicDeco.add(mark.from, mark.from + len, import_view20.Decoration.replace({
4622
4981
  widget: new TextWidget(num, theme.heading(level))
4623
4982
  }));
4624
4983
  }
@@ -4643,7 +5002,7 @@ var buildDecorations2 = (view, options, focus2) => {
4643
5002
  if (node.from === line.to - 1) {
4644
5003
  return false;
4645
5004
  }
4646
- deco.add(line.from, line.from, import_view19.Decoration.line({
5005
+ deco.add(line.from, line.from, import_view20.Decoration.line({
4647
5006
  class: "cm-list-item",
4648
5007
  attributes: {
4649
5008
  style: `padding-left: ${offset}px; text-indent: -${width}px;`
@@ -4660,7 +5019,7 @@ var buildDecorations2 = (view, options, focus2) => {
4660
5019
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
4661
5020
  const line = state.doc.lineAt(node.from);
4662
5021
  const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4663
- atomicDeco.add(line.from, to, import_view19.Decoration.replace({
5022
+ atomicDeco.add(line.from, to, import_view20.Decoration.replace({
4664
5023
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
4665
5024
  }));
4666
5025
  break;
@@ -4747,7 +5106,7 @@ var buildDecorations2 = (view, options, focus2) => {
4747
5106
  if (!editing) {
4748
5107
  atomicDeco.add(node.from, marks[0].to, hide);
4749
5108
  }
4750
- deco.add(marks[0].to, marks[1].from, import_view19.Decoration.mark({
5109
+ deco.add(marks[0].to, marks[1].from, import_view20.Decoration.mark({
4751
5110
  tagName: "a",
4752
5111
  attributes: {
4753
5112
  class: "cm-link",
@@ -4757,7 +5116,7 @@ var buildDecorations2 = (view, options, focus2) => {
4757
5116
  }
4758
5117
  }));
4759
5118
  if (!editing) {
4760
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? import_view19.Decoration.replace({
5119
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? import_view20.Decoration.replace({
4761
5120
  widget: new LinkButton(url, options.renderLinkButton)
4762
5121
  }) : hide);
4763
5122
  }
@@ -4815,7 +5174,7 @@ var buildDecorations2 = (view, options, focus2) => {
4815
5174
  var forceUpdate = import_state17.StateEffect.define();
4816
5175
  var decorateMarkdown = (options = {}) => {
4817
5176
  return [
4818
- import_view19.ViewPlugin.fromClass(class {
5177
+ import_view20.ViewPlugin.fromClass(class {
4819
5178
  constructor(view) {
4820
5179
  ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
4821
5180
  }
@@ -4847,9 +5206,9 @@ var decorateMarkdown = (options = {}) => {
4847
5206
  }
4848
5207
  }, {
4849
5208
  provide: (plugin) => [
4850
- import_view19.EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view19.Decoration.none),
4851
- import_view19.EditorView.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view19.Decoration.none),
4852
- import_view19.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view19.Decoration.none)
5209
+ import_view20.EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view20.Decoration.none),
5210
+ import_view20.EditorView.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view20.Decoration.none),
5211
+ import_view20.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view20.Decoration.none)
4853
5212
  ]
4854
5213
  }),
4855
5214
  image(),
@@ -4859,7 +5218,7 @@ var decorateMarkdown = (options = {}) => {
4859
5218
  ];
4860
5219
  };
4861
5220
  var linkTooltip = (render) => {
4862
- return (0, import_view24.hoverTooltip)((view, pos, side) => {
5221
+ return (0, import_view25.hoverTooltip)((view, pos, side) => {
4863
5222
  const syntax = (0, import_language12.syntaxTree)(view.state).resolveInner(pos, side);
4864
5223
  let link = null;
4865
5224
  for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
@@ -4876,7 +5235,7 @@ var linkTooltip = (render) => {
4876
5235
  above: true,
4877
5236
  create: () => {
4878
5237
  const el = document.createElement("div");
4879
- el.className = (0, import_react_ui_theme7.tooltipContent)({}, "pli-2 plb-1");
5238
+ el.className = (0, import_react_ui_theme9.tooltipContent)({}, "pli-2 plb-1");
4880
5239
  render(el, urlText);
4881
5240
  return {
4882
5241
  dom: el,
@@ -4943,7 +5302,7 @@ var InputModeExtensions = {
4943
5302
  editorInputMode.of({
4944
5303
  type: "vscode"
4945
5304
  }),
4946
- import_view25.keymap.of(import_codemirror_vscode_keymap.vscodeKeymap)
5305
+ import_view26.keymap.of(import_codemirror_vscode_keymap.vscodeKeymap)
4947
5306
  ],
4948
5307
  vim: [
4949
5308
  // https://github.com/replit/codemirror-vim
@@ -4952,7 +5311,7 @@ var InputModeExtensions = {
4952
5311
  type: "vim",
4953
5312
  noTabster: true
4954
5313
  }),
4955
- import_view25.keymap.of([
5314
+ import_view26.keymap.of([
4956
5315
  {
4957
5316
  key: "Alt-Escape",
4958
5317
  run: (view) => {
@@ -4972,7 +5331,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4972
5331
  let t;
4973
5332
  let idx = 0;
4974
5333
  return [
4975
- import_view26.keymap.of([
5334
+ import_view27.keymap.of([
4976
5335
  {
4977
5336
  // Reset.
4978
5337
  key: "alt-meta-'",
@@ -5017,413 +5376,19 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
5017
5376
  ])
5018
5377
  ];
5019
5378
  };
5020
- var iconStyles = (0, import_react_ui_theme.getSize)(5);
5021
- var buttonStyles = "min-bs-0 p-1";
5022
- var tooltipProps = {
5023
- side: "top",
5024
- classNames: "z-10"
5025
- };
5026
- var ToolbarSeparator = () => /* @__PURE__ */ import_react2.default.createElement("div", {
5027
- role: "separator",
5028
- className: "grow"
5029
- });
5030
- var [ToolbarContextProvider, useToolbarContext] = (0, import_react_context.createContext)("Toolbar");
5031
- var ToolbarRoot = ({ children, onAction, classNames, state }) => {
5032
- return /* @__PURE__ */ import_react2.default.createElement(ToolbarContextProvider, {
5033
- onAction,
5034
- state
5035
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ElevationProvider, {
5036
- elevation: "positioned"
5037
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.Root, {
5038
- classNames: [
5039
- "p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden",
5040
- classNames
5041
- ],
5042
- style: {
5043
- contain: "layout"
5044
- }
5045
- }, children)));
5046
- };
5047
- var ToolbarToggleButton = ({ Icon: Icon2, children, ...props }) => {
5048
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Root, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Trigger, {
5049
- asChild: true
5050
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.ToggleGroupItem, {
5051
- variant: "ghost",
5052
- ...props,
5053
- classNames: buttonStyles
5054
- }, /* @__PURE__ */ import_react2.default.createElement(Icon2, {
5055
- className: iconStyles
5056
- }), /* @__PURE__ */ import_react2.default.createElement("span", {
5057
- className: "sr-only"
5058
- }, children))), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Portal, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Content, tooltipProps, children, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Arrow, null))));
5059
- };
5060
- var ToolbarButton = ({ Icon: Icon2, children, ...props }) => {
5061
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Root, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Trigger, {
5062
- asChild: true
5063
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.Button, {
5064
- variant: "ghost",
5065
- ...props,
5066
- classNames: buttonStyles
5067
- }, /* @__PURE__ */ import_react2.default.createElement(Icon2, {
5068
- className: iconStyles
5069
- }), /* @__PURE__ */ import_react2.default.createElement("span", {
5070
- className: "sr-only"
5071
- }, children))), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Portal, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Content, tooltipProps, children, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Arrow, null))));
5072
- };
5073
- var HeadingIcons = {
5074
- "0": import_react.Paragraph,
5075
- "1": import_react.TextHOne,
5076
- "2": import_react.TextHTwo,
5077
- "3": import_react.TextHThree,
5078
- "4": import_react.TextHFour,
5079
- "5": import_react.TextHFive,
5080
- "6": import_react.TextHSix
5081
- };
5082
- var MarkdownHeading = () => {
5083
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5084
- const { onAction, state } = useToolbarContext("MarkdownFormatting");
5085
- const blockType = state ? state.blockType : "paragraph";
5086
- const header = blockType && /heading(\d)/.exec(blockType);
5087
- const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
5088
- const HeadingIcon = HeadingIcons[value ?? "0"];
5089
- const suppressNextTooltip = (0, import_react2.useRef)(false);
5090
- const [tooltipOpen, setTooltipOpen] = (0, import_react2.useState)(false);
5091
- const [selectOpen, setSelectOpen] = (0, import_react2.useState)(false);
5092
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Root, {
5093
- open: tooltipOpen,
5094
- onOpenChange: (nextOpen) => {
5095
- if (nextOpen && suppressNextTooltip.current) {
5096
- suppressNextTooltip.current = false;
5097
- return setTooltipOpen(false);
5098
- } else {
5099
- return setTooltipOpen(nextOpen);
5100
- }
5101
- }
5102
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Root, {
5103
- open: selectOpen,
5104
- onOpenChange: (nextOpen) => {
5105
- if (!nextOpen) {
5106
- suppressNextTooltip.current = true;
5107
- }
5108
- return setSelectOpen(nextOpen);
5109
- }
5110
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Trigger, {
5111
- asChild: true
5112
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.Button, {
5113
- asChild: true
5114
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Trigger, {
5115
- asChild: true
5116
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Button, {
5117
- variant: "ghost",
5118
- classNames: buttonStyles,
5119
- disabled: value === null
5120
- }, /* @__PURE__ */ import_react2.default.createElement("span", {
5121
- className: "sr-only"
5122
- }, t("heading label")), /* @__PURE__ */ import_react2.default.createElement(HeadingIcon, {
5123
- className: iconStyles
5124
- }), /* @__PURE__ */ import_react2.default.createElement(import_react.CaretDown, null))))), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Portal, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Content, {
5125
- classNames: "is-min md:is-min",
5126
- onCloseAutoFocus: (e) => e.preventDefault()
5127
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
5128
- const Icon2 = HeadingIcons[level];
5129
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.CheckboxItem, {
5130
- key: level,
5131
- checked: value === level,
5132
- onClick: () => onAction?.({
5133
- type: "heading",
5134
- data: level
5135
- })
5136
- }, /* @__PURE__ */ import_react2.default.createElement("span", {
5137
- className: "sr-only"
5138
- }, t("heading level label", {
5139
- count: parseInt(level)
5140
- })), /* @__PURE__ */ import_react2.default.createElement(Icon2, {
5141
- className: iconStyles
5142
- }), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.ItemIndicator, null, /* @__PURE__ */ import_react2.default.createElement(import_react.Check, null)));
5143
- })), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Arrow, null)))), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Portal, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Arrow, null))));
5144
- };
5145
- var markdownStyles = [
5146
- {
5147
- type: "strong",
5148
- Icon: import_react.TextB,
5149
- getState: (state) => !!state?.strong
5150
- },
5151
- {
5152
- type: "emphasis",
5153
- Icon: import_react.TextItalic,
5154
- getState: (state) => !!state?.emphasis
5155
- },
5156
- {
5157
- type: "strikethrough",
5158
- Icon: import_react.TextStrikethrough,
5159
- getState: (state) => !!state?.strikethrough
5160
- },
5161
- {
5162
- type: "code",
5163
- Icon: import_react.Code,
5164
- getState: (state) => !!state?.code
5165
- },
5166
- {
5167
- type: "link",
5168
- Icon: import_react.Link,
5169
- getState: (state) => !!state?.link
5170
- }
5171
- ];
5172
- var MarkdownStyles = () => {
5173
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5174
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5175
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.ToggleGroup, {
5176
- type: "multiple",
5177
- value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
5178
- }, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react2.default.createElement(ToolbarToggleButton, {
5179
- key: type,
5180
- value: type,
5181
- Icon: Icon2,
5182
- disabled: state?.blockType === "codeblock",
5183
- onClick: state ? () => onAction?.({
5184
- type,
5185
- data: !getState(state)
5186
- }) : void 0
5187
- }, t(`${type} label`))));
5188
- };
5189
- var markdownLists = [
5190
- {
5191
- type: "list-bullet",
5192
- Icon: import_react.ListBullets,
5193
- getState: (state) => state.listStyle === "bullet"
5194
- },
5195
- {
5196
- type: "list-ordered",
5197
- Icon: import_react.ListNumbers,
5198
- getState: (state) => state.listStyle === "ordered"
5199
- },
5200
- {
5201
- type: "list-task",
5202
- Icon: import_react.ListChecks,
5203
- getState: (state) => state.listStyle === "task"
5204
- }
5205
- ];
5206
- var MarkdownLists = () => {
5207
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5208
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5209
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.ToggleGroup, {
5210
- type: "single",
5211
- value: state?.listStyle ? `list-${state.listStyle}` : ""
5212
- }, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react2.default.createElement(ToolbarToggleButton, {
5213
- key: type,
5214
- value: type,
5215
- Icon: Icon2,
5216
- onClick: state ? () => onAction?.({
5217
- type,
5218
- data: !getState(state)
5219
- }) : void 0
5220
- }, t(`${type} label`))));
5221
- };
5222
- var markdownBlocks = [
5223
- {
5224
- type: "blockquote",
5225
- Icon: import_react.Quotes,
5226
- getState: (state) => !!state?.blockQuote
5227
- },
5228
- {
5229
- type: "codeblock",
5230
- Icon: import_react.CodeBlock,
5231
- getState: (state) => state.blockType === "codeblock"
5232
- },
5233
- {
5234
- type: "table",
5235
- Icon: import_react.Table,
5236
- getState: (state) => state.blockType === "tablecell",
5237
- disabled: (state) => !state.blankLine
5238
- }
5239
- ];
5240
- var MarkdownBlocks = () => {
5241
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5242
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5243
- const value = markdownBlocks.find(({ getState }) => state && getState(state));
5244
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.ToggleGroup, {
5245
- type: "single",
5246
- value: value?.type ?? ""
5247
- }, markdownBlocks.map(({ type, disabled, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react2.default.createElement(ToolbarToggleButton, {
5248
- key: type,
5249
- value: type,
5250
- Icon: Icon2,
5251
- disabled: !state || disabled?.(state),
5252
- onClick: state ? () => onAction?.({
5253
- type,
5254
- data: !getState(state)
5255
- }) : void 0
5256
- }, t(`${type} label`))));
5257
- };
5258
- var MarkdownStandard = () => /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(MarkdownHeading, null), /* @__PURE__ */ import_react2.default.createElement(MarkdownStyles, null), /* @__PURE__ */ import_react2.default.createElement(MarkdownLists, null), /* @__PURE__ */ import_react2.default.createElement(MarkdownBlocks, null));
5259
- var MarkdownCustom = ({ onUpload } = {}) => {
5260
- const { onAction } = useToolbarContext("MarkdownStyles");
5261
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5262
- const { acceptedFiles, getInputProps, open } = (0, import_react_dropzone.useDropzone)({
5263
- multiple: false,
5264
- noDrag: true,
5265
- accept: {
5266
- "image/*": [
5267
- ".jpg",
5268
- ".jpeg",
5269
- ".png",
5270
- ".gif"
5271
- ]
5272
- }
5273
- });
5274
- (0, import_react2.useEffect)(() => {
5275
- if (onUpload && acceptedFiles.length) {
5276
- requestAnimationFrame(async () => {
5277
- const f = acceptedFiles[0];
5278
- const file = new File([
5279
- f
5280
- ], f.name, {
5281
- type: f.type,
5282
- lastModified: f.lastModified
5283
- });
5284
- const info = await onUpload(file);
5285
- if (info) {
5286
- onAction?.({
5287
- type: "image",
5288
- data: info.url
5289
- });
5290
- }
5291
- });
5292
- }
5293
- }, [
5294
- acceptedFiles
5295
- ]);
5296
- return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("input", getInputProps()), /* @__PURE__ */ import_react2.default.createElement(ToolbarButton, {
5297
- value: "image",
5298
- Icon: import_react.Image,
5299
- onClick: () => open()
5300
- }, t("image label")));
5301
- };
5302
- var ViewModeIcons = {
5303
- preview: import_react.PencilSimple,
5304
- readonly: import_react.PencilSimpleSlash,
5305
- source: import_react.MarkdownLogo
5306
- };
5307
- var MarkdownView = ({ mode }) => {
5308
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5309
- const { onAction } = useToolbarContext("ViewMode");
5310
- const ModeIcon = ViewModeIcons[mode ?? "preview"];
5311
- const suppressNextTooltip = (0, import_react2.useRef)(false);
5312
- const [tooltipOpen, setTooltipOpen] = (0, import_react2.useState)(false);
5313
- const [selectOpen, setSelectOpen] = (0, import_react2.useState)(false);
5314
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Root, {
5315
- open: tooltipOpen,
5316
- onOpenChange: (nextOpen) => {
5317
- if (nextOpen && suppressNextTooltip.current) {
5318
- suppressNextTooltip.current = false;
5319
- return setTooltipOpen(false);
5320
- } else {
5321
- return setTooltipOpen(nextOpen);
5322
- }
5323
- }
5324
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Root, {
5325
- open: selectOpen,
5326
- onOpenChange: (nextOpen) => {
5327
- if (!nextOpen) {
5328
- suppressNextTooltip.current = true;
5329
- }
5330
- return setSelectOpen(nextOpen);
5331
- }
5332
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Trigger, {
5333
- asChild: true
5334
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.Button, {
5335
- asChild: true
5336
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Trigger, {
5337
- asChild: true
5338
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Button, {
5339
- variant: "ghost",
5340
- classNames: buttonStyles
5341
- }, /* @__PURE__ */ import_react2.default.createElement("span", {
5342
- className: "sr-only"
5343
- }, t("mode label")), /* @__PURE__ */ import_react2.default.createElement(ModeIcon, {
5344
- className: iconStyles
5345
- }), /* @__PURE__ */ import_react2.default.createElement(import_react.CaretDown, null))))), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Portal, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Content, {
5346
- classNames: "is-min md:is-min",
5347
- onCloseAutoFocus: (e) => e.preventDefault()
5348
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
5349
- const Icon2 = ViewModeIcons[value];
5350
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.CheckboxItem, {
5351
- key: value,
5352
- checked: value === mode,
5353
- onClick: () => onAction?.({
5354
- type: "view-mode",
5355
- data: value
5356
- })
5357
- }, /* @__PURE__ */ import_react2.default.createElement(Icon2, {
5358
- className: iconStyles
5359
- }), /* @__PURE__ */ import_react2.default.createElement("span", {
5360
- className: "whitespace-nowrap grow"
5361
- }, t(`${value} mode label`)), /* @__PURE__ */ import_react2.default.createElement(import_react.Check, {
5362
- className: value === mode ? "visible" : "invisible"
5363
- }));
5364
- })), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Arrow, null)))), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Portal, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Arrow, null))));
5365
- };
5366
- var MarkdownActions = () => {
5367
- const { onAction, state } = useToolbarContext("MarkdownActions");
5368
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5369
- let commentToolTipKey = "comment label";
5370
- if (state?.comment) {
5371
- commentToolTipKey = "selection overlaps existing comment label";
5372
- } else if (state?.selection === false) {
5373
- commentToolTipKey = "select text to comment label";
5374
- }
5375
- return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(ToolbarButton, {
5376
- value: "search",
5377
- Icon: import_react.MagnifyingGlass,
5378
- onClick: () => onAction?.({
5379
- type: "search"
5380
- })
5381
- }, t("search label")), /* @__PURE__ */ import_react2.default.createElement(ToolbarButton, {
5382
- value: "comment",
5383
- Icon: import_react.ChatText,
5384
- "data-testid": "editor.toolbar.comment",
5385
- onClick: () => onAction?.({
5386
- type: "comment"
5387
- }),
5388
- disabled: !state || state.comment || !state.selection
5389
- }, t(commentToolTipKey)));
5390
- };
5391
- var Toolbar = {
5392
- Root: ToolbarRoot,
5393
- Button: ToolbarToggleButton,
5394
- Separator: ToolbarSeparator,
5395
- View: MarkdownView,
5396
- Markdown: MarkdownStandard,
5397
- Custom: MarkdownCustom,
5398
- Actions: MarkdownActions
5399
- };
5400
- var margin = "!mt-[1rem]";
5401
- var editorContent = (0, import_react_ui_theme8.mx)(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5402
- var editorFullWidth = (0, import_react_ui_theme8.mx)(margin);
5403
- var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5404
- var editorGutter = import_view27.EditorView.theme({
5405
- // Match margin from content.
5406
- ".cm-gutters": {
5407
- marginTop: "16px",
5408
- paddingRight: "1rem"
5409
- }
5410
- });
5411
- var editorMonospace = import_view27.EditorView.theme({
5412
- ".cm-content": {
5413
- fontFamily: fontMono
5414
- }
5415
- });
5416
5379
  var useActionHandler = (view) => {
5417
- return (action) => view && processAction(view, action);
5380
+ return (0, import_react7.useCallback)((action) => view && processEditorPayload(view, action.properties), [
5381
+ view
5382
+ ]);
5418
5383
  };
5419
5384
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5420
5385
  var instanceCount = 0;
5421
5386
  var useTextEditor = (props = {}, deps = []) => {
5422
- const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = (0, import_react7.useMemo)(() => (0, import_util5.getProviderValue)(props), deps ?? []);
5423
- const [instanceId] = (0, import_react7.useState)(() => `text-editor-${++instanceCount}`);
5424
- const [view, setView] = (0, import_react7.useState)();
5425
- const parentRef = (0, import_react7.useRef)(null);
5426
- (0, import_react7.useEffect)(() => {
5387
+ const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = (0, import_react8.useMemo)(() => (0, import_util5.getProviderValue)(props), deps ?? []);
5388
+ const [instanceId] = (0, import_react8.useState)(() => `text-editor-${++instanceCount}`);
5389
+ const [view, setView] = (0, import_react8.useState)();
5390
+ const parentRef = (0, import_react8.useRef)(null);
5391
+ (0, import_react8.useEffect)(() => {
5427
5392
  let view2;
5428
5393
  if (parentRef.current) {
5429
5394
  (0, import_log7.log)("create", {
@@ -5497,7 +5462,7 @@ var useTextEditor = (props = {}, deps = []) => {
5497
5462
  view2?.destroy();
5498
5463
  };
5499
5464
  }, deps);
5500
- (0, import_react7.useEffect)(() => {
5465
+ (0, import_react8.useEffect)(() => {
5501
5466
  if (view) {
5502
5467
  if (scrollTo || selection) {
5503
5468
  if (selection && selection.anchor > view.state.doc.length) {
@@ -5524,7 +5489,7 @@ var useTextEditor = (props = {}, deps = []) => {
5524
5489
  scrollTo,
5525
5490
  selection
5526
5491
  ]);
5527
- (0, import_react7.useEffect)(() => {
5492
+ (0, import_react8.useEffect)(() => {
5528
5493
  if (view && autoFocus) {
5529
5494
  view.focus();
5530
5495
  }
@@ -5538,7 +5503,7 @@ var useTextEditor = (props = {}, deps = []) => {
5538
5503
  Escape: view?.state.facet(editorInputMode).noTabster
5539
5504
  }
5540
5505
  });
5541
- const handleKeyUp = (0, import_react7.useCallback)((event) => {
5506
+ const handleKeyUp = (0, import_react8.useCallback)((event) => {
5542
5507
  const { key, target, currentTarget } = event;
5543
5508
  if (target === currentTarget) {
5544
5509
  switch (key) {
@@ -5568,6 +5533,7 @@ var useTextEditor = (props = {}, deps = []) => {
5568
5533
  EditorInputMode,
5569
5534
  EditorInputModes,
5570
5535
  EditorState,
5536
+ EditorToolbar,
5571
5537
  EditorView,
5572
5538
  EditorViewMode,
5573
5539
  EditorViewModes,
@@ -5577,7 +5543,6 @@ var useTextEditor = (props = {}, deps = []) => {
5577
5543
  RemoteSelectionsDecorator,
5578
5544
  SpaceAwarenessProvider,
5579
5545
  TextKind,
5580
- Toolbar,
5581
5546
  addBlockquote,
5582
5547
  addCodeblock,
5583
5548
  addLink,
@@ -5598,6 +5563,8 @@ var useTextEditor = (props = {}, deps = []) => {
5598
5563
  createBasicExtensions,
5599
5564
  createComment,
5600
5565
  createDataExtensions,
5566
+ createEditorAction,
5567
+ createEditorActionGroup,
5601
5568
  createEditorStateStore,
5602
5569
  createEditorStateTransaction,
5603
5570
  createElement,
@@ -5636,7 +5603,7 @@ var useTextEditor = (props = {}, deps = []) => {
5636
5603
  mention,
5637
5604
  overlap,
5638
5605
  preventNewline,
5639
- processAction,
5606
+ processEditorPayload,
5640
5607
  removeBlockquote,
5641
5608
  removeCodeblock,
5642
5609
  removeLink,
@@ -5652,6 +5619,8 @@ var useTextEditor = (props = {}, deps = []) => {
5652
5619
  setSelection,
5653
5620
  setStyle,
5654
5621
  singleValueFacet,
5622
+ stackItemContentEditorClassNames,
5623
+ stackItemContentToolbarClassNames,
5655
5624
  table,
5656
5625
  tags,
5657
5626
  textRange,
@@ -5669,9 +5638,9 @@ var useTextEditor = (props = {}, deps = []) => {
5669
5638
  useCommentClickListener,
5670
5639
  useCommentState,
5671
5640
  useComments,
5641
+ useEditorToolbarState,
5672
5642
  useFormattingState,
5673
5643
  useTextEditor,
5674
- useToolbarContext,
5675
5644
  wrapWithCatch
5676
5645
  });
5677
5646
  //# sourceMappingURL=index.cjs.map