@dxos/react-ui-editor 0.4.2-main.da7c8c5 → 0.4.2-main.ec5936e

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 (49) hide show
  1. package/dist/lib/browser/index.mjs +440 -326
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +24 -1
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  7. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +20 -0
  8. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/TextEditor/automerge.stories.d.ts +22 -2
  10. package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/TextEditor/hooks.stories.d.ts +20 -0
  12. package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -1
  13. package/dist/types/src/components/Toolbar/Toolbar.d.ts +7 -10
  14. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  15. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +23 -6
  16. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  17. package/dist/types/src/extensions/annotations.d.ts +6 -0
  18. package/dist/types/src/extensions/annotations.d.ts.map +1 -0
  19. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  20. package/dist/types/src/extensions/automerge/{semaphore.d.ts → sync.d.ts} +6 -5
  21. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -0
  22. package/dist/types/src/extensions/index.d.ts +1 -0
  23. package/dist/types/src/extensions/index.d.ts.map +1 -1
  24. package/dist/types/src/index.d.ts +1 -1
  25. package/dist/types/src/index.d.ts.map +1 -1
  26. package/dist/types/src/styles/index.d.ts +1 -0
  27. package/dist/types/src/styles/index.d.ts.map +1 -1
  28. package/dist/types/src/styles/layout.d.ts +2 -0
  29. package/dist/types/src/styles/layout.d.ts.map +1 -0
  30. package/dist/types/src/translations.d.ts +20 -0
  31. package/dist/types/src/translations.d.ts.map +1 -0
  32. package/package.json +24 -24
  33. package/src/components/TextEditor/MarkdownEditor.stories.tsx +20 -10
  34. package/src/components/TextEditor/TextEditor.stories.tsx +11 -8
  35. package/src/components/TextEditor/TextEditor.tsx +4 -3
  36. package/src/components/TextEditor/automerge.stories.tsx +40 -50
  37. package/src/components/TextEditor/hooks.stories.tsx +15 -16
  38. package/src/components/Toolbar/Toolbar.stories.tsx +17 -13
  39. package/src/components/Toolbar/Toolbar.tsx +156 -129
  40. package/src/extensions/annotations.ts +78 -0
  41. package/src/extensions/automerge/automerge.ts +5 -21
  42. package/src/extensions/automerge/{semaphore.ts → sync.ts} +32 -34
  43. package/src/extensions/index.ts +1 -0
  44. package/src/hooks/useTextModel.ts +5 -5
  45. package/src/index.ts +1 -1
  46. package/src/styles/index.ts +1 -0
  47. package/src/styles/layout.ts +6 -0
  48. package/src/translations.ts +25 -0
  49. package/dist/types/src/extensions/automerge/semaphore.d.ts.map +0 -1
@@ -8,14 +8,114 @@ import { tags as tags2 } from "@lezer/highlight";
8
8
 
9
9
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
10
10
  import { EditorState as EditorState2 } from "@codemirror/state";
11
- import { EditorView as EditorView14 } from "@codemirror/view";
11
+ import { EditorView as EditorView15 } from "@codemirror/view";
12
12
  import { vim } from "@replit/codemirror-vim";
13
13
  import defaultsDeep2 from "lodash.defaultsdeep";
14
14
  import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
15
15
  import { log as log2 } from "@dxos/log";
16
16
  import { useThemeContext } from "@dxos/react-ui";
17
- import { focusRing, mx as mx3 } from "@dxos/react-ui-theme";
18
- import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
17
+ import { focusRing } from "@dxos/react-ui-theme";
18
+ import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
19
+
20
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
21
+ import { StateField } from "@codemirror/state";
22
+ import { Decoration, EditorView } from "@codemirror/view";
23
+ import { isNotFalsy } from "@dxos/util";
24
+
25
+ // packages/ui/react-ui-editor/src/extensions/cursor.ts
26
+ import { Facet } from "@codemirror/state";
27
+ var defaultCursorConverter = {
28
+ toCursor: (position) => position.toString(),
29
+ fromCursor: (cursor) => parseInt(cursor)
30
+ };
31
+ var Cursor = class _Cursor {
32
+ static {
33
+ this.converter = Facet.define({
34
+ combine: (providers) => providers[0] ?? defaultCursorConverter
35
+ });
36
+ }
37
+ static {
38
+ this.getCursorFromRange = (state, range) => {
39
+ const cursorConverter2 = state.facet(_Cursor.converter);
40
+ const from = cursorConverter2.toCursor(range.from);
41
+ const to = cursorConverter2.toCursor(range.to, -1);
42
+ return [
43
+ from,
44
+ to
45
+ ].join(":");
46
+ };
47
+ }
48
+ static {
49
+ this.getRangeFromCursor = (state, cursor) => {
50
+ const cursorConverter2 = state.facet(_Cursor.converter);
51
+ const parts = cursor.split(":");
52
+ const from = cursorConverter2.fromCursor(parts[0]);
53
+ const to = cursorConverter2.fromCursor(parts[1]);
54
+ return from !== void 0 && to !== void 0 ? {
55
+ from,
56
+ to
57
+ } : void 0;
58
+ };
59
+ }
60
+ };
61
+
62
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
63
+ var annotationMark = Decoration.mark({
64
+ class: "cm-annotation"
65
+ });
66
+ var annotations = (options = {}) => {
67
+ const match = (state) => {
68
+ const annotations2 = [];
69
+ const text = state.doc.toString();
70
+ if (options.match) {
71
+ const matches = text.matchAll(options.match);
72
+ for (const match2 of matches) {
73
+ const from = match2.index;
74
+ const to = from + match2[0].length;
75
+ const cursor = Cursor.getCursorFromRange(state, {
76
+ from,
77
+ to
78
+ });
79
+ annotations2.push({
80
+ cursor
81
+ });
82
+ }
83
+ }
84
+ return annotations2;
85
+ };
86
+ const annotationsState = StateField.define({
87
+ create: (state) => {
88
+ return match(state);
89
+ },
90
+ update: (value, tr) => {
91
+ if (!tr.changes.empty) {
92
+ return match(tr.state);
93
+ }
94
+ return value;
95
+ }
96
+ });
97
+ return [
98
+ annotationsState,
99
+ EditorView.decorations.compute([
100
+ annotationsState
101
+ ], (state) => {
102
+ const annotations2 = state.field(annotationsState);
103
+ const decorations = annotations2.map((annotation) => {
104
+ const range = Cursor.getRangeFromCursor(state, annotation.cursor);
105
+ return range && annotationMark.range(range.from, range.to);
106
+ }).filter(isNotFalsy);
107
+ return Decoration.set(decorations);
108
+ }),
109
+ styles
110
+ ];
111
+ };
112
+ var styles = EditorView.baseTheme({
113
+ ".cm-annotation": {
114
+ textDecoration: "underline",
115
+ textDecorationStyle: "wavy",
116
+ textDecorationColor: "red"
117
+ }
118
+ });
19
119
 
20
120
  // packages/ui/react-ui-editor/src/extensions/autocomplete.ts
21
121
  import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
@@ -54,9 +154,8 @@ var autocomplete = ({ onSearch }) => {
54
154
  };
55
155
 
56
156
  // packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
57
- import { invertedEffects } from "@codemirror/commands";
58
- import { StateField } from "@codemirror/state";
59
- import { EditorView, ViewPlugin } from "@codemirror/view";
157
+ import { StateField as StateField2 } from "@codemirror/state";
158
+ import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
60
159
  import { next as A4 } from "@dxos/automerge/automerge";
61
160
 
62
161
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
@@ -108,7 +207,7 @@ var isReconcile = (tr) => {
108
207
  return !!tr.annotation(reconcileAnnotation);
109
208
  };
110
209
 
111
- // packages/ui/react-ui-editor/src/extensions/automerge/semaphore.ts
210
+ // packages/ui/react-ui-editor/src/extensions/automerge/sync.ts
112
211
  import { next as A3 } from "@dxos/automerge/automerge";
113
212
 
114
213
  // packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
@@ -249,40 +348,42 @@ var charPath = (textPath, candidatePath) => {
249
348
  return null;
250
349
  };
251
350
 
252
- // packages/ui/react-ui-editor/src/extensions/automerge/semaphore.ts
253
- var PatchSemaphore = class {
351
+ // packages/ui/react-ui-editor/src/extensions/automerge/sync.ts
352
+ var Syncer = class {
254
353
  // prettier-ignore
255
354
  constructor(_handle, _state) {
256
355
  this._handle = _handle;
257
356
  this._state = _state;
258
- this._inReconcile = false;
357
+ this._pending = false;
259
358
  }
260
- reconcile(view) {
261
- if (!this._inReconcile) {
262
- this._inReconcile = true;
263
- this.doReconcile(view);
264
- this._inReconcile = false;
359
+ reconcile(view, editor) {
360
+ if (this._pending) {
361
+ return;
362
+ }
363
+ this._pending = true;
364
+ if (editor) {
365
+ this.onEditorChange(view);
366
+ } else {
367
+ this.onAutomergeChange(view);
265
368
  }
369
+ this._pending = false;
266
370
  }
267
- doReconcile(view) {
268
- const path = getPath(view.state, this._state);
269
- const oldHeads = getLastHeads(view.state, this._state);
270
- let selection = view.state.selection;
371
+ onEditorChange(view) {
271
372
  const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
272
- const toInvert = transactions.slice().reverse();
273
- for (const tr of toInvert) {
274
- const inverted = tr.changes.invert(tr.startState.doc);
275
- selection = selection.map(inverted);
373
+ const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
374
+ if (newHeads) {
276
375
  view.dispatch({
277
- changes: inverted,
278
- annotations: reconcileAnnotation.of(true)
376
+ effects: updateHeads(newHeads),
377
+ annotations: reconcileAnnotation.of(false)
279
378
  });
280
379
  }
281
- let newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
282
- if (newHeads === null || newHeads === void 0) {
283
- newHeads = A3.getHeads(this._handle.docSync());
284
- }
380
+ }
381
+ onAutomergeChange(view) {
382
+ const oldHeads = getLastHeads(view.state, this._state);
383
+ const newHeads = A3.getHeads(this._handle.docSync());
285
384
  const diff = A3.equals(oldHeads, newHeads) ? [] : A3.diff(this._handle.docSync(), oldHeads, newHeads);
385
+ const selection = view.state.selection;
386
+ const path = getPath(view.state, this._state);
286
387
  updateCodeMirror(view, selection, path, diff);
287
388
  view.dispatch({
288
389
  effects: updateHeads(newHeads),
@@ -291,46 +392,9 @@ var PatchSemaphore = class {
291
392
  }
292
393
  };
293
394
 
294
- // packages/ui/react-ui-editor/src/extensions/cursor.ts
295
- import { Facet } from "@codemirror/state";
296
- var defaultCursorConverter = {
297
- toCursor: (position) => position.toString(),
298
- fromCursor: (cursor) => parseInt(cursor)
299
- };
300
- var Cursor = class _Cursor {
301
- static {
302
- this.converter = Facet.define({
303
- combine: (providers) => providers[0] ?? defaultCursorConverter
304
- });
305
- }
306
- static {
307
- this.getCursorFromRange = (state, range) => {
308
- const cursorConverter2 = state.facet(_Cursor.converter);
309
- const from = cursorConverter2.toCursor(range.from);
310
- const to = cursorConverter2.toCursor(range.to, -1);
311
- return [
312
- from,
313
- to
314
- ].join(":");
315
- };
316
- }
317
- static {
318
- this.getRangeFromCursor = (state, cursor) => {
319
- const cursorConverter2 = state.facet(_Cursor.converter);
320
- const parts = cursor.split(":");
321
- const from = cursorConverter2.fromCursor(parts[0]);
322
- const to = cursorConverter2.fromCursor(parts[1]);
323
- return from !== void 0 && to !== void 0 ? {
324
- from,
325
- to
326
- } : void 0;
327
- };
328
- }
329
- };
330
-
331
395
  // packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
332
396
  var automerge = ({ handle, path }) => {
333
- const syncState = StateField.define({
397
+ const syncState = StateField2.define({
334
398
  create: () => ({
335
399
  path: path.slice(),
336
400
  lastHeads: A4.getHeads(handle.docSync()),
@@ -359,7 +423,7 @@ var automerge = ({ handle, path }) => {
359
423
  return result;
360
424
  }
361
425
  });
362
- const semaphore = new PatchSemaphore(handle, syncState);
426
+ const syncer = new Syncer(handle, syncState);
363
427
  return [
364
428
  Cursor.converter.of(cursorConverter(handle, path)),
365
429
  syncState,
@@ -373,32 +437,21 @@ var automerge = ({ handle, path }) => {
373
437
  handle.removeListener("change", this._handleChange.bind(this));
374
438
  }
375
439
  _handleChange() {
376
- semaphore.reconcile(this._view);
440
+ syncer.reconcile(this._view, false);
377
441
  }
378
442
  }),
379
443
  // Reconcile local updates.
380
- EditorView.updateListener.of(({ view, changes }) => {
444
+ EditorView2.updateListener.of(({ view, changes }) => {
381
445
  if (!changes.empty) {
382
- semaphore.reconcile(view);
383
- }
384
- }),
385
- // TODO(burdon): Record undo transactions.
386
- // See https://github.com/yjs/y-codemirror.next/tree/main
387
- // https://codemirror.net/examples/inverted-effect
388
- invertedEffects.of((tr) => {
389
- const effects = [];
390
- if (!tr.changes.empty) {
391
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
392
- });
446
+ syncer.reconcile(view, true);
393
447
  }
394
- return effects;
395
448
  })
396
449
  ];
397
450
  };
398
451
 
399
452
  // packages/ui/react-ui-editor/src/extensions/awareness.ts
400
453
  import { Annotation as Annotation2, Facet as Facet2, RangeSet } from "@codemirror/state";
401
- import { Decoration, EditorView as EditorView2, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
454
+ import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
402
455
  import { Event } from "@dxos/async";
403
456
  import { Context } from "@dxos/context";
404
457
  var dummyProvider = {
@@ -421,7 +474,7 @@ var awareness = (provider = dummyProvider) => {
421
474
  ViewPlugin2.fromClass(RemoteSelectionsDecorator, {
422
475
  decorations: (value) => value.decorations
423
476
  }),
424
- styles
477
+ styles2
425
478
  ];
426
479
  };
427
480
  var RemoteSelectionsDecorator = class {
@@ -481,7 +534,7 @@ var RemoteSelectionsDecorator = class {
481
534
  decorations.push({
482
535
  from: start,
483
536
  to: end,
484
- value: Decoration.mark({
537
+ value: Decoration2.mark({
485
538
  attributes: {
486
539
  style: `background-color: ${lightColor}`
487
540
  },
@@ -492,7 +545,7 @@ var RemoteSelectionsDecorator = class {
492
545
  decorations.push({
493
546
  from: start,
494
547
  to: startLine.from + startLine.length,
495
- value: Decoration.mark({
548
+ value: Decoration2.mark({
496
549
  attributes: {
497
550
  style: `background-color: ${color}`
498
551
  },
@@ -502,7 +555,7 @@ var RemoteSelectionsDecorator = class {
502
555
  decorations.push({
503
556
  from: endLine.from,
504
557
  to: end,
505
- value: Decoration.mark({
558
+ value: Decoration2.mark({
506
559
  attributes: {
507
560
  style: `background-color: ${color}`
508
561
  },
@@ -514,7 +567,7 @@ var RemoteSelectionsDecorator = class {
514
567
  decorations.push({
515
568
  from: linePos,
516
569
  to: linePos,
517
- value: Decoration.line({
570
+ value: Decoration2.line({
518
571
  attributes: {
519
572
  style: `background-color: ${color}`,
520
573
  class: "cm-collab-selectionLine"
@@ -526,14 +579,14 @@ var RemoteSelectionsDecorator = class {
526
579
  decorations.push({
527
580
  from: head,
528
581
  to: head,
529
- value: Decoration.widget({
582
+ value: Decoration2.widget({
530
583
  side: head - anchor > 0 ? -1 : 1,
531
584
  block: false,
532
585
  widget: new RemoteCaretWidget(state.info.displayName ?? "Anonymous", color)
533
586
  })
534
587
  });
535
588
  }
536
- this.decorations = Decoration.set(decorations, true);
589
+ this.decorations = Decoration2.set(decorations, true);
537
590
  }
538
591
  };
539
592
  var RemoteCaretWidget = class extends WidgetType {
@@ -572,7 +625,7 @@ var RemoteCaretWidget = class extends WidgetType {
572
625
  return true;
573
626
  }
574
627
  };
575
- var styles = EditorView2.baseTheme({
628
+ var styles2 = EditorView3.baseTheme({
576
629
  ".cm-collab-selection": {},
577
630
  ".cm-collab-selectionLine": {
578
631
  padding: 0,
@@ -636,10 +689,10 @@ import { closeBrackets } from "@codemirror/autocomplete";
636
689
  import { history } from "@codemirror/commands";
637
690
  import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
638
691
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
639
- import { drawSelection, EditorView as EditorView3, highlightActiveLine, placeholder } from "@codemirror/view";
640
- import { isNotFalsy } from "@dxos/util";
692
+ import { drawSelection, EditorView as EditorView4, highlightActiveLine, placeholder } from "@codemirror/view";
693
+ import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
641
694
  var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => [
642
- lineWrapping && EditorView3.lineWrapping,
695
+ lineWrapping && EditorView4.lineWrapping,
643
696
  // https://codemirror.net/docs/ref/#codemirror.minimalSetup
644
697
  bracketMatching(),
645
698
  closeBrackets(),
@@ -649,10 +702,10 @@ var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping =
649
702
  _placeholder && placeholder(_placeholder),
650
703
  // https://github.com/codemirror/theme-one-dark
651
704
  themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
652
- ].filter(isNotFalsy);
705
+ ].filter(isNotFalsy2);
653
706
 
654
707
  // packages/ui/react-ui-editor/src/extensions/blast.ts
655
- import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
708
+ import { EditorView as EditorView5, keymap as keymap2 } from "@codemirror/view";
656
709
  import defaultsDeep from "lodash.defaultsdeep";
657
710
  import { invariant } from "@dxos/invariant";
658
711
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
@@ -700,7 +753,7 @@ var blast = (options = defaultOptions) => {
700
753
  };
701
754
  return [
702
755
  // Cursor moved.
703
- EditorView4.updateListener.of((update2) => {
756
+ EditorView5.updateListener.of((update2) => {
704
757
  if (blaster?.node !== update2.view.scrollDOM) {
705
758
  if (blaster) {
706
759
  blaster.destroy();
@@ -962,9 +1015,9 @@ var random = (min, max) => {
962
1015
  };
963
1016
 
964
1017
  // packages/ui/react-ui-editor/src/extensions/comments.ts
965
- import { invertedEffects as invertedEffects2 } from "@codemirror/commands";
966
- import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
967
- import { hoverTooltip, keymap as keymap3, Decoration as Decoration2, EditorView as EditorView5 } from "@codemirror/view";
1018
+ import { invertedEffects } from "@codemirror/commands";
1019
+ import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
1020
+ import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView6 } from "@codemirror/view";
968
1021
  import sortBy from "lodash.sortby";
969
1022
  import { useEffect } from "react";
970
1023
  import { debounce } from "@dxos/async";
@@ -1037,6 +1090,9 @@ import { tailwindConfig } from "@dxos/react-ui-theme";
1037
1090
  var tokens = tailwindConfig({}).theme;
1038
1091
  var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
1039
1092
 
1093
+ // packages/ui/react-ui-editor/src/styles/layout.ts
1094
+ var editorWithToolbarLayout = "fixed inset-0 grid grid-cols-1 grid-rows-[min-content_1fr] justify-center content-start overflow-hidden";
1095
+
1040
1096
  // packages/ui/react-ui-editor/src/util.ts
1041
1097
  import { log } from "@dxos/log";
1042
1098
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
@@ -1073,7 +1129,7 @@ var logChanges = (trs) => {
1073
1129
  };
1074
1130
 
1075
1131
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1076
- var styles2 = EditorView5.baseTheme({
1132
+ var styles3 = EditorView6.baseTheme({
1077
1133
  "&light .cm-comment, &light .cm-comment-current": {
1078
1134
  mixBlendMode: "darken"
1079
1135
  },
@@ -1095,10 +1151,10 @@ var styles2 = EditorView5.baseTheme({
1095
1151
  backgroundColor: getToken("extend.colors.yellow.950")
1096
1152
  }
1097
1153
  });
1098
- var commentMark = Decoration2.mark({
1154
+ var commentMark = Decoration3.mark({
1099
1155
  class: "cm-comment"
1100
1156
  });
1101
- var commentCurrentMark = Decoration2.mark({
1157
+ var commentCurrentMark = Decoration3.mark({
1102
1158
  class: "cm-comment-current"
1103
1159
  });
1104
1160
  var focusComment = (view, id, center = true) => {
@@ -1114,7 +1170,7 @@ var focusComment = (view, id, center = true) => {
1114
1170
  },
1115
1171
  effects: [
1116
1172
  //
1117
- EditorView5.scrollIntoView(range.from, center ? {
1173
+ EditorView6.scrollIntoView(range.from, center ? {
1118
1174
  y: "center"
1119
1175
  } : void 0),
1120
1176
  setSelection.of({
@@ -1127,7 +1183,7 @@ var focusComment = (view, id, center = true) => {
1127
1183
  var setComments = StateEffect2.define();
1128
1184
  var setSelection = StateEffect2.define();
1129
1185
  var setCommentState = StateEffect2.define();
1130
- var commentsState = StateField2.define({
1186
+ var commentsState = StateField3.define({
1131
1187
  create: () => ({
1132
1188
  comments: [],
1133
1189
  selection: {}
@@ -1163,7 +1219,7 @@ var commentsState = StateField2.define({
1163
1219
  return value;
1164
1220
  }
1165
1221
  });
1166
- var commentsDecorations = EditorView5.decorations.compute([
1222
+ var commentsDecorations = EditorView6.decorations.compute([
1167
1223
  commentsState
1168
1224
  ], (state) => {
1169
1225
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -1179,7 +1235,7 @@ var commentsDecorations = EditorView5.decorations.compute([
1179
1235
  return commentMark.range(range.from, range.to);
1180
1236
  }
1181
1237
  }).filter(nonNullable);
1182
- return Decoration2.set(decorations);
1238
+ return Decoration3.set(decorations);
1183
1239
  });
1184
1240
  var trackPastedComments = (onUpdate) => {
1185
1241
  let tracked = null;
@@ -1201,12 +1257,12 @@ var trackPastedComments = (onUpdate) => {
1201
1257
  }
1202
1258
  };
1203
1259
  return [
1204
- EditorView5.domEventHandlers({
1260
+ EditorView6.domEventHandlers({
1205
1261
  cut: handleTrack,
1206
1262
  copy: handleTrack
1207
1263
  }),
1208
1264
  // Track deleted comments.
1209
- invertedEffects2.of((tr) => {
1265
+ invertedEffects.of((tr) => {
1210
1266
  const { comments: comments2 } = tr.startState.field(commentsState);
1211
1267
  const effects = [];
1212
1268
  tr.changes.iterChangedRanges((fromA, toA) => {
@@ -1223,7 +1279,7 @@ var trackPastedComments = (onUpdate) => {
1223
1279
  return effects;
1224
1280
  }),
1225
1281
  // Handle paste or the undo of comment deletion.
1226
- EditorView5.updateListener.of((update2) => {
1282
+ EditorView6.updateListener.of((update2) => {
1227
1283
  const restore = [];
1228
1284
  for (let i = 0; i < update2.transactions.length; i++) {
1229
1285
  const tr = update2.transactions[i];
@@ -1330,7 +1386,7 @@ var comments = (options = {}) => {
1330
1386
  optionsFacet.of(options),
1331
1387
  commentsState,
1332
1388
  commentsDecorations,
1333
- styles2,
1389
+ styles3,
1334
1390
  //
1335
1391
  // Keymap.
1336
1392
  //
@@ -1373,7 +1429,7 @@ var comments = (options = {}) => {
1373
1429
  //
1374
1430
  // Track deleted ranges and update ranges for decorations.
1375
1431
  //
1376
- EditorView5.updateListener.of(({ view, state, changes }) => {
1432
+ EditorView6.updateListener.of(({ view, state, changes }) => {
1377
1433
  let mod = false;
1378
1434
  const { comments: comments2, ...value } = state.field(commentsState);
1379
1435
  changes.iterChanges((from, to, from2, to2) => {
@@ -1405,7 +1461,7 @@ var comments = (options = {}) => {
1405
1461
  //
1406
1462
  // Track selection/proximity.
1407
1463
  //
1408
- EditorView5.updateListener.of(({ view, state }) => {
1464
+ EditorView6.updateListener.of(({ view, state }) => {
1409
1465
  let min = Infinity;
1410
1466
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
1411
1467
  const { head } = state.selection.main;
@@ -1454,14 +1510,14 @@ var useComments = (view, comments2 = []) => {
1454
1510
  };
1455
1511
 
1456
1512
  // packages/ui/react-ui-editor/src/extensions/listener.ts
1457
- import { EditorView as EditorView6 } from "@codemirror/view";
1513
+ import { EditorView as EditorView7 } from "@codemirror/view";
1458
1514
  var listener = ({ onFocus, onChange }) => {
1459
1515
  const extensions = [];
1460
- onFocus && extensions.push(EditorView6.focusChangeEffect.of((_, focused) => {
1516
+ onFocus && extensions.push(EditorView7.focusChangeEffect.of((_, focused) => {
1461
1517
  onFocus(focused);
1462
1518
  return null;
1463
1519
  }));
1464
- onChange && extensions.push(EditorView6.updateListener.of((update2) => {
1520
+ onChange && extensions.push(EditorView7.updateListener.of((update2) => {
1465
1521
  onChange(update2.state.doc.toString());
1466
1522
  }));
1467
1523
  return extensions;
@@ -1476,8 +1532,8 @@ import { languages } from "@codemirror/language-data";
1476
1532
  import { searchKeymap } from "@codemirror/search";
1477
1533
  import { EditorState } from "@codemirror/state";
1478
1534
  import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
1479
- import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView7, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1480
- import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
1535
+ import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView8, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1536
+ import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
1481
1537
 
1482
1538
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
1483
1539
  import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
@@ -1670,7 +1726,7 @@ var markdownHighlightStyle = (readonly) => {
1670
1726
  // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
1671
1727
  var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
1672
1728
  return [
1673
- lineWrapping && EditorView7.lineWrapping,
1729
+ lineWrapping && EditorView8.lineWrapping,
1674
1730
  EditorState.allowMultipleSelections.of(true),
1675
1731
  EditorState.tabSize.of(2),
1676
1732
  // https://github.com/codemirror/basic-setup
@@ -1717,15 +1773,15 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
1717
1773
  // https://codemirror.net/docs/ref/#commands.standardKeymap
1718
1774
  ...standardKeymap
1719
1775
  ])
1720
- ].filter(isNotFalsy2);
1776
+ ].filter(isNotFalsy3);
1721
1777
  };
1722
1778
 
1723
1779
  // packages/ui/react-ui-editor/src/extensions/markdown/code.ts
1724
1780
  import { syntaxTree } from "@codemirror/language";
1725
1781
  import { RangeSetBuilder } from "@codemirror/state";
1726
- import { ViewPlugin as ViewPlugin3, EditorView as EditorView8, Decoration as Decoration3, WidgetType as WidgetType2 } from "@codemirror/view";
1782
+ import { ViewPlugin as ViewPlugin3, EditorView as EditorView9, Decoration as Decoration4, WidgetType as WidgetType2 } from "@codemirror/view";
1727
1783
  import { mx as mx2 } from "@dxos/react-ui-theme";
1728
- var styles3 = EditorView8.baseTheme({
1784
+ var styles4 = EditorView9.baseTheme({
1729
1785
  "& .cm-code": {
1730
1786
  fontFamily: getToken("fontFamily.mono", []).join(",")
1731
1787
  },
@@ -1802,11 +1858,11 @@ var buildDecorations = (view) => {
1802
1858
  for (let i = range[0]; i <= range[1]; i++) {
1803
1859
  const block = blocks[i];
1804
1860
  if (!edit && (i === range[0] || i === range[1])) {
1805
- builder.add(block.from, block.to, Decoration3.replace({
1861
+ builder.add(block.from, block.to, Decoration4.replace({
1806
1862
  widget: i === range[0] ? top : bottom
1807
1863
  }));
1808
1864
  } else {
1809
- builder.add(block.from, block.from, Decoration3.line({
1865
+ builder.add(block.from, block.from, Decoration4.line({
1810
1866
  class: mx2("cm-code cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
1811
1867
  }));
1812
1868
  }
@@ -1831,7 +1887,7 @@ var code2 = () => {
1831
1887
  }, {
1832
1888
  decorations: (value) => value.decorations
1833
1889
  }),
1834
- styles3
1890
+ styles4
1835
1891
  ];
1836
1892
  };
1837
1893
 
@@ -1839,7 +1895,7 @@ var code2 = () => {
1839
1895
  import { snippet } from "@codemirror/autocomplete";
1840
1896
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
1841
1897
  import { RangeSetBuilder as RangeSetBuilder2, EditorSelection } from "@codemirror/state";
1842
- import { Decoration as Decoration4, EditorView as EditorView9, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1898
+ import { Decoration as Decoration5, EditorView as EditorView10, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1843
1899
  import { useState, useMemo } from "react";
1844
1900
  var compareFormatting = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
1845
1901
  var Inline;
@@ -2681,7 +2737,7 @@ var styling = () => {
2681
2737
  const replace = (node, marks) => {
2682
2738
  if (cursor <= node.from || cursor >= node.to) {
2683
2739
  for (const mark2 of marks) {
2684
- builder.add(mark2.from, mark2.to, Decoration4.replace({}));
2740
+ builder.add(mark2.from, mark2.to, Decoration5.replace({}));
2685
2741
  }
2686
2742
  }
2687
2743
  };
@@ -2911,7 +2967,7 @@ var getFormatting = (state) => {
2911
2967
  };
2912
2968
  var useFormattingState = () => {
2913
2969
  const [state, setState] = useState(null);
2914
- const observer = useMemo(() => EditorView9.updateListener.of((update2) => {
2970
+ const observer = useMemo(() => EditorView10.updateListener.of((update2) => {
2915
2971
  if (update2.docChanged || update2.selectionSet) {
2916
2972
  const newState = getFormatting(update2.state);
2917
2973
  if (!state || !compareFormatting(state, newState)) {
@@ -2928,7 +2984,7 @@ var useFormattingState = () => {
2928
2984
  // packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
2929
2985
  import { syntaxTree as syntaxTree3 } from "@codemirror/language";
2930
2986
  import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
2931
- import { Decoration as Decoration5, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
2987
+ import { Decoration as Decoration6, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
2932
2988
  var buildDecorations2 = (view) => {
2933
2989
  const builder = new RangeSetBuilder3();
2934
2990
  const { state } = view;
@@ -2946,7 +3002,7 @@ var buildDecorations2 = (view) => {
2946
3002
  const mark2 = node.node.getChild("HeaderMark");
2947
3003
  if (mark2) {
2948
3004
  if (!view.hasFocus || view.state.readOnly || cursor < node.from || cursor > node.to) {
2949
- builder.add(mark2.from, mark2.to + 1, Decoration5.replace({}));
3005
+ builder.add(mark2.from, mark2.to + 1, Decoration6.replace({}));
2950
3006
  }
2951
3007
  }
2952
3008
  }
@@ -2976,8 +3032,8 @@ var heading2 = () => {
2976
3032
  // packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
2977
3033
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
2978
3034
  import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
2979
- import { Decoration as Decoration6, EditorView as EditorView10, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
2980
- var styles4 = EditorView10.baseTheme({
3035
+ import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
3036
+ var styles5 = EditorView11.baseTheme({
2981
3037
  "& .cm-hr": {
2982
3038
  // Note that block-level decorations should not have vertical margins,
2983
3039
  borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
@@ -2990,7 +3046,7 @@ var HorizontalRuleWidget = class extends WidgetType3 {
2990
3046
  return el;
2991
3047
  }
2992
3048
  };
2993
- var decoration = Decoration6.replace({
3049
+ var decoration = Decoration7.replace({
2994
3050
  widget: new HorizontalRuleWidget()
2995
3051
  });
2996
3052
  var buildDecorations3 = (view) => {
@@ -3024,18 +3080,18 @@ var hr = () => {
3024
3080
  }, {
3025
3081
  decorations: (value) => value.decorations
3026
3082
  }),
3027
- styles4
3083
+ styles5
3028
3084
  ];
3029
3085
  };
3030
3086
 
3031
3087
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3032
3088
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
3033
- import { StateField as StateField3 } from "@codemirror/state";
3034
- import { Decoration as Decoration7, EditorView as EditorView11, WidgetType as WidgetType4 } from "@codemirror/view";
3089
+ import { StateField as StateField4 } from "@codemirror/state";
3090
+ import { Decoration as Decoration8, EditorView as EditorView12, WidgetType as WidgetType4 } from "@codemirror/view";
3035
3091
  var image = (options = {}) => {
3036
- return StateField3.define({
3092
+ return StateField4.define({
3037
3093
  create: (state) => {
3038
- return Decoration7.set(buildDecorations4(0, state.doc.length, state));
3094
+ return Decoration8.set(buildDecorations4(0, state.doc.length, state));
3039
3095
  },
3040
3096
  update: (value, tr) => {
3041
3097
  if (!tr.docChanged && !tr.selection) {
@@ -3058,7 +3114,7 @@ var image = (options = {}) => {
3058
3114
  add: buildDecorations4(from, to, tr.state)
3059
3115
  });
3060
3116
  },
3061
- provide: (field) => EditorView11.decorations.from(field)
3117
+ provide: (field) => EditorView12.decorations.from(field)
3062
3118
  });
3063
3119
  };
3064
3120
  var buildDecorations4 = (from, to, state) => {
@@ -3071,7 +3127,7 @@ var buildDecorations4 = (from, to, state) => {
3071
3127
  if (urlNode) {
3072
3128
  const hide = state.readOnly || cursor < node.from || cursor > node.to;
3073
3129
  const url = state.sliceDoc(urlNode.from, urlNode.to);
3074
- decorations.push(Decoration7.replace({
3130
+ decorations.push(Decoration8.replace({
3075
3131
  block: true,
3076
3132
  widget: new ImageWidget(url)
3077
3133
  }).range(hide ? node.from : node.to, node.to));
@@ -3103,7 +3159,7 @@ var ImageWidget = class extends WidgetType4 {
3103
3159
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
3104
3160
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
3105
3161
  import { RangeSetBuilder as RangeSetBuilder5 } from "@codemirror/state";
3106
- import { hoverTooltip as hoverTooltip2, Decoration as Decoration8, ViewPlugin as ViewPlugin7, WidgetType as WidgetType5 } from "@codemirror/view";
3162
+ import { hoverTooltip as hoverTooltip2, Decoration as Decoration9, ViewPlugin as ViewPlugin7, WidgetType as WidgetType5 } from "@codemirror/view";
3107
3163
  import { tooltipContent } from "@dxos/react-ui-theme";
3108
3164
  var link = (options = {}) => {
3109
3165
  const extensions = [
@@ -3218,12 +3274,12 @@ var buildDecorations5 = (view, options) => {
3218
3274
  return false;
3219
3275
  }
3220
3276
  if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
3221
- builder.add(node.from, node.to, Decoration8.replace({
3277
+ builder.add(node.from, node.to, Decoration9.replace({
3222
3278
  widget: new LinkText(text, options.link ? url : void 0)
3223
3279
  }));
3224
3280
  }
3225
3281
  if (options.onRender) {
3226
- builder.add(node.to, node.to, Decoration8.replace({
3282
+ builder.add(node.to, node.to, Decoration9.replace({
3227
3283
  widget: new LinkButton(url, options.onRender)
3228
3284
  }));
3229
3285
  }
@@ -3239,13 +3295,13 @@ var buildDecorations5 = (view, options) => {
3239
3295
 
3240
3296
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
3241
3297
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3242
- import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField4 } from "@codemirror/state";
3243
- import { Decoration as Decoration9, EditorView as EditorView12, WidgetType as WidgetType6 } from "@codemirror/view";
3298
+ import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField5 } from "@codemirror/state";
3299
+ import { Decoration as Decoration10, EditorView as EditorView13, WidgetType as WidgetType6 } from "@codemirror/view";
3244
3300
  var table = (options = {}) => {
3245
- return StateField4.define({
3301
+ return StateField5.define({
3246
3302
  create: (state) => update(state, options),
3247
3303
  update: (_, tr) => update(tr.state, options),
3248
- provide: (field) => EditorView12.decorations.from(field)
3304
+ provide: (field) => EditorView13.decorations.from(field)
3249
3305
  });
3250
3306
  };
3251
3307
  var update = (state, options) => {
@@ -3289,10 +3345,10 @@ var update = (state, options) => {
3289
3345
  });
3290
3346
  tables.forEach((table2) => {
3291
3347
  const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
3292
- hide && builder.add(table2.from, table2.to, Decoration9.replace({
3348
+ hide && builder.add(table2.from, table2.to, Decoration10.replace({
3293
3349
  widget: new TableWidget(table2)
3294
3350
  }));
3295
- builder.add(table2.from, table2.to, Decoration9.mark({
3351
+ builder.add(table2.from, table2.to, Decoration10.mark({
3296
3352
  class: "cm-table"
3297
3353
  }));
3298
3354
  });
@@ -3338,8 +3394,8 @@ var TableWidget = class extends WidgetType6 {
3338
3394
  // packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
3339
3395
  import { syntaxTree as syntaxTree8 } from "@codemirror/language";
3340
3396
  import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
3341
- import { EditorView as EditorView13, Decoration as Decoration10, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
3342
- var styles5 = EditorView13.baseTheme({
3397
+ import { EditorView as EditorView14, Decoration as Decoration11, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
3398
+ var styles6 = EditorView14.baseTheme({
3343
3399
  "& .cm-task": {
3344
3400
  color: getToken("extend.colors.blue.500")
3345
3401
  },
@@ -3385,10 +3441,10 @@ var CheckboxWidget = class extends WidgetType7 {
3385
3441
  return false;
3386
3442
  }
3387
3443
  };
3388
- var checkedDecoration = Decoration10.replace({
3444
+ var checkedDecoration = Decoration11.replace({
3389
3445
  widget: new CheckboxWidget(true)
3390
3446
  });
3391
- var uncheckedDecoration = Decoration10.replace({
3447
+ var uncheckedDecoration = Decoration11.replace({
3392
3448
  widget: new CheckboxWidget(false)
3393
3449
  });
3394
3450
  var buildDecorations6 = (view) => {
@@ -3401,7 +3457,7 @@ var buildDecorations6 = (view) => {
3401
3457
  if (node.name === "TaskMarker") {
3402
3458
  if (cursor < node.from || cursor > node.to) {
3403
3459
  const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
3404
- builder.add(node.from - 2, node.from - 1, Decoration10.mark({
3460
+ builder.add(node.from - 2, node.from - 1, Decoration11.mark({
3405
3461
  class: "cm-task"
3406
3462
  }));
3407
3463
  builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
@@ -3428,7 +3484,7 @@ var tasklist = (options = {}) => {
3428
3484
  }, {
3429
3485
  decorations: (value) => value.decorations
3430
3486
  }),
3431
- styles5
3487
+ styles6
3432
3488
  ];
3433
3489
  };
3434
3490
 
@@ -3801,27 +3857,27 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3801
3857
  selection,
3802
3858
  extensions: [
3803
3859
  // TODO(burdon): Doesn't catch errors in keymap functions.
3804
- EditorView14.exceptionSink.of((err) => {
3860
+ EditorView15.exceptionSink.of((err) => {
3805
3861
  log2.catch(err, void 0, {
3806
3862
  F: __dxlog_file3,
3807
- L: 134,
3863
+ L: 135,
3808
3864
  S: void 0,
3809
3865
  C: (f, a) => f(...a)
3810
3866
  });
3811
3867
  }),
3812
3868
  // Theme.
3813
3869
  // TODO(burdon): Make configurable.
3814
- EditorView14.baseTheme(defaultTheme),
3815
- EditorView14.theme(theme ?? {}),
3816
- EditorView14.darkTheme.of(themeMode === "dark"),
3817
- EditorView14.editorAttributes.of({
3870
+ EditorView15.baseTheme(defaultTheme),
3871
+ EditorView15.theme(theme ?? {}),
3872
+ EditorView15.darkTheme.of(themeMode === "dark"),
3873
+ EditorView15.editorAttributes.of({
3818
3874
  class: slots.editor?.className ?? ""
3819
3875
  }),
3820
- EditorView14.contentAttributes.of({
3876
+ EditorView15.contentAttributes.of({
3821
3877
  class: slots.content?.className ?? ""
3822
3878
  }),
3823
3879
  // State.
3824
- EditorView14.editable.of(!readonly),
3880
+ EditorView15.editable.of(!readonly),
3825
3881
  EditorState2.readOnly.of(!!readonly),
3826
3882
  // Storage and replication.
3827
3883
  // NOTE: This must come before user extensions.
@@ -3830,9 +3886,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3830
3886
  editorMode === "vim" && vim(),
3831
3887
  // Custom.
3832
3888
  ...extensions
3833
- ].filter(isNotFalsy3)
3889
+ ].filter(isNotFalsy4)
3834
3890
  });
3835
- const newView = new EditorView14({
3891
+ const newView = new EditorView15({
3836
3892
  state,
3837
3893
  parent: rootRef.current,
3838
3894
  scrollTo,
@@ -3925,10 +3981,10 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
3925
3981
  });
3926
3982
  var defaultSlots = {
3927
3983
  root: {
3928
- className: mx3("grow", focusRing)
3984
+ className: focusRing
3929
3985
  },
3930
3986
  editor: {
3931
- className: "bs-full"
3987
+ className: "min-bs-full"
3932
3988
  }
3933
3989
  };
3934
3990
  var defaultTextSlots = {
@@ -3939,11 +3995,35 @@ var defaultMarkdownSlots = {
3939
3995
  };
3940
3996
 
3941
3997
  // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
3942
- import { CaretRight, ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic } from "@phosphor-icons/react";
3998
+ import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes, CaretDown } from "@phosphor-icons/react";
3943
3999
  import { createContext } from "@radix-ui/react-context";
3944
4000
  import React2 from "react";
3945
- import { Button, DensityProvider, Select } from "@dxos/react-ui";
3946
- import { getSize, mx as mx4 } from "@dxos/react-ui-theme";
4001
+ import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, useTranslation } from "@dxos/react-ui";
4002
+ import { getSize } from "@dxos/react-ui-theme";
4003
+
4004
+ // packages/ui/react-ui-editor/src/translations.ts
4005
+ var translationKey = "react-ui-editor";
4006
+ var translations_default = [
4007
+ {
4008
+ "en-US": {
4009
+ [translationKey]: {
4010
+ "strong label": "Strong",
4011
+ "emphasis label": "Emphasis",
4012
+ "strikethrough label": "Strike-through",
4013
+ "code label": "Code",
4014
+ "bullet label": "Bullet list",
4015
+ "ordered label": "Numbered list",
4016
+ "task label": "Task list",
4017
+ "blockquote label": "Block quote",
4018
+ "codeblock label": "Code block",
4019
+ "comment label": "Create comment",
4020
+ "heading label": "Heading level"
4021
+ }
4022
+ }
4023
+ }
4024
+ ];
4025
+
4026
+ // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
3947
4027
  var HeadingIcons = {
3948
4028
  "0": Paragraph,
3949
4029
  "1": TextHOne,
@@ -3954,42 +4034,40 @@ var HeadingIcons = {
3954
4034
  "6": TextHSix
3955
4035
  };
3956
4036
  var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
3957
- var ToolbarRoot = ({ children, onAction, state }) => {
4037
+ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
3958
4038
  return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
3959
4039
  onAction,
3960
4040
  state
3961
4041
  }, /* @__PURE__ */ React2.createElement(DensityProvider, {
3962
4042
  density: "fine"
3963
- }, /* @__PURE__ */ React2.createElement("div", {
3964
- role: "toolbar",
3965
- className: "flex w-full shrink-0 p-1 gap-4 items-center whitespace-nowrap overflow-hidden"
3966
- }, children)));
4043
+ }, /* @__PURE__ */ React2.createElement(ElevationProvider, {
4044
+ elevation: "chrome"
4045
+ }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Root, {
4046
+ classNames: [
4047
+ "is-full shrink-0 overflow-x-auto p-1",
4048
+ classNames
4049
+ ]
4050
+ }, children))));
3967
4051
  };
3968
- var ToolbarButton = ({ Icon, onClick, title, getState, disable }) => {
3969
- const { onAction, state } = useToolbarContext("ToolbarButton");
3970
- const active = getState && state ? getState(state) : false;
3971
- const disabled = disable && state ? disable(state) : false;
3972
- const handleClick = (event) => {
3973
- const action = onClick(state);
3974
- if (action) {
3975
- onAction?.(action);
3976
- event.preventDefault();
3977
- }
3978
- };
3979
- return /* @__PURE__ */ React2.createElement(Button, {
4052
+ var buttonStyles = "min-bs-0 p-2";
4053
+ var iconStyles = getSize(4);
4054
+ var ToolbarButton = ({ Icon, children, ...props }) => {
4055
+ return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
3980
4056
  variant: "ghost",
3981
- classNames: mx4("p-2", active && "ring-[1px]"),
3982
- onMouseDown: handleClick,
3983
- title,
3984
- disabled
4057
+ ...props,
4058
+ classNames: buttonStyles
3985
4059
  }, /* @__PURE__ */ React2.createElement(Icon, {
3986
- className: getSize(5)
3987
- }));
4060
+ className: iconStyles
4061
+ }), /* @__PURE__ */ React2.createElement("span", {
4062
+ className: "sr-only"
4063
+ }, children));
3988
4064
  };
3989
4065
  var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
4066
+ role: "separator",
3990
4067
  className: "grow"
3991
4068
  });
3992
4069
  var MarkdownHeading = () => {
4070
+ const { t } = useTranslation(translationKey);
3993
4071
  const { onAction, state } = useToolbarContext("MarkdownFormatting");
3994
4072
  const blockType = state ? state.blockType : "paragraph";
3995
4073
  const header = blockType && /heading(\d)/.exec(blockType);
@@ -4002,9 +4080,19 @@ var MarkdownHeading = () => {
4002
4080
  type: "heading",
4003
4081
  data: parseInt(value2)
4004
4082
  })
4005
- }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, null, /* @__PURE__ */ React2.createElement(HeadingIcon, {
4006
- className: getSize(5)
4007
- })), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
4083
+ }, /* @__PURE__ */ React2.createElement(Select.Trigger, {
4084
+ asChild: true
4085
+ }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4086
+ variant: "ghost",
4087
+ classNames: buttonStyles
4088
+ }, /* @__PURE__ */ React2.createElement("span", {
4089
+ className: "sr-only"
4090
+ }, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
4091
+ className: iconStyles
4092
+ }), /* @__PURE__ */ React2.createElement(CaretDown, {
4093
+ className: getSize(2),
4094
+ weight: "bold"
4095
+ }))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
4008
4096
  value: "0"
4009
4097
  }, "Paragraph"), [
4010
4098
  1,
@@ -4016,120 +4104,142 @@ var MarkdownHeading = () => {
4016
4104
  ].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
4017
4105
  key: level,
4018
4106
  value: String(level)
4019
- }, "Heading ", level))))));
4107
+ }, "Heading ", level))), /* @__PURE__ */ React2.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React2.createElement(Select.Arrow, null))));
4108
+ };
4109
+ var markdownStyles = [
4110
+ {
4111
+ key: "strong",
4112
+ Icon: TextB
4113
+ },
4114
+ {
4115
+ key: "emphasis",
4116
+ Icon: TextItalic
4117
+ },
4118
+ {
4119
+ key: "strikethrough",
4120
+ Icon: TextStrikethrough
4121
+ },
4122
+ {
4123
+ key: "code",
4124
+ Icon: Code
4125
+ },
4126
+ {
4127
+ key: "link",
4128
+ Icon: Link
4129
+ }
4130
+ ];
4131
+ var MarkdownStyles = () => {
4132
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
4133
+ const { t } = useTranslation(translationKey);
4134
+ return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4135
+ type: "multiple",
4136
+ value: markdownStyles.filter(({ key }) => !!state?.[key]).map(({ key }) => key)
4137
+ }, markdownStyles.map(({ key, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4138
+ key,
4139
+ value: key,
4140
+ Icon,
4141
+ disabled: state?.blockType === "codeblock",
4142
+ onClick: () => onAction?.({
4143
+ type: key,
4144
+ data: state ? !state[key] : null
4145
+ })
4146
+ }, t(`${key} label`))));
4147
+ };
4148
+ var markdownLists = [
4149
+ {
4150
+ key: "bullet",
4151
+ Icon: ListBullets,
4152
+ actionType: "list-bullet"
4153
+ },
4154
+ {
4155
+ key: "ordered",
4156
+ Icon: ListNumbers,
4157
+ actionType: "list-ordered"
4158
+ },
4159
+ {
4160
+ key: "task",
4161
+ Icon: ListChecks,
4162
+ actionType: "list-tasks"
4163
+ }
4164
+ ];
4165
+ var MarkdownLists = () => {
4166
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
4167
+ const { t } = useTranslation(translationKey);
4168
+ return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4169
+ type: "single",
4170
+ value: state?.listStyle ?? void 0
4171
+ }, markdownLists.map(({ key, Icon, actionType }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4172
+ key,
4173
+ value: key,
4174
+ Icon,
4175
+ onClick: () => onAction?.({
4176
+ type: actionType,
4177
+ data: state ? state.listStyle !== key : null
4178
+ })
4179
+ }, t(`${key} label`))));
4180
+ };
4181
+ var markdownBlocks = [
4182
+ {
4183
+ key: "blockquote",
4184
+ Icon: Quotes,
4185
+ pressed: (state) => state?.blockQuote,
4186
+ action: (state) => ({
4187
+ type: "blockquote",
4188
+ data: state ? !state.blockQuote : null
4189
+ }),
4190
+ disabled: (state) => false
4191
+ },
4192
+ {
4193
+ key: "codeblock",
4194
+ Icon: CodeBlock,
4195
+ pressed: (state) => state?.blockType === "codeblock",
4196
+ action: (state) => ({
4197
+ type: "blockquote",
4198
+ data: state ? !state.blockQuote : null
4199
+ }),
4200
+ disabled: (state) => !state?.blankLine
4201
+ }
4202
+ ];
4203
+ var MarkdownBlocks = () => {
4204
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
4205
+ const { t } = useTranslation(translationKey);
4206
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4207
+ type: "multiple",
4208
+ value: markdownBlocks.filter(({ pressed }) => pressed(state)).map(({ key }) => key)
4209
+ }, markdownBlocks.map(({ key, Icon, action }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4210
+ key,
4211
+ value: key,
4212
+ Icon,
4213
+ onClick: () => onAction?.(action(state))
4214
+ }, t(`${key} label`)))), /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4215
+ variant: "ghost",
4216
+ disabled: !state?.blankLine,
4217
+ onClick: () => onAction?.({
4218
+ type: "table"
4219
+ }),
4220
+ classNames: buttonStyles
4221
+ }, /* @__PURE__ */ React2.createElement(Table2, {
4222
+ className: iconStyles
4223
+ }), /* @__PURE__ */ React2.createElement("span", {
4224
+ className: "sr-only"
4225
+ }, t("table label"))));
4226
+ };
4227
+ var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(MarkdownHeading, null), /* @__PURE__ */ React2.createElement(MarkdownStyles, null), /* @__PURE__ */ React2.createElement(MarkdownLists, null), /* @__PURE__ */ React2.createElement(MarkdownBlocks, null));
4228
+ var MarkdownExtended = () => {
4229
+ const { onAction } = useToolbarContext("MarkdownStyles");
4230
+ const { t } = useTranslation(translationKey);
4231
+ return /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4232
+ variant: "ghost",
4233
+ onClick: () => onAction?.({
4234
+ type: "comment"
4235
+ }),
4236
+ classNames: buttonStyles
4237
+ }, /* @__PURE__ */ React2.createElement(ChatText, {
4238
+ className: iconStyles
4239
+ }), /* @__PURE__ */ React2.createElement("span", {
4240
+ className: "sr-only"
4241
+ }, t("comment label")));
4020
4242
  };
4021
- var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
4022
- role: "none"
4023
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4024
- Icon: TextB,
4025
- title: "String",
4026
- disable: (s) => s.blockType === "codeblock",
4027
- getState: (s) => s.strong,
4028
- onClick: (s) => ({
4029
- type: "strong",
4030
- data: s ? !s.strong : null
4031
- })
4032
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4033
- Icon: TextItalic,
4034
- title: "Emphasis",
4035
- disable: (s) => s.blockType === "codeblock",
4036
- getState: (s) => s.emphasis,
4037
- onClick: (s) => ({
4038
- type: "emphasis",
4039
- data: s ? !s.emphasis : null
4040
- })
4041
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4042
- Icon: TextStrikethrough,
4043
- title: "Strike-through",
4044
- disable: (s) => s.blockType === "codeblock",
4045
- getState: (s) => s.strikethrough,
4046
- onClick: (s) => ({
4047
- type: "strikethrough",
4048
- data: s ? !s.strikethrough : null
4049
- })
4050
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4051
- Icon: Code,
4052
- title: "Inline code",
4053
- disable: (s) => s.blockType === "codeblock",
4054
- getState: (s) => s.code,
4055
- onClick: (s) => ({
4056
- type: "code",
4057
- data: s ? !s.code : null
4058
- })
4059
- }));
4060
- var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
4061
- role: "none"
4062
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4063
- Icon: ListBullets,
4064
- title: "Bullet list",
4065
- getState: (s) => s.listStyle === "bullet",
4066
- onClick: (s) => ({
4067
- type: "list-bullet",
4068
- data: s ? s.listStyle !== "bullet" : null
4069
- })
4070
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4071
- Icon: ListNumbers,
4072
- title: "Numbered list",
4073
- getState: (s) => s.listStyle === "ordered",
4074
- onClick: (s) => ({
4075
- type: "list-ordered",
4076
- data: s ? s.listStyle !== "ordered" : null
4077
- })
4078
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4079
- Icon: ListChecks,
4080
- title: "Task list",
4081
- getState: (s) => s.listStyle === "task",
4082
- onClick: (s) => ({
4083
- type: "list-tasks",
4084
- data: s ? s.listStyle !== "task" : null
4085
- })
4086
- }));
4087
- var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
4088
- role: "none"
4089
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4090
- Icon: CaretRight,
4091
- title: "Block quote",
4092
- getState: (s) => s.blockQuote,
4093
- onClick: (s) => ({
4094
- type: "blockquote",
4095
- data: s ? !s.blockQuote : null
4096
- })
4097
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4098
- Icon: CodeBlock,
4099
- title: "Code block",
4100
- disable: (s) => !s.blankLine,
4101
- getState: (s) => s.blockType === "codeblock",
4102
- onClick: (s) => ({
4103
- type: "codeblock",
4104
- data: s ? s.blockType !== "codeblock" : null
4105
- })
4106
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4107
- Icon: Table2,
4108
- title: "Table",
4109
- disable: (s) => !s.blankLine,
4110
- onClick: () => ({
4111
- type: "table"
4112
- })
4113
- }));
4114
- var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
4115
- role: "none"
4116
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4117
- Icon: Link,
4118
- title: "Link",
4119
- getState: (s) => s.link,
4120
- onClick: (s) => ({
4121
- type: "link",
4122
- data: s ? !s.link : null
4123
- })
4124
- }));
4125
- var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(MarkdownHeading, null), /* @__PURE__ */ React2.createElement(MarkdownStyles, null), /* @__PURE__ */ React2.createElement(MarkdownLists, null), /* @__PURE__ */ React2.createElement(MarkdownBlocks, null), /* @__PURE__ */ React2.createElement(MarkdownLinks, null));
4126
- var MarkdownExtended = () => /* @__PURE__ */ React2.createElement(Toolbar.Button, {
4127
- Icon: ChatText,
4128
- title: "Create comment",
4129
- onClick: () => ({
4130
- type: "comment"
4131
- })
4132
- });
4133
4243
  var Toolbar = {
4134
4244
  Root: ToolbarRoot,
4135
4245
  Button: ToolbarButton,
@@ -4243,8 +4353,8 @@ var SpaceAwarenessProvider = class {
4243
4353
  };
4244
4354
 
4245
4355
  // packages/ui/react-ui-editor/src/hooks/defs.ts
4246
- import { StateField as StateField5 } from "@codemirror/state";
4247
- var modelState = StateField5.define({
4356
+ import { StateField as StateField6 } from "@codemirror/state";
4357
+ var modelState = StateField6.define({
4248
4358
  create: () => void 0,
4249
4359
  update: (model) => model
4250
4360
  });
@@ -4311,10 +4421,10 @@ var useEditorView = () => {
4311
4421
 
4312
4422
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
4313
4423
  import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
4314
- import { EditorView as EditorView15 } from "@codemirror/view";
4424
+ import { EditorView as EditorView16 } from "@codemirror/view";
4315
4425
  import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
4316
4426
  import { log as log4 } from "@dxos/log";
4317
- import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
4427
+ import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
4318
4428
  var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
4319
4429
  var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
4320
4430
  const onUpdate = useRef2();
@@ -4327,7 +4437,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4327
4437
  selection,
4328
4438
  extensions: [
4329
4439
  // TODO(burdon): Doesn't catch errors in keymap functions.
4330
- EditorView15.exceptionSink.of((err) => {
4440
+ EditorView16.exceptionSink.of((err) => {
4331
4441
  log4.catch(err, void 0, {
4332
4442
  F: __dxlog_file5,
4333
4443
  L: 57,
@@ -4336,12 +4446,12 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4336
4446
  });
4337
4447
  }),
4338
4448
  extensions,
4339
- EditorView15.updateListener.of(() => {
4449
+ EditorView16.updateListener.of(() => {
4340
4450
  onUpdate.current?.();
4341
4451
  })
4342
- ].filter(isNotFalsy4)
4452
+ ].filter(isNotFalsy5)
4343
4453
  });
4344
- const view2 = new EditorView15({
4454
+ const view2 = new EditorView16({
4345
4455
  parent: parentRef.current,
4346
4456
  scrollTo,
4347
4457
  state,
@@ -4398,22 +4508,22 @@ var createDataExtensions = ({ readonly = false } = {}) => {
4398
4508
  return [
4399
4509
  //
4400
4510
  EditorState3.readOnly.of(readonly),
4401
- EditorView15.editable.of(!readonly)
4511
+ EditorView16.editable.of(!readonly)
4402
4512
  ];
4403
4513
  };
4404
4514
  var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
4405
4515
  return [
4406
4516
  //
4407
- EditorView15.baseTheme(defaultTheme),
4408
- theme && EditorView15.theme(theme),
4409
- EditorView15.darkTheme.of(themeMode === "dark"),
4410
- EditorView15.editorAttributes.of({
4517
+ EditorView16.baseTheme(defaultTheme),
4518
+ theme && EditorView16.theme(theme),
4519
+ EditorView16.darkTheme.of(themeMode === "dark"),
4520
+ EditorView16.editorAttributes.of({
4411
4521
  class: slots?.editor?.className ?? ""
4412
4522
  }),
4413
- EditorView15.contentAttributes.of({
4523
+ EditorView16.contentAttributes.of({
4414
4524
  class: slots?.content?.className ?? ""
4415
4525
  })
4416
- ].filter(isNotFalsy4);
4526
+ ].filter(isNotFalsy5);
4417
4527
  };
4418
4528
 
4419
4529
  // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
@@ -4444,9 +4554,12 @@ var useInMemoryTextModel = ({ id, defaultContent }) => {
4444
4554
  };
4445
4555
  };
4446
4556
  var createModel = ({ space, identity, text }) => {
4557
+ if (!text) {
4558
+ return void 0;
4559
+ }
4447
4560
  invariant3(isAutomergeObject(text), void 0, {
4448
4561
  F: __dxlog_file6,
4449
- L: 50,
4562
+ L: 54,
4450
4563
  S: void 0,
4451
4564
  A: [
4452
4565
  "isAutomergeObject(text)",
@@ -4468,7 +4581,6 @@ var createModel = ({ space, identity, text }) => {
4468
4581
  peerId: identity?.identityKey.toHex() ?? "Anonymous"
4469
4582
  });
4470
4583
  const extensions = [
4471
- //
4472
4584
  modelState.init(() => model),
4473
4585
  automerge({
4474
4586
  handle: doc.handle,
@@ -4510,6 +4622,7 @@ export {
4510
4622
  addLink,
4511
4623
  addList,
4512
4624
  addStyle,
4625
+ annotations,
4513
4626
  autocomplete,
4514
4627
  automerge,
4515
4628
  awareness,
@@ -4530,6 +4643,7 @@ export {
4530
4643
  defaultSlots,
4531
4644
  defaultTextSlots,
4532
4645
  defaultTheme,
4646
+ editorWithToolbarLayout,
4533
4647
  focusComment,
4534
4648
  formatting,
4535
4649
  getFormatting,