@dxos/react-ui-editor 0.7.4 → 0.7.5-labs.071a3e2

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 (81) hide show
  1. package/dist/lib/browser/index.mjs +1119 -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 +1183 -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 +1119 -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 +30 -29
  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 +23 -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/decorate.ts +1 -1
  63. package/src/extensions/markdown/{action.ts → editorAction.ts} +22 -20
  64. package/src/extensions/markdown/formatting.test.ts +7 -6
  65. package/src/extensions/markdown/formatting.ts +20 -24
  66. package/src/extensions/markdown/index.ts +1 -1
  67. package/src/extensions/markdown/styles.ts +21 -0
  68. package/src/extensions/modes.ts +6 -2
  69. package/src/hooks/useActionHandler.ts +4 -4
  70. package/src/index.ts +6 -2
  71. package/src/styles/markdown.ts +1 -1
  72. package/src/styles/stack-item-content-class-names.ts +17 -0
  73. package/src/styles/theme.ts +1 -1
  74. package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -34
  75. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
  76. package/dist/types/src/components/Toolbar/index.d.ts +0 -2
  77. package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
  78. package/dist/types/src/extensions/markdown/action.d.ts +0 -9
  79. package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
  80. package/src/components/Toolbar/Toolbar.tsx +0 -522
  81. 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,196 +316,763 @@ 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([
387
+ commentLabel(state.comment, state.selection),
388
+ {
389
+ ns: translationKey
390
+ }
391
+ ])
392
+ ],
393
+ edges: [
394
+ {
395
+ source: "root",
396
+ target: "comment"
397
+ }
398
+ ]
399
+ });
400
+ var formats = {
401
+ strong: "ph--text-b--regular",
402
+ emphasis: "ph--text-italic--regular",
403
+ strikethrough: "ph--text-strikethrough--regular",
404
+ code: "ph--code--regular",
405
+ link: "ph--link--regular"
406
+ };
407
+ var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
408
+ variant: "toggleGroup",
409
+ selectCardinality: "multiple",
410
+ value: Object.keys(formats).filter((key) => !!formatting[key])
411
+ });
412
+ var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
413
+ type,
414
+ checked: !!formatting[type]
415
+ }, icon));
416
+ var createFormatting = (state) => {
417
+ const formattingGroupAction = createFormattingGroup(state);
418
+ const formattingActions = createFormattingActions(state);
419
+ return {
420
+ nodes: [
421
+ formattingGroupAction,
422
+ ...formattingActions
423
+ ],
424
+ edges: [
425
+ {
426
+ source: "root",
427
+ target: "formatting"
428
+ },
429
+ ...formattingActions.map(({ id }) => ({
430
+ source: formattingGroupAction.id,
431
+ target: id
432
+ }))
433
+ ]
434
+ };
344
435
  };
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
- });
436
+ var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
437
+ variant: "dropdownMenu",
438
+ applyActive: true,
439
+ selectCardinality: "single",
440
+ value
441
+ }, "ph--text-h--regular");
442
+ var createHeadingActions = (value) => Object.entries({
443
+ "0": "ph--paragraph--regular",
444
+ "1": "ph--text-h-one--regular",
445
+ "2": "ph--text-h-two--regular",
446
+ "3": "ph--text-h-three--regular",
447
+ "4": "ph--text-h-four--regular",
448
+ "5": "ph--text-h-five--regular",
449
+ "6": "ph--text-h-six--regular"
450
+ }).map(([levelStr, icon]) => {
451
+ const level = parseInt(levelStr);
452
+ return createEditorAction({
453
+ type: "heading",
454
+ data: level,
455
+ checked: value === levelStr
456
+ }, icon, [
457
+ "heading level label",
458
+ {
459
+ count: level,
460
+ ns: translationKey
357
461
  }
462
+ ], `heading--${levelStr}`);
463
+ });
464
+ var computeHeadingValue = (state) => {
465
+ const blockType = state ? state.blockType : "paragraph";
466
+ const header = blockType && /heading(\d)/.exec(blockType);
467
+ return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
468
+ };
469
+ var createHeadings = (state) => {
470
+ const headingValue = computeHeadingValue(state);
471
+ const headingGroupAction = createHeadingGroupAction(headingValue);
472
+ const headingActions = createHeadingActions(headingValue);
473
+ return {
474
+ nodes: [
475
+ headingGroupAction,
476
+ ...headingActions
477
+ ],
478
+ edges: [
479
+ {
480
+ source: "root",
481
+ target: "heading"
482
+ },
483
+ ...headingActions.map(({ id }) => ({
484
+ source: headingGroupAction.id,
485
+ target: id
486
+ }))
487
+ ]
358
488
  };
359
489
  };
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
- }
490
+ var listStyles = {
491
+ bullet: "ph--list-bullets--regular",
492
+ ordered: "ph--list-numbers--regular",
493
+ task: "ph--list-checks--regular"
371
494
  };
372
- var debugDispatcher = (trs, view) => {
373
- logChanges(trs);
374
- view.update(trs);
495
+ var createListGroupAction = (value) => createEditorActionGroup("list", {
496
+ variant: "toggleGroup",
497
+ selectCardinality: "single",
498
+ value
499
+ });
500
+ var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
501
+ type: `list-${listStyle}`,
502
+ checked: value === listStyle
503
+ }, icon));
504
+ var createLists = (state) => {
505
+ const value = state.listStyle ?? "";
506
+ const listGroupAction = createListGroupAction(value);
507
+ const listActionsMap = createListActions(value);
508
+ return {
509
+ nodes: [
510
+ listGroupAction,
511
+ ...listActionsMap
512
+ ],
513
+ edges: [
514
+ {
515
+ source: "root",
516
+ target: "list"
517
+ },
518
+ ...listActionsMap.map(({ id }) => ({
519
+ source: listGroupAction.id,
520
+ target: id
521
+ }))
522
+ ]
523
+ };
375
524
  };
376
- var logChanges = (trs) => {
377
- const changes = trs.flatMap((tr) => {
378
- if (tr.changes.empty) {
379
- return void 0;
525
+ var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
526
+ variant: "dropdownMenu",
527
+ applyActive: true,
528
+ selectCardinality: "single",
529
+ value
530
+ }, "ph--eye--regular");
531
+ var createViewModeActions = (value) => Object.entries({
532
+ preview: "ph--eye--regular",
533
+ source: "ph--pencil-simple--regular",
534
+ readonly: "ph--pencil-slash--regular"
535
+ }).map(([viewMode, icon]) => {
536
+ return createEditorAction({
537
+ type: "view-mode",
538
+ data: viewMode,
539
+ checked: viewMode === value
540
+ }, icon, [
541
+ `${viewMode} mode label`,
542
+ {
543
+ ns: translationKey
380
544
  }
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)
545
+ ], `view-mode--${viewMode}`);
546
+ });
547
+ var createViewMode = (state) => {
548
+ const value = state.viewMode ?? "source";
549
+ const viewModeGroupAction = createViewModeGroupAction(value);
550
+ const viewModeActions = createViewModeActions(value);
551
+ return {
552
+ nodes: [
553
+ viewModeGroupAction,
554
+ ...viewModeActions
555
+ ],
556
+ edges: [
557
+ {
558
+ source: "root",
559
+ target: "viewMode"
560
+ },
561
+ ...viewModeActions.map(({ id }) => ({
562
+ source: viewModeGroupAction.id,
563
+ target: id
564
+ }))
565
+ ]
566
+ };
567
+ };
568
+ var stackItemContentEditorClassNames = (role) => (0, import_react_ui_theme2.mx)("dx-focus-ring-inset data-[toolbar=disabled]:pbs-2 attention-surface", role === "article" ? "min-bs-0" : "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24");
569
+ var stackItemContentToolbarClassNames = (role) => (0, import_react_ui_theme2.mx)("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
570
+ var createToolbar = ({ state, customActions, ...features }) => {
571
+ const nodes = [];
572
+ const edges = [];
573
+ if (features.headings ?? true) {
574
+ const headings2 = createHeadings(state);
575
+ nodes.push(...headings2.nodes);
576
+ edges.push(...headings2.edges);
577
+ }
578
+ if (features.formatting ?? true) {
579
+ const formatting = createFormatting(state);
580
+ nodes.push(...formatting.nodes);
581
+ edges.push(...formatting.edges);
582
+ }
583
+ if (features.lists ?? true) {
584
+ const lists = createLists(state);
585
+ nodes.push(...lists.nodes);
586
+ edges.push(...lists.edges);
587
+ }
588
+ if (features.blocks ?? true) {
589
+ const blocks = createBlocks(state);
590
+ nodes.push(...blocks.nodes);
591
+ edges.push(...blocks.edges);
592
+ }
593
+ if (customActions) {
594
+ const custom = customActions();
595
+ nodes.push(...custom.nodes);
596
+ edges.push(...custom.edges);
597
+ }
598
+ const editorToolbarGap = (0, import_react_ui_menu.createGapSeparator)();
599
+ nodes.push(...editorToolbarGap.nodes);
600
+ edges.push(...editorToolbarGap.edges);
601
+ if (features.comment ?? true) {
602
+ const comment = createComment(state);
603
+ nodes.push(...comment.nodes);
604
+ edges.push(...comment.edges);
605
+ }
606
+ if (features.search ?? true) {
607
+ nodes.push(editorToolbarSearch);
608
+ edges.push({
609
+ source: "root",
610
+ target: editorToolbarSearch.id
399
611
  });
400
612
  }
613
+ if (features.viewMode ?? true) {
614
+ const viewMode = createViewMode(state);
615
+ nodes.push(...viewMode.nodes);
616
+ edges.push(...viewMode.edges);
617
+ }
618
+ return {
619
+ nodes,
620
+ edges
621
+ };
401
622
  };
402
- var flattenRect = (rect, left) => {
403
- const x = left ? rect.left : rect.right;
623
+ var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
624
+ const menuCreator = (0, import_react.useCallback)(() => createToolbar(props), [
625
+ props
626
+ ]);
627
+ const { resolveGroupItems } = (0, import_react_ui_menu.useMenuActions)(menuCreator);
404
628
  return {
405
- left: x,
406
- right: x,
407
- top: rect.top,
408
- bottom: rect.bottom
629
+ resolveGroupItems,
630
+ onAction
409
631
  };
410
632
  };
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;
633
+ var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
634
+ const menuProps = useEditorToolbarActionGraph(props);
635
+ return /* @__PURE__ */ import_react.default.createElement("div", {
636
+ role: "none",
637
+ className: stackItemContentToolbarClassNames(role)
638
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.ElevationProvider, {
639
+ elevation: role === "section" ? "positioned" : "base"
640
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.MenuProvider, {
641
+ ...menuProps,
642
+ attendableId
643
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.ToolbarMenu, {
644
+ classNames: [
645
+ import_react_ui_theme.textBlockWidth,
646
+ "!bg-transparent",
647
+ classNames
648
+ ]
649
+ }))));
417
650
  };
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
- }
651
+ var headings = {
652
+ 1: "text-4xl",
653
+ 2: "text-3xl",
654
+ 3: "text-2xl",
655
+ 4: "text-xl",
656
+ 5: "text-lg",
657
+ 6: ""
426
658
  };
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
- ]);
659
+ var theme = {
660
+ code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
661
+ codeMark: "font-mono text-primary-500",
662
+ mark: "opacity-50",
663
+ heading: (level) => {
664
+ return (0, import_react_ui_theme4.mx)(headings[level], "dark:text-primary-400");
436
665
  }
437
- return el;
438
666
  };
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;
667
+ var getToken = (path, defaultValue) => {
668
+ const value = (0, import_lodash.default)(import_react_ui_theme5.tokens, path, defaultValue);
669
+ return value?.toString() ?? "";
444
670
  };
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);
671
+ var fontBody = getToken("fontFamily.body");
672
+ var fontMono = getToken("fontFamily.mono");
673
+ var defaultTheme = {
674
+ "&": {},
675
+ "&.cm-focused": {
676
+ outline: "none"
677
+ },
678
+ /**
679
+ * Scroller
680
+ */
681
+ ".cm-scroller": {
682
+ overflowY: "auto"
683
+ },
684
+ /**
685
+ * Content
686
+ * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
687
+ */
688
+ ".cm-content": {
689
+ padding: "unset",
690
+ fontFamily: fontBody,
691
+ // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
692
+ fontSize: "16px",
693
+ lineHeight: 1.5,
694
+ color: "unset"
695
+ },
696
+ /**
697
+ * Gutters
698
+ * NOTE: Gutters should have the same top margin as the content.
699
+ * NOTE: They can't be transparent since the content needs to scroll below.
700
+ */
701
+ ".cm-gutters": {
702
+ background: "var(--surface-bg)",
703
+ borderRight: "none"
704
+ },
705
+ ".cm-gutter": {},
706
+ ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
707
+ minWidth: "40px",
708
+ alignContent: "center"
709
+ },
710
+ /**
711
+ * Height is set to match the corresponding line.
712
+ */
713
+ ".cm-gutterElement": {
714
+ alignItems: "center",
715
+ fontSize: "16px"
716
+ },
717
+ /**
718
+ * Line.
719
+ */
720
+ ".cm-line": {
721
+ paddingInline: 0
722
+ },
723
+ ".cm-activeLine": {
724
+ background: "var(--dx-cmActiveLine)"
725
+ },
726
+ /**
727
+ * Cursor (layer).
728
+ */
729
+ ".cm-cursor, .cm-dropCursor": {
730
+ borderLeft: "2px solid var(--dx-cmCursor)"
731
+ },
732
+ ".cm-placeholder": {
733
+ color: "var(--dx-subdued)"
734
+ },
735
+ /**
736
+ * Selection (layer).
737
+ */
738
+ ".cm-selectionBackground": {
739
+ background: "var(--dx-cmSelection)"
740
+ },
741
+ /**
742
+ * Search.
743
+ * NOTE: Matches comment.
744
+ */
745
+ ".cm-searchMatch": {
746
+ margin: "0 -3px",
747
+ padding: "3px",
748
+ borderRadius: "3px",
749
+ background: "var(--dx-cmHighlightSurface)",
750
+ color: "var(--dx-cmHighlight)"
751
+ },
752
+ ".cm-searchMatch-selected": {
753
+ textDecoration: "underline"
754
+ },
755
+ /**
756
+ * Link.
757
+ */
758
+ ".cm-link": {
759
+ textDecorationLine: "underline",
760
+ textDecorationThickness: "1px",
761
+ textUnderlineOffset: "2px",
762
+ borderRadius: ".125rem"
763
+ },
764
+ ".cm-link > span": {
765
+ color: "var(--dx-accentText)"
766
+ },
767
+ /**
768
+ * Tooltip.
769
+ */
770
+ ".cm-tooltip": {
771
+ background: "var(--dx-baseSurface)"
772
+ },
773
+ ".cm-tooltip-below": {},
774
+ /**
775
+ * Autocomplete.
776
+ * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
777
+ */
778
+ ".cm-tooltip.cm-tooltip-autocomplete": {
779
+ marginTop: "4px",
780
+ marginLeft: "-3px"
781
+ },
782
+ ".cm-tooltip.cm-tooltip-autocomplete > ul": {
783
+ maxHeight: "20em"
784
+ },
785
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
786
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
787
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
788
+ paddingLeft: "4px !important",
789
+ borderBottom: "none !important",
790
+ color: "var(--dx-accentText)"
791
+ },
792
+ ".cm-tooltip.cm-completionInfo": {
793
+ width: "360px !important",
794
+ margin: "-10px 1px 0 1px",
795
+ padding: "8px !important",
796
+ borderColor: "var(--dx-separator)"
797
+ },
798
+ ".cm-completionIcon": {
799
+ display: "none"
800
+ },
801
+ ".cm-completionLabel": {
802
+ fontFamily: fontBody
803
+ },
804
+ ".cm-completionMatchedText": {
805
+ textDecoration: "none !important",
806
+ opacity: 0.5
807
+ },
808
+ /**
809
+ * Panels
810
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
811
+ *
812
+ * Find/replace panel.
813
+ * <div class="cm-announced">...</div>
814
+ * <div class="cm-scroller">...</div>
815
+ * <div class="cm-panels cm-panels-bottom">
816
+ * <div class="cm-search cm-panel">
817
+ * <input class="cm-textfield" />
818
+ * <button class="cm-button">...</button>
819
+ * <label><input type="checkbox" />...</label>
820
+ * </div>
821
+ * </div
822
+ */
823
+ // TODO(burdon): Implement custom panel (with icon buttons).
824
+ ".cm-panels": {},
825
+ ".cm-panel": {
826
+ fontFamily: fontBody,
827
+ backgroundColor: "var(--surface-bg)"
828
+ },
829
+ ".cm-panel input, .cm-panel button, .cm-panel label": {
830
+ color: "var(--dx-subdued)",
831
+ fontFamily: fontBody,
832
+ fontSize: "14px",
833
+ all: "unset",
834
+ margin: "3px !important",
835
+ padding: "2px 6px !important",
836
+ outline: "1px solid transparent"
837
+ },
838
+ ".cm-panel input, .cm-panel button": {
839
+ backgroundColor: "var(--dx-input)"
840
+ },
841
+ ".cm-panel input:focus, .cm-panel button:focus": {
842
+ outline: "1px solid var(--dx-accentFocusIndicator)"
843
+ },
844
+ ".cm-panel label": {
845
+ display: "inline-flex",
846
+ alignItems: "center",
847
+ cursor: "pointer"
848
+ },
849
+ ".cm-panel input.cm-textfield": {},
850
+ ".cm-panel input[type=checkbox]": {
851
+ width: "8px",
852
+ height: "8px",
853
+ marginRight: "6px !important",
854
+ padding: "2px !important",
855
+ color: "var(--dx-accentFocusIndicator)"
856
+ },
857
+ ".cm-panel button": {
858
+ "&:hover": {
859
+ backgroundColor: "var(--dx-accentSurfaceHover) !important"
471
860
  },
472
- update: (value, tr) => {
473
- if (!tr.changes.empty) {
474
- return match(tr.state);
475
- }
476
- return value;
861
+ "&:active": {
862
+ backgroundColor: "var(--dx-accentSurfaceHover)"
477
863
  }
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": {
864
+ },
865
+ ".cm-panel.cm-search": {
866
+ padding: "4px",
867
+ borderTop: "1px solid var(--dx-separator)"
868
+ }
869
+ };
870
+ var margin = "!mt-[1rem]";
871
+ var editorContent = (0, import_react_ui_theme3.mx)(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
872
+ var editorFullWidth = (0, import_react_ui_theme3.mx)(margin);
873
+ var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
874
+ var editorGutter = import_view2.EditorView.theme({
875
+ // Match margin from content.
876
+ ".cm-gutters": {
877
+ marginTop: "16px",
878
+ paddingRight: "1rem"
879
+ }
880
+ });
881
+ var editorMonospace = import_view2.EditorView.theme({
882
+ ".cm-content": {
883
+ fontFamily: fontMono
884
+ }
885
+ });
886
+ var singleValueFacet = (defaultValue) => import_state3.Facet.define({
887
+ // Called immediately.
888
+ combine: (providers) => {
889
+ return providers[0] ?? defaultValue;
890
+ }
891
+ });
892
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
893
+ var defaultCursorConverter = {
894
+ toCursor: (position) => position.toString(),
895
+ fromCursor: (cursor) => parseInt(cursor)
896
+ };
897
+ var Cursor = class _Cursor {
898
+ static {
899
+ this.converter = singleValueFacet(defaultCursorConverter);
900
+ }
901
+ static {
902
+ this.getCursorFromRange = (state, range) => {
903
+ const cursorConverter2 = state.facet(_Cursor.converter);
904
+ const from = cursorConverter2.toCursor(range.from);
905
+ const to = cursorConverter2.toCursor(range.to, -1);
906
+ return [
907
+ from,
908
+ to
909
+ ].join(":");
910
+ };
911
+ }
912
+ static {
913
+ this.getRangeFromCursor = (state, cursor) => {
914
+ const cursorConverter2 = state.facet(_Cursor.converter);
915
+ const parts = cursor.split(":");
916
+ const from = cursorConverter2.fromCursor(parts[0]);
917
+ const to = cursorConverter2.fromCursor(parts[1]);
918
+ return from !== void 0 && to !== void 0 ? {
919
+ from,
920
+ to
921
+ } : void 0;
922
+ };
923
+ }
924
+ };
925
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
926
+ var wrapWithCatch = (fn) => {
927
+ return (...args) => {
928
+ try {
929
+ return fn(...args);
930
+ } catch (err) {
931
+ import_log.log.catch(err, void 0, {
932
+ F: __dxlog_file,
933
+ L: 15,
934
+ S: void 0,
935
+ C: (f, a) => f(...a)
936
+ });
937
+ }
938
+ };
939
+ };
940
+ var callbackWrapper = (fn) => (...args) => {
941
+ try {
942
+ return fn(...args);
943
+ } catch (err) {
944
+ import_log.log.catch(err, void 0, {
945
+ F: __dxlog_file,
946
+ L: 29,
947
+ S: void 0,
948
+ C: (f, a) => f(...a)
949
+ });
950
+ }
951
+ };
952
+ var debugDispatcher = (trs, view) => {
953
+ logChanges(trs);
954
+ view.update(trs);
955
+ };
956
+ var logChanges = (trs) => {
957
+ const changes = trs.flatMap((tr) => {
958
+ if (tr.changes.empty) {
959
+ return void 0;
960
+ }
961
+ const changes2 = [];
962
+ tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
963
+ fromA,
964
+ toA,
965
+ fromB,
966
+ toB,
967
+ inserted: inserted.toString()
968
+ })));
969
+ return changes2;
970
+ }).filter(Boolean);
971
+ if (changes.length) {
972
+ import_log.log.info("changes", {
973
+ changes
974
+ }, {
975
+ F: __dxlog_file,
976
+ L: 62,
977
+ S: void 0,
978
+ C: (f, a) => f(...a)
979
+ });
980
+ }
981
+ };
982
+ var flattenRect = (rect, left) => {
983
+ const x = left ? rect.left : rect.right;
984
+ return {
985
+ left: x,
986
+ right: x,
987
+ top: rect.top,
988
+ bottom: rect.bottom
989
+ };
990
+ };
991
+ var scratchRange;
992
+ var textRange = (node, from, to = from) => {
993
+ const range = scratchRange || (scratchRange = document.createRange());
994
+ range.setEnd(node, to);
995
+ range.setStart(node, from);
996
+ return range;
997
+ };
998
+ var clientRectsFor = (dom) => {
999
+ if (dom.nodeType === 3) {
1000
+ return textRange(dom, 0, dom.nodeValue.length).getClientRects();
1001
+ } else if (dom.nodeType === 1) {
1002
+ return dom.getClientRects();
1003
+ } else {
1004
+ return [];
1005
+ }
1006
+ };
1007
+ var createElement = (tag, options, children) => {
1008
+ const el = document.createElement(tag);
1009
+ if (options?.className) {
1010
+ el.className = options.className;
1011
+ }
1012
+ if (children) {
1013
+ el.append(...Array.isArray(children) ? children : [
1014
+ children
1015
+ ]);
1016
+ }
1017
+ return el;
1018
+ };
1019
+ var renderRoot = (root, node) => {
1020
+ (0, import_client.createRoot)(root).render(/* @__PURE__ */ import_react3.default.createElement(import_react_ui2.ThemeProvider, {
1021
+ tx: import_react_ui_theme6.defaultTx
1022
+ }, node));
1023
+ return root;
1024
+ };
1025
+ var annotationMark = import_view3.Decoration.mark({
1026
+ class: "cm-annotation"
1027
+ });
1028
+ var annotations = (options = {}) => {
1029
+ const match = (state) => {
1030
+ const annotations2 = [];
1031
+ const text = state.doc.toString();
1032
+ if (options.match) {
1033
+ const matches = text.matchAll(options.match);
1034
+ for (const match2 of matches) {
1035
+ const from = match2.index;
1036
+ const to = from + match2[0].length;
1037
+ const cursor = Cursor.getCursorFromRange(state, {
1038
+ from,
1039
+ to
1040
+ });
1041
+ annotations2.push({
1042
+ cursor
1043
+ });
1044
+ }
1045
+ }
1046
+ return annotations2;
1047
+ };
1048
+ const annotationsState = import_state2.StateField.define({
1049
+ create: (state) => {
1050
+ return match(state);
1051
+ },
1052
+ update: (value, tr) => {
1053
+ if (!tr.changes.empty) {
1054
+ return match(tr.state);
1055
+ }
1056
+ return value;
1057
+ }
1058
+ });
1059
+ return [
1060
+ annotationsState,
1061
+ import_view3.EditorView.decorations.compute([
1062
+ annotationsState
1063
+ ], (state) => {
1064
+ const annotations2 = state.field(annotationsState);
1065
+ const decorations = annotations2.map((annotation) => {
1066
+ const range = Cursor.getRangeFromCursor(state, annotation.cursor);
1067
+ return range && annotationMark.range(range.from, range.to);
1068
+ }).filter(import_util.isNotFalsy);
1069
+ return import_view3.Decoration.set(decorations);
1070
+ }),
1071
+ styles
1072
+ ];
1073
+ };
1074
+ var styles = import_view3.EditorView.theme({
1075
+ ".cm-annotation": {
496
1076
  textDecoration: "underline",
497
1077
  textDecorationStyle: "wavy",
498
1078
  textDecorationColor: "var(--dx-error)"
@@ -503,7 +1083,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
503
1083
  // https://codemirror.net/docs/ref/#view.keymap
504
1084
  // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
505
1085
  // TODO(burdon): Set custom keymap.
506
- import_view3.keymap.of(import_autocomplete.completionKeymap),
1086
+ import_view4.keymap.of(import_autocomplete.completionKeymap),
507
1087
  // https://codemirror.net/examples/autocompletion
508
1088
  // https://codemirror.net/docs/ref/#autocomplete.autocompletion
509
1089
  (0, import_autocomplete.autocompletion)({
@@ -563,11 +1143,11 @@ var cursorConverter = (accessor) => ({
563
1143
  });
564
1144
  var getPath = (state, field) => state.field(field).path;
565
1145
  var getLastHeads = (state, field) => state.field(field).lastHeads;
566
- var updateHeadsEffect = import_state4.StateEffect.define({});
1146
+ var updateHeadsEffect = import_state5.StateEffect.define({});
567
1147
  var updateHeads = (newHeads) => updateHeadsEffect.of({
568
1148
  newHeads
569
1149
  });
570
- var reconcileAnnotation = import_state4.Annotation.define();
1150
+ var reconcileAnnotation = import_state5.Annotation.define();
571
1151
  var isReconcile = (tr) => {
572
1152
  return !!tr.annotation(reconcileAnnotation);
573
1153
  };
@@ -603,7 +1183,7 @@ var updateCodeMirror = (view, selection, target, patches) => {
603
1183
  for (const patch of patches) {
604
1184
  const changeSpec = handlePatch(patch, target, view.state);
605
1185
  if (changeSpec != null) {
606
- const changeSet = import_state5.ChangeSet.of(changeSpec, view.state.doc.length, "\n");
1186
+ const changeSet = import_state6.ChangeSet.of(changeSpec, view.state.doc.length, "\n");
607
1187
  selection = selection.map(changeSet, 1);
608
1188
  view.dispatch({
609
1189
  changes: changeSet,
@@ -746,7 +1326,7 @@ var Syncer = class {
746
1326
  }
747
1327
  };
748
1328
  var automerge = (accessor) => {
749
- const syncState = import_state3.StateField.define({
1329
+ const syncState = import_state4.StateField.define({
750
1330
  create: () => ({
751
1331
  path: accessor.path.slice(),
752
1332
  lastHeads: import_automerge.next.getHeads(accessor.handle.docSync()),
@@ -781,7 +1361,7 @@ var automerge = (accessor) => {
781
1361
  // Track heads.
782
1362
  syncState,
783
1363
  // Reconcile external updates.
784
- import_view4.ViewPlugin.fromClass(class {
1364
+ import_view5.ViewPlugin.fromClass(class {
785
1365
  constructor(_view) {
786
1366
  this._view = _view;
787
1367
  this._handleChange = () => {
@@ -794,7 +1374,7 @@ var automerge = (accessor) => {
794
1374
  }
795
1375
  }),
796
1376
  // Reconcile local updates.
797
- import_view4.EditorView.updateListener.of(({ view, changes }) => {
1377
+ import_view5.EditorView.updateListener.of(({ view, changes }) => {
798
1378
  if (!changes.empty) {
799
1379
  syncer.reconcile(view, true);
800
1380
  }
@@ -813,11 +1393,11 @@ var dummyProvider = {
813
1393
  }
814
1394
  };
815
1395
  var awarenessProvider = singleValueFacet(dummyProvider);
816
- var RemoteSelectionChangedAnnotation = import_state6.Annotation.define();
1396
+ var RemoteSelectionChangedAnnotation = import_state7.Annotation.define();
817
1397
  var awareness = (provider = dummyProvider) => {
818
1398
  return [
819
1399
  awarenessProvider.of(provider),
820
- import_view5.ViewPlugin.fromClass(RemoteSelectionsDecorator, {
1400
+ import_view6.ViewPlugin.fromClass(RemoteSelectionsDecorator, {
821
1401
  decorations: (value) => value.decorations
822
1402
  }),
823
1403
  styles2
@@ -829,7 +1409,7 @@ var RemoteSelectionsDecorator = class {
829
1409
  F: __dxlog_file3,
830
1410
  L: 80
831
1411
  });
832
- this.decorations = import_state6.RangeSet.of([]);
1412
+ this.decorations = import_state7.RangeSet.of([]);
833
1413
  this._cursorConverter = view.state.facet(Cursor.converter);
834
1414
  this._provider = view.state.facet(awarenessProvider);
835
1415
  this._provider.open();
@@ -881,7 +1461,7 @@ var RemoteSelectionsDecorator = class {
881
1461
  decorations.push({
882
1462
  from: start,
883
1463
  to: end,
884
- value: import_view5.Decoration.mark({
1464
+ value: import_view6.Decoration.mark({
885
1465
  attributes: {
886
1466
  style: `background-color: ${lightColor}`
887
1467
  },
@@ -892,7 +1472,7 @@ var RemoteSelectionsDecorator = class {
892
1472
  decorations.push({
893
1473
  from: start,
894
1474
  to: startLine.from + startLine.length,
895
- value: import_view5.Decoration.mark({
1475
+ value: import_view6.Decoration.mark({
896
1476
  attributes: {
897
1477
  style: `background-color: ${lightColor}`
898
1478
  },
@@ -902,7 +1482,7 @@ var RemoteSelectionsDecorator = class {
902
1482
  decorations.push({
903
1483
  from: endLine.from,
904
1484
  to: end,
905
- value: import_view5.Decoration.mark({
1485
+ value: import_view6.Decoration.mark({
906
1486
  attributes: {
907
1487
  style: `background-color: ${lightColor}`
908
1488
  },
@@ -914,7 +1494,7 @@ var RemoteSelectionsDecorator = class {
914
1494
  decorations.push({
915
1495
  from: linePos,
916
1496
  to: linePos,
917
- value: import_view5.Decoration.line({
1497
+ value: import_view6.Decoration.line({
918
1498
  attributes: {
919
1499
  style: `background-color: ${lightColor}`,
920
1500
  class: "cm-collab-selectionLine"
@@ -926,17 +1506,17 @@ var RemoteSelectionsDecorator = class {
926
1506
  decorations.push({
927
1507
  from: head,
928
1508
  to: head,
929
- value: import_view5.Decoration.widget({
1509
+ value: import_view6.Decoration.widget({
930
1510
  side: head - anchor > 0 ? -1 : 1,
931
1511
  block: false,
932
1512
  widget: new RemoteCaretWidget(state.info.displayName ?? "Anonymous", darkColor)
933
1513
  })
934
1514
  });
935
1515
  }
936
- this.decorations = import_view5.Decoration.set(decorations, true);
1516
+ this.decorations = import_view6.Decoration.set(decorations, true);
937
1517
  }
938
1518
  };
939
- var RemoteCaretWidget = class extends import_view5.WidgetType {
1519
+ var RemoteCaretWidget = class extends import_view6.WidgetType {
940
1520
  constructor(_name, _color) {
941
1521
  super();
942
1522
  this._name = _name;
@@ -972,7 +1552,7 @@ var RemoteCaretWidget = class extends import_view5.WidgetType {
972
1552
  return true;
973
1553
  }
974
1554
  };
975
- var styles2 = import_view5.EditorView.theme({
1555
+ var styles2 = import_view6.EditorView.theme({
976
1556
  ".cm-collab-selection": {},
977
1557
  ".cm-collab-selectionLine": {
978
1558
  padding: 0,
@@ -1175,12 +1755,12 @@ var blast = (options = defaultOptions) => {
1175
1755
  };
1176
1756
  return [
1177
1757
  // Cursor moved.
1178
- import_view6.EditorView.updateListener.of((update2) => {
1758
+ import_view7.EditorView.updateListener.of((update2) => {
1179
1759
  if (blaster?.node !== update2.view.scrollDOM) {
1180
1760
  if (blaster) {
1181
1761
  blaster.destroy();
1182
1762
  }
1183
- blaster = new Blaster(update2.view.scrollDOM, (0, import_lodash.default)({
1763
+ blaster = new Blaster(update2.view.scrollDOM, (0, import_lodash2.default)({
1184
1764
  particleGravity: 0.2,
1185
1765
  particleShrinkRate: 0.995,
1186
1766
  color: () => [
@@ -1206,7 +1786,7 @@ var blast = (options = defaultOptions) => {
1206
1786
  }
1207
1787
  }
1208
1788
  }),
1209
- import_view6.keymap.of([
1789
+ import_view7.keymap.of([
1210
1790
  {
1211
1791
  any: (_, event) => {
1212
1792
  if (blaster) {
@@ -1436,7 +2016,7 @@ var random = (min, max) => {
1436
2016
  return min + ~~(Math.random() * (max - min + 1));
1437
2017
  };
1438
2018
  var commandConfig = singleValueFacet();
1439
- var commandState = import_state8.StateField.define({
2019
+ var commandState = import_state9.StateField.define({
1440
2020
  create: () => ({}),
1441
2021
  update: (state, tr) => {
1442
2022
  for (const effect of tr.effects) {
@@ -1492,11 +2072,11 @@ var commandState = import_state8.StateField.define({
1492
2072
  return state;
1493
2073
  },
1494
2074
  provide: (field) => [
1495
- import_view9.showTooltip.from(field, (value) => value.tooltip ?? null)
2075
+ import_view10.showTooltip.from(field, (value) => value.tooltip ?? null)
1496
2076
  ]
1497
2077
  });
1498
- var openEffect = import_state8.StateEffect.define();
1499
- var closeEffect = import_state8.StateEffect.define();
2078
+ var openEffect = import_state9.StateEffect.define();
2079
+ var closeEffect = import_state9.StateEffect.define();
1500
2080
  var openCommand = (view) => {
1501
2081
  if (view.state.field(commandState, false)) {
1502
2082
  const selection = view.state.selection.main;
@@ -1532,7 +2112,7 @@ var commandKeyBindings = [
1532
2112
  run: closeCommand
1533
2113
  }
1534
2114
  ];
1535
- var CommandHint = class extends import_view8.WidgetType {
2115
+ var CommandHint = class extends import_view9.WidgetType {
1536
2116
  constructor(content) {
1537
2117
  super();
1538
2118
  this.content = content;
@@ -1571,12 +2151,12 @@ var CommandHint = class extends import_view8.WidgetType {
1571
2151
  return false;
1572
2152
  }
1573
2153
  };
1574
- var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
2154
+ var hintViewPlugin = ({ onHint }) => import_view9.ViewPlugin.fromClass(class {
1575
2155
  constructor() {
1576
- this.deco = import_view8.Decoration.none;
2156
+ this.deco = import_view9.Decoration.none;
1577
2157
  }
1578
2158
  update(update2) {
1579
- const builder = new import_state7.RangeSetBuilder();
2159
+ const builder = new import_state8.RangeSetBuilder();
1580
2160
  const cState = update2.view.state.field(commandState, false);
1581
2161
  if (!cState?.tooltip) {
1582
2162
  const selection = update2.view.state.selection.main;
@@ -1584,7 +2164,7 @@ var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
1584
2164
  if (selection.from === selection.to && line.from === line.to) {
1585
2165
  const hint = onHint();
1586
2166
  if (hint) {
1587
- builder.add(selection.from, selection.to, import_view8.Decoration.widget({
2167
+ builder.add(selection.from, selection.to, import_view9.Decoration.widget({
1588
2168
  widget: new CommandHint(hint)
1589
2169
  }));
1590
2170
  }
@@ -1594,16 +2174,16 @@ var hintViewPlugin = ({ onHint }) => import_view8.ViewPlugin.fromClass(class {
1594
2174
  }
1595
2175
  }, {
1596
2176
  provide: (plugin) => [
1597
- import_view8.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view8.Decoration.none)
2177
+ import_view9.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view9.Decoration.none)
1598
2178
  ]
1599
2179
  });
1600
2180
  var command = (options) => {
1601
2181
  return [
1602
2182
  commandConfig.of(options),
1603
2183
  commandState,
1604
- import_view7.keymap.of(commandKeyBindings),
2184
+ import_view8.keymap.of(commandKeyBindings),
1605
2185
  hintViewPlugin(options),
1606
- import_view7.EditorView.focusChangeEffect.of((_, focusing) => {
2186
+ import_view8.EditorView.focusChangeEffect.of((_, focusing) => {
1607
2187
  return focusing ? closeEffect.of(null) : null;
1608
2188
  })
1609
2189
  ];
@@ -1615,10 +2195,10 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1615
2195
  return {
1616
2196
  selection,
1617
2197
  scrollIntoView: !scrollTo,
1618
- effects: scrollTo ? import_view11.EditorView.scrollIntoView(scrollTo, {
2198
+ effects: scrollTo ? import_view12.EditorView.scrollIntoView(scrollTo, {
1619
2199
  yMargin: 96
1620
2200
  }) : void 0,
1621
- annotations: import_state10.Transaction.userEvent.of(stateRestoreAnnotation)
2201
+ annotations: import_state11.Transaction.userEvent.of(stateRestoreAnnotation)
1622
2202
  };
1623
2203
  };
1624
2204
  var createEditorStateStore = (keyPrefix) => ({
@@ -1657,7 +2237,7 @@ var selectionState = ({ getState, setState } = {}) => {
1657
2237
  // setStateDebounced(id, {});
1658
2238
  // },
1659
2239
  // }),
1660
- import_view11.EditorView.updateListener.of(({ view, transactions }) => {
2240
+ import_view12.EditorView.updateListener.of(({ view, transactions }) => {
1661
2241
  const id = view.state.facet(documentId);
1662
2242
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1663
2243
  return;
@@ -1680,7 +2260,7 @@ var selectionState = ({ getState, setState } = {}) => {
1680
2260
  }
1681
2261
  }
1682
2262
  }),
1683
- getState && import_view11.keymap.of([
2263
+ getState && import_view12.keymap.of([
1684
2264
  {
1685
2265
  key: "ctrl-r",
1686
2266
  run: (view) => {
@@ -1695,10 +2275,10 @@ var selectionState = ({ getState, setState } = {}) => {
1695
2275
  ].filter(import_util3.isNotFalsy);
1696
2276
  };
1697
2277
  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({
2278
+ var setComments = import_state10.StateEffect.define();
2279
+ var setSelection = import_state10.StateEffect.define();
2280
+ var setCommentState = import_state10.StateEffect.define();
2281
+ var commentsState = import_state10.StateField.define({
1702
2282
  create: (state) => ({
1703
2283
  id: state.facet(documentId),
1704
2284
  comments: [],
@@ -1736,7 +2316,7 @@ var commentsState = import_state9.StateField.define({
1736
2316
  return value;
1737
2317
  }
1738
2318
  });
1739
- var styles3 = import_view10.EditorView.theme({
2319
+ var styles3 = import_view11.EditorView.theme({
1740
2320
  ".cm-comment, .cm-comment-current": {
1741
2321
  margin: "0 -3px",
1742
2322
  padding: "3px",
@@ -1749,23 +2329,23 @@ var styles3 = import_view10.EditorView.theme({
1749
2329
  textDecoration: "underline"
1750
2330
  }
1751
2331
  });
1752
- var createCommentMark = (id, isCurrent) => import_view10.Decoration.mark({
2332
+ var createCommentMark = (id, isCurrent) => import_view11.Decoration.mark({
1753
2333
  class: isCurrent ? "cm-comment-current" : "cm-comment",
1754
2334
  attributes: {
1755
2335
  "data-testid": "cm-comment",
1756
2336
  "data-comment-id": id
1757
2337
  }
1758
2338
  });
1759
- var commentsDecorations = import_view10.EditorView.decorations.compute([
2339
+ var commentsDecorations = import_view11.EditorView.decorations.compute([
1760
2340
  commentsState
1761
2341
  ], (state) => {
1762
2342
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
1763
- const decorations = (0, import_lodash2.default)(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
2343
+ const decorations = (0, import_lodash3.default)(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
1764
2344
  const range = comment.range;
1765
2345
  if (!range) {
1766
2346
  import_log4.log.warn("Invalid range:", range, {
1767
2347
  F: __dxlog_file7,
1768
- L: 142,
2348
+ L: 144,
1769
2349
  S: void 0,
1770
2350
  C: (f, a) => f(...a)
1771
2351
  });
@@ -1776,10 +2356,10 @@ var commentsDecorations = import_view10.EditorView.decorations.compute([
1776
2356
  const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
1777
2357
  return mark.range(range.from, range.to);
1778
2358
  }).filter(import_util2.nonNullable);
1779
- return import_view10.Decoration.set(decorations);
2359
+ return import_view11.Decoration.set(decorations);
1780
2360
  });
1781
- var commentClickedEffect = import_state9.StateEffect.define();
1782
- var handleCommentClick = import_view10.EditorView.domEventHandlers({
2361
+ var commentClickedEffect = import_state10.StateEffect.define();
2362
+ var handleCommentClick = import_view11.EditorView.domEventHandlers({
1783
2363
  click: (event, view) => {
1784
2364
  let target = event.target;
1785
2365
  const editorRoot = view.dom;
@@ -1818,7 +2398,7 @@ var trackPastedComments = (onUpdate) => {
1818
2398
  }
1819
2399
  };
1820
2400
  return [
1821
- import_view10.EditorView.domEventHandlers({
2401
+ import_view11.EditorView.domEventHandlers({
1822
2402
  cut: handleTrack,
1823
2403
  copy: handleTrack
1824
2404
  }),
@@ -1840,7 +2420,7 @@ var trackPastedComments = (onUpdate) => {
1840
2420
  return effects;
1841
2421
  }),
1842
2422
  // Handle paste or the undo of comment deletion.
1843
- import_view10.EditorView.updateListener.of((update2) => {
2423
+ import_view11.EditorView.updateListener.of((update2) => {
1844
2424
  const restore = [];
1845
2425
  for (let i = 0; i < update2.transactions.length; i++) {
1846
2426
  const tr = update2.transactions[i];
@@ -1896,10 +2476,10 @@ var mapTrackedComment = (comment, changes) => ({
1896
2476
  from: changes.mapPos(comment.from, 1),
1897
2477
  to: changes.mapPos(comment.to, 1)
1898
2478
  });
1899
- var restoreCommentEffect = import_state9.StateEffect.define({
2479
+ var restoreCommentEffect = import_state10.StateEffect.define({
1900
2480
  map: mapTrackedComment
1901
2481
  });
1902
- var createComment = (view) => {
2482
+ var createComment2 = (view) => {
1903
2483
  const options = view.state.facet(optionsFacet);
1904
2484
  const { from, to } = view.state.selection.main;
1905
2485
  if (from === to) {
@@ -1941,17 +2521,17 @@ var comments = (options = {}) => {
1941
2521
  //
1942
2522
  // Keymap.
1943
2523
  //
1944
- options.onCreate && import_view10.keymap.of([
2524
+ options.onCreate && import_view11.keymap.of([
1945
2525
  {
1946
2526
  key: shortcut,
1947
- run: callbackWrapper(createComment)
2527
+ run: callbackWrapper(createComment2)
1948
2528
  }
1949
2529
  ]),
1950
2530
  //
1951
2531
  // Hover tooltip (for key shortcut hints, etc.)
1952
2532
  // TODO(burdon): Factor out to generic hints extension for current selection/line.
1953
2533
  //
1954
- options.onHover && (0, import_view10.hoverTooltip)((view, pos) => {
2534
+ options.onHover && (0, import_view11.hoverTooltip)((view, pos) => {
1955
2535
  const selection = view.state.selection.main;
1956
2536
  if (selection && pos >= selection.from && pos <= selection.to) {
1957
2537
  return {
@@ -1980,7 +2560,7 @@ var comments = (options = {}) => {
1980
2560
  //
1981
2561
  // Track deleted ranges and update ranges for decorations.
1982
2562
  //
1983
- import_view10.EditorView.updateListener.of(({ view, state, changes }) => {
2563
+ import_view11.EditorView.updateListener.of(({ view, state, changes }) => {
1984
2564
  let mod = false;
1985
2565
  const { comments: comments2, ...value } = state.field(commentsState);
1986
2566
  changes.iterChanges((from, to, from2, to2) => {
@@ -2012,7 +2592,7 @@ var comments = (options = {}) => {
2012
2592
  //
2013
2593
  // Track selection/proximity.
2014
2594
  //
2015
- import_view10.EditorView.updateListener.of(({ view, state }) => {
2595
+ import_view11.EditorView.updateListener.of(({ view, state }) => {
2016
2596
  let min = Infinity;
2017
2597
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2018
2598
  const { head } = state.selection.main;
@@ -2039,419 +2619,192 @@ var comments = (options = {}) => {
2039
2619
  id: state.facet(documentId),
2040
2620
  comments: comments2.map(({ comment, range }) => ({
2041
2621
  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)"
2622
+ range,
2623
+ location: view.coordsAtPos(range.from)
2624
+ }))
2625
+ });
2626
+ }
2627
+ }),
2628
+ options.onUpdate && trackPastedComments(options.onUpdate)
2629
+ ].filter(import_util2.nonNullable);
2630
+ };
2631
+ var scrollThreadIntoView = (view, id, center = true) => {
2632
+ const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
2633
+ if (!comment?.comment.cursor) {
2634
+ return;
2635
+ }
2636
+ const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
2637
+ if (range) {
2638
+ const currentSelection = view.state.selection.main;
2639
+ const currentScrollPosition = view.scrollDOM.scrollTop;
2640
+ const targetScrollPosition = view.coordsAtPos(range.from)?.top;
2641
+ const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
2642
+ const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
2643
+ if (needsScroll || needsSelectionUpdate) {
2644
+ view.dispatch({
2645
+ selection: needsSelectionUpdate ? {
2646
+ anchor: range.from
2647
+ } : void 0,
2648
+ effects: [
2649
+ needsScroll ? import_view11.EditorView.scrollIntoView(range.from, center ? {
2650
+ y: "center"
2651
+ } : void 0) : [],
2652
+ needsSelectionUpdate ? setSelection.of({
2653
+ current: id
2654
+ }) : []
2655
+ ].flat()
2656
+ });
2657
+ }
2658
+ }
2659
+ };
2660
+ var selectionOverlapsComment = (state) => {
2661
+ const commentState = state.field(commentsState, false);
2662
+ if (commentState === void 0) {
2663
+ return false;
2664
+ }
2665
+ const { selection } = state;
2666
+ for (const range of selection.ranges) {
2667
+ if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
2668
+ return true;
2669
+ }
2670
+ }
2671
+ return false;
2672
+ };
2673
+ var hasActiveSelection = (state) => {
2674
+ return state.selection.ranges.some((range) => !range.empty);
2675
+ };
2676
+ var ExternalCommentSync = class {
2677
+ constructor(view, id, subscribe, getComments) {
2678
+ this.destroy = () => {
2679
+ this.unsubscribe();
2680
+ };
2681
+ const updateComments = () => {
2682
+ const comments2 = getComments();
2683
+ if (id === view.state.facet(documentId)) {
2684
+ queueMicrotask(() => view.dispatch({
2685
+ effects: setComments.of({
2686
+ id,
2687
+ comments: comments2
2688
+ })
2689
+ }));
2690
+ }
2691
+ };
2692
+ this.unsubscribe = subscribe(updateComments);
2693
+ }
2694
+ };
2695
+ var createExternalCommentSync = (id, subscribe, getComments) => import_view11.ViewPlugin.fromClass(class {
2696
+ constructor(view) {
2697
+ return new ExternalCommentSync(view, id, subscribe, getComments);
2698
+ }
2699
+ });
2700
+ var useCommentState = (state) => {
2701
+ return (0, import_react4.useMemo)(() => import_view11.EditorView.updateListener.of((update2) => {
2702
+ if (update2.docChanged || update2.selectionSet) {
2703
+ state.comment = selectionOverlapsComment(update2.state);
2704
+ state.selection = hasActiveSelection(update2.state);
2705
+ }
2706
+ }), [
2707
+ state
2708
+ ]);
2709
+ };
2710
+ var useComments = (view, id, comments2) => {
2711
+ (0, import_react4.useEffect)(() => {
2712
+ if (view) {
2713
+ if (id === view.state.facet(documentId)) {
2714
+ view.dispatch({
2715
+ effects: setComments.of({
2716
+ id,
2717
+ comments: comments2 ?? []
2718
+ })
2719
+ });
2720
+ }
2446
2721
  }
2722
+ });
2723
+ };
2724
+ var useCommentClickListener = (onCommentClick) => {
2725
+ return (0, import_react4.useMemo)(() => import_view11.EditorView.updateListener.of((update2) => {
2726
+ update2.transactions.forEach((transaction) => {
2727
+ transaction.effects.forEach((effect) => {
2728
+ if (effect.is(commentClickedEffect)) {
2729
+ onCommentClick(effect.value);
2730
+ }
2731
+ });
2732
+ });
2733
+ }), [
2734
+ onCommentClick
2735
+ ]);
2736
+ };
2737
+ var debugNodeLogger = (log8 = console.log) => {
2738
+ const logTokens = (state) => (0, import_language.syntaxTree)(state).iterate({
2739
+ enter: (node) => log8(node.type)
2740
+ });
2741
+ return import_state12.StateField.define({
2742
+ create: (state) => logTokens(state),
2743
+ update: (_, tr) => logTokens(tr.state)
2744
+ });
2745
+ };
2746
+ var styles4 = import_view13.EditorView.theme({
2747
+ ".cm-dropCursor": {
2748
+ borderLeft: "2px solid var(--dx-accentText)",
2749
+ color: "var(--dx-accentText)",
2750
+ padding: "0 4px"
2447
2751
  },
2448
- ".cm-panel.cm-search": {
2449
- padding: "4px",
2450
- borderTop: "1px solid var(--dx-separator)"
2752
+ ".cm-dropCursor:after": {
2753
+ content: '"\u2190"'
2451
2754
  }
2755
+ });
2756
+ var dropFile = (options = {}) => {
2757
+ return [
2758
+ styles4,
2759
+ (0, import_view13.dropCursor)(),
2760
+ import_view13.EditorView.domEventHandlers({
2761
+ drop: (event, view) => {
2762
+ event.preventDefault();
2763
+ const files = event.dataTransfer?.files;
2764
+ const pos = view.posAtCoords(event);
2765
+ if (files?.length && pos !== null) {
2766
+ view.dispatch({
2767
+ selection: {
2768
+ anchor: pos
2769
+ }
2770
+ });
2771
+ options.onDrop?.(view, {
2772
+ files
2773
+ });
2774
+ }
2775
+ }
2776
+ })
2777
+ ];
2452
2778
  };
2779
+ var focusEffect = import_state14.StateEffect.define();
2780
+ var focusField = import_state14.StateField.define({
2781
+ create: () => false,
2782
+ update: (value, tr) => {
2783
+ for (const effect of tr.effects) {
2784
+ if (effect.is(focusEffect)) {
2785
+ return effect.value;
2786
+ }
2787
+ }
2788
+ return value;
2789
+ }
2790
+ });
2791
+ var focus = [
2792
+ focusField,
2793
+ import_view15.EditorView.domEventHandlers({
2794
+ focus: (event, view) => {
2795
+ setTimeout(() => view.dispatch({
2796
+ effects: focusEffect.of(true)
2797
+ }));
2798
+ },
2799
+ blur: (event, view) => {
2800
+ setTimeout(() => view.dispatch({
2801
+ effects: focusEffect.of(false)
2802
+ }));
2803
+ }
2804
+ })
2805
+ ];
2453
2806
  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);
2807
+ var preventNewline = import_state13.EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
2455
2808
  var defaultBasicOptions = {
2456
2809
  allowMultipleSelections: true,
2457
2810
  bracketMatching: true,
@@ -2471,10 +2824,10 @@ var keymaps = {
2471
2824
  default: import_commands2.defaultKeymap
2472
2825
  };
2473
2826
  var createBasicExtensions = (_props) => {
2474
- const props = (0, import_lodash3.default)({}, _props, defaultBasicOptions);
2827
+ const props = (0, import_lodash4.default)({}, _props, defaultBasicOptions);
2475
2828
  return [
2476
2829
  // NOTE: Doesn't catch errors in keymap functions.
2477
- import_view13.EditorView.exceptionSink.of((err) => {
2830
+ import_view14.EditorView.exceptionSink.of((err) => {
2478
2831
  import_log5.log.catch(err, void 0, {
2479
2832
  F: __dxlog_file8,
2480
2833
  L: 96,
@@ -2482,27 +2835,27 @@ var createBasicExtensions = (_props) => {
2482
2835
  C: (f, a) => f(...a)
2483
2836
  });
2484
2837
  }),
2485
- props.allowMultipleSelections && import_state12.EditorState.allowMultipleSelections.of(true),
2838
+ props.allowMultipleSelections && import_state13.EditorState.allowMultipleSelections.of(true),
2486
2839
  props.bracketMatching && (0, import_language2.bracketMatching)(),
2487
2840
  props.closeBrackets && (0, import_autocomplete2.closeBrackets)(),
2488
- props.dropCursor && (0, import_view13.dropCursor)(),
2489
- props.drawSelection && (0, import_view13.drawSelection)({
2841
+ props.dropCursor && (0, import_view14.dropCursor)(),
2842
+ props.drawSelection && (0, import_view14.drawSelection)({
2490
2843
  cursorBlinkRate: 1200
2491
2844
  }),
2492
2845
  props.focus && focus,
2493
- props.highlightActiveLine && (0, import_view13.highlightActiveLine)(),
2846
+ props.highlightActiveLine && (0, import_view14.highlightActiveLine)(),
2494
2847
  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),
2848
+ props.lineNumbers && (0, import_view14.lineNumbers)(),
2849
+ props.lineWrapping && import_view14.EditorView.lineWrapping,
2850
+ props.placeholder && (0, import_view14.placeholder)(props.placeholder),
2498
2851
  props.readonly && [
2499
- import_state12.EditorState.readOnly.of(true),
2500
- import_view13.EditorView.editable.of(false)
2852
+ import_state13.EditorState.readOnly.of(true),
2853
+ import_view14.EditorView.editable.of(false)
2501
2854
  ],
2502
- props.scrollPastEnd && (0, import_view13.scrollPastEnd)(),
2503
- props.tabSize && import_state12.EditorState.tabSize.of(props.tabSize),
2855
+ props.scrollPastEnd && (0, import_view14.scrollPastEnd)(),
2856
+ props.tabSize && import_state13.EditorState.tabSize.of(props.tabSize),
2504
2857
  // https://codemirror.net/docs/ref/#view.KeyBinding
2505
- import_view13.keymap.of([
2858
+ import_view14.keymap.of([
2506
2859
  ...(props.keymap && keymaps[props.keymap]) ?? [],
2507
2860
  // NOTE: Tabs are also configured by markdown extension.
2508
2861
  // https://codemirror.net/docs/ref/#commands.indentWithTab
@@ -2524,16 +2877,16 @@ var defaultThemeSlots = {
2524
2877
  }
2525
2878
  };
2526
2879
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2527
- const slots = (0, import_lodash3.default)({}, _slots, defaultThemeSlots);
2880
+ const slots = (0, import_lodash4.default)({}, _slots, defaultThemeSlots);
2528
2881
  return [
2529
- import_view13.EditorView.darkTheme.of(themeMode === "dark"),
2530
- import_view13.EditorView.baseTheme(styles5 ? (0, import_lodash4.default)({}, defaultTheme, styles5) : defaultTheme),
2882
+ import_view14.EditorView.darkTheme.of(themeMode === "dark"),
2883
+ import_view14.EditorView.baseTheme(styles5 ? (0, import_lodash5.default)({}, defaultTheme, styles5) : defaultTheme),
2531
2884
  // https://github.com/codemirror/theme-one-dark
2532
2885
  _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({
2886
+ slots.editor?.className && import_view14.EditorView.editorAttributes.of({
2534
2887
  class: slots.editor.className
2535
2888
  }),
2536
- slots.content?.className && import_view13.EditorView.contentAttributes.of({
2889
+ slots.content?.className && import_view14.EditorView.contentAttributes.of({
2537
2890
  class: slots.content.className
2538
2891
  })
2539
2892
  ].filter(import_util4.isNotFalsy);
@@ -2545,7 +2898,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2545
2898
  }
2546
2899
  if (space && identity) {
2547
2900
  const peerId = identity?.identityKey.toHex();
2548
- const { cursorLightValue, cursorDarkValue } = import_react_ui_theme3.hueTokens[identity?.profile?.data?.hue ?? (0, import_util4.hexToHue)(peerId ?? "0")];
2901
+ const { cursorLightValue, cursorDarkValue } = import_react_ui_theme7.hueTokens[identity?.profile?.data?.hue ?? (0, import_util4.hexToHue)(peerId ?? "0")];
2549
2902
  extensions.push(awareness(new SpaceAwarenessProvider({
2550
2903
  space,
2551
2904
  channel: `awareness.${id}`,
@@ -2580,7 +2933,7 @@ var folding = (_props = {}) => [
2580
2933
  }));
2581
2934
  }
2582
2935
  }),
2583
- import_view15.EditorView.theme({
2936
+ import_view16.EditorView.theme({
2584
2937
  ".cm-foldGutter": {
2585
2938
  opacity: 0.3,
2586
2939
  transition: "opacity 0.3s",
@@ -2593,11 +2946,11 @@ var folding = (_props = {}) => [
2593
2946
  ];
2594
2947
  var listener = ({ onFocus, onChange }) => {
2595
2948
  const extensions = [];
2596
- onFocus && extensions.push(import_view16.EditorView.focusChangeEffect.of((_, focusing) => {
2949
+ onFocus && extensions.push(import_view17.EditorView.focusChangeEffect.of((_, focusing) => {
2597
2950
  onFocus(focusing);
2598
2951
  return null;
2599
2952
  }));
2600
- onChange && extensions.push(import_view16.EditorView.updateListener.of((update2) => {
2953
+ onChange && extensions.push(import_view17.EditorView.updateListener.of((update2) => {
2601
2954
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
2602
2955
  }));
2603
2956
  return extensions;
@@ -2720,7 +3073,7 @@ var setStyle = (type, enable) => {
2720
3073
  to: range.head + found + marker.length
2721
3074
  }
2722
3075
  ],
2723
- range: import_state14.EditorSelection.cursor(range.from - marker.length)
3076
+ range: import_state15.EditorSelection.cursor(range.from - marker.length)
2724
3077
  };
2725
3078
  }
2726
3079
  }
@@ -2848,13 +3201,13 @@ var setStyle = (type, enable) => {
2848
3201
  from: range.head,
2849
3202
  insert: marker + marker
2850
3203
  },
2851
- range: import_state14.EditorSelection.cursor(range.head + marker.length)
3204
+ range: import_state15.EditorSelection.cursor(range.head + marker.length)
2852
3205
  };
2853
3206
  }
2854
3207
  const changeSet = state.changes(changes2.concat(changesAtEnd));
2855
3208
  return {
2856
3209
  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))
3210
+ 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
3211
  };
2859
3212
  });
2860
3213
  dispatch(state.update(changes, {
@@ -3054,7 +3407,7 @@ var addLink = ({ url, image: image2 } = {}) => {
3054
3407
  const changeSet = state.changes(changes2.concat(changesAfter));
3055
3408
  return {
3056
3409
  changes: changeSet,
3057
- range: import_state14.EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
3410
+ range: import_state15.EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
3058
3411
  };
3059
3412
  });
3060
3413
  if (changes.changes.empty) {
@@ -3488,7 +3841,7 @@ var toggleCodeblock = (target) => {
3488
3841
  };
3489
3842
  var formattingKeymap = (_options = {}) => {
3490
3843
  return [
3491
- import_view17.keymap.of([
3844
+ import_view18.keymap.of([
3492
3845
  {
3493
3846
  key: "meta-b",
3494
3847
  run: toggleStrong
@@ -3688,63 +4041,54 @@ var getFormatting = (state) => {
3688
4041
  listStyle: listStyle || null
3689
4042
  };
3690
4043
  };
3691
- var useFormattingState = () => {
3692
- const [state, setState] = (0, import_react6.useState)();
3693
- const observer = (0, import_react6.useMemo)(() => import_view17.EditorView.updateListener.of((update2) => {
4044
+ var useFormattingState = (state) => {
4045
+ return (0, import_react6.useMemo)(() => import_view18.EditorView.updateListener.of((update2) => {
3694
4046
  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;
4047
+ Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
4048
+ state[key] = active;
3701
4049
  });
3702
4050
  }
3703
4051
  }), []);
3704
- return [
3705
- state,
3706
- observer
3707
- ];
3708
4052
  };
3709
- var processAction = (view, action) => {
4053
+ var processEditorPayload = (view, { type, data }) => {
3710
4054
  let inlineType, listType;
3711
- switch (action.type) {
4055
+ switch (type) {
3712
4056
  case "heading":
3713
- setHeading(parseInt(action.data))(view);
4057
+ setHeading(parseInt(data))(view);
3714
4058
  break;
3715
4059
  case "strong":
3716
4060
  case "emphasis":
3717
4061
  case "strikethrough":
3718
4062
  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);
4063
+ inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
4064
+ (typeof data === "boolean" ? setStyle(inlineType, data) : toggleStyle(inlineType))(view);
3721
4065
  break;
3722
4066
  case "list-ordered":
3723
4067
  case "list-bullet":
3724
4068
  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);
4069
+ listType = type === "list-ordered" ? List.Ordered : type === "list-bullet" ? List.Bullet : List.Task;
4070
+ (data === false ? removeList(listType) : data === true ? addList(listType) : toggleList(listType))(view);
3727
4071
  break;
3728
4072
  case "blockquote":
3729
- (action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
4073
+ (data === false ? removeBlockquote : data === true ? addBlockquote : toggleBlockquote)(view);
3730
4074
  break;
3731
4075
  case "codeblock":
3732
- (action.data === false ? removeCodeblock : addCodeblock)(view);
4076
+ (data === false ? removeCodeblock : addCodeblock)(view);
3733
4077
  break;
3734
4078
  case "table":
3735
4079
  insertTable(view);
3736
4080
  break;
3737
4081
  case "link":
3738
- (action.data === false ? removeLink : addLink())(view);
4082
+ (data === false ? removeLink : addLink())(view);
3739
4083
  break;
3740
4084
  case "image":
3741
4085
  addLink({
3742
- url: action.data,
4086
+ url: data,
3743
4087
  image: true
3744
4088
  })(view);
3745
4089
  break;
3746
4090
  case "comment":
3747
- createComment(view);
4091
+ createComment2(view);
3748
4092
  break;
3749
4093
  }
3750
4094
  requestAnimationFrame(() => {
@@ -3950,7 +4294,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3950
4294
  }),
3951
4295
  // Custom styles.
3952
4296
  (0, import_language5.syntaxHighlighting)(markdownHighlightStyle()),
3953
- import_view18.keymap.of([
4297
+ import_view19.keymap.of([
3954
4298
  // https://codemirror.net/docs/ref/#commands.indentWithTab
3955
4299
  import_commands3.indentWithTab,
3956
4300
  // https://codemirror.net/docs/ref/#commands.defaultKeymap
@@ -3960,7 +4304,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3960
4304
  ])
3961
4305
  ];
3962
4306
  };
3963
- var debugTree = (cb) => import_state15.StateField.define({
4307
+ var debugTree = (cb) => import_state16.StateField.define({
3964
4308
  create: (state) => cb(convertTreeToJson(state)),
3965
4309
  update: (value, tr) => cb(convertTreeToJson(tr.state))
3966
4310
  });
@@ -3984,12 +4328,12 @@ var convertTreeToJson = (state) => {
3984
4328
  return treeToJson((0, import_language7.syntaxTree)(state).cursor());
3985
4329
  };
3986
4330
  var adjustChanges = () => {
3987
- return import_view20.ViewPlugin.fromClass(class {
4331
+ return import_view21.ViewPlugin.fromClass(class {
3988
4332
  update(update2) {
3989
4333
  const tree = (0, import_language9.syntaxTree)(update2.state);
3990
4334
  const adjustments = [];
3991
4335
  for (const tr of update2.transactions) {
3992
- const event = tr.annotation(import_state17.Transaction.userEvent);
4336
+ const event = tr.annotation(import_state18.Transaction.userEvent);
3993
4337
  switch (event) {
3994
4338
  //
3995
4339
  // Enter
@@ -4124,9 +4468,9 @@ var getValidUrl = (str) => {
4124
4468
  };
4125
4469
  var image = (_options = {}) => {
4126
4470
  return [
4127
- import_state18.StateField.define({
4471
+ import_state19.StateField.define({
4128
4472
  create: (state) => {
4129
- return import_view21.Decoration.set(buildDecorations(0, state.doc.length, state));
4473
+ return import_view22.Decoration.set(buildDecorations(0, state.doc.length, state));
4130
4474
  },
4131
4475
  update: (value, tr) => {
4132
4476
  if (!tr.docChanged && !tr.selection) {
@@ -4149,7 +4493,7 @@ var image = (_options = {}) => {
4149
4493
  add: buildDecorations(from, to, tr.state)
4150
4494
  });
4151
4495
  },
4152
- provide: (field) => import_view21.EditorView.decorations.from(field)
4496
+ provide: (field) => import_view22.EditorView.decorations.from(field)
4153
4497
  })
4154
4498
  ];
4155
4499
  };
@@ -4175,7 +4519,7 @@ var buildDecorations = (from, to, state) => {
4175
4519
  return;
4176
4520
  }
4177
4521
  preloadImage(url);
4178
- decorations.push(import_view21.Decoration.replace({
4522
+ decorations.push(import_view22.Decoration.replace({
4179
4523
  block: true,
4180
4524
  widget: new ImageWidget(url)
4181
4525
  }).range(hide2 ? node.from : node.to, node.to));
@@ -4187,7 +4531,7 @@ var buildDecorations = (from, to, state) => {
4187
4531
  });
4188
4532
  return decorations;
4189
4533
  };
4190
- var ImageWidget = class extends import_view21.WidgetType {
4534
+ var ImageWidget = class extends import_view22.WidgetType {
4191
4535
  constructor(_url) {
4192
4536
  super();
4193
4537
  this._url = _url;
@@ -4209,7 +4553,7 @@ var ImageWidget = class extends import_view21.WidgetType {
4209
4553
  };
4210
4554
  var bulletListIndentationWidth = 24;
4211
4555
  var orderedListIndentationWidth = 36;
4212
- var formattingStyles = import_view22.EditorView.theme({
4556
+ var formattingStyles = import_view23.EditorView.theme({
4213
4557
  /**
4214
4558
  * Horizontal rule.
4215
4559
  */
@@ -4303,17 +4647,38 @@ var formattingStyles = import_view22.EditorView.theme({
4303
4647
  height: "auto",
4304
4648
  borderTop: "0.5rem solid transparent",
4305
4649
  borderBottom: "0.5rem solid transparent"
4650
+ },
4651
+ ".cm-image-with-loader": {
4652
+ display: "block",
4653
+ opacity: "0",
4654
+ transitionDuration: "350ms",
4655
+ transitionProperty: "opacity"
4656
+ },
4657
+ ".cm-image-with-loader.cm-loaded-image": {
4658
+ opacity: "1"
4659
+ },
4660
+ ".cm-image-wrapper": {
4661
+ "grid-template-columns": "1fr",
4662
+ display: "grid",
4663
+ margin: "0.5rem 0",
4664
+ overflow: "hidden",
4665
+ transitionDuration: "350ms",
4666
+ transitionProperty: "height",
4667
+ "& > *": {
4668
+ "grid-row-start": 1,
4669
+ "grid-column-start": 1
4670
+ }
4306
4671
  }
4307
4672
  });
4308
4673
  var table = (options = {}) => {
4309
- return import_state19.StateField.define({
4674
+ return import_state20.StateField.define({
4310
4675
  create: (state) => update(state, options),
4311
4676
  update: (_, tr) => update(tr.state, options),
4312
- provide: (field) => import_view23.EditorView.decorations.from(field)
4677
+ provide: (field) => import_view24.EditorView.decorations.from(field)
4313
4678
  });
4314
4679
  };
4315
4680
  var update = (state, _options) => {
4316
- const builder = new import_state19.RangeSetBuilder();
4681
+ const builder = new import_state20.RangeSetBuilder();
4317
4682
  const cursor = state.selection.main.head;
4318
4683
  const tables = [];
4319
4684
  const getTable = () => tables[tables.length - 1];
@@ -4354,19 +4719,19 @@ var update = (state, _options) => {
4354
4719
  tables.forEach((table2) => {
4355
4720
  const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4356
4721
  if (replace) {
4357
- builder.add(table2.from, table2.to, import_view23.Decoration.replace({
4722
+ builder.add(table2.from, table2.to, import_view24.Decoration.replace({
4358
4723
  block: true,
4359
4724
  widget: new TableWidget(table2)
4360
4725
  }));
4361
4726
  } else {
4362
- builder.add(table2.from, table2.to, import_view23.Decoration.mark({
4727
+ builder.add(table2.from, table2.to, import_view24.Decoration.mark({
4363
4728
  class: "cm-table"
4364
4729
  }));
4365
4730
  }
4366
4731
  });
4367
4732
  return builder.finish();
4368
4733
  };
4369
- var TableWidget = class extends import_view23.WidgetType {
4734
+ var TableWidget = class extends import_view24.WidgetType {
4370
4735
  constructor(_table) {
4371
4736
  super();
4372
4737
  this._table = _table;
@@ -4406,14 +4771,14 @@ var Unicode = {
4406
4771
  bulletSmall: "\u2219",
4407
4772
  bulletSquare: "\u2B1D"
4408
4773
  };
4409
- var HorizontalRuleWidget = class extends import_view19.WidgetType {
4774
+ var HorizontalRuleWidget = class extends import_view20.WidgetType {
4410
4775
  toDOM() {
4411
4776
  const el = document.createElement("span");
4412
4777
  el.className = "cm-hr";
4413
4778
  return el;
4414
4779
  }
4415
4780
  };
4416
- var LinkButton = class extends import_view19.WidgetType {
4781
+ var LinkButton = class extends import_view20.WidgetType {
4417
4782
  constructor(url, render) {
4418
4783
  super();
4419
4784
  this.url = url;
@@ -4429,7 +4794,7 @@ var LinkButton = class extends import_view19.WidgetType {
4429
4794
  return el;
4430
4795
  }
4431
4796
  };
4432
- var CheckboxWidget = class extends import_view19.WidgetType {
4797
+ var CheckboxWidget = class extends import_view20.WidgetType {
4433
4798
  constructor(_checked) {
4434
4799
  super();
4435
4800
  this._checked = _checked;
@@ -4439,7 +4804,7 @@ var CheckboxWidget = class extends import_view19.WidgetType {
4439
4804
  }
4440
4805
  toDOM(view) {
4441
4806
  const input = document.createElement("input");
4442
- input.className = "cm-task-checkbox ch-checkbox";
4807
+ input.className = "cm-task-checkbox dx-checkbox";
4443
4808
  input.type = "checkbox";
4444
4809
  input.tabIndex = -1;
4445
4810
  input.checked = this._checked;
@@ -4474,7 +4839,7 @@ var CheckboxWidget = class extends import_view19.WidgetType {
4474
4839
  return false;
4475
4840
  }
4476
4841
  };
4477
- var TextWidget = class extends import_view19.WidgetType {
4842
+ var TextWidget = class extends import_view20.WidgetType {
4478
4843
  constructor(text, className) {
4479
4844
  super();
4480
4845
  this.text = text;
@@ -4489,29 +4854,29 @@ var TextWidget = class extends import_view19.WidgetType {
4489
4854
  return el;
4490
4855
  }
4491
4856
  };
4492
- var hide = import_view19.Decoration.replace({});
4493
- var blockQuote = import_view19.Decoration.line({
4494
- class: (0, import_react_ui_theme6.mx)("cm-blockquote")
4857
+ var hide = import_view20.Decoration.replace({});
4858
+ var blockQuote = import_view20.Decoration.line({
4859
+ class: (0, import_react_ui_theme8.mx)("cm-blockquote")
4495
4860
  });
4496
- var fencedCodeLine = import_view19.Decoration.line({
4497
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line")
4861
+ var fencedCodeLine = import_view20.Decoration.line({
4862
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line")
4498
4863
  });
4499
- var fencedCodeLineFirst = import_view19.Decoration.line({
4500
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line", "cm-codeblock-first")
4864
+ var fencedCodeLineFirst = import_view20.Decoration.line({
4865
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line", "cm-codeblock-first")
4501
4866
  });
4502
- var fencedCodeLineLast = import_view19.Decoration.line({
4503
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line", "cm-codeblock-last")
4867
+ var fencedCodeLineLast = import_view20.Decoration.line({
4868
+ class: (0, import_react_ui_theme8.mx)("cm-code cm-codeblock-line", "cm-codeblock-last")
4504
4869
  });
4505
4870
  var commentBlockLine = fencedCodeLine;
4506
4871
  var commentBlockLineFirst = fencedCodeLineFirst;
4507
4872
  var commentBlockLineLast = fencedCodeLineLast;
4508
- var horizontalRule = import_view19.Decoration.replace({
4873
+ var horizontalRule = import_view20.Decoration.replace({
4509
4874
  widget: new HorizontalRuleWidget()
4510
4875
  });
4511
- var checkedTask = import_view19.Decoration.replace({
4876
+ var checkedTask = import_view20.Decoration.replace({
4512
4877
  widget: new CheckboxWidget(true)
4513
4878
  });
4514
- var uncheckedTask = import_view19.Decoration.replace({
4879
+ var uncheckedTask = import_view20.Decoration.replace({
4515
4880
  widget: new CheckboxWidget(false)
4516
4881
  });
4517
4882
  var editingRange = (state, range, focus2) => {
@@ -4527,8 +4892,8 @@ var autoHideTags = /* @__PURE__ */ new Set([
4527
4892
  "SuperscriptMark"
4528
4893
  ]);
4529
4894
  var buildDecorations2 = (view, options, focus2) => {
4530
- const deco = new import_state16.RangeSetBuilder();
4531
- const atomicDeco = new import_state16.RangeSetBuilder();
4895
+ const deco = new import_state17.RangeSetBuilder();
4896
+ const atomicDeco = new import_state17.RangeSetBuilder();
4532
4897
  const { state } = view;
4533
4898
  const headerLevels = [];
4534
4899
  const getHeaderLevels = (node, level) => {
@@ -4612,7 +4977,7 @@ var buildDecorations2 = (view, options, focus2) => {
4612
4977
  } else {
4613
4978
  const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
4614
4979
  if (num.length) {
4615
- atomicDeco.add(mark.from, mark.from + len, import_view19.Decoration.replace({
4980
+ atomicDeco.add(mark.from, mark.from + len, import_view20.Decoration.replace({
4616
4981
  widget: new TextWidget(num, theme.heading(level))
4617
4982
  }));
4618
4983
  }
@@ -4637,7 +5002,7 @@ var buildDecorations2 = (view, options, focus2) => {
4637
5002
  if (node.from === line.to - 1) {
4638
5003
  return false;
4639
5004
  }
4640
- deco.add(line.from, line.from, import_view19.Decoration.line({
5005
+ deco.add(line.from, line.from, import_view20.Decoration.line({
4641
5006
  class: "cm-list-item",
4642
5007
  attributes: {
4643
5008
  style: `padding-left: ${offset}px; text-indent: -${width}px;`
@@ -4654,7 +5019,7 @@ var buildDecorations2 = (view, options, focus2) => {
4654
5019
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
4655
5020
  const line = state.doc.lineAt(node.from);
4656
5021
  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({
5022
+ atomicDeco.add(line.from, to, import_view20.Decoration.replace({
4658
5023
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
4659
5024
  }));
4660
5025
  break;
@@ -4741,7 +5106,7 @@ var buildDecorations2 = (view, options, focus2) => {
4741
5106
  if (!editing) {
4742
5107
  atomicDeco.add(node.from, marks[0].to, hide);
4743
5108
  }
4744
- deco.add(marks[0].to, marks[1].from, import_view19.Decoration.mark({
5109
+ deco.add(marks[0].to, marks[1].from, import_view20.Decoration.mark({
4745
5110
  tagName: "a",
4746
5111
  attributes: {
4747
5112
  class: "cm-link",
@@ -4751,7 +5116,7 @@ var buildDecorations2 = (view, options, focus2) => {
4751
5116
  }
4752
5117
  }));
4753
5118
  if (!editing) {
4754
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? import_view19.Decoration.replace({
5119
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? import_view20.Decoration.replace({
4755
5120
  widget: new LinkButton(url, options.renderLinkButton)
4756
5121
  }) : hide);
4757
5122
  }
@@ -4806,10 +5171,10 @@ var buildDecorations2 = (view, options, focus2) => {
4806
5171
  atomicDeco: atomicDeco.finish()
4807
5172
  };
4808
5173
  };
4809
- var forceUpdate = import_state16.StateEffect.define();
5174
+ var forceUpdate = import_state17.StateEffect.define();
4810
5175
  var decorateMarkdown = (options = {}) => {
4811
5176
  return [
4812
- import_view19.ViewPlugin.fromClass(class {
5177
+ import_view20.ViewPlugin.fromClass(class {
4813
5178
  constructor(view) {
4814
5179
  ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
4815
5180
  }
@@ -4841,9 +5206,9 @@ var decorateMarkdown = (options = {}) => {
4841
5206
  }
4842
5207
  }, {
4843
5208
  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)
5209
+ import_view20.EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view20.Decoration.none),
5210
+ import_view20.EditorView.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view20.Decoration.none),
5211
+ import_view20.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view20.Decoration.none)
4847
5212
  ]
4848
5213
  }),
4849
5214
  image(),
@@ -4853,7 +5218,7 @@ var decorateMarkdown = (options = {}) => {
4853
5218
  ];
4854
5219
  };
4855
5220
  var linkTooltip = (render) => {
4856
- return (0, import_view24.hoverTooltip)((view, pos, side) => {
5221
+ return (0, import_view25.hoverTooltip)((view, pos, side) => {
4857
5222
  const syntax = (0, import_language12.syntaxTree)(view.state).resolveInner(pos, side);
4858
5223
  let link = null;
4859
5224
  for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
@@ -4870,7 +5235,7 @@ var linkTooltip = (render) => {
4870
5235
  above: true,
4871
5236
  create: () => {
4872
5237
  const el = document.createElement("div");
4873
- el.className = (0, import_react_ui_theme7.tooltipContent)({}, "pli-2 plb-1");
5238
+ el.className = (0, import_react_ui_theme9.tooltipContent)({}, "pli-2 plb-1");
4874
5239
  render(el, urlText);
4875
5240
  return {
4876
5241
  dom: el,
@@ -4922,11 +5287,13 @@ var EditorViewModes = [
4922
5287
  "readonly",
4923
5288
  "source"
4924
5289
  ];
5290
+ var EditorViewMode = import_echo_schema.S.Union(...EditorViewModes.map((mode) => import_echo_schema.S.Literal(mode)));
4925
5291
  var EditorInputModes = [
4926
5292
  "default",
4927
5293
  "vim",
4928
5294
  "vscode"
4929
5295
  ];
5296
+ var EditorInputMode = import_echo_schema.S.Union(...EditorInputModes.map((mode) => import_echo_schema.S.Literal(mode)));
4930
5297
  var editorInputMode = singleValueFacet({});
4931
5298
  var InputModeExtensions = {
4932
5299
  default: [],
@@ -4935,7 +5302,7 @@ var InputModeExtensions = {
4935
5302
  editorInputMode.of({
4936
5303
  type: "vscode"
4937
5304
  }),
4938
- import_view25.keymap.of(import_codemirror_vscode_keymap.vscodeKeymap)
5305
+ import_view26.keymap.of(import_codemirror_vscode_keymap.vscodeKeymap)
4939
5306
  ],
4940
5307
  vim: [
4941
5308
  // https://github.com/replit/codemirror-vim
@@ -4944,7 +5311,7 @@ var InputModeExtensions = {
4944
5311
  type: "vim",
4945
5312
  noTabster: true
4946
5313
  }),
4947
- import_view25.keymap.of([
5314
+ import_view26.keymap.of([
4948
5315
  {
4949
5316
  key: "Alt-Escape",
4950
5317
  run: (view) => {
@@ -4964,7 +5331,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4964
5331
  let t;
4965
5332
  let idx = 0;
4966
5333
  return [
4967
- import_view26.keymap.of([
5334
+ import_view27.keymap.of([
4968
5335
  {
4969
5336
  // Reset.
4970
5337
  key: "alt-meta-'",
@@ -5009,413 +5376,19 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
5009
5376
  ])
5010
5377
  ];
5011
5378
  };
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
5379
  var useActionHandler = (view) => {
5409
- return (action) => view && processAction(view, action);
5380
+ return (0, import_react7.useCallback)((action) => view && processEditorPayload(view, action.properties), [
5381
+ view
5382
+ ]);
5410
5383
  };
5411
5384
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5412
5385
  var instanceCount = 0;
5413
5386
  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)(() => {
5387
+ const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = (0, import_react8.useMemo)(() => (0, import_util5.getProviderValue)(props), deps ?? []);
5388
+ const [instanceId] = (0, import_react8.useState)(() => `text-editor-${++instanceCount}`);
5389
+ const [view, setView] = (0, import_react8.useState)();
5390
+ const parentRef = (0, import_react8.useRef)(null);
5391
+ (0, import_react8.useEffect)(() => {
5419
5392
  let view2;
5420
5393
  if (parentRef.current) {
5421
5394
  (0, import_log7.log)("create", {
@@ -5440,7 +5413,7 @@ var useTextEditor = (props = {}, deps = []) => {
5440
5413
  anchor
5441
5414
  };
5442
5415
  }
5443
- const state = import_state20.EditorState.create({
5416
+ const state = import_state21.EditorState.create({
5444
5417
  doc: initialValue,
5445
5418
  // selection: initialSelection,
5446
5419
  extensions: [
@@ -5489,7 +5462,7 @@ var useTextEditor = (props = {}, deps = []) => {
5489
5462
  view2?.destroy();
5490
5463
  };
5491
5464
  }, deps);
5492
- (0, import_react7.useEffect)(() => {
5465
+ (0, import_react8.useEffect)(() => {
5493
5466
  if (view) {
5494
5467
  if (scrollTo || selection) {
5495
5468
  if (selection && selection.anchor > view.state.doc.length) {
@@ -5516,7 +5489,7 @@ var useTextEditor = (props = {}, deps = []) => {
5516
5489
  scrollTo,
5517
5490
  selection
5518
5491
  ]);
5519
- (0, import_react7.useEffect)(() => {
5492
+ (0, import_react8.useEffect)(() => {
5520
5493
  if (view && autoFocus) {
5521
5494
  view.focus();
5522
5495
  }
@@ -5530,7 +5503,7 @@ var useTextEditor = (props = {}, deps = []) => {
5530
5503
  Escape: view?.state.facet(editorInputMode).noTabster
5531
5504
  }
5532
5505
  });
5533
- const handleKeyUp = (0, import_react7.useCallback)((event) => {
5506
+ const handleKeyUp = (0, import_react8.useCallback)((event) => {
5534
5507
  const { key, target, currentTarget } = event;
5535
5508
  if (target === currentTarget) {
5536
5509
  switch (key) {
@@ -5557,7 +5530,12 @@ var useTextEditor = (props = {}, deps = []) => {
5557
5530
  // Annotate the CommonJS export names for ESM import in node:
5558
5531
  0 && (module.exports = {
5559
5532
  Cursor,
5533
+ EditorInputMode,
5560
5534
  EditorInputModes,
5535
+ EditorState,
5536
+ EditorToolbar,
5537
+ EditorView,
5538
+ EditorViewMode,
5561
5539
  EditorViewModes,
5562
5540
  Inline,
5563
5541
  InputModeExtensions,
@@ -5565,7 +5543,6 @@ var useTextEditor = (props = {}, deps = []) => {
5565
5543
  RemoteSelectionsDecorator,
5566
5544
  SpaceAwarenessProvider,
5567
5545
  TextKind,
5568
- Toolbar,
5569
5546
  addBlockquote,
5570
5547
  addCodeblock,
5571
5548
  addLink,
@@ -5586,6 +5563,8 @@ var useTextEditor = (props = {}, deps = []) => {
5586
5563
  createBasicExtensions,
5587
5564
  createComment,
5588
5565
  createDataExtensions,
5566
+ createEditorAction,
5567
+ createEditorActionGroup,
5589
5568
  createEditorStateStore,
5590
5569
  createEditorStateTransaction,
5591
5570
  createElement,
@@ -5624,7 +5603,7 @@ var useTextEditor = (props = {}, deps = []) => {
5624
5603
  mention,
5625
5604
  overlap,
5626
5605
  preventNewline,
5627
- processAction,
5606
+ processEditorPayload,
5628
5607
  removeBlockquote,
5629
5608
  removeCodeblock,
5630
5609
  removeLink,
@@ -5640,6 +5619,8 @@ var useTextEditor = (props = {}, deps = []) => {
5640
5619
  setSelection,
5641
5620
  setStyle,
5642
5621
  singleValueFacet,
5622
+ stackItemContentEditorClassNames,
5623
+ stackItemContentToolbarClassNames,
5643
5624
  table,
5644
5625
  tags,
5645
5626
  textRange,
@@ -5657,9 +5638,9 @@ var useTextEditor = (props = {}, deps = []) => {
5657
5638
  useCommentClickListener,
5658
5639
  useCommentState,
5659
5640
  useComments,
5641
+ useEditorToolbarState,
5660
5642
  useFormattingState,
5661
5643
  useTextEditor,
5662
- useToolbarContext,
5663
5644
  wrapWithCatch
5664
5645
  });
5665
5646
  //# sourceMappingURL=index.cjs.map