@dxos/react-ui-editor 0.8.2-main.5ca3450 → 0.8.2-main.600d381

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 (51) hide show
  1. package/dist/lib/browser/index.mjs +1591 -1523
  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 +1383 -1316
  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 +1591 -1523
  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/components/EditorToolbar/EditorToolbar.d.ts +1 -1
  11. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  12. package/dist/types/src/{stories/InputMode.stories.d.ts → components/EditorToolbar/EditorToolbar.stories.d.ts} +3 -7
  13. package/dist/types/src/components/EditorToolbar/EditorToolbar.stories.d.ts.map +1 -0
  14. package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -3
  15. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  16. package/dist/types/src/components/EditorToolbar/comment.d.ts +4 -3
  17. package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -1
  18. package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -3
  19. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  20. package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -3
  21. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  22. package/dist/types/src/components/EditorToolbar/image.d.ts +16 -0
  23. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -0
  24. package/dist/types/src/components/EditorToolbar/lists.d.ts +4 -3
  25. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
  26. package/dist/types/src/components/EditorToolbar/search.d.ts +17 -0
  27. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -0
  28. package/dist/types/src/components/EditorToolbar/util.d.ts +11 -17
  29. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +4 -3
  31. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  32. package/dist/types/src/hooks/index.d.ts +0 -1
  33. package/dist/types/src/hooks/index.d.ts.map +1 -1
  34. package/package.json +28 -28
  35. package/src/components/EditorToolbar/EditorToolbar.stories.tsx +90 -0
  36. package/src/components/EditorToolbar/EditorToolbar.tsx +30 -31
  37. package/src/components/EditorToolbar/blocks.ts +27 -6
  38. package/src/components/EditorToolbar/comment.ts +11 -4
  39. package/src/components/EditorToolbar/formatting.ts +34 -7
  40. package/src/components/EditorToolbar/headings.ts +9 -8
  41. package/src/components/EditorToolbar/image.ts +16 -0
  42. package/src/components/EditorToolbar/lists.ts +26 -7
  43. package/src/components/EditorToolbar/search.ts +19 -0
  44. package/src/components/EditorToolbar/util.ts +14 -14
  45. package/src/components/EditorToolbar/view-mode.ts +9 -8
  46. package/src/hooks/index.ts +0 -1
  47. package/dist/types/src/hooks/useActionHandler.d.ts +0 -4
  48. package/dist/types/src/hooks/useActionHandler.d.ts.map +0 -1
  49. package/dist/types/src/stories/InputMode.stories.d.ts.map +0 -1
  50. package/src/hooks/useActionHandler.ts +0 -12
  51. package/src/stories/InputMode.stories.tsx +0 -124
@@ -63,7 +63,7 @@ __export(node_exports, {
63
63
  commentsState: () => commentsState,
64
64
  convertTreeToJson: () => convertTreeToJson,
65
65
  createBasicExtensions: () => createBasicExtensions,
66
- createComment: () => createComment2,
66
+ createComment: () => createComment,
67
67
  createDataExtensions: () => createDataExtensions,
68
68
  createEditorAction: () => createEditorAction,
69
69
  createEditorActionGroup: () => createEditorActionGroup,
@@ -141,7 +141,6 @@ __export(node_exports, {
141
141
  toggleStyle: () => toggleStyle,
142
142
  translations: () => translations_default,
143
143
  typewriter: () => typewriter,
144
- useActionHandler: () => useActionHandler,
145
144
  useCommentClickListener: () => useCommentClickListener,
146
145
  useCommentState: () => useCommentState,
147
146
  useComments: () => useComments,
@@ -162,25 +161,20 @@ var import_react_ui_theme = require("@dxos/react-ui-theme");
162
161
  var import_react2 = require("react");
163
162
  var import_live_object = require("@dxos/live-object");
164
163
  var import_react_ui_menu2 = require("@dxos/react-ui-menu");
165
- var import_view2 = require("@codemirror/view");
166
- var import_react_ui_theme2 = require("@dxos/react-ui-theme");
167
- var import_react_ui_theme3 = require("@dxos/react-ui-theme");
168
- var import_lodash = __toESM(require("lodash.get"));
169
- var import_react_ui_theme4 = require("@dxos/react-ui-theme");
170
164
  var import_state2 = require("@codemirror/state");
171
- var import_view3 = require("@codemirror/view");
165
+ var import_view2 = require("@codemirror/view");
172
166
  var import_util = require("@dxos/util");
173
167
  var import_state3 = require("@codemirror/state");
174
168
  var import_log = require("@dxos/log");
175
169
  var import_react3 = __toESM(require("react"));
176
170
  var import_client = require("react-dom/client");
177
171
  var import_react_ui2 = require("@dxos/react-ui");
178
- var import_react_ui_theme5 = require("@dxos/react-ui-theme");
172
+ var import_react_ui_theme2 = require("@dxos/react-ui-theme");
179
173
  var import_autocomplete = require("@codemirror/autocomplete");
180
174
  var import_lang_markdown = require("@codemirror/lang-markdown");
181
- var import_view4 = require("@codemirror/view");
175
+ var import_view3 = require("@codemirror/view");
182
176
  var import_state4 = require("@codemirror/state");
183
- var import_view5 = require("@codemirror/view");
177
+ var import_view4 = require("@codemirror/view");
184
178
  var import_automerge = require("@dxos/automerge/automerge");
185
179
  var import_log2 = require("@dxos/log");
186
180
  var import_echo = require("@dxos/react-client/echo");
@@ -189,62 +183,65 @@ var import_automerge2 = require("@dxos/automerge/automerge");
189
183
  var import_automerge3 = require("@dxos/automerge/automerge");
190
184
  var import_state6 = require("@codemirror/state");
191
185
  var import_state7 = require("@codemirror/state");
192
- var import_view6 = require("@codemirror/view");
186
+ var import_view5 = require("@codemirror/view");
193
187
  var import_async = require("@dxos/async");
194
188
  var import_context = require("@dxos/context");
195
189
  var import_async2 = require("@dxos/async");
196
190
  var import_context2 = require("@dxos/context");
197
191
  var import_invariant = require("@dxos/invariant");
198
192
  var import_log3 = require("@dxos/log");
199
- var import_view7 = require("@codemirror/view");
200
- var import_lodash2 = __toESM(require("lodash.defaultsdeep"));
193
+ var import_view6 = require("@codemirror/view");
194
+ var import_lodash = __toESM(require("lodash.defaultsdeep"));
201
195
  var import_invariant2 = require("@dxos/invariant");
202
196
  var import_state8 = require("@codemirror/state");
203
197
  var import_state9 = require("@codemirror/state");
198
+ var import_view7 = require("@codemirror/view");
204
199
  var import_view8 = require("@codemirror/view");
205
- var import_view9 = require("@codemirror/view");
206
200
  var import_state10 = require("@codemirror/state");
201
+ var import_view9 = require("@codemirror/view");
207
202
  var import_view10 = require("@codemirror/view");
208
- var import_view11 = require("@codemirror/view");
209
203
  var import_commands = require("@codemirror/commands");
210
204
  var import_state11 = require("@codemirror/state");
211
- var import_view12 = require("@codemirror/view");
212
- var import_lodash3 = __toESM(require("lodash.sortby"));
205
+ var import_view11 = require("@codemirror/view");
206
+ var import_lodash2 = __toESM(require("lodash.sortby"));
213
207
  var import_react4 = require("react");
214
208
  var import_async3 = require("@dxos/async");
215
209
  var import_log4 = require("@dxos/log");
216
210
  var import_util2 = require("@dxos/util");
217
211
  var import_state12 = require("@codemirror/state");
218
- var import_view13 = require("@codemirror/view");
212
+ var import_view12 = require("@codemirror/view");
219
213
  var import_async4 = require("@dxos/async");
220
214
  var import_invariant3 = require("@dxos/invariant");
221
215
  var import_util3 = require("@dxos/util");
222
216
  var import_language = require("@codemirror/language");
223
217
  var import_state13 = require("@codemirror/state");
224
- var import_view14 = require("@codemirror/view");
218
+ var import_view13 = require("@codemirror/view");
225
219
  var import_autocomplete2 = require("@codemirror/autocomplete");
226
220
  var import_commands2 = require("@codemirror/commands");
227
221
  var import_language2 = require("@codemirror/language");
228
222
  var import_search = require("@codemirror/search");
229
223
  var import_state14 = require("@codemirror/state");
230
224
  var import_theme_one_dark = require("@codemirror/theme-one-dark");
231
- var import_view15 = require("@codemirror/view");
232
- var import_lodash4 = __toESM(require("lodash.defaultsdeep"));
233
- var import_lodash5 = __toESM(require("lodash.merge"));
225
+ var import_view14 = require("@codemirror/view");
226
+ var import_lodash3 = __toESM(require("lodash.defaultsdeep"));
227
+ var import_lodash4 = __toESM(require("lodash.merge"));
234
228
  var import_display_name = require("@dxos/display-name");
235
229
  var import_log5 = require("@dxos/log");
236
230
  var import_util4 = require("@dxos/util");
237
231
  var import_state15 = require("@codemirror/state");
238
- var import_view16 = require("@codemirror/view");
232
+ var import_view15 = require("@codemirror/view");
233
+ var import_react_ui_theme3 = require("@dxos/react-ui-theme");
234
+ var import_lodash5 = __toESM(require("lodash.get"));
235
+ var import_react_ui_theme4 = require("@dxos/react-ui-theme");
239
236
  var import_language3 = require("@codemirror/language");
240
- var import_view17 = require("@codemirror/view");
237
+ var import_view16 = require("@codemirror/view");
241
238
  var import_react5 = __toESM(require("react"));
242
239
  var import_react_ui3 = require("@dxos/react-ui");
243
- var import_view18 = require("@codemirror/view");
240
+ var import_view17 = require("@codemirror/view");
244
241
  var import_autocomplete3 = require("@codemirror/autocomplete");
245
242
  var import_language4 = require("@codemirror/language");
246
243
  var import_state16 = require("@codemirror/state");
247
- var import_view19 = require("@codemirror/view");
244
+ var import_view18 = require("@codemirror/view");
248
245
  var import_react6 = require("react");
249
246
  var import_autocomplete4 = require("@codemirror/autocomplete");
250
247
  var import_commands3 = require("@codemirror/commands");
@@ -252,7 +249,7 @@ var import_lang_markdown2 = require("@codemirror/lang-markdown");
252
249
  var import_language5 = require("@codemirror/language");
253
250
  var import_language_data = require("@codemirror/language-data");
254
251
  var import_lint = require("@codemirror/lint");
255
- var import_view20 = require("@codemirror/view");
252
+ var import_view19 = require("@codemirror/view");
256
253
  var import_lang_markdown3 = require("@codemirror/lang-markdown");
257
254
  var import_language6 = require("@codemirror/language");
258
255
  var import_highlight2 = require("@lezer/highlight");
@@ -261,38 +258,40 @@ var import_language7 = require("@codemirror/language");
261
258
  var import_state17 = require("@codemirror/state");
262
259
  var import_language8 = require("@codemirror/language");
263
260
  var import_state18 = require("@codemirror/state");
264
- var import_view21 = require("@codemirror/view");
261
+ var import_view20 = require("@codemirror/view");
265
262
  var import_invariant4 = require("@dxos/invariant");
266
- var import_react_ui_theme6 = require("@dxos/react-ui-theme");
263
+ var import_react_ui_theme5 = require("@dxos/react-ui-theme");
267
264
  var import_language9 = require("@codemirror/language");
268
265
  var import_state19 = require("@codemirror/state");
269
- var import_view22 = require("@codemirror/view");
266
+ var import_view21 = require("@codemirror/view");
270
267
  var import_language10 = require("@codemirror/language");
271
268
  var import_state20 = require("@codemirror/state");
269
+ var import_view22 = require("@codemirror/view");
272
270
  var import_view23 = require("@codemirror/view");
273
- var import_view24 = require("@codemirror/view");
274
271
  var import_language11 = require("@codemirror/language");
275
272
  var import_state21 = require("@codemirror/state");
276
- var import_view25 = require("@codemirror/view");
273
+ var import_view24 = require("@codemirror/view");
277
274
  var import_language12 = require("@codemirror/language");
278
- var import_view26 = require("@codemirror/view");
279
- var import_react_ui_theme7 = require("@dxos/react-ui-theme");
275
+ var import_view25 = require("@codemirror/view");
276
+ var import_react_ui_theme6 = require("@dxos/react-ui-theme");
280
277
  var import_autocomplete5 = require("@codemirror/autocomplete");
281
278
  var import_log6 = require("@dxos/log");
282
- var import_view27 = require("@codemirror/view");
279
+ var import_view26 = require("@codemirror/view");
283
280
  var import_codemirror_vim = require("@replit/codemirror-vim");
284
281
  var import_codemirror_vscode_keymap = require("@replit/codemirror-vscode-keymap");
285
282
  var import_effect = require("effect");
286
283
  var import_dx_ref_tag = require("@dxos/lit-ui/dx-ref-tag.pcss");
287
284
  var import_language13 = require("@codemirror/language");
288
285
  var import_state22 = require("@codemirror/state");
286
+ var import_view27 = require("@codemirror/view");
289
287
  var import_view28 = require("@codemirror/view");
288
+ var import_search2 = require("@codemirror/search");
290
289
  var import_view29 = require("@codemirror/view");
291
- var import_react7 = require("react");
290
+ var import_react_ui_theme7 = require("@dxos/react-ui-theme");
292
291
  var import_state23 = require("@codemirror/state");
293
292
  var import_view30 = require("@codemirror/view");
294
293
  var import_react_tabster = require("@fluentui/react-tabster");
295
- var import_react8 = require("react");
294
+ var import_react7 = require("react");
296
295
  var import_log7 = require("@dxos/log");
297
296
  var import_util5 = require("@dxos/util");
298
297
  var translationKey = "react-ui-editor";
@@ -331,674 +330,121 @@ var translations_default = [
331
330
  var useEditorToolbarState = (initialState = {}) => {
332
331
  return (0, import_react2.useMemo)(() => (0, import_live_object.live)(initialState), []);
333
332
  };
334
- var createEditorAction = (payload, icon, label = [
335
- `${payload.type} label`,
336
- {
337
- ns: translationKey
338
- }
339
- ], id = payload.type) => (0, import_react_ui_menu2.createMenuAction)(id, {
340
- icon,
341
- label,
342
- ...payload
343
- });
333
+ var createEditorAction = (id, invoke, properties) => {
334
+ const { label = [
335
+ `${id} label`,
336
+ {
337
+ ns: translationKey
338
+ }
339
+ ], ...rest } = properties;
340
+ return (0, import_react_ui_menu2.createMenuAction)(id, invoke, {
341
+ label,
342
+ ...rest
343
+ });
344
+ };
344
345
  var createEditorActionGroup = (id, props, icon) => (0, import_react_ui_menu2.createMenuItemGroup)(id, {
345
346
  icon,
346
347
  iconOnly: true,
347
348
  ...props
348
349
  });
349
- var editorToolbarSearch = createEditorAction({
350
- type: "search"
351
- }, "ph--magnifying-glass--regular");
352
- var createBlockGroupAction = (value) => createEditorActionGroup("block", {
353
- variant: "toggleGroup",
354
- selectCardinality: "single",
355
- value
350
+ var singleValueFacet = (defaultValue) => import_state3.Facet.define({
351
+ // Called immediately.
352
+ combine: (providers) => {
353
+ return providers[0] ?? defaultValue;
354
+ }
356
355
  });
357
- var createBlockActions = (value, blankLine) => Object.entries({
358
- blockquote: "ph--quotes--regular",
359
- codeblock: "ph--code-block--regular",
360
- table: "ph--table--regular"
361
- }).map(([type, icon]) => {
362
- return createEditorAction({
363
- type,
364
- checked: type === value,
365
- ...type === "table" && {
366
- disabled: !!blankLine
356
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
357
+ var defaultCursorConverter = {
358
+ toCursor: (position) => position.toString(),
359
+ fromCursor: (cursor) => parseInt(cursor)
360
+ };
361
+ var Cursor = class _Cursor {
362
+ static {
363
+ this.converter = singleValueFacet(defaultCursorConverter);
364
+ }
365
+ static {
366
+ this.getCursorFromRange = (state, range) => {
367
+ const cursorConverter2 = state.facet(_Cursor.converter);
368
+ const from = cursorConverter2.toCursor(range.from);
369
+ const to = cursorConverter2.toCursor(range.to, -1);
370
+ return [
371
+ from,
372
+ to
373
+ ].join(":");
374
+ };
375
+ }
376
+ static {
377
+ this.getRangeFromCursor = (state, cursor) => {
378
+ const cursorConverter2 = state.facet(_Cursor.converter);
379
+ const parts = cursor.split(":");
380
+ const from = cursorConverter2.fromCursor(parts[0]);
381
+ const to = cursorConverter2.fromCursor(parts[1]);
382
+ return from !== void 0 && to !== void 0 ? {
383
+ from,
384
+ to
385
+ } : void 0;
386
+ };
387
+ }
388
+ };
389
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
390
+ var wrapWithCatch = (fn) => {
391
+ return (...args) => {
392
+ try {
393
+ return fn(...args);
394
+ } catch (err) {
395
+ import_log.log.catch(err, void 0, {
396
+ F: __dxlog_file,
397
+ L: 15,
398
+ S: void 0,
399
+ C: (f, a) => f(...a)
400
+ });
367
401
  }
368
- }, icon);
369
- });
370
- var createBlocks = (state) => {
371
- const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
372
- const blockGroupAction = createBlockGroupAction(value);
373
- const blockActions = createBlockActions(value, state.blankLine);
374
- return {
375
- nodes: [
376
- blockGroupAction,
377
- ...blockActions
378
- ],
379
- edges: [
380
- {
381
- source: "root",
382
- target: "block"
383
- },
384
- ...blockActions.map(({ id }) => ({
385
- source: blockGroupAction.id,
386
- target: id
387
- }))
388
- ]
389
402
  };
390
403
  };
391
- var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
392
- var createCommentAction = (label) => createEditorAction({
393
- type: "comment",
394
- testId: "editor.toolbar.comment"
395
- }, "ph--chat-text--regular", label);
396
- var createComment = (state) => ({
397
- nodes: [
398
- createCommentAction([
399
- commentLabel(state.comment, state.selection),
400
- {
401
- ns: translationKey
402
- }
403
- ])
404
- ],
405
- edges: [
406
- {
407
- source: "root",
408
- target: "comment"
409
- }
410
- ]
411
- });
412
- var formats = {
413
- strong: "ph--text-b--regular",
414
- emphasis: "ph--text-italic--regular",
415
- strikethrough: "ph--text-strikethrough--regular",
416
- code: "ph--code--regular",
417
- link: "ph--link--regular"
404
+ var callbackWrapper = (fn) => (...args) => {
405
+ try {
406
+ return fn(...args);
407
+ } catch (err) {
408
+ import_log.log.catch(err, void 0, {
409
+ F: __dxlog_file,
410
+ L: 29,
411
+ S: void 0,
412
+ C: (f, a) => f(...a)
413
+ });
414
+ }
418
415
  };
419
- var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
420
- variant: "toggleGroup",
421
- selectCardinality: "multiple",
422
- value: Object.keys(formats).filter((key) => !!formatting[key])
423
- });
424
- var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
425
- type,
426
- checked: !!formatting[type]
427
- }, icon));
428
- var createFormatting = (state) => {
429
- const formattingGroupAction = createFormattingGroup(state);
430
- const formattingActions = createFormattingActions(state);
431
- return {
432
- nodes: [
433
- formattingGroupAction,
434
- ...formattingActions
435
- ],
436
- edges: [
437
- {
438
- source: "root",
439
- target: "formatting"
440
- },
441
- ...formattingActions.map(({ id }) => ({
442
- source: formattingGroupAction.id,
443
- target: id
444
- }))
445
- ]
446
- };
416
+ var debugDispatcher = (trs, view) => {
417
+ logChanges(trs);
418
+ view.update(trs);
447
419
  };
448
- var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
449
- variant: "dropdownMenu",
450
- applyActive: true,
451
- selectCardinality: "single",
452
- value
453
- }, "ph--text-h--regular");
454
- var createHeadingActions = (value) => Object.entries({
455
- "0": "ph--paragraph--regular",
456
- "1": "ph--text-h-one--regular",
457
- "2": "ph--text-h-two--regular",
458
- "3": "ph--text-h-three--regular",
459
- "4": "ph--text-h-four--regular",
460
- "5": "ph--text-h-five--regular",
461
- "6": "ph--text-h-six--regular"
462
- }).map(([levelStr, icon]) => {
463
- const level = parseInt(levelStr);
464
- return createEditorAction({
465
- type: "heading",
466
- data: level,
467
- checked: value === levelStr
468
- }, icon, [
469
- "heading level label",
470
- {
471
- count: level,
472
- ns: translationKey
420
+ var logChanges = (trs) => {
421
+ const changes = trs.flatMap((tr) => {
422
+ if (tr.changes.empty) {
423
+ return void 0;
473
424
  }
474
- ], `heading--${levelStr}`);
475
- });
476
- var computeHeadingValue = (state) => {
477
- const blockType = state ? state.blockType : "paragraph";
478
- const header = blockType && /heading(\d)/.exec(blockType);
479
- return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
425
+ const changes2 = [];
426
+ tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
427
+ fromA,
428
+ toA,
429
+ fromB,
430
+ toB,
431
+ inserted: inserted.toString()
432
+ })));
433
+ return changes2;
434
+ }).filter(Boolean);
435
+ if (changes.length) {
436
+ (0, import_log.log)("changes", {
437
+ changes
438
+ }, {
439
+ F: __dxlog_file,
440
+ L: 62,
441
+ S: void 0,
442
+ C: (f, a) => f(...a)
443
+ });
444
+ }
480
445
  };
481
- var createHeadings = (state) => {
482
- const headingValue = computeHeadingValue(state);
483
- const headingGroupAction = createHeadingGroupAction(headingValue);
484
- const headingActions = createHeadingActions(headingValue);
485
- return {
486
- nodes: [
487
- headingGroupAction,
488
- ...headingActions
489
- ],
490
- edges: [
491
- {
492
- source: "root",
493
- target: "heading"
494
- },
495
- ...headingActions.map(({ id }) => ({
496
- source: headingGroupAction.id,
497
- target: id
498
- }))
499
- ]
500
- };
501
- };
502
- var listStyles = {
503
- bullet: "ph--list-bullets--regular",
504
- ordered: "ph--list-numbers--regular",
505
- task: "ph--list-checks--regular"
506
- };
507
- var createListGroupAction = (value) => createEditorActionGroup("list", {
508
- variant: "toggleGroup",
509
- selectCardinality: "single",
510
- value
511
- });
512
- var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
513
- type: `list-${listStyle}`,
514
- checked: value === listStyle
515
- }, icon));
516
- var createLists = (state) => {
517
- const value = state.listStyle ?? "";
518
- const listGroupAction = createListGroupAction(value);
519
- const listActionsMap = createListActions(value);
520
- return {
521
- nodes: [
522
- listGroupAction,
523
- ...listActionsMap
524
- ],
525
- edges: [
526
- {
527
- source: "root",
528
- target: "list"
529
- },
530
- ...listActionsMap.map(({ id }) => ({
531
- source: listGroupAction.id,
532
- target: id
533
- }))
534
- ]
535
- };
536
- };
537
- var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
538
- variant: "dropdownMenu",
539
- applyActive: true,
540
- selectCardinality: "single",
541
- value
542
- }, "ph--eye--regular");
543
- var createViewModeActions = (value) => Object.entries({
544
- preview: "ph--eye--regular",
545
- source: "ph--pencil-simple--regular",
546
- readonly: "ph--pencil-slash--regular"
547
- }).map(([viewMode, icon]) => {
548
- return createEditorAction({
549
- type: "view-mode",
550
- data: viewMode,
551
- checked: viewMode === value
552
- }, icon, [
553
- `${viewMode} mode label`,
554
- {
555
- ns: translationKey
556
- }
557
- ], `view-mode--${viewMode}`);
558
- });
559
- var createViewMode = (state) => {
560
- const value = state.viewMode ?? "source";
561
- const viewModeGroupAction = createViewModeGroupAction(value);
562
- const viewModeActions = createViewModeActions(value);
563
- return {
564
- nodes: [
565
- viewModeGroupAction,
566
- ...viewModeActions
567
- ],
568
- edges: [
569
- {
570
- source: "root",
571
- target: "viewMode"
572
- },
573
- ...viewModeActions.map(({ id }) => ({
574
- source: viewModeGroupAction.id,
575
- target: id
576
- }))
577
- ]
578
- };
579
- };
580
- var headings = {
581
- 1: "text-4xl",
582
- 2: "text-3xl",
583
- 3: "text-2xl",
584
- 4: "text-xl",
585
- 5: "text-lg",
586
- 6: ""
587
- };
588
- var theme = {
589
- code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
590
- codeMark: "font-mono text-primary-500",
591
- mark: "opacity-50",
592
- heading: (level) => {
593
- return (0, import_react_ui_theme3.mx)(headings[level], "dark:text-primary-400");
594
- }
595
- };
596
- var getToken = (path, defaultValue) => {
597
- const value = (0, import_lodash.default)(import_react_ui_theme4.tokens, path, defaultValue);
598
- return value?.toString() ?? "";
599
- };
600
- var fontBody = getToken("fontFamily.body");
601
- var fontMono = getToken("fontFamily.mono");
602
- var defaultTheme = {
603
- "&": {},
604
- "&.cm-focused": {
605
- outline: "none"
606
- },
607
- /**
608
- * Scroller
609
- */
610
- ".cm-scroller": {
611
- overflowY: "auto"
612
- },
613
- /**
614
- * Content
615
- * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
616
- */
617
- ".cm-content": {
618
- padding: "unset",
619
- fontFamily: fontBody,
620
- // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
621
- fontSize: "16px",
622
- lineHeight: 1.5,
623
- color: "unset"
624
- },
625
- /**
626
- * Gutters
627
- * NOTE: Gutters should have the same top margin as the content.
628
- */
629
- ".cm-gutters": {
630
- borderRight: "none",
631
- background: "transparent"
632
- },
633
- ".cm-gutter": {},
634
- ".cm-gutter.cm-lineNumbers": {
635
- paddingRight: "4px",
636
- borderRight: "1px solid var(--dx-separator)"
637
- },
638
- ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
639
- minWidth: "40px",
640
- alignContent: "center"
641
- },
642
- /**
643
- * Height is set to match the corresponding line.
644
- */
645
- ".cm-gutterElement": {
646
- alignItems: "center",
647
- fontSize: "12px"
648
- },
649
- /**
650
- * Line.
651
- */
652
- ".cm-line": {
653
- paddingInline: 0
654
- },
655
- ".cm-activeLine": {
656
- background: "var(--dx-cmActiveLine)"
657
- },
658
- /**
659
- * Cursor (layer).
660
- */
661
- ".cm-cursor, .cm-dropCursor": {
662
- borderLeft: "2px solid var(--dx-cmCursor)"
663
- },
664
- ".cm-placeholder": {
665
- color: "var(--dx-subdued)"
666
- },
667
- /**
668
- * Selection (layer).
669
- */
670
- ".cm-selectionBackground": {
671
- background: "var(--dx-cmSelection)"
672
- },
673
- /**
674
- * Search.
675
- * NOTE: Matches comment.
676
- */
677
- ".cm-searchMatch": {
678
- margin: "0 -3px",
679
- padding: "3px",
680
- borderRadius: "3px",
681
- background: "var(--dx-cmHighlightSurface)",
682
- color: "var(--dx-cmHighlight)"
683
- },
684
- ".cm-searchMatch-selected": {
685
- textDecoration: "underline"
686
- },
687
- /**
688
- * Link.
689
- */
690
- ".cm-link": {
691
- textDecorationLine: "underline",
692
- textDecorationThickness: "1px",
693
- textDecorationColor: "var(--dx-separator)",
694
- textUnderlineOffset: "2px",
695
- borderRadius: ".125rem"
696
- },
697
- ".cm-link > span": {
698
- color: "var(--dx-accentText)"
699
- },
700
- /**
701
- * Tooltip.
702
- */
703
- ".cm-tooltip": {
704
- background: "var(--dx-baseSurface)"
705
- },
706
- ".cm-tooltip-below": {},
707
- /**
708
- * Autocomplete.
709
- * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
710
- */
711
- ".cm-tooltip.cm-tooltip-autocomplete": {
712
- marginTop: "4px",
713
- marginLeft: "-3px"
714
- },
715
- ".cm-tooltip.cm-tooltip-autocomplete > ul": {
716
- maxHeight: "20em"
717
- },
718
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
719
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
720
- ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
721
- paddingLeft: "4px !important",
722
- borderBottom: "none !important",
723
- color: "var(--dx-accentText)"
724
- },
725
- ".cm-tooltip.cm-completionInfo": {
726
- width: "360px !important",
727
- margin: "-10px 1px 0 1px",
728
- padding: "8px !important",
729
- borderColor: "var(--dx-separator)"
730
- },
731
- ".cm-completionIcon": {
732
- display: "none"
733
- },
734
- ".cm-completionLabel": {
735
- fontFamily: fontBody
736
- },
737
- ".cm-completionMatchedText": {
738
- textDecoration: "none !important",
739
- opacity: 0.5
740
- },
741
- /**
742
- * Panels
743
- * https://github.com/codemirror/search/blob/main/src/search.ts#L745
744
- *
745
- * Find/replace panel.
746
- * <div class="cm-announced">...</div>
747
- * <div class="cm-scroller">...</div>
748
- * <div class="cm-panels cm-panels-bottom">
749
- * <div class="cm-search cm-panel">
750
- * <input class="cm-textfield" />
751
- * <button class="cm-button">...</button>
752
- * <label><input type="checkbox" />...</label>
753
- * </div>
754
- * </div
755
- */
756
- // TODO(burdon): Implement custom panel (with icon buttons).
757
- ".cm-panels": {},
758
- ".cm-panel": {
759
- fontFamily: fontBody,
760
- backgroundColor: "var(--surface-bg)"
761
- },
762
- ".cm-panel input, .cm-panel button, .cm-panel label": {
763
- color: "var(--dx-subdued)",
764
- fontFamily: fontBody,
765
- fontSize: "14px",
766
- all: "unset",
767
- margin: "3px !important",
768
- padding: "2px 6px !important",
769
- outline: "1px solid transparent"
770
- },
771
- ".cm-panel input, .cm-panel button": {
772
- backgroundColor: "var(--dx-input)"
773
- },
774
- ".cm-panel input:focus, .cm-panel button:focus": {
775
- outline: "1px solid var(--dx-accentFocusIndicator)"
776
- },
777
- ".cm-panel label": {
778
- display: "inline-flex",
779
- alignItems: "center",
780
- cursor: "pointer"
781
- },
782
- ".cm-panel input.cm-textfield": {},
783
- ".cm-panel input[type=checkbox]": {
784
- width: "8px",
785
- height: "8px",
786
- marginRight: "6px !important",
787
- padding: "2px !important",
788
- color: "var(--dx-accentFocusIndicator)"
789
- },
790
- ".cm-panel button": {
791
- "&:hover": {
792
- backgroundColor: "var(--dx-accentSurfaceHover) !important"
793
- },
794
- "&:active": {
795
- backgroundColor: "var(--dx-accentSurfaceHover)"
796
- }
797
- },
798
- ".cm-panel.cm-search": {
799
- padding: "4px",
800
- borderTop: "1px solid var(--dx-separator)"
801
- }
802
- };
803
- var margin = "!mt-[1rem]";
804
- var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
805
- var editorContent = (0, import_react_ui_theme2.mx)(margin, editorWidth);
806
- var editorFullWidth = (0, import_react_ui_theme2.mx)(margin);
807
- var editorGutter = import_view2.EditorView.theme({
808
- // Match margin from content.
809
- // Gutter = 2rem + 1rem margin.
810
- ".cm-gutters": {
811
- marginTop: "1rem",
812
- paddingRight: "1rem"
813
- }
814
- });
815
- var editorMonospace = import_view2.EditorView.theme({
816
- ".cm-content": {
817
- fontFamily: fontMono
818
- }
819
- });
820
- var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
821
- var stackItemContentEditorClassNames = (role) => (0, import_react_ui_theme2.mx)("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
822
- var stackItemContentToolbarClassNames = (role) => (0, import_react_ui_theme2.mx)("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
823
- var createToolbar = ({ state, customActions, ...features }) => {
824
- const nodes = [];
825
- const edges = [];
826
- if (features.headings ?? true) {
827
- const headings2 = createHeadings(state);
828
- nodes.push(...headings2.nodes);
829
- edges.push(...headings2.edges);
830
- }
831
- if (features.formatting ?? true) {
832
- const formatting = createFormatting(state);
833
- nodes.push(...formatting.nodes);
834
- edges.push(...formatting.edges);
835
- }
836
- if (features.lists ?? true) {
837
- const lists = createLists(state);
838
- nodes.push(...lists.nodes);
839
- edges.push(...lists.edges);
840
- }
841
- if (features.blocks ?? true) {
842
- const blocks = createBlocks(state);
843
- nodes.push(...blocks.nodes);
844
- edges.push(...blocks.edges);
845
- }
846
- if (customActions) {
847
- const custom = customActions();
848
- nodes.push(...custom.nodes);
849
- edges.push(...custom.edges);
850
- }
851
- const editorToolbarGap = (0, import_react_ui_menu.createGapSeparator)();
852
- nodes.push(...editorToolbarGap.nodes);
853
- edges.push(...editorToolbarGap.edges);
854
- if (features.comment ?? true) {
855
- const comment = createComment(state);
856
- nodes.push(...comment.nodes);
857
- edges.push(...comment.edges);
858
- }
859
- if (features.search ?? true) {
860
- nodes.push(editorToolbarSearch);
861
- edges.push({
862
- source: "root",
863
- target: editorToolbarSearch.id
864
- });
865
- }
866
- if (features.viewMode ?? true) {
867
- const viewMode = createViewMode(state);
868
- nodes.push(...viewMode.nodes);
869
- edges.push(...viewMode.edges);
870
- }
871
- return {
872
- nodes,
873
- edges
874
- };
875
- };
876
- var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
877
- const menuCreator = (0, import_react.useCallback)(() => createToolbar(props), [
878
- props
879
- ]);
880
- const { resolveGroupItems } = (0, import_react_ui_menu.useMenuActions)(menuCreator);
881
- return {
882
- resolveGroupItems,
883
- onAction
884
- };
885
- };
886
- var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
887
- const menuProps = useEditorToolbarActionGraph(props);
888
- return /* @__PURE__ */ import_react.default.createElement("div", {
889
- role: "none",
890
- className: stackItemContentToolbarClassNames(role)
891
- }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.ElevationProvider, {
892
- elevation: role === "section" ? "positioned" : "base"
893
- }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.MenuProvider, {
894
- ...menuProps,
895
- attendableId
896
- }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.ToolbarMenu, {
897
- classNames: [
898
- import_react_ui_theme.textBlockWidth,
899
- "!bg-transparent",
900
- classNames
901
- ]
902
- }))));
903
- };
904
- var singleValueFacet = (defaultValue) => import_state3.Facet.define({
905
- // Called immediately.
906
- combine: (providers) => {
907
- return providers[0] ?? defaultValue;
908
- }
909
- });
910
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
911
- var defaultCursorConverter = {
912
- toCursor: (position) => position.toString(),
913
- fromCursor: (cursor) => parseInt(cursor)
914
- };
915
- var Cursor = class _Cursor {
916
- static {
917
- this.converter = singleValueFacet(defaultCursorConverter);
918
- }
919
- static {
920
- this.getCursorFromRange = (state, range) => {
921
- const cursorConverter2 = state.facet(_Cursor.converter);
922
- const from = cursorConverter2.toCursor(range.from);
923
- const to = cursorConverter2.toCursor(range.to, -1);
924
- return [
925
- from,
926
- to
927
- ].join(":");
928
- };
929
- }
930
- static {
931
- this.getRangeFromCursor = (state, cursor) => {
932
- const cursorConverter2 = state.facet(_Cursor.converter);
933
- const parts = cursor.split(":");
934
- const from = cursorConverter2.fromCursor(parts[0]);
935
- const to = cursorConverter2.fromCursor(parts[1]);
936
- return from !== void 0 && to !== void 0 ? {
937
- from,
938
- to
939
- } : void 0;
940
- };
941
- }
942
- };
943
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
944
- var wrapWithCatch = (fn) => {
945
- return (...args) => {
946
- try {
947
- return fn(...args);
948
- } catch (err) {
949
- import_log.log.catch(err, void 0, {
950
- F: __dxlog_file,
951
- L: 15,
952
- S: void 0,
953
- C: (f, a) => f(...a)
954
- });
955
- }
956
- };
957
- };
958
- var callbackWrapper = (fn) => (...args) => {
959
- try {
960
- return fn(...args);
961
- } catch (err) {
962
- import_log.log.catch(err, void 0, {
963
- F: __dxlog_file,
964
- L: 29,
965
- S: void 0,
966
- C: (f, a) => f(...a)
967
- });
968
- }
969
- };
970
- var debugDispatcher = (trs, view) => {
971
- logChanges(trs);
972
- view.update(trs);
973
- };
974
- var logChanges = (trs) => {
975
- const changes = trs.flatMap((tr) => {
976
- if (tr.changes.empty) {
977
- return void 0;
978
- }
979
- const changes2 = [];
980
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
981
- fromA,
982
- toA,
983
- fromB,
984
- toB,
985
- inserted: inserted.toString()
986
- })));
987
- return changes2;
988
- }).filter(Boolean);
989
- if (changes.length) {
990
- (0, import_log.log)("changes", {
991
- changes
992
- }, {
993
- F: __dxlog_file,
994
- L: 62,
995
- S: void 0,
996
- C: (f, a) => f(...a)
997
- });
998
- }
999
- };
1000
- var flattenRect = (rect, left) => {
1001
- const x = left ? rect.left : rect.right;
446
+ var flattenRect = (rect, left) => {
447
+ const x = left ? rect.left : rect.right;
1002
448
  return {
1003
449
  left: x,
1004
450
  right: x,
@@ -1036,16 +482,16 @@ var createElement = (tag, options, children) => {
1036
482
  };
1037
483
  var renderRoot = (root, node) => {
1038
484
  (0, import_client.createRoot)(root).render(/* @__PURE__ */ import_react3.default.createElement(import_react_ui2.ThemeProvider, {
1039
- tx: import_react_ui_theme5.defaultTx
485
+ tx: import_react_ui_theme2.defaultTx
1040
486
  }, node));
1041
487
  return root;
1042
488
  };
1043
489
  var createRenderer = (Component) => (el, props) => {
1044
490
  renderRoot(el, /* @__PURE__ */ import_react3.default.createElement(import_react_ui2.ThemeProvider, {
1045
- tx: import_react_ui_theme5.defaultTx
491
+ tx: import_react_ui_theme2.defaultTx
1046
492
  }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui2.Tooltip.Provider, null, /* @__PURE__ */ import_react3.default.createElement(Component, props))));
1047
493
  };
1048
- var annotationMark = import_view3.Decoration.mark({
494
+ var annotationMark = import_view2.Decoration.mark({
1049
495
  class: "cm-annotation"
1050
496
  });
1051
497
  var annotations = (options = {}) => {
@@ -1081,7 +527,7 @@ var annotations = (options = {}) => {
1081
527
  });
1082
528
  return [
1083
529
  annotationsState,
1084
- import_view3.EditorView.decorations.compute([
530
+ import_view2.EditorView.decorations.compute([
1085
531
  annotationsState
1086
532
  ], (state) => {
1087
533
  const annotations2 = state.field(annotationsState);
@@ -1089,12 +535,12 @@ var annotations = (options = {}) => {
1089
535
  const range = Cursor.getRangeFromCursor(state, annotation.cursor);
1090
536
  return range && annotationMark.range(range.from, range.to);
1091
537
  }).filter(import_util.isNotFalsy);
1092
- return import_view3.Decoration.set(decorations);
538
+ return import_view2.Decoration.set(decorations);
1093
539
  }),
1094
540
  styles
1095
541
  ];
1096
542
  };
1097
- var styles = import_view3.EditorView.theme({
543
+ var styles = import_view2.EditorView.theme({
1098
544
  ".cm-annotation": {
1099
545
  textDecoration: "underline",
1100
546
  textDecorationStyle: "wavy",
@@ -1106,7 +552,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
1106
552
  // https://codemirror.net/docs/ref/#view.keymap
1107
553
  // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
1108
554
  // TODO(burdon): Set custom keymap.
1109
- import_view4.keymap.of(import_autocomplete.completionKeymap),
555
+ import_view3.keymap.of(import_autocomplete.completionKeymap),
1110
556
  // https://codemirror.net/examples/autocompletion
1111
557
  // https://codemirror.net/docs/ref/#autocomplete.autocompletion
1112
558
  (0, import_autocomplete.autocompletion)({
@@ -1384,7 +830,7 @@ var automerge = (accessor) => {
1384
830
  // Track heads.
1385
831
  syncState,
1386
832
  // Reconcile external updates.
1387
- import_view5.ViewPlugin.fromClass(class {
833
+ import_view4.ViewPlugin.fromClass(class {
1388
834
  constructor(_view) {
1389
835
  this._view = _view;
1390
836
  this._handleChange = () => {
@@ -1397,7 +843,7 @@ var automerge = (accessor) => {
1397
843
  }
1398
844
  }),
1399
845
  // Reconcile local updates.
1400
- import_view5.EditorView.updateListener.of(({ view, changes }) => {
846
+ import_view4.EditorView.updateListener.of(({ view, changes }) => {
1401
847
  if (!changes.empty) {
1402
848
  syncer.reconcile(view, true);
1403
849
  }
@@ -1420,7 +866,7 @@ var RemoteSelectionChangedAnnotation = import_state7.Annotation.define();
1420
866
  var awareness = (provider = dummyProvider) => {
1421
867
  return [
1422
868
  awarenessProvider.of(provider),
1423
- import_view6.ViewPlugin.fromClass(RemoteSelectionsDecorator, {
869
+ import_view5.ViewPlugin.fromClass(RemoteSelectionsDecorator, {
1424
870
  decorations: (value) => value.decorations
1425
871
  }),
1426
872
  styles2
@@ -1484,7 +930,7 @@ var RemoteSelectionsDecorator = class {
1484
930
  decorations.push({
1485
931
  from: start,
1486
932
  to: end,
1487
- value: import_view6.Decoration.mark({
933
+ value: import_view5.Decoration.mark({
1488
934
  attributes: {
1489
935
  style: `background-color: ${lightColor}`
1490
936
  },
@@ -1495,7 +941,7 @@ var RemoteSelectionsDecorator = class {
1495
941
  decorations.push({
1496
942
  from: start,
1497
943
  to: startLine.from + startLine.length,
1498
- value: import_view6.Decoration.mark({
944
+ value: import_view5.Decoration.mark({
1499
945
  attributes: {
1500
946
  style: `background-color: ${lightColor}`
1501
947
  },
@@ -1505,7 +951,7 @@ var RemoteSelectionsDecorator = class {
1505
951
  decorations.push({
1506
952
  from: endLine.from,
1507
953
  to: end,
1508
- value: import_view6.Decoration.mark({
954
+ value: import_view5.Decoration.mark({
1509
955
  attributes: {
1510
956
  style: `background-color: ${lightColor}`
1511
957
  },
@@ -1517,7 +963,7 @@ var RemoteSelectionsDecorator = class {
1517
963
  decorations.push({
1518
964
  from: linePos,
1519
965
  to: linePos,
1520
- value: import_view6.Decoration.line({
966
+ value: import_view5.Decoration.line({
1521
967
  attributes: {
1522
968
  style: `background-color: ${lightColor}`,
1523
969
  class: "cm-collab-selectionLine"
@@ -1529,17 +975,17 @@ var RemoteSelectionsDecorator = class {
1529
975
  decorations.push({
1530
976
  from: head,
1531
977
  to: head,
1532
- value: import_view6.Decoration.widget({
978
+ value: import_view5.Decoration.widget({
1533
979
  side: head - anchor > 0 ? -1 : 1,
1534
980
  block: false,
1535
981
  widget: new RemoteCaretWidget(state.info.displayName ?? "Anonymous", darkColor)
1536
982
  })
1537
983
  });
1538
984
  }
1539
- this.decorations = import_view6.Decoration.set(decorations, true);
985
+ this.decorations = import_view5.Decoration.set(decorations, true);
1540
986
  }
1541
987
  };
1542
- var RemoteCaretWidget = class extends import_view6.WidgetType {
988
+ var RemoteCaretWidget = class extends import_view5.WidgetType {
1543
989
  constructor(_name, _color) {
1544
990
  super();
1545
991
  this._name = _name;
@@ -1575,7 +1021,7 @@ var RemoteCaretWidget = class extends import_view6.WidgetType {
1575
1021
  return true;
1576
1022
  }
1577
1023
  };
1578
- var styles2 = import_view6.EditorView.theme({
1024
+ var styles2 = import_view5.EditorView.theme({
1579
1025
  ".cm-collab-selection": {},
1580
1026
  ".cm-collab-selectionLine": {
1581
1027
  padding: 0,
@@ -1778,12 +1224,12 @@ var blast = (options = defaultOptions) => {
1778
1224
  };
1779
1225
  return [
1780
1226
  // Cursor moved.
1781
- import_view7.EditorView.updateListener.of((update2) => {
1227
+ import_view6.EditorView.updateListener.of((update2) => {
1782
1228
  if (blaster?.node !== update2.view.scrollDOM) {
1783
1229
  if (blaster) {
1784
1230
  blaster.destroy();
1785
1231
  }
1786
- blaster = new Blaster(update2.view.scrollDOM, (0, import_lodash2.default)({
1232
+ blaster = new Blaster(update2.view.scrollDOM, (0, import_lodash.default)({
1787
1233
  particleGravity: 0.2,
1788
1234
  particleShrinkRate: 0.995,
1789
1235
  color: () => [
@@ -1809,7 +1255,7 @@ var blast = (options = defaultOptions) => {
1809
1255
  }
1810
1256
  }
1811
1257
  }),
1812
- import_view7.keymap.of([
1258
+ import_view6.keymap.of([
1813
1259
  {
1814
1260
  any: (_, event) => {
1815
1261
  if (blaster) {
@@ -2101,7 +1547,7 @@ var commandState = import_state9.StateField.define({
2101
1547
  return state;
2102
1548
  },
2103
1549
  provide: (field) => [
2104
- import_view8.showTooltip.from(field, (value) => value.tooltip ?? null)
1550
+ import_view7.showTooltip.from(field, (value) => value.tooltip ?? null)
2105
1551
  ]
2106
1552
  });
2107
1553
  var openEffect = import_state8.StateEffect.define();
@@ -2141,9 +1587,9 @@ var commandKeyBindings = [
2141
1587
  run: closeCommand
2142
1588
  }
2143
1589
  ];
2144
- var hintViewPlugin = ({ onHint }) => import_view10.ViewPlugin.fromClass(class {
1590
+ var hintViewPlugin = ({ onHint }) => import_view9.ViewPlugin.fromClass(class {
2145
1591
  constructor() {
2146
- this.deco = import_view10.Decoration.none;
1592
+ this.deco = import_view9.Decoration.none;
2147
1593
  }
2148
1594
  update(update2) {
2149
1595
  const builder = new import_state10.RangeSetBuilder();
@@ -2154,7 +1600,7 @@ var hintViewPlugin = ({ onHint }) => import_view10.ViewPlugin.fromClass(class {
2154
1600
  if (selection.from === selection.to && line.from === line.to) {
2155
1601
  const hint = onHint();
2156
1602
  if (hint) {
2157
- builder.add(selection.from, selection.to, import_view10.Decoration.widget({
1603
+ builder.add(selection.from, selection.to, import_view9.Decoration.widget({
2158
1604
  widget: new CommandHint(hint)
2159
1605
  }));
2160
1606
  }
@@ -2164,10 +1610,10 @@ var hintViewPlugin = ({ onHint }) => import_view10.ViewPlugin.fromClass(class {
2164
1610
  }
2165
1611
  }, {
2166
1612
  provide: (plugin) => [
2167
- import_view10.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view10.Decoration.none)
1613
+ import_view9.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view9.Decoration.none)
2168
1614
  ]
2169
1615
  });
2170
- var CommandHint = class extends import_view10.WidgetType {
1616
+ var CommandHint = class extends import_view9.WidgetType {
2171
1617
  constructor(content) {
2172
1618
  super();
2173
1619
  this.content = content;
@@ -2206,7 +1652,7 @@ var CommandHint = class extends import_view10.WidgetType {
2206
1652
  return false;
2207
1653
  }
2208
1654
  };
2209
- var floatingMenu = (options) => import_view11.ViewPlugin.fromClass(class {
1655
+ var floatingMenu = (options) => import_view10.ViewPlugin.fromClass(class {
2210
1656
  constructor(view) {
2211
1657
  this.rafId = null;
2212
1658
  this.view = view;
@@ -2269,7 +1715,7 @@ var floatingMenu = (options) => import_view11.ViewPlugin.fromClass(class {
2269
1715
  });
2270
1716
  var command = (options = {}) => {
2271
1717
  return [
2272
- import_view9.keymap.of(commandKeyBindings),
1718
+ import_view8.keymap.of(commandKeyBindings),
2273
1719
  commandConfig.of(options),
2274
1720
  commandState,
2275
1721
  options.renderMenu ? floatingMenu({
@@ -2278,10 +1724,10 @@ var command = (options = {}) => {
2278
1724
  options.onHint ? hintViewPlugin({
2279
1725
  onHint: options.onHint
2280
1726
  }) : [],
2281
- import_view9.EditorView.focusChangeEffect.of((_, focusing) => {
1727
+ import_view8.EditorView.focusChangeEffect.of((_, focusing) => {
2282
1728
  return focusing ? closeEffect.of(null) : null;
2283
1729
  }),
2284
- import_view9.EditorView.theme({
1730
+ import_view8.EditorView.theme({
2285
1731
  ".cm-tooltip": {
2286
1732
  background: "transparent"
2287
1733
  }
@@ -2295,7 +1741,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
2295
1741
  return {
2296
1742
  selection,
2297
1743
  scrollIntoView: !scrollTo,
2298
- effects: scrollTo ? import_view13.EditorView.scrollIntoView(scrollTo, {
1744
+ effects: scrollTo ? import_view12.EditorView.scrollIntoView(scrollTo, {
2299
1745
  yMargin: 96
2300
1746
  }) : void 0,
2301
1747
  annotations: import_state12.Transaction.userEvent.of(stateRestoreAnnotation)
@@ -2337,7 +1783,7 @@ var selectionState = ({ getState, setState } = {}) => {
2337
1783
  // setStateDebounced(id, {});
2338
1784
  // },
2339
1785
  // }),
2340
- import_view13.EditorView.updateListener.of(({ view, transactions }) => {
1786
+ import_view12.EditorView.updateListener.of(({ view, transactions }) => {
2341
1787
  const id = view.state.facet(documentId);
2342
1788
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
2343
1789
  return;
@@ -2360,7 +1806,7 @@ var selectionState = ({ getState, setState } = {}) => {
2360
1806
  }
2361
1807
  }
2362
1808
  }),
2363
- getState && import_view13.keymap.of([
1809
+ getState && import_view12.keymap.of([
2364
1810
  {
2365
1811
  key: "ctrl-r",
2366
1812
  run: (view) => {
@@ -2416,7 +1862,7 @@ var commentsState = import_state11.StateField.define({
2416
1862
  return value;
2417
1863
  }
2418
1864
  });
2419
- var styles3 = import_view12.EditorView.theme({
1865
+ var styles3 = import_view11.EditorView.theme({
2420
1866
  ".cm-comment, .cm-comment-current": {
2421
1867
  margin: "0 -3px",
2422
1868
  padding: "3px",
@@ -2429,18 +1875,18 @@ var styles3 = import_view12.EditorView.theme({
2429
1875
  textDecoration: "underline"
2430
1876
  }
2431
1877
  });
2432
- var createCommentMark = (id, isCurrent) => import_view12.Decoration.mark({
1878
+ var createCommentMark = (id, isCurrent) => import_view11.Decoration.mark({
2433
1879
  class: isCurrent ? "cm-comment-current" : "cm-comment",
2434
1880
  attributes: {
2435
1881
  "data-testid": "cm-comment",
2436
1882
  "data-comment-id": id
2437
1883
  }
2438
1884
  });
2439
- var commentsDecorations = import_view12.EditorView.decorations.compute([
1885
+ var commentsDecorations = import_view11.EditorView.decorations.compute([
2440
1886
  commentsState
2441
1887
  ], (state) => {
2442
1888
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
2443
- const decorations = (0, import_lodash3.default)(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
1889
+ const decorations = (0, import_lodash2.default)(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
2444
1890
  const range = comment.range;
2445
1891
  if (!range) {
2446
1892
  import_log4.log.warn("Invalid range:", range, {
@@ -2456,10 +1902,10 @@ var commentsDecorations = import_view12.EditorView.decorations.compute([
2456
1902
  const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
2457
1903
  return mark.range(range.from, range.to);
2458
1904
  }).filter(import_util2.isNonNullable);
2459
- return import_view12.Decoration.set(decorations);
1905
+ return import_view11.Decoration.set(decorations);
2460
1906
  });
2461
1907
  var commentClickedEffect = import_state11.StateEffect.define();
2462
- var handleCommentClick = import_view12.EditorView.domEventHandlers({
1908
+ var handleCommentClick = import_view11.EditorView.domEventHandlers({
2463
1909
  click: (event, view) => {
2464
1910
  let target = event.target;
2465
1911
  const editorRoot = view.dom;
@@ -2498,7 +1944,7 @@ var trackPastedComments = (onUpdate) => {
2498
1944
  }
2499
1945
  };
2500
1946
  return [
2501
- import_view12.EditorView.domEventHandlers({
1947
+ import_view11.EditorView.domEventHandlers({
2502
1948
  cut: handleTrack,
2503
1949
  copy: handleTrack
2504
1950
  }),
@@ -2520,7 +1966,7 @@ var trackPastedComments = (onUpdate) => {
2520
1966
  return effects;
2521
1967
  }),
2522
1968
  // Handle paste or the undo of comment deletion.
2523
- import_view12.EditorView.updateListener.of((update2) => {
1969
+ import_view11.EditorView.updateListener.of((update2) => {
2524
1970
  const restore = [];
2525
1971
  for (let i = 0; i < update2.transactions.length; i++) {
2526
1972
  const tr = update2.transactions[i];
@@ -2579,7 +2025,7 @@ var mapTrackedComment = (comment, changes) => ({
2579
2025
  var restoreCommentEffect = import_state11.StateEffect.define({
2580
2026
  map: mapTrackedComment
2581
2027
  });
2582
- var createComment2 = (view) => {
2028
+ var createComment = (view) => {
2583
2029
  const options = view.state.facet(optionsFacet);
2584
2030
  const { from, to } = view.state.selection.main;
2585
2031
  if (from === to) {
@@ -2621,17 +2067,17 @@ var comments = (options = {}) => {
2621
2067
  //
2622
2068
  // Keymap.
2623
2069
  //
2624
- options.onCreate && import_view12.keymap.of([
2070
+ options.onCreate && import_view11.keymap.of([
2625
2071
  {
2626
2072
  key: shortcut,
2627
- run: callbackWrapper(createComment2)
2073
+ run: callbackWrapper(createComment)
2628
2074
  }
2629
2075
  ]),
2630
2076
  //
2631
2077
  // Hover tooltip (for key shortcut hints, etc.)
2632
2078
  // TODO(burdon): Factor out to generic hints extension for current selection/line.
2633
2079
  //
2634
- options.renderTooltip && (0, import_view12.hoverTooltip)((view, pos) => {
2080
+ options.renderTooltip && (0, import_view11.hoverTooltip)((view, pos) => {
2635
2081
  const selection = view.state.selection.main;
2636
2082
  if (selection && pos >= selection.from && pos <= selection.to) {
2637
2083
  return {
@@ -2662,7 +2108,7 @@ var comments = (options = {}) => {
2662
2108
  //
2663
2109
  // Track deleted ranges and update ranges for decorations.
2664
2110
  //
2665
- import_view12.EditorView.updateListener.of(({ view, state, changes }) => {
2111
+ import_view11.EditorView.updateListener.of(({ view, state, changes }) => {
2666
2112
  let mod = false;
2667
2113
  const { comments: comments2, ...value } = state.field(commentsState);
2668
2114
  changes.iterChanges((from, to, from2, to2) => {
@@ -2694,7 +2140,7 @@ var comments = (options = {}) => {
2694
2140
  //
2695
2141
  // Track selection/proximity.
2696
2142
  //
2697
- import_view12.EditorView.updateListener.of(({ view, state }) => {
2143
+ import_view11.EditorView.updateListener.of(({ view, state }) => {
2698
2144
  let min = Infinity;
2699
2145
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2700
2146
  const { head } = state.selection.main;
@@ -2748,7 +2194,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
2748
2194
  anchor: range.from
2749
2195
  } : void 0,
2750
2196
  effects: [
2751
- needsScroll ? import_view12.EditorView.scrollIntoView(range.from, center ? {
2197
+ needsScroll ? import_view11.EditorView.scrollIntoView(range.from, center ? {
2752
2198
  y: "center"
2753
2199
  } : void 0) : [],
2754
2200
  needsSelectionUpdate ? setSelection.of({
@@ -2794,13 +2240,13 @@ var ExternalCommentSync = class {
2794
2240
  this.unsubscribe = subscribe(updateComments);
2795
2241
  }
2796
2242
  };
2797
- var createExternalCommentSync = (id, subscribe, getComments) => import_view12.ViewPlugin.fromClass(class {
2243
+ var createExternalCommentSync = (id, subscribe, getComments) => import_view11.ViewPlugin.fromClass(class {
2798
2244
  constructor(view) {
2799
2245
  return new ExternalCommentSync(view, id, subscribe, getComments);
2800
2246
  }
2801
2247
  });
2802
2248
  var useCommentState = (state) => {
2803
- return (0, import_react4.useMemo)(() => import_view12.EditorView.updateListener.of((update2) => {
2249
+ return (0, import_react4.useMemo)(() => import_view11.EditorView.updateListener.of((update2) => {
2804
2250
  if (update2.docChanged || update2.selectionSet) {
2805
2251
  state.comment = selectionOverlapsComment(update2.state);
2806
2252
  state.selection = hasActiveSelection(update2.state);
@@ -2824,7 +2270,7 @@ var useComments = (view, id, comments2) => {
2824
2270
  });
2825
2271
  };
2826
2272
  var useCommentClickListener = (onCommentClick) => {
2827
- return (0, import_react4.useMemo)(() => import_view12.EditorView.updateListener.of((update2) => {
2273
+ return (0, import_react4.useMemo)(() => import_view11.EditorView.updateListener.of((update2) => {
2828
2274
  update2.transactions.forEach((transaction) => {
2829
2275
  transaction.effects.forEach((effect) => {
2830
2276
  if (effect.is(commentClickedEffect)) {
@@ -2845,7 +2291,7 @@ var debugNodeLogger = (log8 = console.log) => {
2845
2291
  update: (_, tr) => logTokens(tr.state)
2846
2292
  });
2847
2293
  };
2848
- var styles4 = import_view14.EditorView.theme({
2294
+ var styles4 = import_view13.EditorView.theme({
2849
2295
  ".cm-dropCursor": {
2850
2296
  borderLeft: "2px solid var(--dx-accentText)",
2851
2297
  color: "var(--dx-accentText)",
@@ -2858,8 +2304,8 @@ var styles4 = import_view14.EditorView.theme({
2858
2304
  var dropFile = (options = {}) => {
2859
2305
  return [
2860
2306
  styles4,
2861
- (0, import_view14.dropCursor)(),
2862
- import_view14.EditorView.domEventHandlers({
2307
+ (0, import_view13.dropCursor)(),
2308
+ import_view13.EditorView.domEventHandlers({
2863
2309
  drop: (event, view) => {
2864
2310
  event.preventDefault();
2865
2311
  const files = event.dataTransfer?.files;
@@ -2892,7 +2338,7 @@ var focusField = import_state15.StateField.define({
2892
2338
  });
2893
2339
  var focus = [
2894
2340
  focusField,
2895
- import_view16.EditorView.domEventHandlers({
2341
+ import_view15.EditorView.domEventHandlers({
2896
2342
  focus: (event, view) => {
2897
2343
  setTimeout(() => view.dispatch({
2898
2344
  effects: focusEffect.of(true)
@@ -2905,6 +2351,229 @@ var focus = [
2905
2351
  }
2906
2352
  })
2907
2353
  ];
2354
+ var headings = {
2355
+ 1: "text-4xl",
2356
+ 2: "text-3xl",
2357
+ 3: "text-2xl",
2358
+ 4: "text-xl",
2359
+ 5: "text-lg",
2360
+ 6: ""
2361
+ };
2362
+ var theme = {
2363
+ code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
2364
+ codeMark: "font-mono text-primary-500",
2365
+ mark: "opacity-50",
2366
+ heading: (level) => {
2367
+ return (0, import_react_ui_theme3.mx)(headings[level], "dark:text-primary-400");
2368
+ }
2369
+ };
2370
+ var getToken = (path, defaultValue) => {
2371
+ const value = (0, import_lodash5.default)(import_react_ui_theme4.tokens, path, defaultValue);
2372
+ return value?.toString() ?? "";
2373
+ };
2374
+ var fontBody = getToken("fontFamily.body");
2375
+ var fontMono = getToken("fontFamily.mono");
2376
+ var defaultTheme = {
2377
+ "&": {},
2378
+ "&.cm-focused": {
2379
+ outline: "none"
2380
+ },
2381
+ /**
2382
+ * Scroller
2383
+ */
2384
+ ".cm-scroller": {
2385
+ overflowY: "auto"
2386
+ },
2387
+ /**
2388
+ * Content
2389
+ * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
2390
+ */
2391
+ ".cm-content": {
2392
+ padding: "unset",
2393
+ fontFamily: fontBody,
2394
+ // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
2395
+ fontSize: "16px",
2396
+ lineHeight: 1.5,
2397
+ color: "unset"
2398
+ },
2399
+ /**
2400
+ * Gutters
2401
+ * NOTE: Gutters should have the same top margin as the content.
2402
+ */
2403
+ ".cm-gutters": {
2404
+ borderRight: "none",
2405
+ background: "transparent"
2406
+ },
2407
+ ".cm-gutter": {},
2408
+ ".cm-gutter.cm-lineNumbers": {
2409
+ paddingRight: "4px",
2410
+ borderRight: "1px solid var(--dx-separator)"
2411
+ },
2412
+ ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2413
+ minWidth: "40px",
2414
+ alignContent: "center"
2415
+ },
2416
+ /**
2417
+ * Height is set to match the corresponding line.
2418
+ */
2419
+ ".cm-gutterElement": {
2420
+ alignItems: "center",
2421
+ fontSize: "12px"
2422
+ },
2423
+ /**
2424
+ * Line.
2425
+ */
2426
+ ".cm-line": {
2427
+ paddingInline: 0
2428
+ },
2429
+ ".cm-activeLine": {
2430
+ background: "var(--dx-cmActiveLine)"
2431
+ },
2432
+ /**
2433
+ * Cursor (layer).
2434
+ */
2435
+ ".cm-cursor, .cm-dropCursor": {
2436
+ borderLeft: "2px solid var(--dx-cmCursor)"
2437
+ },
2438
+ ".cm-placeholder": {
2439
+ color: "var(--dx-subdued)"
2440
+ },
2441
+ /**
2442
+ * Selection (layer).
2443
+ */
2444
+ ".cm-selectionBackground": {
2445
+ background: "var(--dx-cmSelection)"
2446
+ },
2447
+ /**
2448
+ * Search.
2449
+ * NOTE: Matches comment.
2450
+ */
2451
+ ".cm-searchMatch": {
2452
+ margin: "0 -3px",
2453
+ padding: "3px",
2454
+ borderRadius: "3px",
2455
+ background: "var(--dx-cmHighlightSurface)",
2456
+ color: "var(--dx-cmHighlight)"
2457
+ },
2458
+ ".cm-searchMatch-selected": {
2459
+ textDecoration: "underline"
2460
+ },
2461
+ /**
2462
+ * Link.
2463
+ */
2464
+ ".cm-link": {
2465
+ textDecorationLine: "underline",
2466
+ textDecorationThickness: "1px",
2467
+ textDecorationColor: "var(--dx-separator)",
2468
+ textUnderlineOffset: "2px",
2469
+ borderRadius: ".125rem"
2470
+ },
2471
+ ".cm-link > span": {
2472
+ color: "var(--dx-accentText)"
2473
+ },
2474
+ /**
2475
+ * Tooltip.
2476
+ */
2477
+ ".cm-tooltip": {
2478
+ background: "var(--dx-baseSurface)"
2479
+ },
2480
+ ".cm-tooltip-below": {},
2481
+ /**
2482
+ * Autocomplete.
2483
+ * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
2484
+ */
2485
+ ".cm-tooltip.cm-tooltip-autocomplete": {
2486
+ marginTop: "4px",
2487
+ marginLeft: "-3px"
2488
+ },
2489
+ ".cm-tooltip.cm-tooltip-autocomplete > ul": {
2490
+ maxHeight: "20em"
2491
+ },
2492
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
2493
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
2494
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2495
+ paddingLeft: "4px !important",
2496
+ borderBottom: "none !important",
2497
+ color: "var(--dx-accentText)"
2498
+ },
2499
+ ".cm-tooltip.cm-completionInfo": {
2500
+ width: "360px !important",
2501
+ margin: "-10px 1px 0 1px",
2502
+ padding: "8px !important",
2503
+ borderColor: "var(--dx-separator)"
2504
+ },
2505
+ ".cm-completionIcon": {
2506
+ display: "none"
2507
+ },
2508
+ ".cm-completionLabel": {
2509
+ fontFamily: fontBody
2510
+ },
2511
+ ".cm-completionMatchedText": {
2512
+ textDecoration: "none !important",
2513
+ opacity: 0.5
2514
+ },
2515
+ /**
2516
+ * Panels
2517
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
2518
+ *
2519
+ * Find/replace panel.
2520
+ * <div class="cm-announced">...</div>
2521
+ * <div class="cm-scroller">...</div>
2522
+ * <div class="cm-panels cm-panels-bottom">
2523
+ * <div class="cm-search cm-panel">
2524
+ * <input class="cm-textfield" />
2525
+ * <button class="cm-button">...</button>
2526
+ * <label><input type="checkbox" />...</label>
2527
+ * </div>
2528
+ * </div
2529
+ */
2530
+ // TODO(burdon): Implement custom panel (with icon buttons).
2531
+ ".cm-panels": {},
2532
+ ".cm-panel": {
2533
+ fontFamily: fontBody,
2534
+ backgroundColor: "var(--surface-bg)"
2535
+ },
2536
+ ".cm-panel input, .cm-panel button, .cm-panel label": {
2537
+ color: "var(--dx-subdued)",
2538
+ fontFamily: fontBody,
2539
+ fontSize: "14px",
2540
+ all: "unset",
2541
+ margin: "3px !important",
2542
+ padding: "2px 6px !important",
2543
+ outline: "1px solid transparent"
2544
+ },
2545
+ ".cm-panel input, .cm-panel button": {
2546
+ backgroundColor: "var(--dx-input)"
2547
+ },
2548
+ ".cm-panel input:focus, .cm-panel button:focus": {
2549
+ outline: "1px solid var(--dx-accentFocusIndicator)"
2550
+ },
2551
+ ".cm-panel label": {
2552
+ display: "inline-flex",
2553
+ alignItems: "center",
2554
+ cursor: "pointer"
2555
+ },
2556
+ ".cm-panel input.cm-textfield": {},
2557
+ ".cm-panel input[type=checkbox]": {
2558
+ width: "8px",
2559
+ height: "8px",
2560
+ marginRight: "6px !important",
2561
+ padding: "2px !important",
2562
+ color: "var(--dx-accentFocusIndicator)"
2563
+ },
2564
+ ".cm-panel button": {
2565
+ "&:hover": {
2566
+ backgroundColor: "var(--dx-accentSurfaceHover) !important"
2567
+ },
2568
+ "&:active": {
2569
+ backgroundColor: "var(--dx-accentSurfaceHover)"
2570
+ }
2571
+ },
2572
+ ".cm-panel.cm-search": {
2573
+ padding: "4px",
2574
+ borderTop: "1px solid var(--dx-separator)"
2575
+ }
2576
+ };
2908
2577
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2909
2578
  var preventNewline = import_state14.EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
2910
2579
  var defaultBasicOptions = {
@@ -2925,10 +2594,10 @@ var keymaps = {
2925
2594
  default: import_commands2.defaultKeymap
2926
2595
  };
2927
2596
  var createBasicExtensions = (_props) => {
2928
- const props = (0, import_lodash4.default)({}, _props, defaultBasicOptions);
2597
+ const props = (0, import_lodash3.default)({}, _props, defaultBasicOptions);
2929
2598
  return [
2930
2599
  // NOTE: Doesn't catch errors in keymap functions.
2931
- import_view15.EditorView.exceptionSink.of((err) => {
2600
+ import_view14.EditorView.exceptionSink.of((err) => {
2932
2601
  import_log5.log.catch(err, void 0, {
2933
2602
  F: __dxlog_file8,
2934
2603
  L: 96,
@@ -2939,22 +2608,22 @@ var createBasicExtensions = (_props) => {
2939
2608
  props.allowMultipleSelections && import_state14.EditorState.allowMultipleSelections.of(true),
2940
2609
  props.bracketMatching && (0, import_language2.bracketMatching)(),
2941
2610
  props.closeBrackets && (0, import_autocomplete2.closeBrackets)(),
2942
- props.dropCursor && (0, import_view15.dropCursor)(),
2943
- props.drawSelection && (0, import_view15.drawSelection)({
2611
+ props.dropCursor && (0, import_view14.dropCursor)(),
2612
+ props.drawSelection && (0, import_view14.drawSelection)({
2944
2613
  cursorBlinkRate: 1200
2945
2614
  }),
2946
- props.editable !== void 0 && import_view15.EditorView.editable.of(props.editable),
2615
+ props.editable !== void 0 && import_view14.EditorView.editable.of(props.editable),
2947
2616
  props.focus && focus,
2948
- props.highlightActiveLine && (0, import_view15.highlightActiveLine)(),
2617
+ props.highlightActiveLine && (0, import_view14.highlightActiveLine)(),
2949
2618
  props.history && (0, import_commands2.history)(),
2950
- props.lineNumbers && (0, import_view15.lineNumbers)(),
2951
- props.lineWrapping && import_view15.EditorView.lineWrapping,
2952
- props.placeholder && (0, import_view15.placeholder)(props.placeholder),
2619
+ props.lineNumbers && (0, import_view14.lineNumbers)(),
2620
+ props.lineWrapping && import_view14.EditorView.lineWrapping,
2621
+ props.placeholder && (0, import_view14.placeholder)(props.placeholder),
2953
2622
  props.readOnly !== void 0 && import_state14.EditorState.readOnly.of(props.readOnly),
2954
- props.scrollPastEnd && (0, import_view15.scrollPastEnd)(),
2623
+ props.scrollPastEnd && (0, import_view14.scrollPastEnd)(),
2955
2624
  props.tabSize && import_state14.EditorState.tabSize.of(props.tabSize),
2956
2625
  // https://codemirror.net/docs/ref/#view.KeyBinding
2957
- import_view15.keymap.of([
2626
+ import_view14.keymap.of([
2958
2627
  ...(props.keymap && keymaps[props.keymap]) ?? [],
2959
2628
  // NOTE: Tabs are also configured by markdown extension.
2960
2629
  // https://codemirror.net/docs/ref/#commands.indentWithTab
@@ -2983,16 +2652,16 @@ var defaultThemeSlots = {
2983
2652
  }
2984
2653
  };
2985
2654
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2986
- const slots = (0, import_lodash4.default)({}, _slots, defaultThemeSlots);
2655
+ const slots = (0, import_lodash3.default)({}, _slots, defaultThemeSlots);
2987
2656
  return [
2988
- import_view15.EditorView.darkTheme.of(themeMode === "dark"),
2989
- import_view15.EditorView.baseTheme(styles5 ? (0, import_lodash5.default)({}, defaultTheme, styles5) : defaultTheme),
2657
+ import_view14.EditorView.darkTheme.of(themeMode === "dark"),
2658
+ import_view14.EditorView.baseTheme(styles5 ? (0, import_lodash4.default)({}, defaultTheme, styles5) : defaultTheme),
2990
2659
  // https://github.com/codemirror/theme-one-dark
2991
2660
  _syntaxHighlighting && (themeMode === "dark" ? (0, import_language2.syntaxHighlighting)(import_theme_one_dark.oneDarkHighlightStyle) : (0, import_language2.syntaxHighlighting)(import_language2.defaultHighlightStyle)),
2992
- slots.editor?.className && import_view15.EditorView.editorAttributes.of({
2661
+ slots.editor?.className && import_view14.EditorView.editorAttributes.of({
2993
2662
  class: slots.editor.className
2994
2663
  }),
2995
- slots.content?.className && import_view15.EditorView.contentAttributes.of({
2664
+ slots.content?.className && import_view14.EditorView.contentAttributes.of({
2996
2665
  class: slots.content.className
2997
2666
  })
2998
2667
  ].filter(import_util4.isNotFalsy);
@@ -3039,7 +2708,7 @@ var folding = (_props = {}) => [
3039
2708
  }));
3040
2709
  }
3041
2710
  }),
3042
- import_view17.EditorView.theme({
2711
+ import_view16.EditorView.theme({
3043
2712
  ".cm-foldGutter": {
3044
2713
  opacity: 0.3,
3045
2714
  transition: "opacity 0.3s",
@@ -3052,11 +2721,11 @@ var folding = (_props = {}) => [
3052
2721
  ];
3053
2722
  var listener = ({ onFocus, onChange }) => {
3054
2723
  const extensions = [];
3055
- onFocus && extensions.push(import_view18.EditorView.focusChangeEffect.of((_, focusing) => {
2724
+ onFocus && extensions.push(import_view17.EditorView.focusChangeEffect.of((_, focusing) => {
3056
2725
  onFocus(focusing);
3057
2726
  return null;
3058
2727
  }));
3059
- onChange && extensions.push(import_view18.EditorView.updateListener.of((update2) => {
2728
+ onChange && extensions.push(import_view17.EditorView.updateListener.of((update2) => {
3060
2729
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
3061
2730
  }));
3062
2731
  return extensions;
@@ -3947,7 +3616,7 @@ var toggleCodeblock = (target) => {
3947
3616
  };
3948
3617
  var formattingKeymap = (_options = {}) => {
3949
3618
  return [
3950
- import_view19.keymap.of([
3619
+ import_view18.keymap.of([
3951
3620
  {
3952
3621
  key: "meta-b",
3953
3622
  run: toggleStrong
@@ -4148,7 +3817,7 @@ var getFormatting = (state) => {
4148
3817
  };
4149
3818
  };
4150
3819
  var useFormattingState = (state) => {
4151
- return (0, import_react6.useMemo)(() => import_view19.EditorView.updateListener.of((update2) => {
3820
+ return (0, import_react6.useMemo)(() => import_view18.EditorView.updateListener.of((update2) => {
4152
3821
  if (update2.docChanged || update2.selectionSet) {
4153
3822
  Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
4154
3823
  state[key] = active;
@@ -4194,7 +3863,7 @@ var processEditorPayload = (view, { type, data }) => {
4194
3863
  })(view);
4195
3864
  break;
4196
3865
  case "comment":
4197
- createComment2(view);
3866
+ createComment(view);
4198
3867
  break;
4199
3868
  }
4200
3869
  requestAnimationFrame(() => {
@@ -4400,7 +4069,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
4400
4069
  }),
4401
4070
  // Custom styles.
4402
4071
  (0, import_language5.syntaxHighlighting)(markdownHighlightStyle()),
4403
- import_view20.keymap.of([
4072
+ import_view19.keymap.of([
4404
4073
  // https://codemirror.net/docs/ref/#commands.indentWithTab
4405
4074
  import_commands3.indentWithTab,
4406
4075
  // https://codemirror.net/docs/ref/#commands.defaultKeymap
@@ -4434,7 +4103,7 @@ var convertTreeToJson = (state) => {
4434
4103
  return treeToJson((0, import_language7.syntaxTree)(state).cursor());
4435
4104
  };
4436
4105
  var adjustChanges = () => {
4437
- return import_view22.ViewPlugin.fromClass(class {
4106
+ return import_view21.ViewPlugin.fromClass(class {
4438
4107
  update(update2) {
4439
4108
  const tree = (0, import_language9.syntaxTree)(update2.state);
4440
4109
  const adjustments = [];
@@ -4576,7 +4245,7 @@ var image = (_options = {}) => {
4576
4245
  return [
4577
4246
  import_state20.StateField.define({
4578
4247
  create: (state) => {
4579
- return import_view23.Decoration.set(buildDecorations(0, state.doc.length, state));
4248
+ return import_view22.Decoration.set(buildDecorations(0, state.doc.length, state));
4580
4249
  },
4581
4250
  update: (value, tr) => {
4582
4251
  if (!tr.docChanged && !tr.selection) {
@@ -4599,7 +4268,7 @@ var image = (_options = {}) => {
4599
4268
  add: buildDecorations(from, to, tr.state)
4600
4269
  });
4601
4270
  },
4602
- provide: (field) => import_view23.EditorView.decorations.from(field)
4271
+ provide: (field) => import_view22.EditorView.decorations.from(field)
4603
4272
  })
4604
4273
  ];
4605
4274
  };
@@ -4617,7 +4286,7 @@ var buildDecorations = (from, to, state) => {
4617
4286
  return;
4618
4287
  }
4619
4288
  preloadImage(url);
4620
- decorations.push(import_view23.Decoration.replace({
4289
+ decorations.push(import_view22.Decoration.replace({
4621
4290
  block: true,
4622
4291
  widget: new ImageWidget(url)
4623
4292
  }).range(hide2 ? node.from : node.to, node.to));
@@ -4637,7 +4306,7 @@ var preloadImage = (url) => {
4637
4306
  preloaded.add(url);
4638
4307
  }
4639
4308
  };
4640
- var ImageWidget = class extends import_view23.WidgetType {
4309
+ var ImageWidget = class extends import_view22.WidgetType {
4641
4310
  constructor(_url) {
4642
4311
  super();
4643
4312
  this._url = _url;
@@ -4659,7 +4328,7 @@ var ImageWidget = class extends import_view23.WidgetType {
4659
4328
  };
4660
4329
  var bulletListIndentationWidth = 24;
4661
4330
  var orderedListIndentationWidth = 36;
4662
- var formattingStyles = import_view24.EditorView.theme({
4331
+ var formattingStyles = import_view23.EditorView.theme({
4663
4332
  /**
4664
4333
  * Horizontal rule.
4665
4334
  */
@@ -4780,7 +4449,7 @@ var table = (options = {}) => {
4780
4449
  return import_state21.StateField.define({
4781
4450
  create: (state) => update(state, options),
4782
4451
  update: (_, tr) => update(tr.state, options),
4783
- provide: (field) => import_view25.EditorView.decorations.from(field)
4452
+ provide: (field) => import_view24.EditorView.decorations.from(field)
4784
4453
  });
4785
4454
  };
4786
4455
  var update = (state, _options) => {
@@ -4825,19 +4494,19 @@ var update = (state, _options) => {
4825
4494
  tables.forEach((table2) => {
4826
4495
  const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4827
4496
  if (replace) {
4828
- builder.add(table2.from, table2.to, import_view25.Decoration.replace({
4497
+ builder.add(table2.from, table2.to, import_view24.Decoration.replace({
4829
4498
  block: true,
4830
4499
  widget: new TableWidget(table2)
4831
4500
  }));
4832
4501
  } else {
4833
- builder.add(table2.from, table2.to, import_view25.Decoration.mark({
4502
+ builder.add(table2.from, table2.to, import_view24.Decoration.mark({
4834
4503
  class: "cm-table"
4835
4504
  }));
4836
4505
  }
4837
4506
  });
4838
4507
  return builder.finish();
4839
4508
  };
4840
- var TableWidget = class extends import_view25.WidgetType {
4509
+ var TableWidget = class extends import_view24.WidgetType {
4841
4510
  constructor(_table) {
4842
4511
  super();
4843
4512
  this._table = _table;
@@ -4877,14 +4546,14 @@ var Unicode = {
4877
4546
  bulletSmall: "\u2219",
4878
4547
  bulletSquare: "\u2B1D"
4879
4548
  };
4880
- var HorizontalRuleWidget = class extends import_view21.WidgetType {
4549
+ var HorizontalRuleWidget = class extends import_view20.WidgetType {
4881
4550
  toDOM() {
4882
4551
  const el = document.createElement("span");
4883
4552
  el.className = "cm-hr";
4884
4553
  return el;
4885
4554
  }
4886
4555
  };
4887
- var LinkButton = class extends import_view21.WidgetType {
4556
+ var LinkButton = class extends import_view20.WidgetType {
4888
4557
  constructor(url, render) {
4889
4558
  super();
4890
4559
  this.url = url;
@@ -4902,7 +4571,7 @@ var LinkButton = class extends import_view21.WidgetType {
4902
4571
  return el;
4903
4572
  }
4904
4573
  };
4905
- var CheckboxWidget = class extends import_view21.WidgetType {
4574
+ var CheckboxWidget = class extends import_view20.WidgetType {
4906
4575
  constructor(_checked) {
4907
4576
  super();
4908
4577
  this._checked = _checked;
@@ -4947,7 +4616,7 @@ var CheckboxWidget = class extends import_view21.WidgetType {
4947
4616
  return false;
4948
4617
  }
4949
4618
  };
4950
- var TextWidget = class extends import_view21.WidgetType {
4619
+ var TextWidget = class extends import_view20.WidgetType {
4951
4620
  constructor(text, className) {
4952
4621
  super();
4953
4622
  this.text = text;
@@ -4962,29 +4631,29 @@ var TextWidget = class extends import_view21.WidgetType {
4962
4631
  return el;
4963
4632
  }
4964
4633
  };
4965
- var hide = import_view21.Decoration.replace({});
4966
- var blockQuote = import_view21.Decoration.line({
4967
- class: (0, import_react_ui_theme6.mx)("cm-blockquote")
4634
+ var hide = import_view20.Decoration.replace({});
4635
+ var blockQuote = import_view20.Decoration.line({
4636
+ class: (0, import_react_ui_theme5.mx)("cm-blockquote")
4968
4637
  });
4969
- var fencedCodeLine = import_view21.Decoration.line({
4970
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line")
4638
+ var fencedCodeLine = import_view20.Decoration.line({
4639
+ class: (0, import_react_ui_theme5.mx)("cm-code cm-codeblock-line")
4971
4640
  });
4972
- var fencedCodeLineFirst = import_view21.Decoration.line({
4973
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line", "cm-codeblock-first")
4641
+ var fencedCodeLineFirst = import_view20.Decoration.line({
4642
+ class: (0, import_react_ui_theme5.mx)("cm-code cm-codeblock-line", "cm-codeblock-first")
4974
4643
  });
4975
- var fencedCodeLineLast = import_view21.Decoration.line({
4976
- class: (0, import_react_ui_theme6.mx)("cm-code cm-codeblock-line", "cm-codeblock-last")
4644
+ var fencedCodeLineLast = import_view20.Decoration.line({
4645
+ class: (0, import_react_ui_theme5.mx)("cm-code cm-codeblock-line", "cm-codeblock-last")
4977
4646
  });
4978
4647
  var commentBlockLine = fencedCodeLine;
4979
4648
  var commentBlockLineFirst = fencedCodeLineFirst;
4980
4649
  var commentBlockLineLast = fencedCodeLineLast;
4981
- var horizontalRule = import_view21.Decoration.replace({
4650
+ var horizontalRule = import_view20.Decoration.replace({
4982
4651
  widget: new HorizontalRuleWidget()
4983
4652
  });
4984
- var checkedTask = import_view21.Decoration.replace({
4653
+ var checkedTask = import_view20.Decoration.replace({
4985
4654
  widget: new CheckboxWidget(true)
4986
4655
  });
4987
- var uncheckedTask = import_view21.Decoration.replace({
4656
+ var uncheckedTask = import_view20.Decoration.replace({
4988
4657
  widget: new CheckboxWidget(false)
4989
4658
  });
4990
4659
  var editingRange = (state, range, focus2) => {
@@ -5088,577 +4757,976 @@ var buildDecorations2 = (view, options, focus2) => {
5088
4757
  } else {
5089
4758
  const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
5090
4759
  if (num.length) {
5091
- atomicDeco.add(mark.from, mark.from + len, import_view21.Decoration.replace({
4760
+ atomicDeco.add(mark.from, mark.from + len, import_view20.Decoration.replace({
5092
4761
  widget: new TextWidget(num, theme.heading(level))
5093
4762
  }));
5094
4763
  }
5095
4764
  }
5096
- }
5097
- return false;
5098
- }
5099
- //
5100
- // Lists.
5101
- // [BulletList | OrderedList] > (ListItem > ListMark) > (Task > TaskMarker)?
5102
- //
5103
- case "BulletList":
5104
- case "OrderedList": {
5105
- enterList(node);
5106
- break;
4765
+ }
4766
+ return false;
4767
+ }
4768
+ //
4769
+ // Lists.
4770
+ // [BulletList | OrderedList] > (ListItem > ListMark) > (Task > TaskMarker)?
4771
+ //
4772
+ case "BulletList":
4773
+ case "OrderedList": {
4774
+ enterList(node);
4775
+ break;
4776
+ }
4777
+ case "ListItem": {
4778
+ const line = state.doc.lineAt(node.from);
4779
+ const list = getCurrentListLevel();
4780
+ const width = list.type === "OrderedList" ? orderedListIndentationWidth : bulletListIndentationWidth;
4781
+ const offset = ((list.level ?? 0) + 1) * width;
4782
+ if (node.from === line.to - 1) {
4783
+ return false;
4784
+ }
4785
+ deco.add(line.from, line.from, import_view20.Decoration.line({
4786
+ class: "cm-list-item",
4787
+ attributes: {
4788
+ style: `padding-left: ${offset}px; text-indent: -${width}px;`
4789
+ }
4790
+ }));
4791
+ break;
4792
+ }
4793
+ case "ListMark": {
4794
+ const list = getCurrentListLevel();
4795
+ const next = tree.resolve(node.to + 1, 1);
4796
+ if (next?.name === "TaskMarker") {
4797
+ break;
4798
+ }
4799
+ const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
4800
+ const line = state.doc.lineAt(node.from);
4801
+ const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4802
+ atomicDeco.add(line.from, to, import_view20.Decoration.replace({
4803
+ widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
4804
+ }));
4805
+ break;
4806
+ }
4807
+ case "TaskMarker": {
4808
+ const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
4809
+ const line = state.doc.lineAt(node.from);
4810
+ const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4811
+ atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
4812
+ break;
4813
+ }
4814
+ //
4815
+ // Blockquote > QuoteMark > Paragraph
4816
+ //
4817
+ case "Blockquote": {
4818
+ const editing = editingRange(state, node, focus2);
4819
+ const quoteMark = node.node.getChild("QuoteMark");
4820
+ const paragraph = node.node.getChild("Paragraph");
4821
+ if (!editing && quoteMark && paragraph) {
4822
+ atomicDeco.add(quoteMark.from, paragraph.from, hide);
4823
+ }
4824
+ for (const block of view.viewportLineBlocks) {
4825
+ if (block.to < node.from) {
4826
+ continue;
4827
+ }
4828
+ if (block.from > node.to) {
4829
+ break;
4830
+ }
4831
+ deco.add(block.from, block.from, blockQuote);
4832
+ }
4833
+ break;
4834
+ }
4835
+ //
4836
+ // CommentBlock
4837
+ //
4838
+ case "CommentBlock": {
4839
+ const editing = editingRange(state, node, focus2);
4840
+ for (const block of view.viewportLineBlocks) {
4841
+ if (block.to < node.from) {
4842
+ continue;
4843
+ }
4844
+ if (block.from > node.to) {
4845
+ break;
4846
+ }
4847
+ const isFirst = block.from <= node.from;
4848
+ const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
4849
+ deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
4850
+ if (!editing && (isFirst || isLast)) {
4851
+ atomicDeco.add(block.from, block.to, hide);
4852
+ }
4853
+ }
4854
+ break;
4855
+ }
4856
+ //
4857
+ // FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
4858
+ //
4859
+ case "FencedCode": {
4860
+ for (const block of view.viewportLineBlocks) {
4861
+ if (block.to < node.from) {
4862
+ continue;
4863
+ }
4864
+ if (block.from > node.to) {
4865
+ break;
4866
+ }
4867
+ const first = block.from <= node.from;
4868
+ const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
4869
+ deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
4870
+ const editing = editingRange(state, node, focus2);
4871
+ if (!editing && (first || last)) {
4872
+ atomicDeco.add(block.from, block.to, hide);
4873
+ }
4874
+ }
4875
+ return false;
4876
+ }
4877
+ //
4878
+ // Link > [LinkMark, URL]
4879
+ //
4880
+ case "Link": {
4881
+ const marks = node.node.getChildren("LinkMark");
4882
+ const urlNode = node.node.getChild("URL");
4883
+ const editing = editingRange(state, node, focus2);
4884
+ if (urlNode && marks.length >= 2) {
4885
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
4886
+ if (!editing) {
4887
+ atomicDeco.add(node.from, marks[0].to, hide);
4888
+ }
4889
+ deco.add(marks[0].to, marks[1].from, import_view20.Decoration.mark({
4890
+ tagName: "a",
4891
+ attributes: {
4892
+ class: "cm-link",
4893
+ href: url,
4894
+ rel: "noreferrer",
4895
+ target: "_blank"
4896
+ }
4897
+ }));
4898
+ if (!editing) {
4899
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? import_view20.Decoration.replace({
4900
+ widget: new LinkButton(url, options.renderLinkButton)
4901
+ }) : hide);
4902
+ }
4903
+ }
4904
+ break;
4905
+ }
4906
+ //
4907
+ // HR
4908
+ //
4909
+ case "HorizontalRule": {
4910
+ if (!editingRange(state, node, focus2)) {
4911
+ deco.add(node.from, node.to, horizontalRule);
4912
+ }
4913
+ break;
4914
+ }
4915
+ default: {
4916
+ if (autoHideTags.has(node.name)) {
4917
+ if (!editingRange(state, node.node.parent, focus2)) {
4918
+ atomicDeco.add(node.from, node.to, hide);
4919
+ }
4920
+ }
4921
+ }
4922
+ }
4923
+ };
4924
+ const leaveNode = (node) => {
4925
+ switch (node.name) {
4926
+ case "BulletList":
4927
+ case "OrderedList": {
4928
+ leaveList();
4929
+ break;
4930
+ }
4931
+ }
4932
+ };
4933
+ const tree = (0, import_language8.syntaxTree)(state);
4934
+ if (options.numberedHeadings?.from === void 0) {
4935
+ for (const { from, to } of view.visibleRanges) {
4936
+ tree.iterate({
4937
+ from,
4938
+ to,
4939
+ enter: wrapWithCatch(enterNode),
4940
+ leave: wrapWithCatch(leaveNode)
4941
+ });
4942
+ }
4943
+ } else {
4944
+ tree.iterate({
4945
+ enter: wrapWithCatch(enterNode),
4946
+ leave: wrapWithCatch(leaveNode)
4947
+ });
4948
+ }
4949
+ return {
4950
+ deco: deco.finish(),
4951
+ atomicDeco: atomicDeco.finish()
4952
+ };
4953
+ };
4954
+ var forceUpdate = import_state18.StateEffect.define();
4955
+ var decorateMarkdown = (options = {}) => {
4956
+ return [
4957
+ import_view20.ViewPlugin.fromClass(class {
4958
+ constructor(view) {
4959
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
4960
+ }
4961
+ update(update2) {
4962
+ if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
4963
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
4964
+ this.clearUpdate();
4965
+ } else if (update2.selectionSet) {
4966
+ this.scheduleUpdate(update2.view);
4967
+ }
4968
+ }
4969
+ // Defer update in case moving through the document.
4970
+ scheduleUpdate(view) {
4971
+ this.clearUpdate();
4972
+ this.pendingUpdate = setTimeout(() => {
4973
+ view.dispatch({
4974
+ effects: forceUpdate.of(null)
4975
+ });
4976
+ }, options.selectionChangeDelay);
4977
+ }
4978
+ clearUpdate() {
4979
+ if (this.pendingUpdate) {
4980
+ clearTimeout(this.pendingUpdate);
4981
+ this.pendingUpdate = void 0;
4982
+ }
4983
+ }
4984
+ destroy() {
4985
+ this.clearUpdate();
4986
+ }
4987
+ }, {
4988
+ provide: (plugin) => [
4989
+ import_view20.EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view20.Decoration.none),
4990
+ import_view20.EditorView.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view20.Decoration.none),
4991
+ import_view20.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view20.Decoration.none)
4992
+ ]
4993
+ }),
4994
+ image(),
4995
+ table(),
4996
+ adjustChanges(),
4997
+ formattingStyles
4998
+ ];
4999
+ };
5000
+ var linkTooltip = (renderTooltip) => {
5001
+ return (0, import_view25.hoverTooltip)((view, pos, side) => {
5002
+ const syntax = (0, import_language12.syntaxTree)(view.state).resolveInner(pos, side);
5003
+ let link = null;
5004
+ for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
5005
+ link = node.name === "Link" ? node : null;
5006
+ }
5007
+ const url = link && link.getChild("URL");
5008
+ if (!url || !link) {
5009
+ return null;
5010
+ }
5011
+ const urlText = view.state.sliceDoc(url.from, url.to);
5012
+ return {
5013
+ pos: link.from,
5014
+ end: link.to,
5015
+ // NOTE: Forcing above causes the tooltip to flicker.
5016
+ // above: true,
5017
+ create: () => {
5018
+ const el = document.createElement("div");
5019
+ el.className = (0, import_react_ui_theme6.tooltipContent)({});
5020
+ renderTooltip(el, {
5021
+ url: urlText
5022
+ }, view);
5023
+ return {
5024
+ dom: el,
5025
+ offset: {
5026
+ x: 0,
5027
+ y: 4
5028
+ }
5029
+ };
5107
5030
  }
5108
- case "ListItem": {
5109
- const line = state.doc.lineAt(node.from);
5110
- const list = getCurrentListLevel();
5111
- const width = list.type === "OrderedList" ? orderedListIndentationWidth : bulletListIndentationWidth;
5112
- const offset = ((list.level ?? 0) + 1) * width;
5113
- if (node.from === line.to - 1) {
5114
- return false;
5031
+ };
5032
+ }, {
5033
+ // NOTE: 0 = default of 300ms.
5034
+ hoverTime: 1
5035
+ });
5036
+ };
5037
+ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
5038
+ var mention = ({ debug, onSearch }) => {
5039
+ return (0, import_autocomplete5.autocompletion)({
5040
+ // TODO(burdon): Not working.
5041
+ activateOnTyping: true,
5042
+ // activateOnTypingDelay: 100,
5043
+ // selectOnOpen: true,
5044
+ closeOnBlur: !debug,
5045
+ // defaultKeymap: false,
5046
+ icons: false,
5047
+ override: [
5048
+ (context) => {
5049
+ import_log6.log.info("completion context", {
5050
+ context
5051
+ }, {
5052
+ F: __dxlog_file10,
5053
+ L: 27,
5054
+ S: void 0,
5055
+ C: (f, a) => f(...a)
5056
+ });
5057
+ const match = context.matchBefore(/@(\w+)?/);
5058
+ if (!match || match.from === match.to && !context.explicit) {
5059
+ return null;
5115
5060
  }
5116
- deco.add(line.from, line.from, import_view21.Decoration.line({
5117
- class: "cm-list-item",
5118
- attributes: {
5119
- style: `padding-left: ${offset}px; text-indent: -${width}px;`
5120
- }
5121
- }));
5122
- break;
5061
+ return {
5062
+ from: match.from,
5063
+ options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
5064
+ label: `@${value}`
5065
+ }))
5066
+ };
5123
5067
  }
5124
- case "ListMark": {
5125
- const list = getCurrentListLevel();
5126
- const next = tree.resolve(node.to + 1, 1);
5127
- if (next?.name === "TaskMarker") {
5128
- break;
5068
+ ]
5069
+ });
5070
+ };
5071
+ var EditorViewModes = [
5072
+ "preview",
5073
+ "readonly",
5074
+ "source"
5075
+ ];
5076
+ var EditorViewMode = import_effect.Schema.Union(...EditorViewModes.map((mode) => import_effect.Schema.Literal(mode)));
5077
+ var EditorInputModes = [
5078
+ "default",
5079
+ "vim",
5080
+ "vscode"
5081
+ ];
5082
+ var EditorInputMode = import_effect.Schema.Union(...EditorInputModes.map((mode) => import_effect.Schema.Literal(mode)));
5083
+ var editorInputMode = singleValueFacet({});
5084
+ var InputModeExtensions = {
5085
+ default: [],
5086
+ vscode: [
5087
+ // https://github.com/replit/codemirror-vscode-keymap
5088
+ editorInputMode.of({
5089
+ type: "vscode"
5090
+ }),
5091
+ import_view26.keymap.of(import_codemirror_vscode_keymap.vscodeKeymap)
5092
+ ],
5093
+ vim: [
5094
+ // https://github.com/replit/codemirror-vim
5095
+ (0, import_codemirror_vim.vim)(),
5096
+ editorInputMode.of({
5097
+ type: "vim",
5098
+ noTabster: true
5099
+ }),
5100
+ import_view26.keymap.of([
5101
+ {
5102
+ key: "Alt-Escape",
5103
+ run: (view) => {
5104
+ view.dom.parentElement?.focus();
5105
+ return true;
5129
5106
  }
5130
- const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
5131
- const line = state.doc.lineAt(node.from);
5132
- const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
5133
- atomicDeco.add(line.from, to, import_view21.Decoration.replace({
5134
- widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
5135
- }));
5136
- break;
5137
5107
  }
5138
- case "TaskMarker": {
5139
- const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
5140
- const line = state.doc.lineAt(node.from);
5141
- const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
5142
- atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
5143
- break;
5108
+ ])
5109
+ ]
5110
+ };
5111
+ var preview = (options = {}) => {
5112
+ return [
5113
+ // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
5114
+ // "Block decorations may not be specified via plugins"
5115
+ import_state22.StateField.define({
5116
+ create: (state) => buildDecorations3(state, options),
5117
+ update: (_, tr) => buildDecorations3(tr.state, options),
5118
+ provide: (field) => [
5119
+ import_view27.EditorView.decorations.from(field),
5120
+ import_view27.EditorView.atomicRanges.of((view) => view.state.field(field))
5121
+ ]
5122
+ }),
5123
+ import_view27.EditorView.theme({
5124
+ ".cm-preview-block": {
5125
+ marginLeft: "-1rem",
5126
+ marginRight: "-1rem",
5127
+ padding: "1rem",
5128
+ borderRadius: "0.5rem",
5129
+ background: "var(--dx-modalSurface)",
5130
+ border: "1px solid var(--dx-separator)"
5144
5131
  }
5145
- //
5146
- // Blockquote > QuoteMark > Paragraph
5147
- //
5148
- case "Blockquote": {
5149
- const editing = editingRange(state, node, focus2);
5150
- const quoteMark = node.node.getChild("QuoteMark");
5151
- const paragraph = node.node.getChild("Paragraph");
5152
- if (!editing && quoteMark && paragraph) {
5153
- atomicDeco.add(quoteMark.from, paragraph.from, hide);
5154
- }
5155
- for (const block of view.viewportLineBlocks) {
5156
- if (block.to < node.from) {
5157
- continue;
5158
- }
5159
- if (block.from > node.to) {
5160
- break;
5132
+ })
5133
+ ];
5134
+ };
5135
+ var getLinkRef = (state, node) => {
5136
+ const mark = node.getChild("LinkMark");
5137
+ const label = node.getChild("LinkLabel");
5138
+ if (mark && label) {
5139
+ const ref = state.sliceDoc(label.from + 1, label.to - 1);
5140
+ return {
5141
+ suggest: ref.startsWith("?"),
5142
+ block: state.sliceDoc(mark.from, mark.from + 1) === "!",
5143
+ label: state.sliceDoc(mark.to, label.from - 1),
5144
+ ref: ref.startsWith("?") ? ref.slice(1) : ref
5145
+ };
5146
+ }
5147
+ };
5148
+ var buildDecorations3 = (state, options) => {
5149
+ const builder = new import_state22.RangeSetBuilder();
5150
+ (0, import_language13.syntaxTree)(state).iterate({
5151
+ enter: (node) => {
5152
+ switch (node.name) {
5153
+ //
5154
+ // Decoration.
5155
+ // [Label][dxn:echo:123]
5156
+ //
5157
+ case "Link": {
5158
+ const link = getLinkRef(state, node.node);
5159
+ if (link) {
5160
+ builder.add(node.from, node.to, import_view27.Decoration.replace({
5161
+ widget: new PreviewInlineWidget(options, link)
5162
+ }));
5161
5163
  }
5162
- deco.add(block.from, block.from, blockQuote);
5164
+ break;
5163
5165
  }
5164
- break;
5165
- }
5166
- //
5167
- // CommentBlock
5168
- //
5169
- case "CommentBlock": {
5170
- const editing = editingRange(state, node, focus2);
5171
- for (const block of view.viewportLineBlocks) {
5172
- if (block.to < node.from) {
5173
- continue;
5174
- }
5175
- if (block.from > node.to) {
5176
- break;
5177
- }
5178
- const isFirst = block.from <= node.from;
5179
- const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
5180
- deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
5181
- if (!editing && (isFirst || isLast)) {
5182
- atomicDeco.add(block.from, block.to, hide);
5166
+ //
5167
+ // Block widget.
5168
+ // ![Label][dxn:echo:123]
5169
+ //
5170
+ case "Image": {
5171
+ const link = getLinkRef(state, node.node);
5172
+ if (options.renderBlock && link) {
5173
+ builder.add(node.from, node.to, import_view27.Decoration.replace({
5174
+ block: true,
5175
+ // atomic: true,
5176
+ widget: new PreviewBlockWidget(options, link)
5177
+ }));
5183
5178
  }
5179
+ break;
5184
5180
  }
5185
- break;
5186
5181
  }
5187
- //
5188
- // FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
5189
- //
5190
- case "FencedCode": {
5191
- for (const block of view.viewportLineBlocks) {
5192
- if (block.to < node.from) {
5193
- continue;
5194
- }
5195
- if (block.from > node.to) {
5196
- break;
5197
- }
5198
- const first = block.from <= node.from;
5199
- const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
5200
- deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
5201
- const editing = editingRange(state, node, focus2);
5202
- if (!editing && (first || last)) {
5203
- atomicDeco.add(block.from, block.to, hide);
5204
- }
5205
- }
5206
- return false;
5182
+ }
5183
+ });
5184
+ return builder.finish();
5185
+ };
5186
+ var PreviewInlineWidget = class extends import_view27.WidgetType {
5187
+ constructor(_options, _link) {
5188
+ super();
5189
+ this._options = _options;
5190
+ this._link = _link;
5191
+ }
5192
+ // override ignoreEvent() {
5193
+ // return false;
5194
+ // }
5195
+ eq(other) {
5196
+ return this._link.ref === other._link.ref && this._link.label === other._link.label;
5197
+ }
5198
+ toDOM(view) {
5199
+ const root = document.createElement("dx-ref-tag");
5200
+ root.textContent = this._link.label;
5201
+ root.setAttribute("ref", this._link.ref);
5202
+ return root;
5203
+ }
5204
+ };
5205
+ var PreviewBlockWidget = class extends import_view27.WidgetType {
5206
+ constructor(_options, _link) {
5207
+ super();
5208
+ this._options = _options;
5209
+ this._link = _link;
5210
+ }
5211
+ // override ignoreEvent() {
5212
+ // return true;
5213
+ // }
5214
+ eq(other) {
5215
+ return this._link.ref === other._link.ref;
5216
+ }
5217
+ toDOM(view) {
5218
+ const root = document.createElement("div");
5219
+ root.classList.add("cm-preview-block");
5220
+ const handleAction = (action) => {
5221
+ const pos = view.posAtDOM(root);
5222
+ const node = (0, import_language13.syntaxTree)(view.state).resolve(pos + 1).node.parent;
5223
+ if (!node) {
5224
+ return;
5225
+ }
5226
+ const link = getLinkRef(view.state, node);
5227
+ if (link?.ref !== action.link.ref) {
5228
+ return;
5207
5229
  }
5208
- //
5209
- // Link > [LinkMark, URL]
5210
- //
5211
- case "Link": {
5212
- const marks = node.node.getChildren("LinkMark");
5213
- const urlNode = node.node.getChild("URL");
5214
- const editing = editingRange(state, node, focus2);
5215
- if (urlNode && marks.length >= 2) {
5216
- const url = state.sliceDoc(urlNode.from, urlNode.to);
5217
- if (!editing) {
5218
- atomicDeco.add(node.from, marks[0].to, hide);
5219
- }
5220
- deco.add(marks[0].to, marks[1].from, import_view21.Decoration.mark({
5221
- tagName: "a",
5222
- attributes: {
5223
- class: "cm-link",
5224
- href: url,
5225
- rel: "noreferrer",
5226
- target: "_blank"
5230
+ switch (action.type) {
5231
+ // TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
5232
+ // Insert ref text.
5233
+ case "insert": {
5234
+ view.dispatch({
5235
+ changes: {
5236
+ from: node.from,
5237
+ to: node.to,
5238
+ insert: action.target.text
5227
5239
  }
5228
- }));
5229
- if (!editing) {
5230
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? import_view21.Decoration.replace({
5231
- widget: new LinkButton(url, options.renderLinkButton)
5232
- }) : hide);
5233
- }
5240
+ });
5241
+ break;
5234
5242
  }
5235
- break;
5236
- }
5237
- //
5238
- // HR
5239
- //
5240
- case "HorizontalRule": {
5241
- if (!editingRange(state, node, focus2)) {
5242
- deco.add(node.from, node.to, horizontalRule);
5243
+ // Remove ref.
5244
+ case "delete": {
5245
+ view.dispatch({
5246
+ changes: {
5247
+ from: node.from,
5248
+ to: node.to
5249
+ }
5250
+ });
5251
+ break;
5243
5252
  }
5244
- break;
5245
5253
  }
5246
- default: {
5247
- if (autoHideTags.has(node.name)) {
5248
- if (!editingRange(state, node.node.parent, focus2)) {
5249
- atomicDeco.add(node.from, node.to, hide);
5254
+ };
5255
+ this._options.renderBlock(root, {
5256
+ readonly: view.state.readOnly,
5257
+ link: this._link,
5258
+ onAction: handleAction,
5259
+ onLookup: this._options.onLookup
5260
+ }, view);
5261
+ return root;
5262
+ }
5263
+ };
5264
+ var defaultItems = [
5265
+ "hello world!",
5266
+ "this is a test.",
5267
+ "this is [DXOS](https://dxos.org)"
5268
+ ];
5269
+ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
5270
+ let t;
5271
+ let idx = 0;
5272
+ return [
5273
+ import_view28.keymap.of([
5274
+ {
5275
+ // Reset.
5276
+ key: "alt-meta-'",
5277
+ run: (view) => {
5278
+ clearTimeout(t);
5279
+ idx = 0;
5280
+ return true;
5281
+ }
5282
+ },
5283
+ {
5284
+ // Next prompt.
5285
+ // TODO(burdon): Press 1-9 to select prompt?
5286
+ key: "shift-meta-'",
5287
+ run: (view) => {
5288
+ clearTimeout(t);
5289
+ const text = items[idx++];
5290
+ if (idx === items?.length) {
5291
+ idx = 0;
5250
5292
  }
5293
+ let i = 0;
5294
+ const insert = (d = 0) => {
5295
+ t = setTimeout(() => {
5296
+ const pos = view.state.selection.main.head;
5297
+ view.dispatch({
5298
+ changes: {
5299
+ from: pos,
5300
+ insert: text[i++]
5301
+ },
5302
+ selection: {
5303
+ anchor: pos + 1
5304
+ }
5305
+ });
5306
+ if (i < text.length) {
5307
+ insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
5308
+ }
5309
+ }, d);
5310
+ };
5311
+ insert();
5312
+ return true;
5251
5313
  }
5252
5314
  }
5315
+ ])
5316
+ ];
5317
+ };
5318
+ var createBlockGroupAction = (value) => createEditorActionGroup("block", {
5319
+ variant: "toggleGroup",
5320
+ selectCardinality: "single",
5321
+ value
5322
+ });
5323
+ var createBlockActions = (value, getView, blankLine) => Object.entries({
5324
+ blockquote: "ph--quotes--regular",
5325
+ codeblock: "ph--code-block--regular",
5326
+ table: "ph--table--regular"
5327
+ }).map(([type, icon]) => {
5328
+ const checked = type === value;
5329
+ return createEditorAction(type, () => {
5330
+ const view = getView();
5331
+ if (!view) {
5332
+ return;
5253
5333
  }
5254
- };
5255
- const leaveNode = (node) => {
5256
- switch (node.name) {
5257
- case "BulletList":
5258
- case "OrderedList": {
5259
- leaveList();
5334
+ switch (type) {
5335
+ case "blockquote":
5336
+ checked ? removeBlockquote(view) : addBlockquote(view);
5337
+ break;
5338
+ case "codeblock":
5339
+ checked ? removeCodeblock(view) : addCodeblock(view);
5340
+ break;
5341
+ case "table":
5342
+ insertTable(view);
5260
5343
  break;
5261
- }
5262
- }
5263
- };
5264
- const tree = (0, import_language8.syntaxTree)(state);
5265
- if (options.numberedHeadings?.from === void 0) {
5266
- for (const { from, to } of view.visibleRanges) {
5267
- tree.iterate({
5268
- from,
5269
- to,
5270
- enter: wrapWithCatch(enterNode),
5271
- leave: wrapWithCatch(leaveNode)
5272
- });
5273
5344
  }
5274
- } else {
5275
- tree.iterate({
5276
- enter: wrapWithCatch(enterNode),
5277
- leave: wrapWithCatch(leaveNode)
5278
- });
5279
- }
5345
+ }, {
5346
+ checked,
5347
+ ...type === "table" && {
5348
+ disabled: !!blankLine
5349
+ },
5350
+ icon
5351
+ });
5352
+ });
5353
+ var createBlocks = (state, getView) => {
5354
+ const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
5355
+ const blockGroupAction = createBlockGroupAction(value);
5356
+ const blockActions = createBlockActions(value, getView, state.blankLine);
5280
5357
  return {
5281
- deco: deco.finish(),
5282
- atomicDeco: atomicDeco.finish()
5358
+ nodes: [
5359
+ blockGroupAction,
5360
+ ...blockActions
5361
+ ],
5362
+ edges: [
5363
+ {
5364
+ source: "root",
5365
+ target: "block"
5366
+ },
5367
+ ...blockActions.map(({ id }) => ({
5368
+ source: blockGroupAction.id,
5369
+ target: id
5370
+ }))
5371
+ ]
5283
5372
  };
5284
5373
  };
5285
- var forceUpdate = import_state18.StateEffect.define();
5286
- var decorateMarkdown = (options = {}) => {
5287
- return [
5288
- import_view21.ViewPlugin.fromClass(class {
5289
- constructor(view) {
5290
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
5291
- }
5292
- update(update2) {
5293
- if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
5294
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
5295
- this.clearUpdate();
5296
- } else if (update2.selectionSet) {
5297
- this.scheduleUpdate(update2.view);
5298
- }
5299
- }
5300
- // Defer update in case moving through the document.
5301
- scheduleUpdate(view) {
5302
- this.clearUpdate();
5303
- this.pendingUpdate = setTimeout(() => {
5304
- view.dispatch({
5305
- effects: forceUpdate.of(null)
5306
- });
5307
- }, options.selectionChangeDelay);
5308
- }
5309
- clearUpdate() {
5310
- if (this.pendingUpdate) {
5311
- clearTimeout(this.pendingUpdate);
5312
- this.pendingUpdate = void 0;
5313
- }
5314
- }
5315
- destroy() {
5316
- this.clearUpdate();
5374
+ var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
5375
+ var createCommentAction = (label, getView) => createEditorAction("comment", () => createComment(getView()), {
5376
+ testId: "editor.toolbar.comment",
5377
+ icon: "ph--chat-text--regular",
5378
+ label
5379
+ });
5380
+ var createComment2 = (state, getView) => ({
5381
+ nodes: [
5382
+ createCommentAction([
5383
+ commentLabel(state.comment, state.selection),
5384
+ {
5385
+ ns: translationKey
5317
5386
  }
5318
- }, {
5319
- provide: (plugin) => [
5320
- import_view21.EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view21.Decoration.none),
5321
- import_view21.EditorView.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? import_view21.Decoration.none),
5322
- import_view21.EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? import_view21.Decoration.none)
5323
- ]
5324
- }),
5325
- image(),
5326
- table(),
5327
- adjustChanges(),
5328
- formattingStyles
5329
- ];
5387
+ ], getView)
5388
+ ],
5389
+ edges: [
5390
+ {
5391
+ source: "root",
5392
+ target: "comment"
5393
+ }
5394
+ ]
5395
+ });
5396
+ var formats = {
5397
+ strong: "ph--text-b--regular",
5398
+ emphasis: "ph--text-italic--regular",
5399
+ strikethrough: "ph--text-strikethrough--regular",
5400
+ code: "ph--code--regular",
5401
+ link: "ph--link--regular"
5330
5402
  };
5331
- var linkTooltip = (renderTooltip) => {
5332
- return (0, import_view26.hoverTooltip)((view, pos, side) => {
5333
- const syntax = (0, import_language12.syntaxTree)(view.state).resolveInner(pos, side);
5334
- let link = null;
5335
- for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
5336
- link = node.name === "Link" ? node : null;
5403
+ var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
5404
+ variant: "toggleGroup",
5405
+ selectCardinality: "multiple",
5406
+ value: Object.keys(formats).filter((key) => !!formatting[key])
5407
+ });
5408
+ var createFormattingActions = (formatting, getView) => Object.entries(formats).map(([type, icon]) => {
5409
+ const checked = !!formatting[type];
5410
+ return createEditorAction(type, () => {
5411
+ const view = getView();
5412
+ if (!view) {
5413
+ return;
5337
5414
  }
5338
- const url = link && link.getChild("URL");
5339
- if (!url || !link) {
5340
- return null;
5415
+ if (type === "link") {
5416
+ checked ? removeLink(view) : addLink()(view);
5417
+ return;
5341
5418
  }
5342
- const urlText = view.state.sliceDoc(url.from, url.to);
5343
- return {
5344
- pos: link.from,
5345
- end: link.to,
5346
- // NOTE: Forcing above causes the tooltip to flicker.
5347
- // above: true,
5348
- create: () => {
5349
- const el = document.createElement("div");
5350
- el.className = (0, import_react_ui_theme7.tooltipContent)({});
5351
- renderTooltip(el, {
5352
- url: urlText
5353
- }, view);
5354
- return {
5355
- dom: el,
5356
- offset: {
5357
- x: 0,
5358
- y: 4
5359
- }
5360
- };
5361
- }
5362
- };
5419
+ const inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
5420
+ setStyle(inlineType, !checked)(view);
5363
5421
  }, {
5364
- // NOTE: 0 = default of 300ms.
5365
- hoverTime: 1
5422
+ checked,
5423
+ icon
5366
5424
  });
5367
- };
5368
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
5369
- var mention = ({ debug, onSearch }) => {
5370
- return (0, import_autocomplete5.autocompletion)({
5371
- // TODO(burdon): Not working.
5372
- activateOnTyping: true,
5373
- // activateOnTypingDelay: 100,
5374
- // selectOnOpen: true,
5375
- closeOnBlur: !debug,
5376
- // defaultKeymap: false,
5377
- icons: false,
5378
- override: [
5379
- (context) => {
5380
- import_log6.log.info("completion context", {
5381
- context
5382
- }, {
5383
- F: __dxlog_file10,
5384
- L: 27,
5385
- S: void 0,
5386
- C: (f, a) => f(...a)
5387
- });
5388
- const match = context.matchBefore(/@(\w+)?/);
5389
- if (!match || match.from === match.to && !context.explicit) {
5390
- return null;
5391
- }
5392
- return {
5393
- from: match.from,
5394
- options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
5395
- label: `@${value}`
5396
- }))
5397
- };
5398
- }
5425
+ });
5426
+ var createFormatting = (state, getView) => {
5427
+ const formattingGroupAction = createFormattingGroup(state);
5428
+ const formattingActions = createFormattingActions(state, getView);
5429
+ return {
5430
+ nodes: [
5431
+ formattingGroupAction,
5432
+ ...formattingActions
5433
+ ],
5434
+ edges: [
5435
+ {
5436
+ source: "root",
5437
+ target: "formatting"
5438
+ },
5439
+ ...formattingActions.map(({ id }) => ({
5440
+ source: formattingGroupAction.id,
5441
+ target: id
5442
+ }))
5399
5443
  ]
5400
- });
5444
+ };
5401
5445
  };
5402
- var EditorViewModes = [
5403
- "preview",
5404
- "readonly",
5405
- "source"
5406
- ];
5407
- var EditorViewMode = import_effect.Schema.Union(...EditorViewModes.map((mode) => import_effect.Schema.Literal(mode)));
5408
- var EditorInputModes = [
5409
- "default",
5410
- "vim",
5411
- "vscode"
5412
- ];
5413
- var EditorInputMode = import_effect.Schema.Union(...EditorInputModes.map((mode) => import_effect.Schema.Literal(mode)));
5414
- var editorInputMode = singleValueFacet({});
5415
- var InputModeExtensions = {
5416
- default: [],
5417
- vscode: [
5418
- // https://github.com/replit/codemirror-vscode-keymap
5419
- editorInputMode.of({
5420
- type: "vscode"
5421
- }),
5422
- import_view27.keymap.of(import_codemirror_vscode_keymap.vscodeKeymap)
5423
- ],
5424
- vim: [
5425
- // https://github.com/replit/codemirror-vim
5426
- (0, import_codemirror_vim.vim)(),
5427
- editorInputMode.of({
5428
- type: "vim",
5429
- noTabster: true
5430
- }),
5431
- import_view27.keymap.of([
5446
+ var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
5447
+ variant: "dropdownMenu",
5448
+ applyActive: true,
5449
+ selectCardinality: "single",
5450
+ value
5451
+ }, "ph--text-h--regular");
5452
+ var createHeadingActions = (getView) => Object.entries({
5453
+ "0": "ph--paragraph--regular",
5454
+ "1": "ph--text-h-one--regular",
5455
+ "2": "ph--text-h-two--regular",
5456
+ "3": "ph--text-h-three--regular",
5457
+ "4": "ph--text-h-four--regular",
5458
+ "5": "ph--text-h-five--regular",
5459
+ "6": "ph--text-h-six--regular"
5460
+ }).map(([levelStr, icon]) => {
5461
+ const level = parseInt(levelStr);
5462
+ return createEditorAction(`heading--${levelStr}`, () => setHeading(level)(getView()), {
5463
+ label: [
5464
+ "heading level label",
5432
5465
  {
5433
- key: "Alt-Escape",
5434
- run: (view) => {
5435
- view.dom.parentElement?.focus();
5436
- return true;
5437
- }
5466
+ count: level,
5467
+ ns: translationKey
5438
5468
  }
5439
- ])
5440
- ]
5469
+ ],
5470
+ icon
5471
+ });
5472
+ });
5473
+ var computeHeadingValue = (state) => {
5474
+ const blockType = state ? state.blockType : "paragraph";
5475
+ const header = blockType && /heading(\d)/.exec(blockType);
5476
+ return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
5441
5477
  };
5442
- var preview = (options = {}) => {
5443
- return [
5444
- // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
5445
- // "Block decorations may not be specified via plugins"
5446
- import_state22.StateField.define({
5447
- create: (state) => buildDecorations3(state, options),
5448
- update: (_, tr) => buildDecorations3(tr.state, options),
5449
- provide: (field) => [
5450
- import_view28.EditorView.decorations.from(field),
5451
- import_view28.EditorView.atomicRanges.of((view) => view.state.field(field))
5452
- ]
5453
- }),
5454
- import_view28.EditorView.theme({
5455
- ".cm-preview-block": {
5456
- marginLeft: "-1rem",
5457
- marginRight: "-1rem",
5458
- padding: "1rem",
5459
- borderRadius: "0.5rem",
5460
- background: "var(--dx-modalSurface)",
5461
- border: "1px solid var(--dx-separator)"
5462
- }
5463
- })
5464
- ];
5478
+ var createHeadings = (state, getView) => {
5479
+ const headingValue = computeHeadingValue(state);
5480
+ const headingGroupAction = createHeadingGroupAction(headingValue);
5481
+ const headingActions = createHeadingActions(getView);
5482
+ return {
5483
+ nodes: [
5484
+ headingGroupAction,
5485
+ ...headingActions
5486
+ ],
5487
+ edges: [
5488
+ {
5489
+ source: "root",
5490
+ target: "heading"
5491
+ },
5492
+ ...headingActions.map(({ id }) => ({
5493
+ source: headingGroupAction.id,
5494
+ target: id
5495
+ }))
5496
+ ]
5497
+ };
5465
5498
  };
5466
- var getLinkRef = (state, node) => {
5467
- const mark = node.getChild("LinkMark");
5468
- const label = node.getChild("LinkLabel");
5469
- if (mark && label) {
5470
- const ref = state.sliceDoc(label.from + 1, label.to - 1);
5471
- return {
5472
- suggest: ref.startsWith("?"),
5473
- block: state.sliceDoc(mark.from, mark.from + 1) === "!",
5474
- label: state.sliceDoc(mark.to, label.from - 1),
5475
- ref: ref.startsWith("?") ? ref.slice(1) : ref
5476
- };
5477
- }
5499
+ var createImageUploadAction = (onImageUpload) => createEditorAction("image", onImageUpload, {
5500
+ testId: "editor.toolbar.image",
5501
+ icon: "ph--image-square--regular"
5502
+ });
5503
+ var createImageUpload = (onImageUpload) => ({
5504
+ nodes: [
5505
+ createImageUploadAction(onImageUpload)
5506
+ ],
5507
+ edges: [
5508
+ {
5509
+ source: "root",
5510
+ target: "image"
5511
+ }
5512
+ ]
5513
+ });
5514
+ var listStyles = {
5515
+ bullet: "ph--list-bullets--regular",
5516
+ ordered: "ph--list-numbers--regular",
5517
+ task: "ph--list-checks--regular"
5478
5518
  };
5479
- var buildDecorations3 = (state, options) => {
5480
- const builder = new import_state22.RangeSetBuilder();
5481
- (0, import_language13.syntaxTree)(state).iterate({
5482
- enter: (node) => {
5483
- switch (node.name) {
5484
- //
5485
- // Decoration.
5486
- // [Label][dxn:echo:123]
5487
- //
5488
- case "Link": {
5489
- const link = getLinkRef(state, node.node);
5490
- if (link) {
5491
- builder.add(node.from, node.to, import_view28.Decoration.replace({
5492
- widget: new PreviewInlineWidget(options, link)
5493
- }));
5494
- }
5495
- break;
5496
- }
5497
- //
5498
- // Block widget.
5499
- // ![Label][dxn:echo:123]
5500
- //
5501
- case "Image": {
5502
- const link = getLinkRef(state, node.node);
5503
- if (options.renderBlock && link) {
5504
- builder.add(node.from, node.to, import_view28.Decoration.replace({
5505
- block: true,
5506
- // atomic: true,
5507
- widget: new PreviewBlockWidget(options, link)
5508
- }));
5509
- }
5510
- break;
5511
- }
5512
- }
5519
+ var createListGroupAction = (value) => createEditorActionGroup("list", {
5520
+ variant: "toggleGroup",
5521
+ selectCardinality: "single",
5522
+ value
5523
+ });
5524
+ var createListActions = (value, getView) => Object.entries(listStyles).map(([listStyle, icon]) => {
5525
+ const checked = value === listStyle;
5526
+ return createEditorAction(`list-${listStyle}`, () => {
5527
+ const view = getView();
5528
+ if (!view) {
5529
+ return;
5513
5530
  }
5531
+ const listType = listStyle === "ordered" ? List.Ordered : listStyle === "bullet" ? List.Bullet : List.Task;
5532
+ if (checked) {
5533
+ removeList(listType)(view);
5534
+ } else {
5535
+ addList(listType)(view);
5536
+ }
5537
+ }, {
5538
+ checked,
5539
+ icon
5514
5540
  });
5515
- return builder.finish();
5541
+ });
5542
+ var createLists = (state, getView) => {
5543
+ const value = state.listStyle ?? "";
5544
+ const listGroupAction = createListGroupAction(value);
5545
+ const listActionsMap = createListActions(value, getView);
5546
+ return {
5547
+ nodes: [
5548
+ listGroupAction,
5549
+ ...listActionsMap
5550
+ ],
5551
+ edges: [
5552
+ {
5553
+ source: "root",
5554
+ target: "list"
5555
+ },
5556
+ ...listActionsMap.map(({ id }) => ({
5557
+ source: listGroupAction.id,
5558
+ target: id
5559
+ }))
5560
+ ]
5561
+ };
5516
5562
  };
5517
- var PreviewInlineWidget = class extends import_view28.WidgetType {
5518
- constructor(_options, _link) {
5519
- super();
5520
- this._options = _options;
5521
- this._link = _link;
5563
+ var createSearchAction = (getView) => createEditorAction("search", () => (0, import_search2.openSearchPanel)(getView()), {
5564
+ testId: "editor.toolbar.search",
5565
+ icon: "ph--magnifying-glass--regular"
5566
+ });
5567
+ var createSearch = (getView) => ({
5568
+ nodes: [
5569
+ createSearchAction(getView)
5570
+ ],
5571
+ edges: [
5572
+ {
5573
+ source: "root",
5574
+ target: "search"
5575
+ }
5576
+ ]
5577
+ });
5578
+ var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
5579
+ variant: "dropdownMenu",
5580
+ applyActive: true,
5581
+ selectCardinality: "single",
5582
+ value
5583
+ }, "ph--eye--regular");
5584
+ var createViewModeActions = (value, onViewModeChange) => Object.entries({
5585
+ preview: "ph--eye--regular",
5586
+ source: "ph--pencil-simple--regular",
5587
+ readonly: "ph--pencil-slash--regular"
5588
+ }).map(([viewMode, icon]) => {
5589
+ const checked = viewMode === value;
5590
+ return createEditorAction(`view-mode--${viewMode}`, () => onViewModeChange(viewMode), {
5591
+ label: [
5592
+ `${viewMode} mode label`,
5593
+ {
5594
+ ns: translationKey
5595
+ }
5596
+ ],
5597
+ checked,
5598
+ icon
5599
+ });
5600
+ });
5601
+ var createViewMode = (state, onViewModeChange) => {
5602
+ const value = state.viewMode ?? "source";
5603
+ const viewModeGroupAction = createViewModeGroupAction(value);
5604
+ const viewModeActions = createViewModeActions(value, onViewModeChange);
5605
+ return {
5606
+ nodes: [
5607
+ viewModeGroupAction,
5608
+ ...viewModeActions
5609
+ ],
5610
+ edges: [
5611
+ {
5612
+ source: "root",
5613
+ target: "viewMode"
5614
+ },
5615
+ ...viewModeActions.map(({ id }) => ({
5616
+ source: viewModeGroupAction.id,
5617
+ target: id
5618
+ }))
5619
+ ]
5620
+ };
5621
+ };
5622
+ var margin = "!mt-[1rem]";
5623
+ var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
5624
+ var editorContent = (0, import_react_ui_theme7.mx)(margin, editorWidth);
5625
+ var editorFullWidth = (0, import_react_ui_theme7.mx)(margin);
5626
+ var editorGutter = import_view29.EditorView.theme({
5627
+ // Match margin from content.
5628
+ // Gutter = 2rem + 1rem margin.
5629
+ ".cm-gutters": {
5630
+ marginTop: "1rem",
5631
+ paddingRight: "1rem"
5522
5632
  }
5523
- // override ignoreEvent() {
5524
- // return false;
5525
- // }
5526
- eq(other) {
5527
- return this._link.ref === other._link.ref && this._link.label === other._link.label;
5633
+ });
5634
+ var editorMonospace = import_view29.EditorView.theme({
5635
+ ".cm-content": {
5636
+ fontFamily: fontMono
5528
5637
  }
5529
- toDOM(view) {
5530
- const root = document.createElement("dx-ref-tag");
5531
- root.textContent = this._link.label;
5532
- root.setAttribute("ref", this._link.ref);
5533
- return root;
5638
+ });
5639
+ var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5640
+ var stackItemContentEditorClassNames = (role) => (0, import_react_ui_theme7.mx)("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
5641
+ var stackItemContentToolbarClassNames = (role) => (0, import_react_ui_theme7.mx)("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
5642
+ var createToolbar = ({ getView, state, customActions, ...features }) => {
5643
+ const nodes = [];
5644
+ const edges = [];
5645
+ if (features.headings ?? true) {
5646
+ const headings2 = createHeadings(state, getView);
5647
+ nodes.push(...headings2.nodes);
5648
+ edges.push(...headings2.edges);
5534
5649
  }
5535
- };
5536
- var PreviewBlockWidget = class extends import_view28.WidgetType {
5537
- constructor(_options, _link) {
5538
- super();
5539
- this._options = _options;
5540
- this._link = _link;
5650
+ if (features.formatting ?? true) {
5651
+ const formatting = createFormatting(state, getView);
5652
+ nodes.push(...formatting.nodes);
5653
+ edges.push(...formatting.edges);
5541
5654
  }
5542
- // override ignoreEvent() {
5543
- // return true;
5544
- // }
5545
- eq(other) {
5546
- return this._link.ref === other._link.ref;
5655
+ if (features.lists ?? true) {
5656
+ const lists = createLists(state, getView);
5657
+ nodes.push(...lists.nodes);
5658
+ edges.push(...lists.edges);
5547
5659
  }
5548
- toDOM(view) {
5549
- const root = document.createElement("div");
5550
- root.classList.add("cm-preview-block");
5551
- const handleAction = (action) => {
5552
- const pos = view.posAtDOM(root);
5553
- const node = (0, import_language13.syntaxTree)(view.state).resolve(pos + 1).node.parent;
5554
- if (!node) {
5555
- return;
5556
- }
5557
- const link = getLinkRef(view.state, node);
5558
- if (link?.ref !== action.link.ref) {
5559
- return;
5560
- }
5561
- switch (action.type) {
5562
- // TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
5563
- // Insert ref text.
5564
- case "insert": {
5565
- view.dispatch({
5566
- changes: {
5567
- from: node.from,
5568
- to: node.to,
5569
- insert: action.target.text
5570
- }
5571
- });
5572
- break;
5573
- }
5574
- // Remove ref.
5575
- case "delete": {
5576
- view.dispatch({
5577
- changes: {
5578
- from: node.from,
5579
- to: node.to
5580
- }
5581
- });
5582
- break;
5583
- }
5584
- }
5585
- };
5586
- this._options.renderBlock(root, {
5587
- readonly: view.state.readOnly,
5588
- link: this._link,
5589
- onAction: handleAction,
5590
- onLookup: this._options.onLookup
5591
- }, view);
5592
- return root;
5660
+ if (features.blocks ?? true) {
5661
+ const blocks = createBlocks(state, getView);
5662
+ nodes.push(...blocks.nodes);
5663
+ edges.push(...blocks.edges);
5593
5664
  }
5665
+ if (features.image) {
5666
+ const image2 = createImageUpload(features.image);
5667
+ nodes.push(...image2.nodes);
5668
+ edges.push(...image2.edges);
5669
+ }
5670
+ if (customActions) {
5671
+ const custom = customActions();
5672
+ nodes.push(...custom.nodes);
5673
+ edges.push(...custom.edges);
5674
+ }
5675
+ const editorToolbarGap = (0, import_react_ui_menu.createGapSeparator)();
5676
+ nodes.push(...editorToolbarGap.nodes);
5677
+ edges.push(...editorToolbarGap.edges);
5678
+ if (features.comment) {
5679
+ const comment = createComment2(state, getView);
5680
+ nodes.push(...comment.nodes);
5681
+ edges.push(...comment.edges);
5682
+ }
5683
+ if (features.search ?? true) {
5684
+ const search = createSearch(getView);
5685
+ nodes.push(...search.nodes);
5686
+ edges.push(...search.edges);
5687
+ }
5688
+ if (features.viewMode) {
5689
+ const viewMode = createViewMode(state, features.viewMode);
5690
+ nodes.push(...viewMode.nodes);
5691
+ edges.push(...viewMode.edges);
5692
+ }
5693
+ return {
5694
+ nodes,
5695
+ edges
5696
+ };
5594
5697
  };
5595
- var defaultItems = [
5596
- "hello world!",
5597
- "this is a test.",
5598
- "this is [DXOS](https://dxos.org)"
5599
- ];
5600
- var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
5601
- let t;
5602
- let idx = 0;
5603
- return [
5604
- import_view29.keymap.of([
5605
- {
5606
- // Reset.
5607
- key: "alt-meta-'",
5608
- run: (view) => {
5609
- clearTimeout(t);
5610
- idx = 0;
5611
- return true;
5612
- }
5613
- },
5614
- {
5615
- // Next prompt.
5616
- // TODO(burdon): Press 1-9 to select prompt?
5617
- key: "shift-meta-'",
5618
- run: (view) => {
5619
- clearTimeout(t);
5620
- const text = items[idx++];
5621
- if (idx === items?.length) {
5622
- idx = 0;
5623
- }
5624
- let i = 0;
5625
- const insert = (d = 0) => {
5626
- t = setTimeout(() => {
5627
- const pos = view.state.selection.main.head;
5628
- view.dispatch({
5629
- changes: {
5630
- from: pos,
5631
- insert: text[i++]
5632
- },
5633
- selection: {
5634
- anchor: pos + 1
5635
- }
5636
- });
5637
- if (i < text.length) {
5638
- insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
5639
- }
5640
- }, d);
5641
- };
5642
- insert();
5643
- return true;
5644
- }
5645
- }
5646
- ])
5647
- ];
5648
- };
5649
- var useActionHandler = (view) => {
5650
- return (0, import_react7.useCallback)((action) => view && processEditorPayload(view, action.properties), [
5651
- view
5698
+ var useEditorToolbarActionGraph = (props) => {
5699
+ const menuCreator = (0, import_react.useCallback)(() => createToolbar(props), [
5700
+ props
5652
5701
  ]);
5702
+ return (0, import_react_ui_menu.useMenuActions)(menuCreator);
5653
5703
  };
5704
+ var EditorToolbar = /* @__PURE__ */ (0, import_react.memo)(({ classNames, attendableId, role, ...props }) => {
5705
+ const menuProps = useEditorToolbarActionGraph(props);
5706
+ return /* @__PURE__ */ import_react.default.createElement("div", {
5707
+ role: "none",
5708
+ className: stackItemContentToolbarClassNames(role)
5709
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.ElevationProvider, {
5710
+ elevation: role === "section" ? "positioned" : "base"
5711
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.MenuProvider, {
5712
+ ...menuProps,
5713
+ attendableId
5714
+ }, /* @__PURE__ */ import_react.default.createElement(import_react_ui_menu.ToolbarMenu, {
5715
+ classNames: [
5716
+ import_react_ui_theme.textBlockWidth,
5717
+ "!bg-transparent",
5718
+ classNames
5719
+ ]
5720
+ }))));
5721
+ });
5654
5722
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5655
5723
  var instanceCount = 0;
5656
5724
  var useTextEditor = (props = {}, deps = []) => {
5657
- const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = (0, import_react8.useMemo)(() => (0, import_util5.getProviderValue)(props), deps ?? []);
5658
- const [instanceId] = (0, import_react8.useState)(() => `text-editor-${++instanceCount}`);
5659
- const [view, setView] = (0, import_react8.useState)();
5660
- const parentRef = (0, import_react8.useRef)(null);
5661
- (0, import_react8.useEffect)(() => {
5725
+ const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = (0, import_react7.useMemo)(() => (0, import_util5.getProviderValue)(props), deps ?? []);
5726
+ const [instanceId] = (0, import_react7.useState)(() => `text-editor-${++instanceCount}`);
5727
+ const [view, setView] = (0, import_react7.useState)();
5728
+ const parentRef = (0, import_react7.useRef)(null);
5729
+ (0, import_react7.useEffect)(() => {
5662
5730
  let view2;
5663
5731
  if (parentRef.current) {
5664
5732
  (0, import_log7.log)("create", {
@@ -5732,7 +5800,7 @@ var useTextEditor = (props = {}, deps = []) => {
5732
5800
  view2?.destroy();
5733
5801
  };
5734
5802
  }, deps);
5735
- (0, import_react8.useEffect)(() => {
5803
+ (0, import_react7.useEffect)(() => {
5736
5804
  if (view) {
5737
5805
  if (scrollTo || selection) {
5738
5806
  if (selection && selection.anchor > view.state.doc.length) {
@@ -5759,7 +5827,7 @@ var useTextEditor = (props = {}, deps = []) => {
5759
5827
  scrollTo,
5760
5828
  selection
5761
5829
  ]);
5762
- (0, import_react8.useEffect)(() => {
5830
+ (0, import_react7.useEffect)(() => {
5763
5831
  if (view && autoFocus) {
5764
5832
  view.focus();
5765
5833
  }
@@ -5773,7 +5841,7 @@ var useTextEditor = (props = {}, deps = []) => {
5773
5841
  Escape: view?.state.facet(editorInputMode).noTabster
5774
5842
  }
5775
5843
  });
5776
- const handleKeyUp = (0, import_react8.useCallback)((event) => {
5844
+ const handleKeyUp = (0, import_react7.useCallback)((event) => {
5777
5845
  const { key, target, currentTarget } = event;
5778
5846
  if (target === currentTarget) {
5779
5847
  switch (key) {
@@ -5911,7 +5979,6 @@ var useTextEditor = (props = {}, deps = []) => {
5911
5979
  toggleStyle,
5912
5980
  translations,
5913
5981
  typewriter,
5914
- useActionHandler,
5915
5982
  useCommentClickListener,
5916
5983
  useCommentState,
5917
5984
  useComments,