@dxos/react-ui-editor 0.7.4-staging.f7e8224 → 0.7.5-feature-compute.4d9d99a

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 (77) hide show
  1. package/dist/lib/browser/index.mjs +1114 -1128
  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 +1178 -1202
  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 +1114 -1128
  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/extensions/modes.d.ts +5 -2
  41. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  42. package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
  43. package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
  44. package/dist/types/src/index.d.ts +3 -2
  45. package/dist/types/src/index.d.ts.map +1 -1
  46. package/dist/types/src/styles/stack-item-content-class-names.d.ts +3 -0
  47. package/dist/types/src/styles/stack-item-content-class-names.d.ts.map +1 -0
  48. package/dist/types/tsconfig.tsbuildinfo +1 -0
  49. package/package.json +28 -27
  50. package/src/InputMode.stories.tsx +7 -10
  51. package/src/components/EditorToolbar/EditorToolbar.tsx +106 -0
  52. package/src/components/EditorToolbar/blocks.ts +41 -0
  53. package/src/components/EditorToolbar/comment.ts +20 -0
  54. package/src/components/EditorToolbar/formatting.ts +41 -0
  55. package/src/components/EditorToolbar/headings.ts +59 -0
  56. package/src/components/EditorToolbar/index.ts +6 -0
  57. package/src/components/EditorToolbar/lists.ts +40 -0
  58. package/src/components/EditorToolbar/util.ts +65 -0
  59. package/src/components/EditorToolbar/viewMode.ts +48 -0
  60. package/src/components/index.ts +1 -1
  61. package/src/extensions/comments.ts +8 -15
  62. package/src/extensions/markdown/{action.ts → editorAction.ts} +22 -20
  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/extensions/modes.ts +6 -2
  67. package/src/hooks/useActionHandler.ts +4 -4
  68. package/src/index.ts +6 -2
  69. package/src/styles/stack-item-content-class-names.ts +17 -0
  70. package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -34
  71. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
  72. package/dist/types/src/components/Toolbar/index.d.ts +0 -2
  73. package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
  74. package/dist/types/src/extensions/markdown/action.d.ts +0 -9
  75. package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
  76. package/src/components/Toolbar/Toolbar.tsx +0 -522
  77. package/src/components/Toolbar/index.ts +0 -5
@@ -29,7 +29,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var node_exports = {};
30
30
  __export(node_exports, {
31
31
  Cursor: () => Cursor,
32
+ EditorInputMode: () => EditorInputMode,
32
33
  EditorInputModes: () => EditorInputModes,
34
+ EditorState: () => import_state.EditorState,
35
+ EditorToolbar: () => EditorToolbar,
36
+ EditorView: () => import_view.EditorView,
37
+ EditorViewMode: () => EditorViewMode,
33
38
  EditorViewModes: () => EditorViewModes,
34
39
  Inline: () => Inline,
35
40
  InputModeExtensions: () => InputModeExtensions,
@@ -37,7 +42,6 @@ __export(node_exports, {
37
42
  RemoteSelectionsDecorator: () => RemoteSelectionsDecorator,
38
43
  SpaceAwarenessProvider: () => SpaceAwarenessProvider,
39
44
  TextKind: () => import_text.TextKind,
40
- Toolbar: () => Toolbar,
41
45
  addBlockquote: () => addBlockquote,
42
46
  addCodeblock: () => addCodeblock,
43
47
  addLink: () => addLink,
@@ -56,8 +60,10 @@ __export(node_exports, {
56
60
  commentsState: () => commentsState,
57
61
  convertTreeToJson: () => convertTreeToJson,
58
62
  createBasicExtensions: () => createBasicExtensions,
59
- createComment: () => createComment,
63
+ createComment: () => createComment2,
60
64
  createDataExtensions: () => createDataExtensions,
65
+ createEditorAction: () => createEditorAction,
66
+ createEditorActionGroup: () => createEditorActionGroup,
61
67
  createEditorStateStore: () => createEditorStateStore,
62
68
  createEditorStateTransaction: () => createEditorStateTransaction,
63
69
  createElement: () => createElement,
@@ -96,7 +102,7 @@ __export(node_exports, {
96
102
  mention: () => mention,
97
103
  overlap: () => overlap,
98
104
  preventNewline: () => preventNewline,
99
- processAction: () => processAction,
105
+ processEditorPayload: () => processEditorPayload,
100
106
  removeBlockquote: () => removeBlockquote,
101
107
  removeCodeblock: () => removeCodeblock,
102
108
  removeLink: () => removeLink,
@@ -112,6 +118,8 @@ __export(node_exports, {
112
118
  setSelection: () => setSelection,
113
119
  setStyle: () => setStyle,
114
120
  singleValueFacet: () => singleValueFacet,
121
+ stackItemContentEditorClassNames: () => stackItemContentEditorClassNames,
122
+ stackItemContentToolbarClassNames: () => stackItemContentToolbarClassNames,
115
123
  table: () => table,
116
124
  tags: () => import_highlight.tags,
117
125
  textRange: () => textRange,
@@ -129,101 +137,106 @@ __export(node_exports, {
129
137
  useCommentClickListener: () => useCommentClickListener,
130
138
  useCommentState: () => useCommentState,
131
139
  useComments: () => useComments,
140
+ useEditorToolbarState: () => useEditorToolbarState,
132
141
  useFormattingState: () => useFormattingState,
133
142
  useTextEditor: () => useTextEditor,
134
- useToolbarContext: () => useToolbarContext,
135
143
  wrapWithCatch: () => wrapWithCatch
136
144
  });
137
145
  module.exports = __toCommonJS(node_exports);
146
+ var import_state = require("@codemirror/state");
138
147
  var import_view = require("@codemirror/view");
139
148
  var import_highlight = require("@lezer/highlight");
140
149
  var import_text = require("@dxos/protocols/proto/dxos/echo/model/text");
141
- var import_react = require("@phosphor-icons/react");
142
- var import_react_context = require("@radix-ui/react-context");
143
- var import_react2 = __toESM(require("react"));
144
- var import_react_dropzone = require("react-dropzone");
150
+ var import_react = __toESM(require("react"));
145
151
  var import_react_ui = require("@dxos/react-ui");
152
+ var import_react_ui_menu = require("@dxos/react-ui-menu");
146
153
  var import_react_ui_theme = require("@dxos/react-ui-theme");
147
- var import_state = 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");
148
158
  var import_view2 = require("@codemirror/view");
149
- var import_util = require("@dxos/util");
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");
150
163
  var import_state2 = require("@codemirror/state");
164
+ var import_view3 = require("@codemirror/view");
165
+ var import_util = require("@dxos/util");
166
+ var import_state3 = require("@codemirror/state");
151
167
  var import_log = require("@dxos/log");
152
168
  var import_react3 = __toESM(require("react"));
153
169
  var import_client = require("react-dom/client");
154
170
  var import_react_ui2 = require("@dxos/react-ui");
155
- var import_react_ui_theme2 = require("@dxos/react-ui-theme");
171
+ var import_react_ui_theme6 = require("@dxos/react-ui-theme");
156
172
  var import_autocomplete = require("@codemirror/autocomplete");
157
173
  var import_lang_markdown = require("@codemirror/lang-markdown");
158
- var import_view3 = require("@codemirror/view");
159
- var import_state3 = require("@codemirror/state");
160
174
  var import_view4 = require("@codemirror/view");
175
+ var import_state4 = require("@codemirror/state");
176
+ var import_view5 = require("@codemirror/view");
161
177
  var import_automerge = require("@dxos/automerge/automerge");
162
178
  var import_log2 = require("@dxos/log");
163
179
  var import_echo = require("@dxos/react-client/echo");
164
- var import_state4 = require("@codemirror/state");
180
+ var import_state5 = require("@codemirror/state");
165
181
  var import_automerge2 = require("@dxos/automerge/automerge");
166
182
  var import_automerge3 = require("@dxos/automerge/automerge");
167
- var import_state5 = require("@codemirror/state");
168
183
  var import_state6 = require("@codemirror/state");
169
- var import_view5 = require("@codemirror/view");
184
+ var import_state7 = require("@codemirror/state");
185
+ var import_view6 = require("@codemirror/view");
170
186
  var import_async = require("@dxos/async");
171
187
  var import_context = require("@dxos/context");
172
188
  var import_async2 = require("@dxos/async");
173
189
  var import_context2 = require("@dxos/context");
174
190
  var import_invariant = require("@dxos/invariant");
175
191
  var import_log3 = require("@dxos/log");
176
- var import_view6 = require("@codemirror/view");
177
- var import_lodash = __toESM(require("lodash.defaultsdeep"));
178
- var import_invariant2 = require("@dxos/invariant");
179
192
  var import_view7 = require("@codemirror/view");
180
- var import_state7 = require("@codemirror/state");
193
+ var import_lodash2 = __toESM(require("lodash.defaultsdeep"));
194
+ var import_invariant2 = require("@dxos/invariant");
181
195
  var import_view8 = require("@codemirror/view");
182
196
  var import_state8 = require("@codemirror/state");
183
197
  var import_view9 = require("@codemirror/view");
184
- var import_commands = require("@codemirror/commands");
185
198
  var import_state9 = require("@codemirror/state");
186
199
  var import_view10 = require("@codemirror/view");
187
- var import_lodash2 = __toESM(require("lodash.sortby"));
200
+ var import_commands = require("@codemirror/commands");
201
+ var import_state10 = require("@codemirror/state");
202
+ var import_view11 = require("@codemirror/view");
203
+ var import_lodash3 = __toESM(require("lodash.sortby"));
188
204
  var import_react4 = require("react");
189
205
  var import_async3 = require("@dxos/async");
190
206
  var import_log4 = require("@dxos/log");
191
207
  var import_util2 = require("@dxos/util");
192
- var import_state10 = require("@codemirror/state");
193
- var import_view11 = require("@codemirror/view");
208
+ var import_state11 = require("@codemirror/state");
209
+ var import_view12 = require("@codemirror/view");
194
210
  var import_async4 = require("@dxos/async");
195
211
  var import_invariant3 = require("@dxos/invariant");
196
212
  var import_util3 = require("@dxos/util");
197
213
  var import_language = require("@codemirror/language");
198
- var import_state11 = require("@codemirror/state");
199
- var import_view12 = require("@codemirror/view");
214
+ var import_state12 = require("@codemirror/state");
215
+ var import_view13 = require("@codemirror/view");
200
216
  var import_autocomplete2 = require("@codemirror/autocomplete");
201
217
  var import_commands2 = require("@codemirror/commands");
202
218
  var import_language2 = require("@codemirror/language");
203
219
  var import_search = require("@codemirror/search");
204
- var import_state12 = require("@codemirror/state");
220
+ var import_state13 = require("@codemirror/state");
205
221
  var import_theme_one_dark = require("@codemirror/theme-one-dark");
206
- var import_view13 = require("@codemirror/view");
207
- var import_lodash3 = __toESM(require("lodash.defaultsdeep"));
208
- 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"));
209
225
  var import_display_name = require("@dxos/display-name");
210
226
  var import_log5 = require("@dxos/log");
211
- var import_react_ui_theme3 = require("@dxos/react-ui-theme");
227
+ var import_react_ui_theme7 = require("@dxos/react-ui-theme");
212
228
  var import_util4 = require("@dxos/util");
213
- var import_state13 = require("@codemirror/state");
214
- var import_view14 = require("@codemirror/view");
215
- var import_react_ui_theme4 = require("@dxos/react-ui-theme");
216
- var import_lodash5 = __toESM(require("lodash.get"));
217
- var import_react_ui_theme5 = require("@dxos/react-ui-theme");
218
- var import_language3 = require("@codemirror/language");
229
+ var import_state14 = require("@codemirror/state");
219
230
  var import_view15 = require("@codemirror/view");
231
+ var import_language3 = require("@codemirror/language");
232
+ var import_view16 = require("@codemirror/view");
220
233
  var import_react5 = __toESM(require("react"));
221
234
  var import_react_ui3 = require("@dxos/react-ui");
222
- var import_view16 = require("@codemirror/view");
235
+ var import_view17 = require("@codemirror/view");
223
236
  var import_autocomplete3 = require("@codemirror/autocomplete");
224
237
  var import_language4 = require("@codemirror/language");
225
- var import_state14 = require("@codemirror/state");
226
- var import_view17 = require("@codemirror/view");
238
+ var import_state15 = require("@codemirror/state");
239
+ var import_view18 = require("@codemirror/view");
227
240
  var import_react6 = require("react");
228
241
  var import_autocomplete4 = require("@codemirror/autocomplete");
229
242
  var import_commands3 = require("@codemirror/commands");
@@ -231,43 +244,43 @@ var import_lang_markdown2 = require("@codemirror/lang-markdown");
231
244
  var import_language5 = require("@codemirror/language");
232
245
  var import_language_data = require("@codemirror/language-data");
233
246
  var import_lint = require("@codemirror/lint");
234
- var import_view18 = require("@codemirror/view");
247
+ var import_view19 = require("@codemirror/view");
235
248
  var import_lang_markdown3 = require("@codemirror/lang-markdown");
236
249
  var import_language6 = require("@codemirror/language");
237
250
  var import_highlight2 = require("@lezer/highlight");
238
251
  var import_markdown = require("@lezer/markdown");
239
252
  var import_language7 = require("@codemirror/language");
240
- var import_state15 = require("@codemirror/state");
241
- var import_language8 = require("@codemirror/language");
242
253
  var import_state16 = require("@codemirror/state");
243
- var import_view19 = require("@codemirror/view");
244
- var import_invariant4 = require("@dxos/invariant");
245
- var import_react_ui_theme6 = require("@dxos/react-ui-theme");
246
- var import_language9 = require("@codemirror/language");
254
+ var import_language8 = require("@codemirror/language");
247
255
  var import_state17 = require("@codemirror/state");
248
256
  var import_view20 = require("@codemirror/view");
249
- var import_language10 = require("@codemirror/language");
257
+ var import_invariant4 = require("@dxos/invariant");
258
+ var import_react_ui_theme8 = require("@dxos/react-ui-theme");
259
+ var import_language9 = require("@codemirror/language");
250
260
  var import_state18 = require("@codemirror/state");
251
261
  var import_view21 = require("@codemirror/view");
252
- var import_view22 = require("@codemirror/view");
253
- var import_language11 = require("@codemirror/language");
262
+ var import_language10 = require("@codemirror/language");
254
263
  var import_state19 = require("@codemirror/state");
264
+ var import_view22 = require("@codemirror/view");
255
265
  var import_view23 = require("@codemirror/view");
256
- var import_language12 = require("@codemirror/language");
266
+ var import_language11 = require("@codemirror/language");
267
+ var import_state20 = require("@codemirror/state");
257
268
  var import_view24 = require("@codemirror/view");
258
- 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");
259
272
  var import_autocomplete5 = require("@codemirror/autocomplete");
260
273
  var import_log6 = require("@dxos/log");
261
- var import_view25 = require("@codemirror/view");
274
+ var import_view26 = require("@codemirror/view");
262
275
  var import_codemirror_vim = require("@replit/codemirror-vim");
263
276
  var import_codemirror_vscode_keymap = require("@replit/codemirror-vscode-keymap");
264
- var import_view26 = require("@codemirror/view");
277
+ var import_echo_schema = require("@dxos/echo-schema");
265
278
  var import_view27 = require("@codemirror/view");
266
- var import_react_ui_theme8 = require("@dxos/react-ui-theme");
267
- var import_state20 = require("@codemirror/state");
279
+ var import_react7 = require("react");
280
+ var import_state21 = require("@codemirror/state");
268
281
  var import_view28 = require("@codemirror/view");
269
282
  var import_react_tabster = require("@fluentui/react-tabster");
270
- var import_react7 = require("react");
283
+ var import_react8 = require("react");
271
284
  var import_log7 = require("@dxos/log");
272
285
  var import_util5 = require("@dxos/util");
273
286
  var translationKey = "react-ui-editor";
@@ -303,197 +316,759 @@ var translations_default = [
303
316
  }
304
317
  }
305
318
  ];
306
- var singleValueFacet = (defaultValue) => import_state2.Facet.define({
307
- // Called immediately.
308
- combine: (providers) => {
309
- 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
310
326
  }
327
+ ], id = payload.type) => (0, import_react_ui_menu2.createMenuAction)(id, {
328
+ icon,
329
+ label,
330
+ ...payload
311
331
  });
312
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
313
- var defaultCursorConverter = {
314
- toCursor: (position) => position.toString(),
315
- 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
+ };
316
378
  };
317
- var Cursor = class _Cursor {
318
- static {
319
- this.converter = singleValueFacet(defaultCursorConverter);
320
- }
321
- static {
322
- this.getCursorFromRange = (state, range) => {
323
- const cursorConverter2 = state.facet(_Cursor.converter);
324
- const from = cursorConverter2.toCursor(range.from);
325
- const to = cursorConverter2.toCursor(range.to, -1);
326
- return [
327
- from,
328
- to
329
- ].join(":");
330
- };
331
- }
332
- static {
333
- this.getRangeFromCursor = (state, cursor) => {
334
- const cursorConverter2 = state.facet(_Cursor.converter);
335
- const parts = cursor.split(":");
336
- const from = cursorConverter2.fromCursor(parts[0]);
337
- const to = cursorConverter2.fromCursor(parts[1]);
338
- return from !== void 0 && to !== void 0 ? {
339
- from,
340
- to
341
- } : void 0;
342
- };
343
- }
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(commentLabel(state.comment, state.selection))
387
+ ],
388
+ edges: [
389
+ {
390
+ source: "root",
391
+ target: "comment"
392
+ }
393
+ ]
394
+ });
395
+ var formats = {
396
+ strong: "ph--text-b--regular",
397
+ emphasis: "ph--text-italic--regular",
398
+ strikethrough: "ph--text-strikethrough--regular",
399
+ code: "ph--code--regular",
400
+ link: "ph--link--regular"
401
+ };
402
+ var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
403
+ variant: "toggleGroup",
404
+ selectCardinality: "multiple",
405
+ value: Object.keys(formats).filter((key) => !!formatting[key])
406
+ });
407
+ var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
408
+ type,
409
+ checked: !!formatting[type]
410
+ }, icon));
411
+ var createFormatting = (state) => {
412
+ const formattingGroupAction = createFormattingGroup(state);
413
+ const formattingActions = createFormattingActions(state);
414
+ return {
415
+ nodes: [
416
+ formattingGroupAction,
417
+ ...formattingActions
418
+ ],
419
+ edges: [
420
+ {
421
+ source: "root",
422
+ target: "formatting"
423
+ },
424
+ ...formattingActions.map(({ id }) => ({
425
+ source: formattingGroupAction.id,
426
+ target: id
427
+ }))
428
+ ]
429
+ };
344
430
  };
345
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
346
- var wrapWithCatch = (fn) => {
347
- return (...args) => {
348
- try {
349
- return fn(...args);
350
- } catch (err) {
351
- import_log.log.catch(err, void 0, {
352
- F: __dxlog_file,
353
- L: 15,
354
- S: void 0,
355
- C: (f, a) => f(...a)
356
- });
431
+ var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
432
+ variant: "dropdownMenu",
433
+ applyActive: true,
434
+ selectCardinality: "single",
435
+ value
436
+ }, "ph--text-h--regular");
437
+ var createHeadingActions = (value) => Object.entries({
438
+ "0": "ph--paragraph--regular",
439
+ "1": "ph--text-h-one--regular",
440
+ "2": "ph--text-h-two--regular",
441
+ "3": "ph--text-h-three--regular",
442
+ "4": "ph--text-h-four--regular",
443
+ "5": "ph--text-h-five--regular",
444
+ "6": "ph--text-h-six--regular"
445
+ }).map(([levelStr, icon]) => {
446
+ const level = parseInt(levelStr);
447
+ return createEditorAction({
448
+ type: "heading",
449
+ data: level,
450
+ checked: value === levelStr
451
+ }, icon, [
452
+ "heading level label",
453
+ {
454
+ count: level,
455
+ ns: translationKey
357
456
  }
457
+ ], `heading--${levelStr}`);
458
+ });
459
+ var computeHeadingValue = (state) => {
460
+ const blockType = state ? state.blockType : "paragraph";
461
+ const header = blockType && /heading(\d)/.exec(blockType);
462
+ return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
463
+ };
464
+ var createHeadings = (state) => {
465
+ const headingValue = computeHeadingValue(state);
466
+ const headingGroupAction = createHeadingGroupAction(headingValue);
467
+ const headingActions = createHeadingActions(headingValue);
468
+ return {
469
+ nodes: [
470
+ headingGroupAction,
471
+ ...headingActions
472
+ ],
473
+ edges: [
474
+ {
475
+ source: "root",
476
+ target: "heading"
477
+ },
478
+ ...headingActions.map(({ id }) => ({
479
+ source: headingGroupAction.id,
480
+ target: id
481
+ }))
482
+ ]
358
483
  };
359
484
  };
360
- var callbackWrapper = (fn) => (...args) => {
361
- try {
362
- return fn(...args);
363
- } catch (err) {
364
- import_log.log.catch(err, void 0, {
365
- F: __dxlog_file,
366
- L: 29,
367
- S: void 0,
368
- C: (f, a) => f(...a)
369
- });
370
- }
485
+ var listStyles = {
486
+ bullet: "ph--list-bullets--regular",
487
+ ordered: "ph--list-numbers--regular",
488
+ task: "ph--list-checks--regular"
371
489
  };
372
- var debugDispatcher = (trs, view) => {
373
- logChanges(trs);
374
- view.update(trs);
490
+ var createListGroupAction = (value) => createEditorActionGroup("list", {
491
+ variant: "toggleGroup",
492
+ selectCardinality: "single",
493
+ value
494
+ });
495
+ var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
496
+ type: `list-${listStyle}`,
497
+ checked: value === listStyle
498
+ }, icon));
499
+ var createLists = (state) => {
500
+ const value = state.listStyle ?? "";
501
+ const listGroupAction = createListGroupAction(value);
502
+ const listActionsMap = createListActions(value);
503
+ return {
504
+ nodes: [
505
+ listGroupAction,
506
+ ...listActionsMap
507
+ ],
508
+ edges: [
509
+ {
510
+ source: "root",
511
+ target: "list"
512
+ },
513
+ ...listActionsMap.map(({ id }) => ({
514
+ source: listGroupAction.id,
515
+ target: id
516
+ }))
517
+ ]
518
+ };
375
519
  };
376
- var logChanges = (trs) => {
377
- const changes = trs.flatMap((tr) => {
378
- if (tr.changes.empty) {
379
- return void 0;
520
+ var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
521
+ variant: "dropdownMenu",
522
+ applyActive: true,
523
+ selectCardinality: "single",
524
+ value
525
+ }, "ph--eye--regular");
526
+ var createViewModeActions = (value) => Object.entries({
527
+ preview: "ph--eye--regular",
528
+ source: "ph--pencil-simple--regular",
529
+ readonly: "ph--pencil-slash--regular"
530
+ }).map(([viewMode, icon]) => {
531
+ return createEditorAction({
532
+ type: "view-mode",
533
+ data: viewMode,
534
+ checked: viewMode === value
535
+ }, icon, [
536
+ `${viewMode} mode label`,
537
+ {
538
+ ns: translationKey
380
539
  }
381
- const changes2 = [];
382
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
383
- fromA,
384
- toA,
385
- fromB,
386
- toB,
387
- inserted: inserted.toString()
388
- })));
389
- return changes2;
390
- }).filter(Boolean);
391
- if (changes.length) {
392
- import_log.log.info("changes", {
393
- changes
394
- }, {
395
- F: __dxlog_file,
396
- L: 62,
397
- S: void 0,
398
- C: (f, a) => f(...a)
540
+ ], `view-mode--${viewMode}`);
541
+ });
542
+ var createViewMode = (state) => {
543
+ const value = state.viewMode ?? "source";
544
+ const viewModeGroupAction = createViewModeGroupAction(value);
545
+ const viewModeActions = createViewModeActions(value);
546
+ return {
547
+ nodes: [
548
+ viewModeGroupAction,
549
+ ...viewModeActions
550
+ ],
551
+ edges: [
552
+ {
553
+ source: "root",
554
+ target: "viewMode"
555
+ },
556
+ ...viewModeActions.map(({ id }) => ({
557
+ source: viewModeGroupAction.id,
558
+ target: id
559
+ }))
560
+ ]
561
+ };
562
+ };
563
+ var stackItemContentEditorClassNames = (role) => (0, import_react_ui_theme2.mx)("ch-focus-ring-inset data-[toolbar=disabled]:pbs-2 attention-surface", role === "article" ? "min-bs-0" : "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24");
564
+ 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");
565
+ var createToolbar = ({ state, customActions, ...features }) => {
566
+ const nodes = [];
567
+ const edges = [];
568
+ if (features.headings ?? true) {
569
+ const headings2 = createHeadings(state);
570
+ nodes.push(...headings2.nodes);
571
+ edges.push(...headings2.edges);
572
+ }
573
+ if (features.formatting ?? true) {
574
+ const formatting = createFormatting(state);
575
+ nodes.push(...formatting.nodes);
576
+ edges.push(...formatting.edges);
577
+ }
578
+ if (features.lists ?? true) {
579
+ const lists = createLists(state);
580
+ nodes.push(...lists.nodes);
581
+ edges.push(...lists.edges);
582
+ }
583
+ if (features.blocks ?? true) {
584
+ const blocks = createBlocks(state);
585
+ nodes.push(...blocks.nodes);
586
+ edges.push(...blocks.edges);
587
+ }
588
+ if (customActions) {
589
+ const custom = customActions();
590
+ nodes.push(...custom.nodes);
591
+ edges.push(...custom.edges);
592
+ }
593
+ const editorToolbarGap = (0, import_react_ui_menu.createGapSeparator)();
594
+ nodes.push(...editorToolbarGap.nodes);
595
+ edges.push(...editorToolbarGap.edges);
596
+ if (features.comment ?? true) {
597
+ const comment = createComment(state);
598
+ nodes.push(...comment.nodes);
599
+ edges.push(...comment.edges);
600
+ }
601
+ if (features.search ?? true) {
602
+ nodes.push(editorToolbarSearch);
603
+ edges.push({
604
+ source: "root",
605
+ target: editorToolbarSearch.id
399
606
  });
400
607
  }
608
+ if (features.viewMode ?? true) {
609
+ const viewMode = createViewMode(state);
610
+ nodes.push(...viewMode.nodes);
611
+ edges.push(...viewMode.edges);
612
+ }
613
+ return {
614
+ nodes,
615
+ edges
616
+ };
401
617
  };
402
- var flattenRect = (rect, left) => {
403
- const x = left ? rect.left : rect.right;
618
+ var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
619
+ const menuCreator = (0, import_react.useCallback)(() => createToolbar(props), [
620
+ props
621
+ ]);
622
+ const { resolveGroupItems } = (0, import_react_ui_menu.useMenuActions)(menuCreator);
404
623
  return {
405
- left: x,
406
- right: x,
407
- top: rect.top,
408
- bottom: rect.bottom
624
+ resolveGroupItems,
625
+ onAction
409
626
  };
410
627
  };
411
- var scratchRange;
412
- var textRange = (node, from, to = from) => {
413
- const range = scratchRange || (scratchRange = document.createRange());
414
- range.setEnd(node, to);
415
- range.setStart(node, from);
416
- return range;
628
+ var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
629
+ const menuProps = useEditorToolbarActionGraph(props);
630
+ return /* @__PURE__ */ import_react.default.createElement("div", {
631
+ role: "none",
632
+ className: stackItemContentToolbarClassNames(role)
633
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.ElevationProvider, {
634
+ elevation: role === "section" ? "positioned" : "base"
635
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.MenuProvider, {
636
+ ...menuProps,
637
+ attendableId
638
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.ToolbarMenu, {
639
+ classNames: [
640
+ import_react_ui_theme.textBlockWidth,
641
+ "!bg-transparent",
642
+ classNames
643
+ ]
644
+ }))));
417
645
  };
418
- var clientRectsFor = (dom) => {
419
- if (dom.nodeType === 3) {
420
- return textRange(dom, 0, dom.nodeValue.length).getClientRects();
421
- } else if (dom.nodeType === 1) {
422
- return dom.getClientRects();
423
- } else {
424
- return [];
425
- }
646
+ var headings = {
647
+ 1: "text-4xl",
648
+ 2: "text-3xl",
649
+ 3: "text-2xl",
650
+ 4: "text-xl",
651
+ 5: "text-lg",
652
+ 6: "text-md"
426
653
  };
427
- var createElement = (tag, options, children) => {
428
- const el = document.createElement(tag);
429
- if (options?.className) {
430
- el.className = options.className;
431
- }
432
- if (children) {
433
- el.append(...Array.isArray(children) ? children : [
434
- children
435
- ]);
654
+ var theme = {
655
+ code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
656
+ codeMark: "font-mono text-primary-500",
657
+ mark: "opacity-50",
658
+ heading: (level) => {
659
+ return (0, import_react_ui_theme4.mx)(headings[level], "dark:text-primary-400");
436
660
  }
437
- return el;
438
661
  };
439
- var renderRoot = (root, node) => {
440
- (0, import_client.createRoot)(root).render(/* @__PURE__ */ import_react3.default.createElement(import_react_ui2.ThemeProvider, {
441
- tx: import_react_ui_theme2.defaultTx
442
- }, node));
443
- return root;
662
+ var getToken = (path, defaultValue) => {
663
+ const value = (0, import_lodash.default)(import_react_ui_theme5.tokens, path, defaultValue);
664
+ return value?.toString() ?? "";
444
665
  };
445
- var annotationMark = import_view2.Decoration.mark({
446
- class: "cm-annotation"
447
- });
448
- var annotations = (options = {}) => {
449
- const match = (state) => {
450
- const annotations2 = [];
451
- const text = state.doc.toString();
452
- if (options.match) {
453
- const matches = text.matchAll(options.match);
454
- for (const match2 of matches) {
455
- const from = match2.index;
456
- const to = from + match2[0].length;
457
- const cursor = Cursor.getCursorFromRange(state, {
458
- from,
459
- to
460
- });
461
- annotations2.push({
462
- cursor
463
- });
464
- }
465
- }
466
- return annotations2;
467
- };
468
- const annotationsState = import_state.StateField.define({
469
- create: (state) => {
470
- return match(state);
666
+ var fontBody = getToken("fontFamily.body");
667
+ var fontMono = getToken("fontFamily.mono");
668
+ var defaultTheme = {
669
+ "&": {},
670
+ "&.cm-focused": {
671
+ outline: "none"
672
+ },
673
+ /**
674
+ * Scroller
675
+ */
676
+ ".cm-scroller": {
677
+ overflowY: "auto"
678
+ },
679
+ /**
680
+ * Content
681
+ * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
682
+ */
683
+ ".cm-content": {
684
+ padding: "unset",
685
+ fontFamily: fontBody,
686
+ // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
687
+ fontSize: "16px",
688
+ lineHeight: 1.5,
689
+ color: "unset"
690
+ },
691
+ /**
692
+ * Gutters
693
+ * NOTE: Gutters should have the same top margin as the content.
694
+ * NOTE: They can't be transparent since the content needs to scroll below.
695
+ */
696
+ ".cm-gutters": {
697
+ background: "var(--surface-bg)",
698
+ borderRight: "none"
699
+ },
700
+ ".cm-gutter": {},
701
+ ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
702
+ minWidth: "40px",
703
+ alignContent: "center"
704
+ },
705
+ /**
706
+ * Height is set to match the corresponding line.
707
+ */
708
+ ".cm-gutterElement": {
709
+ alignItems: "center",
710
+ fontSize: "16px"
711
+ },
712
+ /**
713
+ * Line.
714
+ */
715
+ ".cm-line": {
716
+ paddingInline: 0
717
+ },
718
+ ".cm-activeLine": {
719
+ background: "var(--dx-cmActiveLine)"
720
+ },
721
+ /**
722
+ * Cursor (layer).
723
+ */
724
+ ".cm-cursor, .cm-dropCursor": {
725
+ borderLeft: "2px solid var(--dx-cmCursor)"
726
+ },
727
+ ".cm-placeholder": {
728
+ color: "var(--dx-subdued)"
729
+ },
730
+ /**
731
+ * Selection (layer).
732
+ */
733
+ ".cm-selectionBackground": {
734
+ background: "var(--dx-cmSelection)"
735
+ },
736
+ /**
737
+ * Search.
738
+ * NOTE: Matches comment.
739
+ */
740
+ ".cm-searchMatch": {
741
+ margin: "0 -3px",
742
+ padding: "3px",
743
+ borderRadius: "3px",
744
+ background: "var(--dx-cmHighlightSurface)",
745
+ color: "var(--dx-cmHighlight)"
746
+ },
747
+ ".cm-searchMatch-selected": {
748
+ textDecoration: "underline"
749
+ },
750
+ /**
751
+ * Link.
752
+ */
753
+ ".cm-link": {
754
+ textDecorationLine: "underline",
755
+ textDecorationThickness: "1px",
756
+ textUnderlineOffset: "2px",
757
+ borderRadius: ".125rem"
758
+ },
759
+ ".cm-link > span": {
760
+ color: "var(--dx-accentText)"
761
+ },
762
+ /**
763
+ * Tooltip.
764
+ */
765
+ ".cm-tooltip": {
766
+ background: "var(--dx-base)"
767
+ },
768
+ ".cm-tooltip-below": {},
769
+ /**
770
+ * Autocomplete.
771
+ * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
772
+ */
773
+ ".cm-tooltip.cm-tooltip-autocomplete": {
774
+ marginTop: "4px",
775
+ marginLeft: "-3px"
776
+ },
777
+ ".cm-tooltip.cm-tooltip-autocomplete > ul": {
778
+ maxHeight: "20em"
779
+ },
780
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
781
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
782
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
783
+ paddingLeft: "4px !important",
784
+ borderBottom: "none !important",
785
+ color: "var(--dx-accentText)"
786
+ },
787
+ ".cm-tooltip.cm-completionInfo": {
788
+ width: "360px !important",
789
+ margin: "-10px 1px 0 1px",
790
+ padding: "8px !important",
791
+ borderColor: "var(--dx-separator)"
792
+ },
793
+ ".cm-completionIcon": {
794
+ display: "none"
795
+ },
796
+ ".cm-completionLabel": {
797
+ fontFamily: fontBody
798
+ },
799
+ ".cm-completionMatchedText": {
800
+ textDecoration: "none !important",
801
+ opacity: 0.5
802
+ },
803
+ /**
804
+ * Panels
805
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
806
+ *
807
+ * Find/replace panel.
808
+ * <div class="cm-announced">...</div>
809
+ * <div class="cm-scroller">...</div>
810
+ * <div class="cm-panels cm-panels-bottom">
811
+ * <div class="cm-search cm-panel">
812
+ * <input class="cm-textfield" />
813
+ * <button class="cm-button">...</button>
814
+ * <label><input type="checkbox" />...</label>
815
+ * </div>
816
+ * </div
817
+ */
818
+ // TODO(burdon): Implement custom panel (with icon buttons).
819
+ ".cm-panels": {},
820
+ ".cm-panel": {
821
+ fontFamily: fontBody,
822
+ backgroundColor: "var(--surface-bg)"
823
+ },
824
+ ".cm-panel input, .cm-panel button, .cm-panel label": {
825
+ color: "var(--dx-subdued)",
826
+ fontFamily: fontBody,
827
+ fontSize: "14px",
828
+ all: "unset",
829
+ margin: "3px !important",
830
+ padding: "2px 6px !important",
831
+ outline: "1px solid transparent"
832
+ },
833
+ ".cm-panel input, .cm-panel button": {
834
+ backgroundColor: "var(--dx-input)"
835
+ },
836
+ ".cm-panel input:focus, .cm-panel button:focus": {
837
+ outline: "1px solid var(--dx-accentFocusIndicator)"
838
+ },
839
+ ".cm-panel label": {
840
+ display: "inline-flex",
841
+ alignItems: "center",
842
+ cursor: "pointer"
843
+ },
844
+ ".cm-panel input.cm-textfield": {},
845
+ ".cm-panel input[type=checkbox]": {
846
+ width: "8px",
847
+ height: "8px",
848
+ marginRight: "6px !important",
849
+ padding: "2px !important",
850
+ color: "var(--dx-accentFocusIndicator)"
851
+ },
852
+ ".cm-panel button": {
853
+ "&:hover": {
854
+ backgroundColor: "var(--dx-accentSurfaceHover) !important"
471
855
  },
472
- update: (value, tr) => {
473
- if (!tr.changes.empty) {
474
- return match(tr.state);
475
- }
476
- return value;
856
+ "&:active": {
857
+ backgroundColor: "var(--dx-accentSurfaceHover)"
477
858
  }
478
- });
479
- return [
480
- annotationsState,
481
- import_view2.EditorView.decorations.compute([
482
- annotationsState
483
- ], (state) => {
484
- const annotations2 = state.field(annotationsState);
485
- const decorations = annotations2.map((annotation) => {
486
- const range = Cursor.getRangeFromCursor(state, annotation.cursor);
487
- return range && annotationMark.range(range.from, range.to);
488
- }).filter(import_util.isNotFalsy);
489
- return import_view2.Decoration.set(decorations);
490
- }),
491
- styles
492
- ];
493
- };
494
- var styles = import_view2.EditorView.theme({
495
- ".cm-annotation": {
496
- textDecoration: "underline",
859
+ },
860
+ ".cm-panel.cm-search": {
861
+ padding: "4px",
862
+ borderTop: "1px solid var(--dx-separator)"
863
+ }
864
+ };
865
+ var margin = "!mt-[1rem]";
866
+ var editorContent = (0, import_react_ui_theme3.mx)(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
867
+ var editorFullWidth = (0, import_react_ui_theme3.mx)(margin);
868
+ var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
869
+ var editorGutter = import_view2.EditorView.theme({
870
+ // Match margin from content.
871
+ ".cm-gutters": {
872
+ marginTop: "16px",
873
+ paddingRight: "1rem"
874
+ }
875
+ });
876
+ var editorMonospace = import_view2.EditorView.theme({
877
+ ".cm-content": {
878
+ fontFamily: fontMono
879
+ }
880
+ });
881
+ var singleValueFacet = (defaultValue) => import_state3.Facet.define({
882
+ // Called immediately.
883
+ combine: (providers) => {
884
+ return providers[0] ?? defaultValue;
885
+ }
886
+ });
887
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
888
+ var defaultCursorConverter = {
889
+ toCursor: (position) => position.toString(),
890
+ fromCursor: (cursor) => parseInt(cursor)
891
+ };
892
+ var Cursor = class _Cursor {
893
+ static {
894
+ this.converter = singleValueFacet(defaultCursorConverter);
895
+ }
896
+ static {
897
+ this.getCursorFromRange = (state, range) => {
898
+ const cursorConverter2 = state.facet(_Cursor.converter);
899
+ const from = cursorConverter2.toCursor(range.from);
900
+ const to = cursorConverter2.toCursor(range.to, -1);
901
+ return [
902
+ from,
903
+ to
904
+ ].join(":");
905
+ };
906
+ }
907
+ static {
908
+ this.getRangeFromCursor = (state, cursor) => {
909
+ const cursorConverter2 = state.facet(_Cursor.converter);
910
+ const parts = cursor.split(":");
911
+ const from = cursorConverter2.fromCursor(parts[0]);
912
+ const to = cursorConverter2.fromCursor(parts[1]);
913
+ return from !== void 0 && to !== void 0 ? {
914
+ from,
915
+ to
916
+ } : void 0;
917
+ };
918
+ }
919
+ };
920
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
921
+ var wrapWithCatch = (fn) => {
922
+ return (...args) => {
923
+ try {
924
+ return fn(...args);
925
+ } catch (err) {
926
+ import_log.log.catch(err, void 0, {
927
+ F: __dxlog_file,
928
+ L: 15,
929
+ S: void 0,
930
+ C: (f, a) => f(...a)
931
+ });
932
+ }
933
+ };
934
+ };
935
+ var callbackWrapper = (fn) => (...args) => {
936
+ try {
937
+ return fn(...args);
938
+ } catch (err) {
939
+ import_log.log.catch(err, void 0, {
940
+ F: __dxlog_file,
941
+ L: 29,
942
+ S: void 0,
943
+ C: (f, a) => f(...a)
944
+ });
945
+ }
946
+ };
947
+ var debugDispatcher = (trs, view) => {
948
+ logChanges(trs);
949
+ view.update(trs);
950
+ };
951
+ var logChanges = (trs) => {
952
+ const changes = trs.flatMap((tr) => {
953
+ if (tr.changes.empty) {
954
+ return void 0;
955
+ }
956
+ const changes2 = [];
957
+ tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
958
+ fromA,
959
+ toA,
960
+ fromB,
961
+ toB,
962
+ inserted: inserted.toString()
963
+ })));
964
+ return changes2;
965
+ }).filter(Boolean);
966
+ if (changes.length) {
967
+ import_log.log.info("changes", {
968
+ changes
969
+ }, {
970
+ F: __dxlog_file,
971
+ L: 62,
972
+ S: void 0,
973
+ C: (f, a) => f(...a)
974
+ });
975
+ }
976
+ };
977
+ var flattenRect = (rect, left) => {
978
+ const x = left ? rect.left : rect.right;
979
+ return {
980
+ left: x,
981
+ right: x,
982
+ top: rect.top,
983
+ bottom: rect.bottom
984
+ };
985
+ };
986
+ var scratchRange;
987
+ var textRange = (node, from, to = from) => {
988
+ const range = scratchRange || (scratchRange = document.createRange());
989
+ range.setEnd(node, to);
990
+ range.setStart(node, from);
991
+ return range;
992
+ };
993
+ var clientRectsFor = (dom) => {
994
+ if (dom.nodeType === 3) {
995
+ return textRange(dom, 0, dom.nodeValue.length).getClientRects();
996
+ } else if (dom.nodeType === 1) {
997
+ return dom.getClientRects();
998
+ } else {
999
+ return [];
1000
+ }
1001
+ };
1002
+ var createElement = (tag, options, children) => {
1003
+ const el = document.createElement(tag);
1004
+ if (options?.className) {
1005
+ el.className = options.className;
1006
+ }
1007
+ if (children) {
1008
+ el.append(...Array.isArray(children) ? children : [
1009
+ children
1010
+ ]);
1011
+ }
1012
+ return el;
1013
+ };
1014
+ var renderRoot = (root, node) => {
1015
+ (0, import_client.createRoot)(root).render(/* @__PURE__ */ import_react3.default.createElement(import_react_ui2.ThemeProvider, {
1016
+ tx: import_react_ui_theme6.defaultTx
1017
+ }, node));
1018
+ return root;
1019
+ };
1020
+ var annotationMark = import_view3.Decoration.mark({
1021
+ class: "cm-annotation"
1022
+ });
1023
+ var annotations = (options = {}) => {
1024
+ const match = (state) => {
1025
+ const annotations2 = [];
1026
+ const text = state.doc.toString();
1027
+ if (options.match) {
1028
+ const matches = text.matchAll(options.match);
1029
+ for (const match2 of matches) {
1030
+ const from = match2.index;
1031
+ const to = from + match2[0].length;
1032
+ const cursor = Cursor.getCursorFromRange(state, {
1033
+ from,
1034
+ to
1035
+ });
1036
+ annotations2.push({
1037
+ cursor
1038
+ });
1039
+ }
1040
+ }
1041
+ return annotations2;
1042
+ };
1043
+ const annotationsState = import_state2.StateField.define({
1044
+ create: (state) => {
1045
+ return match(state);
1046
+ },
1047
+ update: (value, tr) => {
1048
+ if (!tr.changes.empty) {
1049
+ return match(tr.state);
1050
+ }
1051
+ return value;
1052
+ }
1053
+ });
1054
+ return [
1055
+ annotationsState,
1056
+ import_view3.EditorView.decorations.compute([
1057
+ annotationsState
1058
+ ], (state) => {
1059
+ const annotations2 = state.field(annotationsState);
1060
+ const decorations = annotations2.map((annotation) => {
1061
+ const range = Cursor.getRangeFromCursor(state, annotation.cursor);
1062
+ return range && annotationMark.range(range.from, range.to);
1063
+ }).filter(import_util.isNotFalsy);
1064
+ return import_view3.Decoration.set(decorations);
1065
+ }),
1066
+ styles
1067
+ ];
1068
+ };
1069
+ var styles = import_view3.EditorView.theme({
1070
+ ".cm-annotation": {
1071
+ textDecoration: "underline",
497
1072
  textDecorationStyle: "wavy",
498
1073
  textDecorationColor: "var(--dx-error)"
499
1074
  }
@@ -503,7 +1078,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
503
1078
  // https://codemirror.net/docs/ref/#view.keymap
504
1079
  // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
505
1080
  // TODO(burdon): Set custom keymap.
506
- import_view3.keymap.of(import_autocomplete.completionKeymap),
1081
+ import_view4.keymap.of(import_autocomplete.completionKeymap),
507
1082
  // https://codemirror.net/examples/autocompletion
508
1083
  // https://codemirror.net/docs/ref/#autocomplete.autocompletion
509
1084
  (0, import_autocomplete.autocompletion)({
@@ -563,11 +1138,11 @@ var cursorConverter = (accessor) => ({
563
1138
  });
564
1139
  var getPath = (state, field) => state.field(field).path;
565
1140
  var getLastHeads = (state, field) => state.field(field).lastHeads;
566
- var updateHeadsEffect = import_state4.StateEffect.define({});
1141
+ var updateHeadsEffect = import_state5.StateEffect.define({});
567
1142
  var updateHeads = (newHeads) => updateHeadsEffect.of({
568
1143
  newHeads
569
1144
  });
570
- var reconcileAnnotation = import_state4.Annotation.define();
1145
+ var reconcileAnnotation = import_state5.Annotation.define();
571
1146
  var isReconcile = (tr) => {
572
1147
  return !!tr.annotation(reconcileAnnotation);
573
1148
  };
@@ -603,7 +1178,7 @@ var updateCodeMirror = (view, selection, target, patches) => {
603
1178
  for (const patch of patches) {
604
1179
  const changeSpec = handlePatch(patch, target, view.state);
605
1180
  if (changeSpec != null) {
606
- const changeSet = import_state5.ChangeSet.of(changeSpec, view.state.doc.length, "\n");
1181
+ const changeSet = import_state6.ChangeSet.of(changeSpec, view.state.doc.length, "\n");
607
1182
  selection = selection.map(changeSet, 1);
608
1183
  view.dispatch({
609
1184
  changes: changeSet,
@@ -746,7 +1321,7 @@ var Syncer = class {
746
1321
  }
747
1322
  };
748
1323
  var automerge = (accessor) => {
749
- const syncState = import_state3.StateField.define({
1324
+ const syncState = import_state4.StateField.define({
750
1325
  create: () => ({
751
1326
  path: accessor.path.slice(),
752
1327
  lastHeads: import_automerge.next.getHeads(accessor.handle.docSync()),
@@ -781,7 +1356,7 @@ var automerge = (accessor) => {
781
1356
  // Track heads.
782
1357
  syncState,
783
1358
  // Reconcile external updates.
784
- import_view4.ViewPlugin.fromClass(class {
1359
+ import_view5.ViewPlugin.fromClass(class {
785
1360
  constructor(_view) {
786
1361
  this._view = _view;
787
1362
  this._handleChange = () => {
@@ -794,7 +1369,7 @@ var automerge = (accessor) => {
794
1369
  }
795
1370
  }),
796
1371
  // Reconcile local updates.
797
- import_view4.EditorView.updateListener.of(({ view, changes }) => {
1372
+ import_view5.EditorView.updateListener.of(({ view, changes }) => {
798
1373
  if (!changes.empty) {
799
1374
  syncer.reconcile(view, true);
800
1375
  }
@@ -813,11 +1388,11 @@ var dummyProvider = {
813
1388
  }
814
1389
  };
815
1390
  var awarenessProvider = singleValueFacet(dummyProvider);
816
- var RemoteSelectionChangedAnnotation = import_state6.Annotation.define();
1391
+ var RemoteSelectionChangedAnnotation = import_state7.Annotation.define();
817
1392
  var awareness = (provider = dummyProvider) => {
818
1393
  return [
819
1394
  awarenessProvider.of(provider),
820
- import_view5.ViewPlugin.fromClass(RemoteSelectionsDecorator, {
1395
+ import_view6.ViewPlugin.fromClass(RemoteSelectionsDecorator, {
821
1396
  decorations: (value) => value.decorations
822
1397
  }),
823
1398
  styles2
@@ -829,7 +1404,7 @@ var RemoteSelectionsDecorator = class {
829
1404
  F: __dxlog_file3,
830
1405
  L: 80
831
1406
  });
832
- this.decorations = import_state6.RangeSet.of([]);
1407
+ this.decorations = import_state7.RangeSet.of([]);
833
1408
  this._cursorConverter = view.state.facet(Cursor.converter);
834
1409
  this._provider = view.state.facet(awarenessProvider);
835
1410
  this._provider.open();
@@ -881,7 +1456,7 @@ var RemoteSelectionsDecorator = class {
881
1456
  decorations.push({
882
1457
  from: start,
883
1458
  to: end,
884
- value: import_view5.Decoration.mark({
1459
+ value: import_view6.Decoration.mark({
885
1460
  attributes: {
886
1461
  style: `background-color: ${lightColor}`
887
1462
  },
@@ -892,7 +1467,7 @@ var RemoteSelectionsDecorator = class {
892
1467
  decorations.push({
893
1468
  from: start,
894
1469
  to: startLine.from + startLine.length,
895
- value: import_view5.Decoration.mark({
1470
+ value: import_view6.Decoration.mark({
896
1471
  attributes: {
897
1472
  style: `background-color: ${lightColor}`
898
1473
  },
@@ -902,7 +1477,7 @@ var RemoteSelectionsDecorator = class {
902
1477
  decorations.push({
903
1478
  from: endLine.from,
904
1479
  to: end,
905
- value: import_view5.Decoration.mark({
1480
+ value: import_view6.Decoration.mark({
906
1481
  attributes: {
907
1482
  style: `background-color: ${lightColor}`
908
1483
  },
@@ -914,7 +1489,7 @@ var RemoteSelectionsDecorator = class {
914
1489
  decorations.push({
915
1490
  from: linePos,
916
1491
  to: linePos,
917
- value: import_view5.Decoration.line({
1492
+ value: import_view6.Decoration.line({
918
1493
  attributes: {
919
1494
  style: `background-color: ${lightColor}`,
920
1495
  class: "cm-collab-selectionLine"
@@ -926,17 +1501,17 @@ var RemoteSelectionsDecorator = class {
926
1501
  decorations.push({
927
1502
  from: head,
928
1503
  to: head,
929
- value: import_view5.Decoration.widget({
1504
+ value: import_view6.Decoration.widget({
930
1505
  side: head - anchor > 0 ? -1 : 1,
931
1506
  block: false,
932
1507
  widget: new RemoteCaretWidget(state.info.displayName ?? "Anonymous", darkColor)
933
1508
  })
934
1509
  });
935
1510
  }
936
- this.decorations = import_view5.Decoration.set(decorations, true);
1511
+ this.decorations = import_view6.Decoration.set(decorations, true);
937
1512
  }
938
1513
  };
939
- var RemoteCaretWidget = class extends import_view5.WidgetType {
1514
+ var RemoteCaretWidget = class extends import_view6.WidgetType {
940
1515
  constructor(_name, _color) {
941
1516
  super();
942
1517
  this._name = _name;
@@ -972,7 +1547,7 @@ var RemoteCaretWidget = class extends import_view5.WidgetType {
972
1547
  return true;
973
1548
  }
974
1549
  };
975
- var styles2 = import_view5.EditorView.theme({
1550
+ var styles2 = import_view6.EditorView.theme({
976
1551
  ".cm-collab-selection": {},
977
1552
  ".cm-collab-selectionLine": {
978
1553
  padding: 0,
@@ -1175,12 +1750,12 @@ var blast = (options = defaultOptions) => {
1175
1750
  };
1176
1751
  return [
1177
1752
  // Cursor moved.
1178
- import_view6.EditorView.updateListener.of((update2) => {
1753
+ import_view7.EditorView.updateListener.of((update2) => {
1179
1754
  if (blaster?.node !== update2.view.scrollDOM) {
1180
1755
  if (blaster) {
1181
1756
  blaster.destroy();
1182
1757
  }
1183
- blaster = new Blaster(update2.view.scrollDOM, (0, import_lodash.default)({
1758
+ blaster = new Blaster(update2.view.scrollDOM, (0, import_lodash2.default)({
1184
1759
  particleGravity: 0.2,
1185
1760
  particleShrinkRate: 0.995,
1186
1761
  color: () => [
@@ -1206,7 +1781,7 @@ var blast = (options = defaultOptions) => {
1206
1781
  }
1207
1782
  }
1208
1783
  }),
1209
- import_view6.keymap.of([
1784
+ import_view7.keymap.of([
1210
1785
  {
1211
1786
  any: (_, event) => {
1212
1787
  if (blaster) {
@@ -1436,7 +2011,7 @@ var random = (min, max) => {
1436
2011
  return min + ~~(Math.random() * (max - min + 1));
1437
2012
  };
1438
2013
  var commandConfig = singleValueFacet();
1439
- var commandState = import_state8.StateField.define({
2014
+ var commandState = import_state9.StateField.define({
1440
2015
  create: () => ({}),
1441
2016
  update: (state, tr) => {
1442
2017
  for (const effect of tr.effects) {
@@ -1492,11 +2067,11 @@ var commandState = import_state8.StateField.define({
1492
2067
  return state;
1493
2068
  },
1494
2069
  provide: (field) => [
1495
- import_view9.showTooltip.from(field, (value) => value.tooltip ?? null)
2070
+ import_view10.showTooltip.from(field, (value) => value.tooltip ?? null)
1496
2071
  ]
1497
2072
  });
1498
- var openEffect = import_state8.StateEffect.define();
1499
- var closeEffect = import_state8.StateEffect.define();
2073
+ var openEffect = import_state9.StateEffect.define();
2074
+ var closeEffect = import_state9.StateEffect.define();
1500
2075
  var openCommand = (view) => {
1501
2076
  if (view.state.field(commandState, false)) {
1502
2077
  const selection = view.state.selection.main;
@@ -1532,7 +2107,7 @@ var commandKeyBindings = [
1532
2107
  run: closeCommand
1533
2108
  }
1534
2109
  ];
1535
- var CommandHint = class extends import_view8.WidgetType {
2110
+ var CommandHint = class extends import_view9.WidgetType {
1536
2111
  constructor(content) {
1537
2112
  super();
1538
2113
  this.content = content;
@@ -1571,12 +2146,12 @@ var CommandHint = class extends import_view8.WidgetType {
1571
2146
  return false;
1572
2147
  }
1573
2148
  };
1574
- var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
2149
+ var hintViewPlugin = ({ onHint }) => import_view9.ViewPlugin.fromClass(class {
1575
2150
  constructor() {
1576
- this.deco = import_view8.Decoration.none;
2151
+ this.deco = import_view9.Decoration.none;
1577
2152
  }
1578
2153
  update(update2) {
1579
- const builder = new import_state7.RangeSetBuilder();
2154
+ const builder = new import_state8.RangeSetBuilder();
1580
2155
  const cState = update2.view.state.field(commandState, false);
1581
2156
  if (!cState?.tooltip) {
1582
2157
  const selection = update2.view.state.selection.main;
@@ -1584,7 +2159,7 @@ var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
1584
2159
  if (selection.from === selection.to && line.from === line.to) {
1585
2160
  const hint = onHint();
1586
2161
  if (hint) {
1587
- builder.add(selection.from, selection.to, import_view8.Decoration.widget({
2162
+ builder.add(selection.from, selection.to, import_view9.Decoration.widget({
1588
2163
  widget: new CommandHint(hint)
1589
2164
  }));
1590
2165
  }
@@ -1594,16 +2169,16 @@ var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
1594
2169
  }
1595
2170
  }, {
1596
2171
  provide: (plugin) => [
1597
- import_view8.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view8.Decoration.none)
2172
+ import_view9.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view9.Decoration.none)
1598
2173
  ]
1599
2174
  });
1600
2175
  var command = (options) => {
1601
2176
  return [
1602
2177
  commandConfig.of(options),
1603
2178
  commandState,
1604
- import_view7.keymap.of(commandKeyBindings),
2179
+ import_view8.keymap.of(commandKeyBindings),
1605
2180
  hintViewPlugin(options),
1606
- import_view7.EditorView.focusChangeEffect.of((_, focusing) => {
2181
+ import_view8.EditorView.focusChangeEffect.of((_, focusing) => {
1607
2182
  return focusing ? closeEffect.of(null) : null;
1608
2183
  })
1609
2184
  ];
@@ -1615,10 +2190,10 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1615
2190
  return {
1616
2191
  selection,
1617
2192
  scrollIntoView: !scrollTo,
1618
- effects: scrollTo ? import_view11.EditorView.scrollIntoView(scrollTo, {
2193
+ effects: scrollTo ? import_view12.EditorView.scrollIntoView(scrollTo, {
1619
2194
  yMargin: 96
1620
2195
  }) : void 0,
1621
- annotations: import_state10.Transaction.userEvent.of(stateRestoreAnnotation)
2196
+ annotations: import_state11.Transaction.userEvent.of(stateRestoreAnnotation)
1622
2197
  };
1623
2198
  };
1624
2199
  var createEditorStateStore = (keyPrefix) => ({
@@ -1657,7 +2232,7 @@ var selectionState = ({ getState, setState } = {}) => {
1657
2232
  // setStateDebounced(id, {});
1658
2233
  // },
1659
2234
  // }),
1660
- import_view11.EditorView.updateListener.of(({ view, transactions }) => {
2235
+ import_view12.EditorView.updateListener.of(({ view, transactions }) => {
1661
2236
  const id = view.state.facet(documentId);
1662
2237
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1663
2238
  return;
@@ -1680,7 +2255,7 @@ var selectionState = ({ getState, setState } = {}) => {
1680
2255
  }
1681
2256
  }
1682
2257
  }),
1683
- getState && import_view11.keymap.of([
2258
+ getState && import_view12.keymap.of([
1684
2259
  {
1685
2260
  key: "ctrl-r",
1686
2261
  run: (view) => {
@@ -1695,10 +2270,10 @@ var selectionState = ({ getState, setState } = {}) => {
1695
2270
  ].filter(import_util3.isNotFalsy);
1696
2271
  };
1697
2272
  var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
1698
- var setComments = import_state9.StateEffect.define();
1699
- var setSelection = import_state9.StateEffect.define();
1700
- var setCommentState = import_state9.StateEffect.define();
1701
- var commentsState = import_state9.StateField.define({
2273
+ var setComments = import_state10.StateEffect.define();
2274
+ var setSelection = import_state10.StateEffect.define();
2275
+ var setCommentState = import_state10.StateEffect.define();
2276
+ var commentsState = import_state10.StateField.define({
1702
2277
  create: (state) => ({
1703
2278
  id: state.facet(documentId),
1704
2279
  comments: [],
@@ -1736,7 +2311,7 @@ var commentsState = import_state9.StateField.define({
1736
2311
  return value;
1737
2312
  }
1738
2313
  });
1739
- var styles3 = import_view10.EditorView.theme({
2314
+ var styles3 = import_view11.EditorView.theme({
1740
2315
  ".cm-comment, .cm-comment-current": {
1741
2316
  margin: "0 -3px",
1742
2317
  padding: "3px",
@@ -1749,23 +2324,23 @@ var styles3 = import_view10.EditorView.theme({
1749
2324
  textDecoration: "underline"
1750
2325
  }
1751
2326
  });
1752
- var createCommentMark = (id, isCurrent) => import_view10.Decoration.mark({
2327
+ var createCommentMark = (id, isCurrent) => import_view11.Decoration.mark({
1753
2328
  class: isCurrent ? "cm-comment-current" : "cm-comment",
1754
2329
  attributes: {
1755
2330
  "data-testid": "cm-comment",
1756
2331
  "data-comment-id": id
1757
2332
  }
1758
2333
  });
1759
- var commentsDecorations = import_view10.EditorView.decorations.compute([
2334
+ var commentsDecorations = import_view11.EditorView.decorations.compute([
1760
2335
  commentsState
1761
2336
  ], (state) => {
1762
2337
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
1763
- const decorations = (0, import_lodash2.default)(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
2338
+ const decorations = (0, import_lodash3.default)(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
1764
2339
  const range = comment.range;
1765
2340
  if (!range) {
1766
2341
  import_log4.log.warn("Invalid range:", range, {
1767
2342
  F: __dxlog_file7,
1768
- L: 142,
2343
+ L: 144,
1769
2344
  S: void 0,
1770
2345
  C: (f, a) => f(...a)
1771
2346
  });
@@ -1776,10 +2351,10 @@ var commentsDecorations = import_view10.EditorView.decorations.compute([
1776
2351
  const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
1777
2352
  return mark.range(range.from, range.to);
1778
2353
  }).filter(import_util2.nonNullable);
1779
- return import_view10.Decoration.set(decorations);
2354
+ return import_view11.Decoration.set(decorations);
1780
2355
  });
1781
- var commentClickedEffect = import_state9.StateEffect.define();
1782
- var handleCommentClick = import_view10.EditorView.domEventHandlers({
2356
+ var commentClickedEffect = import_state10.StateEffect.define();
2357
+ var handleCommentClick = import_view11.EditorView.domEventHandlers({
1783
2358
  click: (event, view) => {
1784
2359
  let target = event.target;
1785
2360
  const editorRoot = view.dom;
@@ -1818,7 +2393,7 @@ var trackPastedComments = (onUpdate) => {
1818
2393
  }
1819
2394
  };
1820
2395
  return [
1821
- import_view10.EditorView.domEventHandlers({
2396
+ import_view11.EditorView.domEventHandlers({
1822
2397
  cut: handleTrack,
1823
2398
  copy: handleTrack
1824
2399
  }),
@@ -1840,7 +2415,7 @@ var trackPastedComments = (onUpdate) => {
1840
2415
  return effects;
1841
2416
  }),
1842
2417
  // Handle paste or the undo of comment deletion.
1843
- import_view10.EditorView.updateListener.of((update2) => {
2418
+ import_view11.EditorView.updateListener.of((update2) => {
1844
2419
  const restore = [];
1845
2420
  for (let i = 0; i < update2.transactions.length; i++) {
1846
2421
  const tr = update2.transactions[i];
@@ -1896,10 +2471,10 @@ var mapTrackedComment = (comment, changes) => ({
1896
2471
  from: changes.mapPos(comment.from, 1),
1897
2472
  to: changes.mapPos(comment.to, 1)
1898
2473
  });
1899
- var restoreCommentEffect = import_state9.StateEffect.define({
2474
+ var restoreCommentEffect = import_state10.StateEffect.define({
1900
2475
  map: mapTrackedComment
1901
2476
  });
1902
- var createComment = (view) => {
2477
+ var createComment2 = (view) => {
1903
2478
  const options = view.state.facet(optionsFacet);
1904
2479
  const { from, to } = view.state.selection.main;
1905
2480
  if (from === to) {
@@ -1941,17 +2516,17 @@ var comments = (options = {}) => {
1941
2516
  //
1942
2517
  // Keymap.
1943
2518
  //
1944
- options.onCreate && import_view10.keymap.of([
2519
+ options.onCreate && import_view11.keymap.of([
1945
2520
  {
1946
2521
  key: shortcut,
1947
- run: callbackWrapper(createComment)
2522
+ run: callbackWrapper(createComment2)
1948
2523
  }
1949
2524
  ]),
1950
2525
  //
1951
2526
  // Hover tooltip (for key shortcut hints, etc.)
1952
2527
  // TODO(burdon): Factor out to generic hints extension for current selection/line.
1953
2528
  //
1954
- options.onHover && (0, import_view10.hoverTooltip)((view, pos) => {
2529
+ options.onHover && (0, import_view11.hoverTooltip)((view, pos) => {
1955
2530
  const selection = view.state.selection.main;
1956
2531
  if (selection && pos >= selection.from && pos <= selection.to) {
1957
2532
  return {
@@ -1980,7 +2555,7 @@ var comments = (options = {}) => {
1980
2555
  //
1981
2556
  // Track deleted ranges and update ranges for decorations.
1982
2557
  //
1983
- import_view10.EditorView.updateListener.of(({ view, state, changes }) => {
2558
+ import_view11.EditorView.updateListener.of(({ view, state, changes }) => {
1984
2559
  let mod = false;
1985
2560
  const { comments: comments2, ...value } = state.field(commentsState);
1986
2561
  changes.iterChanges((from, to, from2, to2) => {
@@ -2012,7 +2587,7 @@ var comments = (options = {}) => {
2012
2587
  //
2013
2588
  // Track selection/proximity.
2014
2589
  //
2015
- import_view10.EditorView.updateListener.of(({ view, state }) => {
2590
+ import_view11.EditorView.updateListener.of(({ view, state }) => {
2016
2591
  let min = Infinity;
2017
2592
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2018
2593
  const { head } = state.selection.main;
@@ -2039,419 +2614,192 @@ var comments = (options = {}) => {
2039
2614
  id: state.facet(documentId),
2040
2615
  comments: comments2.map(({ comment, range }) => ({
2041
2616
  comment,
2042
- range,
2043
- location: view.coordsAtPos(range.from)
2044
- }))
2045
- });
2046
- }
2047
- }),
2048
- options.onUpdate && trackPastedComments(options.onUpdate)
2049
- ].filter(import_util2.nonNullable);
2050
- };
2051
- var scrollThreadIntoView = (view, id, center = true) => {
2052
- const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
2053
- if (!comment?.comment.cursor) {
2054
- return;
2055
- }
2056
- const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
2057
- if (range) {
2058
- const currentSelection = view.state.selection.main;
2059
- const currentScrollPosition = view.scrollDOM.scrollTop;
2060
- const targetScrollPosition = view.coordsAtPos(range.from)?.top;
2061
- const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
2062
- const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
2063
- if (needsScroll || needsSelectionUpdate) {
2064
- view.dispatch({
2065
- selection: needsSelectionUpdate ? {
2066
- anchor: range.from
2067
- } : void 0,
2068
- effects: [
2069
- needsScroll ? import_view10.EditorView.scrollIntoView(range.from, center ? {
2070
- y: "center"
2071
- } : void 0) : [],
2072
- needsSelectionUpdate ? setSelection.of({
2073
- current: id
2074
- }) : []
2075
- ].flat()
2076
- });
2077
- }
2078
- }
2079
- };
2080
- var selectionOverlapsComment = (state) => {
2081
- const commentState = state.field(commentsState, false);
2082
- if (commentState === void 0) {
2083
- return false;
2084
- }
2085
- const { selection } = state;
2086
- for (const range of selection.ranges) {
2087
- if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
2088
- return true;
2089
- }
2090
- }
2091
- return false;
2092
- };
2093
- var hasActiveSelection = (state) => {
2094
- return state.selection.ranges.some((range) => !range.empty);
2095
- };
2096
- var ExternalCommentSync = class {
2097
- constructor(view, id, subscribe, getComments) {
2098
- this.destroy = () => {
2099
- this.unsubscribe();
2100
- };
2101
- const updateComments = () => {
2102
- const comments2 = getComments();
2103
- if (id === view.state.facet(documentId)) {
2104
- queueMicrotask(() => view.dispatch({
2105
- effects: setComments.of({
2106
- id,
2107
- comments: comments2
2108
- })
2109
- }));
2110
- }
2111
- };
2112
- this.unsubscribe = subscribe(updateComments);
2113
- }
2114
- };
2115
- var createExternalCommentSync = (id, subscribe, getComments) => import_view10.ViewPlugin.fromClass(class {
2116
- constructor(view) {
2117
- return new ExternalCommentSync(view, id, subscribe, getComments);
2118
- }
2119
- });
2120
- var useCommentState = () => {
2121
- const [state, setState] = (0, import_react4.useState)({
2122
- comment: false,
2123
- selection: false
2124
- });
2125
- const observer = (0, import_react4.useMemo)(() => import_view10.EditorView.updateListener.of((update2) => {
2126
- if (update2.docChanged || update2.selectionSet) {
2127
- setState({
2128
- comment: selectionOverlapsComment(update2.state),
2129
- selection: hasActiveSelection(update2.state)
2130
- });
2131
- }
2132
- }), []);
2133
- return [
2134
- state,
2135
- observer
2136
- ];
2137
- };
2138
- var useComments = (view, id, comments2) => {
2139
- (0, import_react4.useEffect)(() => {
2140
- if (view) {
2141
- if (id === view.state.facet(documentId)) {
2142
- view.dispatch({
2143
- effects: setComments.of({
2144
- id,
2145
- comments: comments2 ?? []
2146
- })
2147
- });
2148
- }
2149
- }
2150
- });
2151
- };
2152
- var useCommentClickListener = (onCommentClick) => {
2153
- return (0, import_react4.useMemo)(() => import_view10.EditorView.updateListener.of((update2) => {
2154
- update2.transactions.forEach((transaction) => {
2155
- transaction.effects.forEach((effect) => {
2156
- if (effect.is(commentClickedEffect)) {
2157
- onCommentClick(effect.value);
2158
- }
2159
- });
2160
- });
2161
- }), [
2162
- onCommentClick
2163
- ]);
2164
- };
2165
- var debugNodeLogger = (log8 = console.log) => {
2166
- const logTokens = (state) => (0, import_language.syntaxTree)(state).iterate({
2167
- enter: (node) => log8(node.type)
2168
- });
2169
- return import_state11.StateField.define({
2170
- create: (state) => logTokens(state),
2171
- update: (_, tr) => logTokens(tr.state)
2172
- });
2173
- };
2174
- var styles4 = import_view12.EditorView.theme({
2175
- ".cm-dropCursor": {
2176
- borderLeft: "2px solid var(--dx-accentText)",
2177
- color: "var(--dx-accentText)",
2178
- padding: "0 4px"
2179
- },
2180
- ".cm-dropCursor:after": {
2181
- content: '"\u2190"'
2182
- }
2183
- });
2184
- var dropFile = (options = {}) => {
2185
- return [
2186
- styles4,
2187
- (0, import_view12.dropCursor)(),
2188
- import_view12.EditorView.domEventHandlers({
2189
- drop: (event, view) => {
2190
- event.preventDefault();
2191
- const files = event.dataTransfer?.files;
2192
- const pos = view.posAtCoords(event);
2193
- if (files?.length && pos !== null) {
2194
- view.dispatch({
2195
- selection: {
2196
- anchor: pos
2197
- }
2198
- });
2199
- options.onDrop?.(view, {
2200
- files
2201
- });
2202
- }
2203
- }
2204
- })
2205
- ];
2206
- };
2207
- var focusEffect = import_state13.StateEffect.define();
2208
- var focusField = import_state13.StateField.define({
2209
- create: () => false,
2210
- update: (value, tr) => {
2211
- for (const effect of tr.effects) {
2212
- if (effect.is(focusEffect)) {
2213
- return effect.value;
2214
- }
2215
- }
2216
- return value;
2217
- }
2218
- });
2219
- var focus = [
2220
- focusField,
2221
- import_view14.EditorView.domEventHandlers({
2222
- focus: (event, view) => {
2223
- setTimeout(() => view.dispatch({
2224
- effects: focusEffect.of(true)
2225
- }));
2226
- },
2227
- blur: (event, view) => {
2228
- setTimeout(() => view.dispatch({
2229
- effects: focusEffect.of(false)
2230
- }));
2231
- }
2232
- })
2233
- ];
2234
- var headings = {
2235
- 1: "text-4xl",
2236
- 2: "text-3xl",
2237
- 3: "text-2xl",
2238
- 4: "text-xl",
2239
- 5: "text-lg",
2240
- 6: "text-md"
2241
- };
2242
- var theme = {
2243
- code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
2244
- codeMark: "font-mono text-primary-500",
2245
- mark: "opacity-50",
2246
- heading: (level) => {
2247
- return (0, import_react_ui_theme4.mx)(headings[level], "dark:text-primary-400");
2248
- }
2249
- };
2250
- var getToken = (path, defaultValue) => {
2251
- const value = (0, import_lodash5.default)(import_react_ui_theme5.tokens, path, defaultValue);
2252
- return value?.toString() ?? "";
2253
- };
2254
- var fontBody = getToken("fontFamily.body");
2255
- var fontMono = getToken("fontFamily.mono");
2256
- var defaultTheme = {
2257
- "&": {},
2258
- "&.cm-focused": {
2259
- outline: "none"
2260
- },
2261
- /**
2262
- * Scroller
2263
- */
2264
- ".cm-scroller": {
2265
- overflowY: "auto"
2266
- },
2267
- /**
2268
- * Content
2269
- * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
2270
- */
2271
- ".cm-content": {
2272
- padding: "unset",
2273
- fontFamily: fontBody,
2274
- // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
2275
- fontSize: "16px",
2276
- lineHeight: 1.5,
2277
- color: "unset"
2278
- },
2279
- /**
2280
- * Gutters
2281
- * NOTE: Gutters should have the same top margin as the content.
2282
- * NOTE: They can't be transparent since the content needs to scroll below.
2283
- */
2284
- ".cm-gutters": {
2285
- background: "var(--surface-bg)",
2286
- borderRight: "none"
2287
- },
2288
- ".cm-gutter": {},
2289
- ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2290
- minWidth: "40px",
2291
- alignContent: "center"
2292
- },
2293
- /**
2294
- * Height is set to match the corresponding line.
2295
- */
2296
- ".cm-gutterElement": {
2297
- alignItems: "center",
2298
- fontSize: "16px"
2299
- },
2300
- /**
2301
- * Line.
2302
- */
2303
- ".cm-line": {
2304
- paddingInline: 0
2305
- },
2306
- ".cm-activeLine": {
2307
- background: "var(--dx-cmActiveLine)"
2308
- },
2309
- /**
2310
- * Cursor (layer).
2311
- */
2312
- ".cm-cursor, .cm-dropCursor": {
2313
- borderLeft: "2px solid var(--dx-cmCursor)"
2314
- },
2315
- ".cm-placeholder": {
2316
- color: "var(--dx-subdued)"
2317
- },
2318
- /**
2319
- * Selection (layer).
2320
- */
2321
- ".cm-selectionBackground": {
2322
- background: "var(--dx-cmSelection)"
2323
- },
2324
- /**
2325
- * Search.
2326
- * NOTE: Matches comment.
2327
- */
2328
- ".cm-searchMatch": {
2329
- margin: "0 -3px",
2330
- padding: "3px",
2331
- borderRadius: "3px",
2332
- background: "var(--dx-cmHighlightSurface)",
2333
- color: "var(--dx-cmHighlight)"
2334
- },
2335
- ".cm-searchMatch-selected": {
2336
- textDecoration: "underline"
2337
- },
2338
- /**
2339
- * Link.
2340
- */
2341
- ".cm-link": {
2342
- textDecorationLine: "underline",
2343
- textDecorationThickness: "1px",
2344
- textUnderlineOffset: "2px",
2345
- borderRadius: ".125rem"
2346
- },
2347
- ".cm-link > span": {
2348
- color: "var(--dx-accentText)"
2349
- },
2350
- /**
2351
- * Tooltip.
2352
- */
2353
- ".cm-tooltip": {
2354
- background: "var(--dx-base)"
2355
- },
2356
- ".cm-tooltip-below": {},
2357
- /**
2358
- * Autocomplete.
2359
- * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
2360
- */
2361
- ".cm-tooltip.cm-tooltip-autocomplete": {
2362
- marginTop: "4px",
2363
- marginLeft: "-3px"
2364
- },
2365
- ".cm-tooltip.cm-tooltip-autocomplete > ul": {
2366
- maxHeight: "20em"
2367
- },
2368
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
2369
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
2370
- ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2371
- paddingLeft: "4px !important",
2372
- borderBottom: "none !important",
2373
- color: "var(--dx-accentText)"
2374
- },
2375
- ".cm-tooltip.cm-completionInfo": {
2376
- width: "360px !important",
2377
- margin: "-10px 1px 0 1px",
2378
- padding: "8px !important",
2379
- borderColor: "var(--dx-separator)"
2380
- },
2381
- ".cm-completionIcon": {
2382
- display: "none"
2383
- },
2384
- ".cm-completionLabel": {
2385
- fontFamily: fontBody
2386
- },
2387
- ".cm-completionMatchedText": {
2388
- textDecoration: "none !important",
2389
- opacity: 0.5
2390
- },
2391
- /**
2392
- * Panels
2393
- * https://github.com/codemirror/search/blob/main/src/search.ts#L745
2394
- *
2395
- * Find/replace panel.
2396
- * <div class="cm-announced">...</div>
2397
- * <div class="cm-scroller">...</div>
2398
- * <div class="cm-panels cm-panels-bottom">
2399
- * <div class="cm-search cm-panel">
2400
- * <input class="cm-textfield" />
2401
- * <button class="cm-button">...</button>
2402
- * <label><input type="checkbox" />...</label>
2403
- * </div>
2404
- * </div
2405
- */
2406
- // TODO(burdon): Implement custom panel (with icon buttons).
2407
- ".cm-panels": {},
2408
- ".cm-panel": {
2409
- fontFamily: fontBody,
2410
- backgroundColor: "var(--surface-bg)"
2411
- },
2412
- ".cm-panel input, .cm-panel button, .cm-panel label": {
2413
- color: "var(--dx-subdued)",
2414
- fontFamily: fontBody,
2415
- fontSize: "14px",
2416
- all: "unset",
2417
- margin: "3px !important",
2418
- padding: "2px 6px !important",
2419
- outline: "1px solid transparent"
2420
- },
2421
- ".cm-panel input, .cm-panel button": {
2422
- backgroundColor: "var(--dx-input)"
2423
- },
2424
- ".cm-panel input:focus, .cm-panel button:focus": {
2425
- outline: "1px solid var(--dx-accentFocusIndicator)"
2426
- },
2427
- ".cm-panel label": {
2428
- display: "inline-flex",
2429
- alignItems: "center",
2430
- cursor: "pointer"
2431
- },
2432
- ".cm-panel input.cm-textfield": {},
2433
- ".cm-panel input[type=checkbox]": {
2434
- width: "8px",
2435
- height: "8px",
2436
- marginRight: "6px !important",
2437
- padding: "2px !important",
2438
- color: "var(--dx-accentFocusIndicator)"
2439
- },
2440
- ".cm-panel button": {
2441
- "&:hover": {
2442
- backgroundColor: "var(--dx-accentSurfaceHover) !important"
2443
- },
2444
- "&:active": {
2445
- backgroundColor: "var(--dx-accentSurfaceHover)"
2617
+ range,
2618
+ location: view.coordsAtPos(range.from)
2619
+ }))
2620
+ });
2621
+ }
2622
+ }),
2623
+ options.onUpdate && trackPastedComments(options.onUpdate)
2624
+ ].filter(import_util2.nonNullable);
2625
+ };
2626
+ var scrollThreadIntoView = (view, id, center = true) => {
2627
+ const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
2628
+ if (!comment?.comment.cursor) {
2629
+ return;
2630
+ }
2631
+ const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
2632
+ if (range) {
2633
+ const currentSelection = view.state.selection.main;
2634
+ const currentScrollPosition = view.scrollDOM.scrollTop;
2635
+ const targetScrollPosition = view.coordsAtPos(range.from)?.top;
2636
+ const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
2637
+ const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
2638
+ if (needsScroll || needsSelectionUpdate) {
2639
+ view.dispatch({
2640
+ selection: needsSelectionUpdate ? {
2641
+ anchor: range.from
2642
+ } : void 0,
2643
+ effects: [
2644
+ needsScroll ? import_view11.EditorView.scrollIntoView(range.from, center ? {
2645
+ y: "center"
2646
+ } : void 0) : [],
2647
+ needsSelectionUpdate ? setSelection.of({
2648
+ current: id
2649
+ }) : []
2650
+ ].flat()
2651
+ });
2652
+ }
2653
+ }
2654
+ };
2655
+ var selectionOverlapsComment = (state) => {
2656
+ const commentState = state.field(commentsState, false);
2657
+ if (commentState === void 0) {
2658
+ return false;
2659
+ }
2660
+ const { selection } = state;
2661
+ for (const range of selection.ranges) {
2662
+ if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
2663
+ return true;
2664
+ }
2665
+ }
2666
+ return false;
2667
+ };
2668
+ var hasActiveSelection = (state) => {
2669
+ return state.selection.ranges.some((range) => !range.empty);
2670
+ };
2671
+ var ExternalCommentSync = class {
2672
+ constructor(view, id, subscribe, getComments) {
2673
+ this.destroy = () => {
2674
+ this.unsubscribe();
2675
+ };
2676
+ const updateComments = () => {
2677
+ const comments2 = getComments();
2678
+ if (id === view.state.facet(documentId)) {
2679
+ queueMicrotask(() => view.dispatch({
2680
+ effects: setComments.of({
2681
+ id,
2682
+ comments: comments2
2683
+ })
2684
+ }));
2685
+ }
2686
+ };
2687
+ this.unsubscribe = subscribe(updateComments);
2688
+ }
2689
+ };
2690
+ var createExternalCommentSync = (id, subscribe, getComments) => import_view11.ViewPlugin.fromClass(class {
2691
+ constructor(view) {
2692
+ return new ExternalCommentSync(view, id, subscribe, getComments);
2693
+ }
2694
+ });
2695
+ var useCommentState = (state) => {
2696
+ return (0, import_react4.useMemo)(() => import_view11.EditorView.updateListener.of((update2) => {
2697
+ if (update2.docChanged || update2.selectionSet) {
2698
+ state.comment = selectionOverlapsComment(update2.state);
2699
+ state.selection = hasActiveSelection(update2.state);
2700
+ }
2701
+ }), [
2702
+ state
2703
+ ]);
2704
+ };
2705
+ var useComments = (view, id, comments2) => {
2706
+ (0, import_react4.useEffect)(() => {
2707
+ if (view) {
2708
+ if (id === view.state.facet(documentId)) {
2709
+ view.dispatch({
2710
+ effects: setComments.of({
2711
+ id,
2712
+ comments: comments2 ?? []
2713
+ })
2714
+ });
2715
+ }
2446
2716
  }
2717
+ });
2718
+ };
2719
+ var useCommentClickListener = (onCommentClick) => {
2720
+ return (0, import_react4.useMemo)(() => import_view11.EditorView.updateListener.of((update2) => {
2721
+ update2.transactions.forEach((transaction) => {
2722
+ transaction.effects.forEach((effect) => {
2723
+ if (effect.is(commentClickedEffect)) {
2724
+ onCommentClick(effect.value);
2725
+ }
2726
+ });
2727
+ });
2728
+ }), [
2729
+ onCommentClick
2730
+ ]);
2731
+ };
2732
+ var debugNodeLogger = (log8 = console.log) => {
2733
+ const logTokens = (state) => (0, import_language.syntaxTree)(state).iterate({
2734
+ enter: (node) => log8(node.type)
2735
+ });
2736
+ return import_state12.StateField.define({
2737
+ create: (state) => logTokens(state),
2738
+ update: (_, tr) => logTokens(tr.state)
2739
+ });
2740
+ };
2741
+ var styles4 = import_view13.EditorView.theme({
2742
+ ".cm-dropCursor": {
2743
+ borderLeft: "2px solid var(--dx-accentText)",
2744
+ color: "var(--dx-accentText)",
2745
+ padding: "0 4px"
2447
2746
  },
2448
- ".cm-panel.cm-search": {
2449
- padding: "4px",
2450
- borderTop: "1px solid var(--dx-separator)"
2747
+ ".cm-dropCursor:after": {
2748
+ content: '"\u2190"'
2451
2749
  }
2750
+ });
2751
+ var dropFile = (options = {}) => {
2752
+ return [
2753
+ styles4,
2754
+ (0, import_view13.dropCursor)(),
2755
+ import_view13.EditorView.domEventHandlers({
2756
+ drop: (event, view) => {
2757
+ event.preventDefault();
2758
+ const files = event.dataTransfer?.files;
2759
+ const pos = view.posAtCoords(event);
2760
+ if (files?.length && pos !== null) {
2761
+ view.dispatch({
2762
+ selection: {
2763
+ anchor: pos
2764
+ }
2765
+ });
2766
+ options.onDrop?.(view, {
2767
+ files
2768
+ });
2769
+ }
2770
+ }
2771
+ })
2772
+ ];
2452
2773
  };
2774
+ var focusEffect = import_state14.StateEffect.define();
2775
+ var focusField = import_state14.StateField.define({
2776
+ create: () => false,
2777
+ update: (value, tr) => {
2778
+ for (const effect of tr.effects) {
2779
+ if (effect.is(focusEffect)) {
2780
+ return effect.value;
2781
+ }
2782
+ }
2783
+ return value;
2784
+ }
2785
+ });
2786
+ var focus = [
2787
+ focusField,
2788
+ import_view15.EditorView.domEventHandlers({
2789
+ focus: (event, view) => {
2790
+ setTimeout(() => view.dispatch({
2791
+ effects: focusEffect.of(true)
2792
+ }));
2793
+ },
2794
+ blur: (event, view) => {
2795
+ setTimeout(() => view.dispatch({
2796
+ effects: focusEffect.of(false)
2797
+ }));
2798
+ }
2799
+ })
2800
+ ];
2453
2801
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2454
- var preventNewline = import_state12.EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
2802
+ var preventNewline = import_state13.EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
2455
2803
  var defaultBasicOptions = {
2456
2804
  allowMultipleSelections: true,
2457
2805
  bracketMatching: true,
@@ -2471,10 +2819,10 @@ var keymaps = {
2471
2819
  default: import_commands2.defaultKeymap
2472
2820
  };
2473
2821
  var createBasicExtensions = (_props) => {
2474
- const props = (0, import_lodash3.default)({}, _props, defaultBasicOptions);
2822
+ const props = (0, import_lodash4.default)({}, _props, defaultBasicOptions);
2475
2823
  return [
2476
2824
  // NOTE: Doesn't catch errors in keymap functions.
2477
- import_view13.EditorView.exceptionSink.of((err) => {
2825
+ import_view14.EditorView.exceptionSink.of((err) => {
2478
2826
  import_log5.log.catch(err, void 0, {
2479
2827
  F: __dxlog_file8,
2480
2828
  L: 96,
@@ -2482,27 +2830,27 @@ var createBasicExtensions = (_props) => {
2482
2830
  C: (f, a) => f(...a)
2483
2831
  });
2484
2832
  }),
2485
- props.allowMultipleSelections && import_state12.EditorState.allowMultipleSelections.of(true),
2833
+ props.allowMultipleSelections && import_state13.EditorState.allowMultipleSelections.of(true),
2486
2834
  props.bracketMatching && (0, import_language2.bracketMatching)(),
2487
2835
  props.closeBrackets && (0, import_autocomplete2.closeBrackets)(),
2488
- props.dropCursor && (0, import_view13.dropCursor)(),
2489
- props.drawSelection && (0, import_view13.drawSelection)({
2836
+ props.dropCursor && (0, import_view14.dropCursor)(),
2837
+ props.drawSelection && (0, import_view14.drawSelection)({
2490
2838
  cursorBlinkRate: 1200
2491
2839
  }),
2492
2840
  props.focus && focus,
2493
- props.highlightActiveLine && (0, import_view13.highlightActiveLine)(),
2841
+ props.highlightActiveLine && (0, import_view14.highlightActiveLine)(),
2494
2842
  props.history && (0, import_commands2.history)(),
2495
- props.lineNumbers && (0, import_view13.lineNumbers)(),
2496
- props.lineWrapping && import_view13.EditorView.lineWrapping,
2497
- props.placeholder && (0, import_view13.placeholder)(props.placeholder),
2843
+ props.lineNumbers && (0, import_view14.lineNumbers)(),
2844
+ props.lineWrapping && import_view14.EditorView.lineWrapping,
2845
+ props.placeholder && (0, import_view14.placeholder)(props.placeholder),
2498
2846
  props.readonly && [
2499
- import_state12.EditorState.readOnly.of(true),
2500
- import_view13.EditorView.editable.of(false)
2847
+ import_state13.EditorState.readOnly.of(true),
2848
+ import_view14.EditorView.editable.of(false)
2501
2849
  ],
2502
- props.scrollPastEnd && (0, import_view13.scrollPastEnd)(),
2503
- props.tabSize && import_state12.EditorState.tabSize.of(props.tabSize),
2850
+ props.scrollPastEnd && (0, import_view14.scrollPastEnd)(),
2851
+ props.tabSize && import_state13.EditorState.tabSize.of(props.tabSize),
2504
2852
  // https://codemirror.net/docs/ref/#view.KeyBinding
2505
- import_view13.keymap.of([
2853
+ import_view14.keymap.of([
2506
2854
  ...(props.keymap && keymaps[props.keymap]) ?? [],
2507
2855
  // NOTE: Tabs are also configured by markdown extension.
2508
2856
  // https://codemirror.net/docs/ref/#commands.indentWithTab
@@ -2524,16 +2872,16 @@ var defaultThemeSlots = {
2524
2872
  }
2525
2873
  };
2526
2874
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2527
- const slots = (0, import_lodash3.default)({}, _slots, defaultThemeSlots);
2875
+ const slots = (0, import_lodash4.default)({}, _slots, defaultThemeSlots);
2528
2876
  return [
2529
- import_view13.EditorView.darkTheme.of(themeMode === "dark"),
2530
- import_view13.EditorView.baseTheme(styles5 ? (0, import_lodash4.default)({}, defaultTheme, styles5) : defaultTheme),
2877
+ import_view14.EditorView.darkTheme.of(themeMode === "dark"),
2878
+ import_view14.EditorView.baseTheme(styles5 ? (0, import_lodash5.default)({}, defaultTheme, styles5) : defaultTheme),
2531
2879
  // https://github.com/codemirror/theme-one-dark
2532
2880
  _syntaxHighlighting && (themeMode === "dark" ? (0, import_language2.syntaxHighlighting)(import_theme_one_dark.oneDarkHighlightStyle) : (0, import_language2.syntaxHighlighting)(import_language2.defaultHighlightStyle)),
2533
- slots.editor?.className && import_view13.EditorView.editorAttributes.of({
2881
+ slots.editor?.className && import_view14.EditorView.editorAttributes.of({
2534
2882
  class: slots.editor.className
2535
2883
  }),
2536
- slots.content?.className && import_view13.EditorView.contentAttributes.of({
2884
+ slots.content?.className && import_view14.EditorView.contentAttributes.of({
2537
2885
  class: slots.content.className
2538
2886
  })
2539
2887
  ].filter(import_util4.isNotFalsy);
@@ -2545,7 +2893,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2545
2893
  }
2546
2894
  if (space && identity) {
2547
2895
  const peerId = identity?.identityKey.toHex();
2548
- const { cursorLightValue, cursorDarkValue } = import_react_ui_theme3.hueTokens[identity?.profile?.data?.hue ?? (0, import_util4.hexToHue)(peerId ?? "0")];
2896
+ const { cursorLightValue, cursorDarkValue } = import_react_ui_theme7.hueTokens[identity?.profile?.data?.hue ?? (0, import_util4.hexToHue)(peerId ?? "0")];
2549
2897
  extensions.push(awareness(new SpaceAwarenessProvider({
2550
2898
  space,
2551
2899
  channel: `awareness.${id}`,
@@ -2580,7 +2928,7 @@ var folding = (_props = {}) => [
2580
2928
  }));
2581
2929
  }
2582
2930
  }),
2583
- import_view15.EditorView.theme({
2931
+ import_view16.EditorView.theme({
2584
2932
  ".cm-foldGutter": {
2585
2933
  opacity: 0.3,
2586
2934
  transition: "opacity 0.3s",
@@ -2593,11 +2941,11 @@ var folding = (_props = {}) => [
2593
2941
  ];
2594
2942
  var listener = ({ onFocus, onChange }) => {
2595
2943
  const extensions = [];
2596
- onFocus && extensions.push(import_view16.EditorView.focusChangeEffect.of((_, focusing) => {
2944
+ onFocus && extensions.push(import_view17.EditorView.focusChangeEffect.of((_, focusing) => {
2597
2945
  onFocus(focusing);
2598
2946
  return null;
2599
2947
  }));
2600
- onChange && extensions.push(import_view16.EditorView.updateListener.of((update2) => {
2948
+ onChange && extensions.push(import_view17.EditorView.updateListener.of((update2) => {
2601
2949
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
2602
2950
  }));
2603
2951
  return extensions;
@@ -2720,7 +3068,7 @@ var setStyle = (type, enable) => {
2720
3068
  to: range.head + found + marker.length
2721
3069
  }
2722
3070
  ],
2723
- range: import_state14.EditorSelection.cursor(range.from - marker.length)
3071
+ range: import_state15.EditorSelection.cursor(range.from - marker.length)
2724
3072
  };
2725
3073
  }
2726
3074
  }
@@ -2848,13 +3196,13 @@ var setStyle = (type, enable) => {
2848
3196
  from: range.head,
2849
3197
  insert: marker + marker
2850
3198
  },
2851
- range: import_state14.EditorSelection.cursor(range.head + marker.length)
3199
+ range: import_state15.EditorSelection.cursor(range.head + marker.length)
2852
3200
  };
2853
3201
  }
2854
3202
  const changeSet = state.changes(changes2.concat(changesAtEnd));
2855
3203
  return {
2856
3204
  changes: changeSet,
2857
- range: range.empty && !changeSet.empty ? import_state14.EditorSelection.cursor(range.head + marker.length) : import_state14.EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
3205
+ range: range.empty && !changeSet.empty ? import_state15.EditorSelection.cursor(range.head + marker.length) : import_state15.EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
2858
3206
  };
2859
3207
  });
2860
3208
  dispatch(state.update(changes, {
@@ -3054,7 +3402,7 @@ var addLink = ({ url, image: image2 } = {}) => {
3054
3402
  const changeSet = state.changes(changes2.concat(changesAfter));
3055
3403
  return {
3056
3404
  changes: changeSet,
3057
- range: import_state14.EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
3405
+ range: import_state15.EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
3058
3406
  };
3059
3407
  });
3060
3408
  if (changes.changes.empty) {
@@ -3488,7 +3836,7 @@ var toggleCodeblock = (target) => {
3488
3836
  };
3489
3837
  var formattingKeymap = (_options = {}) => {
3490
3838
  return [
3491
- import_view17.keymap.of([
3839
+ import_view18.keymap.of([
3492
3840
  {
3493
3841
  key: "meta-b",
3494
3842
  run: toggleStrong
@@ -3688,63 +4036,54 @@ var getFormatting = (state) => {
3688
4036
  listStyle: listStyle || null
3689
4037
  };
3690
4038
  };
3691
- var useFormattingState = () => {
3692
- const [state, setState] = (0, import_react6.useState)();
3693
- const observer = (0, import_react6.useMemo)(() => import_view17.EditorView.updateListener.of((update2) => {
4039
+ var useFormattingState = (state) => {
4040
+ return (0, import_react6.useMemo)(() => import_view18.EditorView.updateListener.of((update2) => {
3694
4041
  if (update2.docChanged || update2.selectionSet) {
3695
- setState((prevState) => {
3696
- const newState = getFormatting(update2.state);
3697
- if (!prevState || !formattingEquals(prevState, newState)) {
3698
- return newState;
3699
- }
3700
- return prevState;
4042
+ Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
4043
+ state[key] = active;
3701
4044
  });
3702
4045
  }
3703
4046
  }), []);
3704
- return [
3705
- state,
3706
- observer
3707
- ];
3708
4047
  };
3709
- var processAction = (view, action) => {
4048
+ var processEditorPayload = (view, { type, data }) => {
3710
4049
  let inlineType, listType;
3711
- switch (action.type) {
4050
+ switch (type) {
3712
4051
  case "heading":
3713
- setHeading(parseInt(action.data))(view);
4052
+ setHeading(parseInt(data))(view);
3714
4053
  break;
3715
4054
  case "strong":
3716
4055
  case "emphasis":
3717
4056
  case "strikethrough":
3718
4057
  case "code":
3719
- inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
3720
- (typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
4058
+ inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
4059
+ (typeof data === "boolean" ? setStyle(inlineType, data) : toggleStyle(inlineType))(view);
3721
4060
  break;
3722
4061
  case "list-ordered":
3723
4062
  case "list-bullet":
3724
4063
  case "list-task":
3725
- listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
3726
- (action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
4064
+ listType = type === "list-ordered" ? List.Ordered : type === "list-bullet" ? List.Bullet : List.Task;
4065
+ (data === false ? removeList(listType) : data === true ? addList(listType) : toggleList(listType))(view);
3727
4066
  break;
3728
4067
  case "blockquote":
3729
- (action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
4068
+ (data === false ? removeBlockquote : data === true ? addBlockquote : toggleBlockquote)(view);
3730
4069
  break;
3731
4070
  case "codeblock":
3732
- (action.data === false ? removeCodeblock : addCodeblock)(view);
4071
+ (data === false ? removeCodeblock : addCodeblock)(view);
3733
4072
  break;
3734
4073
  case "table":
3735
4074
  insertTable(view);
3736
4075
  break;
3737
4076
  case "link":
3738
- (action.data === false ? removeLink : addLink())(view);
4077
+ (data === false ? removeLink : addLink())(view);
3739
4078
  break;
3740
4079
  case "image":
3741
4080
  addLink({
3742
- url: action.data,
4081
+ url: data,
3743
4082
  image: true
3744
4083
  })(view);
3745
4084
  break;
3746
4085
  case "comment":
3747
- createComment(view);
4086
+ createComment2(view);
3748
4087
  break;
3749
4088
  }
3750
4089
  requestAnimationFrame(() => {
@@ -3950,7 +4289,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3950
4289
  }),
3951
4290
  // Custom styles.
3952
4291
  (0, import_language5.syntaxHighlighting)(markdownHighlightStyle()),
3953
- import_view18.keymap.of([
4292
+ import_view19.keymap.of([
3954
4293
  // https://codemirror.net/docs/ref/#commands.indentWithTab
3955
4294
  import_commands3.indentWithTab,
3956
4295
  // https://codemirror.net/docs/ref/#commands.defaultKeymap
@@ -3960,7 +4299,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3960
4299
  ])
3961
4300
  ];
3962
4301
  };
3963
- var debugTree = (cb) => import_state15.StateField.define({
4302
+ var debugTree = (cb) => import_state16.StateField.define({
3964
4303
  create: (state) => cb(convertTreeToJson(state)),
3965
4304
  update: (value, tr) => cb(convertTreeToJson(tr.state))
3966
4305
  });
@@ -3984,12 +4323,12 @@ var convertTreeToJson = (state) => {
3984
4323
  return treeToJson((0, import_language7.syntaxTree)(state).cursor());
3985
4324
  };
3986
4325
  var adjustChanges = () => {
3987
- return import_view20.ViewPlugin.fromClass(class {
4326
+ return import_view21.ViewPlugin.fromClass(class {
3988
4327
  update(update2) {
3989
4328
  const tree = (0, import_language9.syntaxTree)(update2.state);
3990
4329
  const adjustments = [];
3991
4330
  for (const tr of update2.transactions) {
3992
- const event = tr.annotation(import_state17.Transaction.userEvent);
4331
+ const event = tr.annotation(import_state18.Transaction.userEvent);
3993
4332
  switch (event) {
3994
4333
  //
3995
4334
  // Enter
@@ -4124,9 +4463,9 @@ var getValidUrl = (str) => {
4124
4463
  };
4125
4464
  var image = (_options = {}) => {
4126
4465
  return [
4127
- import_state18.StateField.define({
4466
+ import_state19.StateField.define({
4128
4467
  create: (state) => {
4129
- return import_view21.Decoration.set(buildDecorations(0, state.doc.length, state));
4468
+ return import_view22.Decoration.set(buildDecorations(0, state.doc.length, state));
4130
4469
  },
4131
4470
  update: (value, tr) => {
4132
4471
  if (!tr.docChanged && !tr.selection) {
@@ -4149,7 +4488,7 @@ var image = (_options = {}) => {
4149
4488
  add: buildDecorations(from, to, tr.state)
4150
4489
  });
4151
4490
  },
4152
- provide: (field) => import_view21.EditorView.decorations.from(field)
4491
+ provide: (field) => import_view22.EditorView.decorations.from(field)
4153
4492
  })
4154
4493
  ];
4155
4494
  };
@@ -4175,7 +4514,7 @@ var buildDecorations = (from, to, state) => {
4175
4514
  return;
4176
4515
  }
4177
4516
  preloadImage(url);
4178
- decorations.push(import_view21.Decoration.replace({
4517
+ decorations.push(import_view22.Decoration.replace({
4179
4518
  block: true,
4180
4519
  widget: new ImageWidget(url)
4181
4520
  }).range(hide2 ? node.from : node.to, node.to));
@@ -4187,7 +4526,7 @@ var buildDecorations = (from, to, state) => {
4187
4526
  });
4188
4527
  return decorations;
4189
4528
  };
4190
- var ImageWidget = class extends import_view21.WidgetType {
4529
+ var ImageWidget = class extends import_view22.WidgetType {
4191
4530
  constructor(_url) {
4192
4531
  super();
4193
4532
  this._url = _url;
@@ -4209,7 +4548,7 @@ var ImageWidget = class extends import_view21.WidgetType {
4209
4548
  };
4210
4549
  var bulletListIndentationWidth = 24;
4211
4550
  var orderedListIndentationWidth = 36;
4212
- var formattingStyles = import_view22.EditorView.theme({
4551
+ var formattingStyles = import_view23.EditorView.theme({
4213
4552
  /**
4214
4553
  * Horizontal rule.
4215
4554
  */
@@ -4303,17 +4642,38 @@ var formattingStyles = import_view22.EditorView.theme({
4303
4642
  height: "auto",
4304
4643
  borderTop: "0.5rem solid transparent",
4305
4644
  borderBottom: "0.5rem solid transparent"
4645
+ },
4646
+ ".cm-image-with-loader": {
4647
+ display: "block",
4648
+ opacity: "0",
4649
+ transitionDuration: "350ms",
4650
+ transitionProperty: "opacity"
4651
+ },
4652
+ ".cm-image-with-loader.cm-loaded-image": {
4653
+ opacity: "1"
4654
+ },
4655
+ ".cm-image-wrapper": {
4656
+ "grid-template-columns": "1fr",
4657
+ display: "grid",
4658
+ margin: "0.5rem 0",
4659
+ overflow: "hidden",
4660
+ transitionDuration: "350ms",
4661
+ transitionProperty: "height",
4662
+ "& > *": {
4663
+ "grid-row-start": 1,
4664
+ "grid-column-start": 1
4665
+ }
4306
4666
  }
4307
4667
  });
4308
4668
  var table = (options = {}) => {
4309
- return import_state19.StateField.define({
4669
+ return import_state20.StateField.define({
4310
4670
  create: (state) => update(state, options),
4311
4671
  update: (_, tr) => update(tr.state, options),
4312
- provide: (field) => import_view23.EditorView.decorations.from(field)
4672
+ provide: (field) => import_view24.EditorView.decorations.from(field)
4313
4673
  });
4314
4674
  };
4315
4675
  var update = (state, _options) => {
4316
- const builder = new import_state19.RangeSetBuilder();
4676
+ const builder = new import_state20.RangeSetBuilder();
4317
4677
  const cursor = state.selection.main.head;
4318
4678
  const tables = [];
4319
4679
  const getTable = () => tables[tables.length - 1];
@@ -4354,19 +4714,19 @@ var update = (state, _options) => {
4354
4714
  tables.forEach((table2) => {
4355
4715
  const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4356
4716
  if (replace) {
4357
- builder.add(table2.from, table2.to, import_view23.Decoration.replace({
4717
+ builder.add(table2.from, table2.to, import_view24.Decoration.replace({
4358
4718
  block: true,
4359
4719
  widget: new TableWidget(table2)
4360
4720
  }));
4361
4721
  } else {
4362
- builder.add(table2.from, table2.to, import_view23.Decoration.mark({
4722
+ builder.add(table2.from, table2.to, import_view24.Decoration.mark({
4363
4723
  class: "cm-table"
4364
4724
  }));
4365
4725
  }
4366
4726
  });
4367
4727
  return builder.finish();
4368
4728
  };
4369
- var TableWidget = class extends import_view23.WidgetType {
4729
+ var TableWidget = class extends import_view24.WidgetType {
4370
4730
  constructor(_table) {
4371
4731
  super();
4372
4732
  this._table = _table;
@@ -4406,14 +4766,14 @@ var Unicode = {
4406
4766
  bulletSmall: "\u2219",
4407
4767
  bulletSquare: "\u2B1D"
4408
4768
  };
4409
- var HorizontalRuleWidget = class extends import_view19.WidgetType {
4769
+ var HorizontalRuleWidget = class extends import_view20.WidgetType {
4410
4770
  toDOM() {
4411
4771
  const el = document.createElement("span");
4412
4772
  el.className = "cm-hr";
4413
4773
  return el;
4414
4774
  }
4415
4775
  };
4416
- var LinkButton = class extends import_view19.WidgetType {
4776
+ var LinkButton = class extends import_view20.WidgetType {
4417
4777
  constructor(url, render) {
4418
4778
  super();
4419
4779
  this.url = url;
@@ -4429,7 +4789,7 @@ var LinkButton = class extends import_view19.WidgetType {
4429
4789
  return el;
4430
4790
  }
4431
4791
  };
4432
- var CheckboxWidget = class extends import_view19.WidgetType {
4792
+ var CheckboxWidget = class extends import_view20.WidgetType {
4433
4793
  constructor(_checked) {
4434
4794
  super();
4435
4795
  this._checked = _checked;
@@ -4474,7 +4834,7 @@ var CheckboxWidget = class extends import_view19.WidgetType {
4474
4834
  return false;
4475
4835
  }
4476
4836
  };
4477
- var TextWidget = class extends import_view19.WidgetType {
4837
+ var TextWidget = class extends import_view20.WidgetType {
4478
4838
  constructor(text, className) {
4479
4839
  super();
4480
4840
  this.text = text;
@@ -4489,29 +4849,29 @@ var TextWidget = class extends import_view19.WidgetType {
4489
4849
  return el;
4490
4850
  }
4491
4851
  };
4492
- var hide = import_view19.Decoration.replace({});
4493
- var blockQuote = import_view19.Decoration.line({
4494
- class: (0, import_react_ui_theme6.mx)("cm-blockquote")
4852
+ var hide = import_view20.Decoration.replace({});
4853
+ var blockQuote = import_view20.Decoration.line({
4854
+ class: (0, import_react_ui_theme8.mx)("cm-blockquote")
4495
4855
  });
4496
- var fencedCodeLine = import_view19.Decoration.line({
4497
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line")
4856
+ var fencedCodeLine = import_view20.Decoration.line({
4857
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line")
4498
4858
  });
4499
- var fencedCodeLineFirst = import_view19.Decoration.line({
4500
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line", "cm-codeblock-first")
4859
+ var fencedCodeLineFirst = import_view20.Decoration.line({
4860
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line", "cm-codeblock-first")
4501
4861
  });
4502
- var fencedCodeLineLast = import_view19.Decoration.line({
4503
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line", "cm-codeblock-last")
4862
+ var fencedCodeLineLast = import_view20.Decoration.line({
4863
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line", "cm-codeblock-last")
4504
4864
  });
4505
4865
  var commentBlockLine = fencedCodeLine;
4506
4866
  var commentBlockLineFirst = fencedCodeLineFirst;
4507
4867
  var commentBlockLineLast = fencedCodeLineLast;
4508
- var horizontalRule = import_view19.Decoration.replace({
4868
+ var horizontalRule = import_view20.Decoration.replace({
4509
4869
  widget: new HorizontalRuleWidget()
4510
4870
  });
4511
- var checkedTask = import_view19.Decoration.replace({
4871
+ var checkedTask = import_view20.Decoration.replace({
4512
4872
  widget: new CheckboxWidget(true)
4513
4873
  });
4514
- var uncheckedTask = import_view19.Decoration.replace({
4874
+ var uncheckedTask = import_view20.Decoration.replace({
4515
4875
  widget: new CheckboxWidget(false)
4516
4876
  });
4517
4877
  var editingRange = (state, range, focus2) => {
@@ -4527,8 +4887,8 @@ var autoHideTags = /* @__PURE__ */ new Set([
4527
4887
  "SuperscriptMark"
4528
4888
  ]);
4529
4889
  var buildDecorations2 = (view, options, focus2) => {
4530
- const deco = new import_state16.RangeSetBuilder();
4531
- const atomicDeco = new import_state16.RangeSetBuilder();
4890
+ const deco = new import_state17.RangeSetBuilder();
4891
+ const atomicDeco = new import_state17.RangeSetBuilder();
4532
4892
  const { state } = view;
4533
4893
  const headerLevels = [];
4534
4894
  const getHeaderLevels = (node, level) => {
@@ -4612,7 +4972,7 @@ var buildDecorations2 = (view, options, focus2) => {
4612
4972
  } else {
4613
4973
  const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
4614
4974
  if (num.length) {
4615
- atomicDeco.add(mark.from, mark.from + len, import_view19.Decoration.replace({
4975
+ atomicDeco.add(mark.from, mark.from + len, import_view20.Decoration.replace({
4616
4976
  widget: new TextWidget(num, theme.heading(level))
4617
4977
  }));
4618
4978
  }
@@ -4637,7 +4997,7 @@ var buildDecorations2 = (view, options, focus2) => {
4637
4997
  if (node.from === line.to - 1) {
4638
4998
  return false;
4639
4999
  }
4640
- deco.add(line.from, line.from, import_view19.Decoration.line({
5000
+ deco.add(line.from, line.from, import_view20.Decoration.line({
4641
5001
  class: "cm-list-item",
4642
5002
  attributes: {
4643
5003
  style: `padding-left: ${offset}px; text-indent: -${width}px;`
@@ -4654,7 +5014,7 @@ var buildDecorations2 = (view, options, focus2) => {
4654
5014
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
4655
5015
  const line = state.doc.lineAt(node.from);
4656
5016
  const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4657
- atomicDeco.add(line.from, to, import_view19.Decoration.replace({
5017
+ atomicDeco.add(line.from, to, import_view20.Decoration.replace({
4658
5018
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
4659
5019
  }));
4660
5020
  break;
@@ -4741,7 +5101,7 @@ var buildDecorations2 = (view, options, focus2) => {
4741
5101
  if (!editing) {
4742
5102
  atomicDeco.add(node.from, marks[0].to, hide);
4743
5103
  }
4744
- deco.add(marks[0].to, marks[1].from, import_view19.Decoration.mark({
5104
+ deco.add(marks[0].to, marks[1].from, import_view20.Decoration.mark({
4745
5105
  tagName: "a",
4746
5106
  attributes: {
4747
5107
  class: "cm-link",
@@ -4751,7 +5111,7 @@ var buildDecorations2 = (view, options, focus2) => {
4751
5111
  }
4752
5112
  }));
4753
5113
  if (!editing) {
4754
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? import_view19.Decoration.replace({
5114
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? import_view20.Decoration.replace({
4755
5115
  widget: new LinkButton(url, options.renderLinkButton)
4756
5116
  }) : hide);
4757
5117
  }
@@ -4806,10 +5166,10 @@ var buildDecorations2 = (view, options, focus2) => {
4806
5166
  atomicDeco: atomicDeco.finish()
4807
5167
  };
4808
5168
  };
4809
- var forceUpdate = import_state16.StateEffect.define();
5169
+ var forceUpdate = import_state17.StateEffect.define();
4810
5170
  var decorateMarkdown = (options = {}) => {
4811
5171
  return [
4812
- import_view19.ViewPlugin.fromClass(class {
5172
+ import_view20.ViewPlugin.fromClass(class {
4813
5173
  constructor(view) {
4814
5174
  ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
4815
5175
  }
@@ -4841,9 +5201,9 @@ var decorateMarkdown = (options = {}) => {
4841
5201
  }
4842
5202
  }, {
4843
5203
  provide: (plugin) => [
4844
- import_view19.EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view19.Decoration.none),
4845
- import_view19.EditorView.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view19.Decoration.none),
4846
- import_view19.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view19.Decoration.none)
5204
+ import_view20.EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view20.Decoration.none),
5205
+ import_view20.EditorView.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view20.Decoration.none),
5206
+ import_view20.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view20.Decoration.none)
4847
5207
  ]
4848
5208
  }),
4849
5209
  image(),
@@ -4853,7 +5213,7 @@ var decorateMarkdown = (options = {}) => {
4853
5213
  ];
4854
5214
  };
4855
5215
  var linkTooltip = (render) => {
4856
- return (0, import_view24.hoverTooltip)((view, pos, side) => {
5216
+ return (0, import_view25.hoverTooltip)((view, pos, side) => {
4857
5217
  const syntax = (0, import_language12.syntaxTree)(view.state).resolveInner(pos, side);
4858
5218
  let link = null;
4859
5219
  for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
@@ -4870,7 +5230,7 @@ var linkTooltip = (render) => {
4870
5230
  above: true,
4871
5231
  create: () => {
4872
5232
  const el = document.createElement("div");
4873
- el.className = (0, import_react_ui_theme7.tooltipContent)({}, "pli-2 plb-1");
5233
+ el.className = (0, import_react_ui_theme9.tooltipContent)({}, "pli-2 plb-1");
4874
5234
  render(el, urlText);
4875
5235
  return {
4876
5236
  dom: el,
@@ -4922,11 +5282,13 @@ var EditorViewModes = [
4922
5282
  "readonly",
4923
5283
  "source"
4924
5284
  ];
5285
+ var EditorViewMode = import_echo_schema.S.Union(...EditorViewModes.map((mode) => import_echo_schema.S.Literal(mode)));
4925
5286
  var EditorInputModes = [
4926
5287
  "default",
4927
5288
  "vim",
4928
5289
  "vscode"
4929
5290
  ];
5291
+ var EditorInputMode = import_echo_schema.S.Union(...EditorInputModes.map((mode) => import_echo_schema.S.Literal(mode)));
4930
5292
  var editorInputMode = singleValueFacet({});
4931
5293
  var InputModeExtensions = {
4932
5294
  default: [],
@@ -4935,7 +5297,7 @@ var InputModeExtensions = {
4935
5297
  editorInputMode.of({
4936
5298
  type: "vscode"
4937
5299
  }),
4938
- import_view25.keymap.of(import_codemirror_vscode_keymap.vscodeKeymap)
5300
+ import_view26.keymap.of(import_codemirror_vscode_keymap.vscodeKeymap)
4939
5301
  ],
4940
5302
  vim: [
4941
5303
  // https://github.com/replit/codemirror-vim
@@ -4944,7 +5306,7 @@ var InputModeExtensions = {
4944
5306
  type: "vim",
4945
5307
  noTabster: true
4946
5308
  }),
4947
- import_view25.keymap.of([
5309
+ import_view26.keymap.of([
4948
5310
  {
4949
5311
  key: "Alt-Escape",
4950
5312
  run: (view) => {
@@ -4964,7 +5326,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4964
5326
  let t;
4965
5327
  let idx = 0;
4966
5328
  return [
4967
- import_view26.keymap.of([
5329
+ import_view27.keymap.of([
4968
5330
  {
4969
5331
  // Reset.
4970
5332
  key: "alt-meta-'",
@@ -5009,413 +5371,19 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
5009
5371
  ])
5010
5372
  ];
5011
5373
  };
5012
- var iconStyles = (0, import_react_ui_theme.getSize)(5);
5013
- var buttonStyles = "min-bs-0 p-1";
5014
- var tooltipProps = {
5015
- side: "top",
5016
- classNames: "z-10"
5017
- };
5018
- var ToolbarSeparator = () => /* @__PURE__ */ import_react2.default.createElement("div", {
5019
- role: "separator",
5020
- className: "grow"
5021
- });
5022
- var [ToolbarContextProvider, useToolbarContext] = (0, import_react_context.createContext)("Toolbar");
5023
- var ToolbarRoot = ({ children, onAction, classNames, state }) => {
5024
- return /* @__PURE__ */ import_react2.default.createElement(ToolbarContextProvider, {
5025
- onAction,
5026
- state
5027
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.ElevationProvider, {
5028
- elevation: "chrome"
5029
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.Root, {
5030
- classNames: [
5031
- "p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden",
5032
- classNames
5033
- ],
5034
- style: {
5035
- contain: "layout"
5036
- }
5037
- }, children)));
5038
- };
5039
- var ToolbarToggleButton = ({ Icon: Icon2, children, ...props }) => {
5040
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Root, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Trigger, {
5041
- asChild: true
5042
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.ToggleGroupItem, {
5043
- variant: "ghost",
5044
- ...props,
5045
- classNames: buttonStyles
5046
- }, /* @__PURE__ */ import_react2.default.createElement(Icon2, {
5047
- className: iconStyles
5048
- }), /* @__PURE__ */ import_react2.default.createElement("span", {
5049
- className: "sr-only"
5050
- }, 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))));
5051
- };
5052
- var ToolbarButton = ({ Icon: Icon2, children, ...props }) => {
5053
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Root, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Trigger, {
5054
- asChild: true
5055
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.Button, {
5056
- variant: "ghost",
5057
- ...props,
5058
- classNames: buttonStyles
5059
- }, /* @__PURE__ */ import_react2.default.createElement(Icon2, {
5060
- className: iconStyles
5061
- }), /* @__PURE__ */ import_react2.default.createElement("span", {
5062
- className: "sr-only"
5063
- }, 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))));
5064
- };
5065
- var HeadingIcons = {
5066
- "0": import_react.Paragraph,
5067
- "1": import_react.TextHOne,
5068
- "2": import_react.TextHTwo,
5069
- "3": import_react.TextHThree,
5070
- "4": import_react.TextHFour,
5071
- "5": import_react.TextHFive,
5072
- "6": import_react.TextHSix
5073
- };
5074
- var MarkdownHeading = () => {
5075
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5076
- const { onAction, state } = useToolbarContext("MarkdownFormatting");
5077
- const blockType = state ? state.blockType : "paragraph";
5078
- const header = blockType && /heading(\d)/.exec(blockType);
5079
- const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
5080
- const HeadingIcon = HeadingIcons[value ?? "0"];
5081
- const suppressNextTooltip = (0, import_react2.useRef)(false);
5082
- const [tooltipOpen, setTooltipOpen] = (0, import_react2.useState)(false);
5083
- const [selectOpen, setSelectOpen] = (0, import_react2.useState)(false);
5084
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Root, {
5085
- open: tooltipOpen,
5086
- onOpenChange: (nextOpen) => {
5087
- if (nextOpen && suppressNextTooltip.current) {
5088
- suppressNextTooltip.current = false;
5089
- return setTooltipOpen(false);
5090
- } else {
5091
- return setTooltipOpen(nextOpen);
5092
- }
5093
- }
5094
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Root, {
5095
- open: selectOpen,
5096
- onOpenChange: (nextOpen) => {
5097
- if (!nextOpen) {
5098
- suppressNextTooltip.current = true;
5099
- }
5100
- return setSelectOpen(nextOpen);
5101
- }
5102
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Trigger, {
5103
- asChild: true
5104
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.Button, {
5105
- asChild: true
5106
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Trigger, {
5107
- asChild: true
5108
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Button, {
5109
- variant: "ghost",
5110
- classNames: buttonStyles,
5111
- disabled: value === null
5112
- }, /* @__PURE__ */ import_react2.default.createElement("span", {
5113
- className: "sr-only"
5114
- }, t("heading label")), /* @__PURE__ */ import_react2.default.createElement(HeadingIcon, {
5115
- className: iconStyles
5116
- }), /* @__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, {
5117
- classNames: "is-min md:is-min",
5118
- onCloseAutoFocus: (e) => e.preventDefault()
5119
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
5120
- const Icon2 = HeadingIcons[level];
5121
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.CheckboxItem, {
5122
- key: level,
5123
- checked: value === level,
5124
- onClick: () => onAction?.({
5125
- type: "heading",
5126
- data: level
5127
- })
5128
- }, /* @__PURE__ */ import_react2.default.createElement("span", {
5129
- className: "sr-only"
5130
- }, t("heading level label", {
5131
- count: parseInt(level)
5132
- })), /* @__PURE__ */ import_react2.default.createElement(Icon2, {
5133
- className: iconStyles
5134
- }), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.ItemIndicator, null, /* @__PURE__ */ import_react2.default.createElement(import_react.Check, null)));
5135
- })), /* @__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))));
5136
- };
5137
- var markdownStyles = [
5138
- {
5139
- type: "strong",
5140
- Icon: import_react.TextB,
5141
- getState: (state) => !!state?.strong
5142
- },
5143
- {
5144
- type: "emphasis",
5145
- Icon: import_react.TextItalic,
5146
- getState: (state) => !!state?.emphasis
5147
- },
5148
- {
5149
- type: "strikethrough",
5150
- Icon: import_react.TextStrikethrough,
5151
- getState: (state) => !!state?.strikethrough
5152
- },
5153
- {
5154
- type: "code",
5155
- Icon: import_react.Code,
5156
- getState: (state) => !!state?.code
5157
- },
5158
- {
5159
- type: "link",
5160
- Icon: import_react.Link,
5161
- getState: (state) => !!state?.link
5162
- }
5163
- ];
5164
- var MarkdownStyles = () => {
5165
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5166
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5167
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.ToggleGroup, {
5168
- type: "multiple",
5169
- value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
5170
- }, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react2.default.createElement(ToolbarToggleButton, {
5171
- key: type,
5172
- value: type,
5173
- Icon: Icon2,
5174
- disabled: state?.blockType === "codeblock",
5175
- onClick: state ? () => onAction?.({
5176
- type,
5177
- data: !getState(state)
5178
- }) : void 0
5179
- }, t(`${type} label`))));
5180
- };
5181
- var markdownLists = [
5182
- {
5183
- type: "list-bullet",
5184
- Icon: import_react.ListBullets,
5185
- getState: (state) => state.listStyle === "bullet"
5186
- },
5187
- {
5188
- type: "list-ordered",
5189
- Icon: import_react.ListNumbers,
5190
- getState: (state) => state.listStyle === "ordered"
5191
- },
5192
- {
5193
- type: "list-task",
5194
- Icon: import_react.ListChecks,
5195
- getState: (state) => state.listStyle === "task"
5196
- }
5197
- ];
5198
- var MarkdownLists = () => {
5199
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5200
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5201
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.ToggleGroup, {
5202
- type: "single",
5203
- value: state?.listStyle ? `list-${state.listStyle}` : ""
5204
- }, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react2.default.createElement(ToolbarToggleButton, {
5205
- key: type,
5206
- value: type,
5207
- Icon: Icon2,
5208
- onClick: state ? () => onAction?.({
5209
- type,
5210
- data: !getState(state)
5211
- }) : void 0
5212
- }, t(`${type} label`))));
5213
- };
5214
- var markdownBlocks = [
5215
- {
5216
- type: "blockquote",
5217
- Icon: import_react.Quotes,
5218
- getState: (state) => !!state?.blockQuote
5219
- },
5220
- {
5221
- type: "codeblock",
5222
- Icon: import_react.CodeBlock,
5223
- getState: (state) => state.blockType === "codeblock"
5224
- },
5225
- {
5226
- type: "table",
5227
- Icon: import_react.Table,
5228
- getState: (state) => state.blockType === "tablecell",
5229
- disabled: (state) => !state.blankLine
5230
- }
5231
- ];
5232
- var MarkdownBlocks = () => {
5233
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5234
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5235
- const value = markdownBlocks.find(({ getState }) => state && getState(state));
5236
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.ToggleGroup, {
5237
- type: "single",
5238
- value: value?.type ?? ""
5239
- }, markdownBlocks.map(({ type, disabled, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react2.default.createElement(ToolbarToggleButton, {
5240
- key: type,
5241
- value: type,
5242
- Icon: Icon2,
5243
- disabled: !state || disabled?.(state),
5244
- onClick: state ? () => onAction?.({
5245
- type,
5246
- data: !getState(state)
5247
- }) : void 0
5248
- }, t(`${type} label`))));
5249
- };
5250
- 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));
5251
- var MarkdownCustom = ({ onUpload } = {}) => {
5252
- const { onAction } = useToolbarContext("MarkdownStyles");
5253
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5254
- const { acceptedFiles, getInputProps, open } = (0, import_react_dropzone.useDropzone)({
5255
- multiple: false,
5256
- noDrag: true,
5257
- accept: {
5258
- "image/*": [
5259
- ".jpg",
5260
- ".jpeg",
5261
- ".png",
5262
- ".gif"
5263
- ]
5264
- }
5265
- });
5266
- (0, import_react2.useEffect)(() => {
5267
- if (onUpload && acceptedFiles.length) {
5268
- requestAnimationFrame(async () => {
5269
- const f = acceptedFiles[0];
5270
- const file = new File([
5271
- f
5272
- ], f.name, {
5273
- type: f.type,
5274
- lastModified: f.lastModified
5275
- });
5276
- const info = await onUpload(file);
5277
- if (info) {
5278
- onAction?.({
5279
- type: "image",
5280
- data: info.url
5281
- });
5282
- }
5283
- });
5284
- }
5285
- }, [
5286
- acceptedFiles
5287
- ]);
5288
- return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("input", getInputProps()), /* @__PURE__ */ import_react2.default.createElement(ToolbarButton, {
5289
- value: "image",
5290
- Icon: import_react.Image,
5291
- onClick: () => open()
5292
- }, t("image label")));
5293
- };
5294
- var ViewModeIcons = {
5295
- preview: import_react.PencilSimple,
5296
- readonly: import_react.PencilSimpleSlash,
5297
- source: import_react.MarkdownLogo
5298
- };
5299
- var MarkdownView = ({ mode }) => {
5300
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5301
- const { onAction } = useToolbarContext("ViewMode");
5302
- const ModeIcon = ViewModeIcons[mode ?? "preview"];
5303
- const suppressNextTooltip = (0, import_react2.useRef)(false);
5304
- const [tooltipOpen, setTooltipOpen] = (0, import_react2.useState)(false);
5305
- const [selectOpen, setSelectOpen] = (0, import_react2.useState)(false);
5306
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Root, {
5307
- open: tooltipOpen,
5308
- onOpenChange: (nextOpen) => {
5309
- if (nextOpen && suppressNextTooltip.current) {
5310
- suppressNextTooltip.current = false;
5311
- return setTooltipOpen(false);
5312
- } else {
5313
- return setTooltipOpen(nextOpen);
5314
- }
5315
- }
5316
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Root, {
5317
- open: selectOpen,
5318
- onOpenChange: (nextOpen) => {
5319
- if (!nextOpen) {
5320
- suppressNextTooltip.current = true;
5321
- }
5322
- return setSelectOpen(nextOpen);
5323
- }
5324
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Tooltip.Trigger, {
5325
- asChild: true
5326
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Toolbar.Button, {
5327
- asChild: true
5328
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Trigger, {
5329
- asChild: true
5330
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.Button, {
5331
- variant: "ghost",
5332
- classNames: buttonStyles
5333
- }, /* @__PURE__ */ import_react2.default.createElement("span", {
5334
- className: "sr-only"
5335
- }, t("mode label")), /* @__PURE__ */ import_react2.default.createElement(ModeIcon, {
5336
- className: iconStyles
5337
- }), /* @__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, {
5338
- classNames: "is-min md:is-min",
5339
- onCloseAutoFocus: (e) => e.preventDefault()
5340
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
5341
- const Icon2 = ViewModeIcons[value];
5342
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.CheckboxItem, {
5343
- key: value,
5344
- checked: value === mode,
5345
- onClick: () => onAction?.({
5346
- type: "view-mode",
5347
- data: value
5348
- })
5349
- }, /* @__PURE__ */ import_react2.default.createElement(Icon2, {
5350
- className: iconStyles
5351
- }), /* @__PURE__ */ import_react2.default.createElement("span", {
5352
- className: "whitespace-nowrap grow"
5353
- }, t(`${value} mode label`)), /* @__PURE__ */ import_react2.default.createElement(import_react.Check, {
5354
- className: value === mode ? "visible" : "invisible"
5355
- }));
5356
- })), /* @__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))));
5357
- };
5358
- var MarkdownActions = () => {
5359
- const { onAction, state } = useToolbarContext("MarkdownActions");
5360
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
5361
- let commentToolTipKey = "comment label";
5362
- if (state?.comment) {
5363
- commentToolTipKey = "selection overlaps existing comment label";
5364
- } else if (state?.selection === false) {
5365
- commentToolTipKey = "select text to comment label";
5366
- }
5367
- return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(ToolbarButton, {
5368
- value: "search",
5369
- Icon: import_react.MagnifyingGlass,
5370
- onClick: () => onAction?.({
5371
- type: "search"
5372
- })
5373
- }, t("search label")), /* @__PURE__ */ import_react2.default.createElement(ToolbarButton, {
5374
- value: "comment",
5375
- Icon: import_react.ChatText,
5376
- "data-testid": "editor.toolbar.comment",
5377
- onClick: () => onAction?.({
5378
- type: "comment"
5379
- }),
5380
- disabled: !state || state.comment || !state.selection
5381
- }, t(commentToolTipKey)));
5382
- };
5383
- var Toolbar = {
5384
- Root: ToolbarRoot,
5385
- Button: ToolbarToggleButton,
5386
- Separator: ToolbarSeparator,
5387
- View: MarkdownView,
5388
- Markdown: MarkdownStandard,
5389
- Custom: MarkdownCustom,
5390
- Actions: MarkdownActions
5391
- };
5392
- var margin = "!mt-[1rem]";
5393
- var editorContent = (0, import_react_ui_theme8.mx)(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5394
- var editorFullWidth = (0, import_react_ui_theme8.mx)(margin);
5395
- var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5396
- var editorGutter = import_view27.EditorView.theme({
5397
- // Match margin from content.
5398
- ".cm-gutters": {
5399
- marginTop: "16px",
5400
- paddingRight: "1rem"
5401
- }
5402
- });
5403
- var editorMonospace = import_view27.EditorView.theme({
5404
- ".cm-content": {
5405
- fontFamily: fontMono
5406
- }
5407
- });
5408
5374
  var useActionHandler = (view) => {
5409
- return (action) => view && processAction(view, action);
5375
+ return (0, import_react7.useCallback)((action) => view && processEditorPayload(view, action.properties), [
5376
+ view
5377
+ ]);
5410
5378
  };
5411
5379
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5412
5380
  var instanceCount = 0;
5413
5381
  var useTextEditor = (props = {}, deps = []) => {
5414
- const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = (0, import_react7.useMemo)(() => (0, import_util5.getProviderValue)(props), deps ?? []);
5415
- const [instanceId] = (0, import_react7.useState)(() => `text-editor-${++instanceCount}`);
5416
- const [view, setView] = (0, import_react7.useState)();
5417
- const parentRef = (0, import_react7.useRef)(null);
5418
- (0, import_react7.useEffect)(() => {
5382
+ const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = (0, import_react8.useMemo)(() => (0, import_util5.getProviderValue)(props), deps ?? []);
5383
+ const [instanceId] = (0, import_react8.useState)(() => `text-editor-${++instanceCount}`);
5384
+ const [view, setView] = (0, import_react8.useState)();
5385
+ const parentRef = (0, import_react8.useRef)(null);
5386
+ (0, import_react8.useEffect)(() => {
5419
5387
  let view2;
5420
5388
  if (parentRef.current) {
5421
5389
  (0, import_log7.log)("create", {
@@ -5440,7 +5408,7 @@ var useTextEditor = (props = {}, deps = []) => {
5440
5408
  anchor
5441
5409
  };
5442
5410
  }
5443
- const state = import_state20.EditorState.create({
5411
+ const state = import_state21.EditorState.create({
5444
5412
  doc: initialValue,
5445
5413
  // selection: initialSelection,
5446
5414
  extensions: [
@@ -5489,7 +5457,7 @@ var useTextEditor = (props = {}, deps = []) => {
5489
5457
  view2?.destroy();
5490
5458
  };
5491
5459
  }, deps);
5492
- (0, import_react7.useEffect)(() => {
5460
+ (0, import_react8.useEffect)(() => {
5493
5461
  if (view) {
5494
5462
  if (scrollTo || selection) {
5495
5463
  if (selection && selection.anchor > view.state.doc.length) {
@@ -5516,7 +5484,7 @@ var useTextEditor = (props = {}, deps = []) => {
5516
5484
  scrollTo,
5517
5485
  selection
5518
5486
  ]);
5519
- (0, import_react7.useEffect)(() => {
5487
+ (0, import_react8.useEffect)(() => {
5520
5488
  if (view && autoFocus) {
5521
5489
  view.focus();
5522
5490
  }
@@ -5530,7 +5498,7 @@ var useTextEditor = (props = {}, deps = []) => {
5530
5498
  Escape: view?.state.facet(editorInputMode).noTabster
5531
5499
  }
5532
5500
  });
5533
- const handleKeyUp = (0, import_react7.useCallback)((event) => {
5501
+ const handleKeyUp = (0, import_react8.useCallback)((event) => {
5534
5502
  const { key, target, currentTarget } = event;
5535
5503
  if (target === currentTarget) {
5536
5504
  switch (key) {
@@ -5557,7 +5525,12 @@ var useTextEditor = (props = {}, deps = []) => {
5557
5525
  // Annotate the CommonJS export names for ESM import in node:
5558
5526
  0 && (module.exports = {
5559
5527
  Cursor,
5528
+ EditorInputMode,
5560
5529
  EditorInputModes,
5530
+ EditorState,
5531
+ EditorToolbar,
5532
+ EditorView,
5533
+ EditorViewMode,
5561
5534
  EditorViewModes,
5562
5535
  Inline,
5563
5536
  InputModeExtensions,
@@ -5565,7 +5538,6 @@ var useTextEditor = (props = {}, deps = []) => {
5565
5538
  RemoteSelectionsDecorator,
5566
5539
  SpaceAwarenessProvider,
5567
5540
  TextKind,
5568
- Toolbar,
5569
5541
  addBlockquote,
5570
5542
  addCodeblock,
5571
5543
  addLink,
@@ -5586,6 +5558,8 @@ var useTextEditor = (props = {}, deps = []) => {
5586
5558
  createBasicExtensions,
5587
5559
  createComment,
5588
5560
  createDataExtensions,
5561
+ createEditorAction,
5562
+ createEditorActionGroup,
5589
5563
  createEditorStateStore,
5590
5564
  createEditorStateTransaction,
5591
5565
  createElement,
@@ -5624,7 +5598,7 @@ var useTextEditor = (props = {}, deps = []) => {
5624
5598
  mention,
5625
5599
  overlap,
5626
5600
  preventNewline,
5627
- processAction,
5601
+ processEditorPayload,
5628
5602
  removeBlockquote,
5629
5603
  removeCodeblock,
5630
5604
  removeLink,
@@ -5640,6 +5614,8 @@ var useTextEditor = (props = {}, deps = []) => {
5640
5614
  setSelection,
5641
5615
  setStyle,
5642
5616
  singleValueFacet,
5617
+ stackItemContentEditorClassNames,
5618
+ stackItemContentToolbarClassNames,
5643
5619
  table,
5644
5620
  tags,
5645
5621
  textRange,
@@ -5657,9 +5633,9 @@ var useTextEditor = (props = {}, deps = []) => {
5657
5633
  useCommentClickListener,
5658
5634
  useCommentState,
5659
5635
  useComments,
5636
+ useEditorToolbarState,
5660
5637
  useFormattingState,
5661
5638
  useTextEditor,
5662
- useToolbarContext,
5663
5639
  wrapWithCatch
5664
5640
  });
5665
5641
  //# sourceMappingURL=index.cjs.map