@dxos/react-ui-editor 0.8.4-main.406dc2a → 0.8.4-main.548089c

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 (108) hide show
  1. package/dist/lib/browser/index.mjs +1379 -1139
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +1379 -1139
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/Editor/Editor.stories.d.ts +0 -3
  8. package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +17 -2
  10. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  11. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  12. package/dist/types/src/components/EditorToolbar/util.d.ts +5 -19
  13. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  14. package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
  15. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  16. package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
  17. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  18. package/dist/types/src/extensions/automerge/sync.d.ts +1 -1
  19. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  20. package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -1
  21. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  22. package/dist/types/src/extensions/autoscroll.d.ts +14 -4
  23. package/dist/types/src/extensions/autoscroll.d.ts.map +1 -1
  24. package/dist/types/src/extensions/awareness/awareness-provider.d.ts +1 -1
  25. package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
  26. package/dist/types/src/extensions/blocks.d.ts +2 -0
  27. package/dist/types/src/extensions/blocks.d.ts.map +1 -0
  28. package/dist/types/src/extensions/bookmarks.d.ts +12 -0
  29. package/dist/types/src/extensions/bookmarks.d.ts.map +1 -0
  30. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  31. package/dist/types/src/extensions/factories.d.ts +4 -4
  32. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  33. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  34. package/dist/types/src/extensions/index.d.ts +4 -0
  35. package/dist/types/src/extensions/index.d.ts.map +1 -1
  36. package/dist/types/src/extensions/listener.d.ts +8 -6
  37. package/dist/types/src/extensions/listener.d.ts.map +1 -1
  38. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  39. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -2
  40. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  41. package/dist/types/src/extensions/popover/PopoverMenuProvider.d.ts +1 -1
  42. package/dist/types/src/extensions/popover/PopoverMenuProvider.d.ts.map +1 -1
  43. package/dist/types/src/extensions/popover/popover.d.ts.map +1 -1
  44. package/dist/types/src/extensions/preview/preview.d.ts +6 -2
  45. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
  46. package/dist/types/src/extensions/replacer.d.ts +21 -0
  47. package/dist/types/src/extensions/replacer.d.ts.map +1 -0
  48. package/dist/types/src/extensions/replacer.test.d.ts +2 -0
  49. package/dist/types/src/extensions/replacer.test.d.ts.map +1 -0
  50. package/dist/types/src/extensions/scrolling.d.ts +78 -0
  51. package/dist/types/src/extensions/scrolling.d.ts.map +1 -0
  52. package/dist/types/src/extensions/tags/xml-tags.d.ts +41 -16
  53. package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -1
  54. package/dist/types/src/stories/CommandDialog.stories.d.ts.map +1 -1
  55. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  56. package/dist/types/src/stories/Popover.stories.d.ts.map +1 -1
  57. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  58. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -1
  59. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  60. package/dist/types/src/stories/components/util.d.ts.map +1 -1
  61. package/dist/types/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +41 -38
  63. package/src/components/Editor/Editor.stories.tsx +4 -7
  64. package/src/components/EditorToolbar/EditorToolbar.tsx +90 -90
  65. package/src/components/EditorToolbar/headings.ts +6 -4
  66. package/src/components/EditorToolbar/util.ts +4 -20
  67. package/src/extensions/autocomplete/autocomplete.ts +5 -5
  68. package/src/extensions/automerge/automerge.stories.tsx +1 -1
  69. package/src/extensions/automerge/automerge.ts +1 -1
  70. package/src/extensions/automerge/cursor.ts +1 -1
  71. package/src/extensions/automerge/sync.ts +1 -1
  72. package/src/extensions/automerge/update-automerge.ts +1 -1
  73. package/src/extensions/autoscroll.ts +74 -68
  74. package/src/extensions/awareness/awareness-provider.ts +2 -2
  75. package/src/extensions/blocks.ts +131 -0
  76. package/src/extensions/bookmarks.ts +75 -0
  77. package/src/extensions/comments.ts +2 -1
  78. package/src/extensions/factories.ts +6 -4
  79. package/src/extensions/folding.tsx +1 -2
  80. package/src/extensions/index.ts +4 -0
  81. package/src/extensions/listener.ts +14 -20
  82. package/src/extensions/markdown/bundle.ts +12 -2
  83. package/src/extensions/markdown/decorate.ts +8 -8
  84. package/src/extensions/markdown/formatting.ts +8 -8
  85. package/src/extensions/markdown/highlight.ts +1 -1
  86. package/src/extensions/markdown/image.ts +2 -2
  87. package/src/extensions/markdown/table.ts +6 -6
  88. package/src/extensions/popover/PopoverMenuProvider.tsx +2 -3
  89. package/src/extensions/popover/popover.ts +0 -4
  90. package/src/extensions/preview/preview.ts +14 -9
  91. package/src/extensions/replacer.test.ts +75 -0
  92. package/src/extensions/replacer.ts +93 -0
  93. package/src/extensions/scrolling.ts +189 -0
  94. package/src/extensions/selection.ts +1 -1
  95. package/src/extensions/tags/extended-markdown.test.ts +2 -1
  96. package/src/extensions/tags/xml-tags.ts +310 -203
  97. package/src/extensions/typewriter.ts +1 -1
  98. package/src/stories/CommandDialog.stories.tsx +9 -4
  99. package/src/stories/Comments.stories.tsx +1 -1
  100. package/src/stories/EditorToolbar.stories.tsx +4 -5
  101. package/src/stories/Popover.stories.tsx +4 -6
  102. package/src/stories/Preview.stories.tsx +15 -8
  103. package/src/stories/Tags.stories.tsx +19 -5
  104. package/src/stories/TextEditor.stories.tsx +2 -2
  105. package/src/stories/components/EditorStory.tsx +3 -3
  106. package/src/stories/components/util.tsx +39 -6
  107. package/src/styles/markdown.ts +1 -1
  108. package/src/styles/theme.ts +1 -1
@@ -43,39 +43,27 @@ var translations = [
43
43
 
44
44
  // src/index.ts
45
45
  import { EditorState as EditorState4 } from "@codemirror/state";
46
- import { EditorView as EditorView30, keymap as keymap13 } from "@codemirror/view";
46
+ import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
47
47
  import { tags as tags2 } from "@lezer/highlight";
48
48
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
49
49
 
50
50
  // src/components/Editor/Editor.tsx
51
51
  import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
52
- import { Transaction as Transaction6 } from "@codemirror/state";
53
- import { EditorView as EditorView29 } from "@codemirror/view";
52
+ import { Transaction as Transaction5 } from "@codemirror/state";
53
+ import { EditorView as EditorView32 } from "@codemirror/view";
54
54
  import React4, { forwardRef, useEffect as useEffect4, useImperativeHandle } from "react";
55
- import { mx as mx6 } from "@dxos/react-ui-theme";
55
+ import { mx as mx7 } from "@dxos/react-ui-theme";
56
56
 
57
57
  // src/extensions/annotations.ts
58
58
  import { RangeSetBuilder } from "@codemirror/state";
59
59
  import { Decoration, EditorView, ViewPlugin } from "@codemirror/view";
60
- function _define_property(obj, key, value) {
61
- if (key in obj) {
62
- Object.defineProperty(obj, key, {
63
- value,
64
- enumerable: true,
65
- configurable: true,
66
- writable: true
67
- });
68
- } else {
69
- obj[key] = value;
70
- }
71
- return obj;
72
- }
73
60
  var annotationMark = Decoration.mark({
74
61
  class: "cm-annotation"
75
62
  });
76
63
  var annotations = ({ match } = {}) => {
77
64
  return [
78
65
  ViewPlugin.fromClass(class {
66
+ decorations = Decoration.none;
79
67
  update(update2) {
80
68
  const builder = new RangeSetBuilder();
81
69
  if (match) {
@@ -92,9 +80,6 @@ var annotations = ({ match } = {}) => {
92
80
  }
93
81
  this.decorations = builder.finish();
94
82
  }
95
- constructor() {
96
- _define_property(this, "decorations", Decoration.none);
97
- }
98
83
  }, {
99
84
  decorations: (v) => v.decorations
100
85
  }),
@@ -111,21 +96,13 @@ var annotations = ({ match } = {}) => {
111
96
  // src/extensions/autocomplete/autocomplete.ts
112
97
  import { Prec } from "@codemirror/state";
113
98
  import { Decoration as Decoration2, EditorView as EditorView2, ViewPlugin as ViewPlugin2, WidgetType, keymap } from "@codemirror/view";
114
- function _define_property2(obj, key, value) {
115
- if (key in obj) {
116
- Object.defineProperty(obj, key, {
117
- value,
118
- enumerable: true,
119
- configurable: true,
120
- writable: true
121
- });
122
- } else {
123
- obj[key] = value;
124
- }
125
- return obj;
126
- }
127
99
  var autocomplete = ({ fireIfEmpty, onSubmit, onSuggest, onCancel } = {}) => {
128
100
  const suggest = ViewPlugin2.fromClass(class {
101
+ _decorations;
102
+ _currentSuggestion = null;
103
+ constructor(view) {
104
+ this._decorations = this.computeDecorations(view);
105
+ }
129
106
  update(update2) {
130
107
  if (update2.docChanged || update2.selectionSet) {
131
108
  this._decorations = this.computeDecorations(update2.view);
@@ -170,11 +147,6 @@ var autocomplete = ({ fireIfEmpty, onSubmit, onSuggest, onCancel } = {}) => {
170
147
  });
171
148
  return true;
172
149
  }
173
- constructor(view) {
174
- _define_property2(this, "_decorations", void 0);
175
- _define_property2(this, "_currentSuggestion", null);
176
- this._decorations = this.computeDecorations(view);
177
- }
178
150
  }, {
179
151
  decorations: (v) => v._decorations
180
152
  });
@@ -261,18 +233,19 @@ var autocomplete = ({ fireIfEmpty, onSubmit, onSuggest, onCancel } = {}) => {
261
233
  ];
262
234
  };
263
235
  var InlineSuggestionWidget = class extends WidgetType {
236
+ suffix;
237
+ constructor(suffix) {
238
+ super(), this.suffix = suffix;
239
+ }
240
+ eq(other) {
241
+ return this.suffix === other.suffix;
242
+ }
264
243
  toDOM() {
265
244
  const span = document.createElement("span");
266
245
  span.textContent = this.suffix;
267
246
  span.className = "cm-inline-suggestion";
268
247
  return span;
269
248
  }
270
- eq(other) {
271
- return other.suffix === this.suffix;
272
- }
273
- constructor(suffix) {
274
- super(), _define_property2(this, "suffix", void 0), this.suffix = suffix;
275
- }
276
249
  };
277
250
 
278
251
  // src/extensions/autocomplete/match.ts
@@ -312,46 +285,33 @@ var singleValueFacet = (defaultValue) => Facet.define({
312
285
  });
313
286
 
314
287
  // src/util/cursor.ts
315
- function _define_property3(obj, key, value) {
316
- if (key in obj) {
317
- Object.defineProperty(obj, key, {
318
- value,
319
- enumerable: true,
320
- configurable: true,
321
- writable: true
322
- });
323
- } else {
324
- obj[key] = value;
325
- }
326
- return obj;
327
- }
328
288
  var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
329
289
  var defaultCursorConverter = {
330
290
  toCursor: (position) => position.toString(),
331
291
  fromCursor: (cursor2) => parseInt(cursor2)
332
292
  };
333
- var Cursor = class {
293
+ var Cursor = class _Cursor {
294
+ static converter = singleValueFacet(defaultCursorConverter);
295
+ static getCursorFromRange = (state, range) => {
296
+ const cursorConverter2 = state.facet(_Cursor.converter);
297
+ const from = cursorConverter2.toCursor(range.from);
298
+ const to = cursorConverter2.toCursor(range.to, -1);
299
+ return [
300
+ from,
301
+ to
302
+ ].join(":");
303
+ };
304
+ static getRangeFromCursor = (state, cursor2) => {
305
+ const cursorConverter2 = state.facet(_Cursor.converter);
306
+ const parts = cursor2.split(":");
307
+ const from = cursorConverter2.fromCursor(parts[0]);
308
+ const to = cursorConverter2.fromCursor(parts[1]);
309
+ return from !== void 0 && to !== void 0 ? {
310
+ from,
311
+ to
312
+ } : void 0;
313
+ };
334
314
  };
335
- _define_property3(Cursor, "converter", singleValueFacet(defaultCursorConverter));
336
- _define_property3(Cursor, "getCursorFromRange", (state, range) => {
337
- const cursorConverter2 = state.facet(Cursor.converter);
338
- const from = cursorConverter2.toCursor(range.from);
339
- const to = cursorConverter2.toCursor(range.to, -1);
340
- return [
341
- from,
342
- to
343
- ].join(":");
344
- });
345
- _define_property3(Cursor, "getRangeFromCursor", (state, cursor2) => {
346
- const cursorConverter2 = state.facet(Cursor.converter);
347
- const parts = cursor2.split(":");
348
- const from = cursorConverter2.fromCursor(parts[0]);
349
- const to = cursorConverter2.fromCursor(parts[1]);
350
- return from !== void 0 && to !== void 0 ? {
351
- from,
352
- to
353
- } : void 0;
354
- });
355
315
 
356
316
  // src/util/decorations.ts
357
317
  var decorationSetToArray = (deco) => {
@@ -475,21 +435,10 @@ var createRenderer = (Component) => (el, props) => {
475
435
  };
476
436
 
477
437
  // src/extensions/autocomplete/placeholder.ts
478
- function _define_property4(obj, key, value) {
479
- if (key in obj) {
480
- Object.defineProperty(obj, key, {
481
- value,
482
- enumerable: true,
483
- configurable: true,
484
- writable: true
485
- });
486
- } else {
487
- obj[key] = value;
488
- }
489
- return obj;
490
- }
491
438
  var placeholder = ({ content, delay = 3e3 }) => {
492
439
  const plugin = ViewPlugin3.fromClass(class {
440
+ _timeout;
441
+ _decorations = Decoration3.none;
493
442
  update(update2) {
494
443
  if (this._timeout) {
495
444
  window.clearTimeout(this._timeout);
@@ -516,10 +465,6 @@ var placeholder = ({ content, delay = 3e3 }) => {
516
465
  clearTimeout(this._timeout);
517
466
  }
518
467
  }
519
- constructor() {
520
- _define_property4(this, "_timeout", void 0);
521
- _define_property4(this, "_decorations", Decoration3.none);
522
- }
523
468
  }, {
524
469
  provide: (plugin2) => {
525
470
  return [
@@ -535,6 +480,10 @@ var placeholder = ({ content, delay = 3e3 }) => {
535
480
  ] : plugin;
536
481
  };
537
482
  var PlaceholderWidget = class extends WidgetType2 {
483
+ content;
484
+ constructor(content) {
485
+ super(), this.content = content;
486
+ }
538
487
  toDOM(view) {
539
488
  const wrap = document.createElement("span");
540
489
  wrap.className = "cm-placeholder";
@@ -550,13 +499,13 @@ var PlaceholderWidget = class extends WidgetType2 {
550
499
  }
551
500
  const style = getComputedStyle(dom.parentNode);
552
501
  const rect = flattenRect(rects[0], style.direction !== "rtl");
553
- const lineHeight2 = parseInt(style.lineHeight);
554
- if (rect.bottom - rect.top > lineHeight2 * 1.5) {
502
+ const lineHeight = parseInt(style.lineHeight);
503
+ if (rect.bottom - rect.top > lineHeight * 1.5) {
555
504
  return {
556
505
  left: rect.left,
557
506
  right: rect.right,
558
507
  top: rect.top,
559
- bottom: rect.top + lineHeight2
508
+ bottom: rect.top + lineHeight
560
509
  };
561
510
  }
562
511
  return rect;
@@ -564,27 +513,11 @@ var PlaceholderWidget = class extends WidgetType2 {
564
513
  ignoreEvent() {
565
514
  return false;
566
515
  }
567
- constructor(content) {
568
- super(), _define_property4(this, "content", void 0), this.content = content;
569
- }
570
516
  };
571
517
 
572
518
  // src/extensions/autocomplete/typeahead.ts
573
519
  import { EditorSelection, Prec as Prec2, RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
574
520
  import { Decoration as Decoration4, ViewPlugin as ViewPlugin4, keymap as keymap2 } from "@codemirror/view";
575
- function _define_property5(obj, key, value) {
576
- if (key in obj) {
577
- Object.defineProperty(obj, key, {
578
- value,
579
- enumerable: true,
580
- configurable: true,
581
- writable: true
582
- });
583
- } else {
584
- obj[key] = value;
585
- }
586
- return obj;
587
- }
588
521
  var typeahead = ({ onComplete } = {}) => {
589
522
  let hint;
590
523
  const complete = (view) => {
@@ -606,6 +539,7 @@ var typeahead = ({ onComplete } = {}) => {
606
539
  };
607
540
  return [
608
541
  ViewPlugin4.fromClass(class {
542
+ decorations = Decoration4.none;
609
543
  update(update2) {
610
544
  const builder = new RangeSetBuilder2();
611
545
  const selection = update2.view.state.selection.main;
@@ -623,9 +557,6 @@ var typeahead = ({ onComplete } = {}) => {
623
557
  }
624
558
  this.decorations = builder.finish();
625
559
  }
626
- constructor() {
627
- _define_property5(this, "decorations", Decoration4.none);
628
- }
629
560
  }, {
630
561
  decorations: (v) => v.decorations
631
562
  }),
@@ -646,97 +577,207 @@ var typeahead = ({ onComplete } = {}) => {
646
577
  };
647
578
 
648
579
  // src/extensions/autoscroll.ts
580
+ import { StateEffect as StateEffect2 } from "@codemirror/state";
581
+ import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
582
+ import { debounce } from "@dxos/async";
583
+ import { Domino } from "@dxos/react-ui";
584
+
585
+ // src/extensions/scrolling.ts
649
586
  import { StateEffect } from "@codemirror/state";
650
587
  import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
651
- import { Domino } from "@dxos/react-ui";
652
- var lineHeight = 24;
653
- var scrollToBottomEffect = StateEffect.define();
654
- var autoScroll = ({ overscroll = 4 * lineHeight, throttle: throttle2 = 2e3 } = {}) => {
655
- let isThrottled = false;
656
- let isPinned = true;
657
- let timeout;
588
+ var scrollToLineEffect = StateEffect.define();
589
+ var smoothScroll = ({ offset = 0, position = "start" } = {}) => {
590
+ const scrollPlugin = ViewPlugin5.fromClass(class SmoothScrollPlugin {
591
+ view;
592
+ constructor(view) {
593
+ this.view = view;
594
+ }
595
+ // No-op.
596
+ destroy() {
597
+ }
598
+ /**
599
+ * Perform smooth scroll to the specified line.
600
+ */
601
+ scrollToLine(lineNumber, options) {
602
+ const { offset: animOffset = 0, position: animPosition, behavior } = options;
603
+ const doc = this.view.state.doc;
604
+ const scroller = this.view.scrollDOM;
605
+ const targetLine = Math.max(0, lineNumber - 1);
606
+ if (behavior === "instant") {
607
+ requestAnimationFrame(() => {
608
+ this.view.dispatch({
609
+ selection: {
610
+ anchor: doc.line(targetLine + 1).from
611
+ },
612
+ scrollIntoView: true
613
+ });
614
+ });
615
+ return;
616
+ }
617
+ if (targetLine >= doc.lines) {
618
+ const targetScrollTop2 = scroller.scrollHeight - scroller.clientHeight + (animOffset || 0);
619
+ this.animateScroll(scroller, targetScrollTop2);
620
+ return;
621
+ }
622
+ const lineStart = doc.line(targetLine + 1).from;
623
+ const coords = this.view.coordsAtPos(lineStart);
624
+ if (!coords) {
625
+ return;
626
+ }
627
+ const currentScrollTop = scroller.scrollTop;
628
+ const scrollerRect = scroller.getBoundingClientRect();
629
+ const maxScrollTop = scroller.scrollHeight - scroller.clientHeight;
630
+ let targetScrollTop;
631
+ if (animPosition === "end") {
632
+ targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + animOffset;
633
+ } else {
634
+ targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + animOffset;
635
+ }
636
+ const clampedScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
637
+ this.animateScroll(scroller, clampedScrollTop);
638
+ }
639
+ /**
640
+ * Animate scroll using browser's built-in smooth scrolling.
641
+ */
642
+ animateScroll(element, targetScrollTop) {
643
+ if (Math.abs(targetScrollTop - element.scrollTop) < 1) {
644
+ return;
645
+ }
646
+ element.scrollTo({
647
+ top: targetScrollTop,
648
+ behavior: "smooth"
649
+ });
650
+ }
651
+ });
652
+ return [
653
+ scrollPlugin,
654
+ // Update listener to handle scroll effects.
655
+ EditorView4.updateListener.of((update2) => {
656
+ update2.transactions.forEach((transaction) => {
657
+ for (const effect of transaction.effects) {
658
+ if (effect.is(scrollToLineEffect)) {
659
+ const { line, options = {} } = effect.value;
660
+ const plugin = update2.view.plugin(scrollPlugin);
661
+ if (plugin) {
662
+ plugin.scrollToLine(line, {
663
+ offset,
664
+ position,
665
+ ...options
666
+ });
667
+ }
668
+ }
669
+ }
670
+ });
671
+ })
672
+ ];
673
+ };
674
+ var scrollToLine = (view, line, options) => {
675
+ view.dispatch({
676
+ effects: scrollToLineEffect.of({
677
+ line,
678
+ options
679
+ })
680
+ });
681
+ };
682
+
683
+ // src/extensions/autoscroll.ts
684
+ var scrollToBottomEffect = StateEffect2.define();
685
+ var autoScroll = ({ autoScroll: autoScroll2 = true, threshold = 100, throttleDelay = 1e3, onAutoScroll } = {}) => {
658
686
  let buttonContainer;
687
+ let hideTimeout;
659
688
  let lastScrollTop = 0;
660
- let scrollCounter = 0;
689
+ let isPinned = true;
690
+ const setPinned = (pin) => {
691
+ isPinned = pin;
692
+ buttonContainer?.classList.toggle("opacity-0", pin);
693
+ };
661
694
  const hideScrollbar = (view) => {
662
695
  view.scrollDOM.classList.add("cm-hide-scrollbar");
663
- clearTimeout(timeout);
664
- timeout = setTimeout(() => {
696
+ clearTimeout(hideTimeout);
697
+ hideTimeout = setTimeout(() => {
665
698
  view.scrollDOM.classList.remove("cm-hide-scrollbar");
666
699
  }, 1e3);
667
700
  };
668
- const scrollToBottom = (view) => {
669
- isPinned = true;
670
- scrollCounter = 0;
671
- buttonContainer?.classList.add("opacity-0");
672
- requestAnimationFrame(() => {
673
- hideScrollbar(view);
674
- view.scrollDOM.scrollTo({
675
- top: view.scrollDOM.scrollHeight,
676
- behavior: "smooth"
677
- });
701
+ const scrollToBottom = (view, behavior) => {
702
+ setPinned(true);
703
+ hideScrollbar(view);
704
+ const line = view.state.doc.lineAt(view.state.doc.length);
705
+ view.dispatch({
706
+ selection: {
707
+ anchor: line.to,
708
+ head: line.to
709
+ },
710
+ effects: scrollToLineEffect.of({
711
+ line: line.number,
712
+ options: {
713
+ position: "end",
714
+ offset: threshold,
715
+ behavior
716
+ }
717
+ })
678
718
  });
679
719
  };
720
+ const checkDistance = debounce((view) => {
721
+ const scrollerRect = view.scrollDOM.getBoundingClientRect();
722
+ const coords = view.coordsAtPos(view.state.doc.length);
723
+ const distanceFromBottom = coords ? coords.bottom - scrollerRect.bottom : 0;
724
+ setPinned(distanceFromBottom < 0);
725
+ }, 1e3);
726
+ const triggerUpdate = debounce((view) => scrollToBottom(view), throttleDelay);
680
727
  return [
681
728
  // Update listener for logging when scrolling is needed.
682
- EditorView4.updateListener.of((update2) => {
683
- update2.transactions.forEach((transaction) => {
729
+ EditorView5.updateListener.of(({ view, transactions, heightChanged }) => {
730
+ transactions.forEach((transaction) => {
684
731
  for (const effect of transaction.effects) {
685
732
  if (effect.is(scrollToBottomEffect)) {
686
- scrollToBottom(update2.view);
733
+ scrollToBottom(view, effect.value);
687
734
  }
688
735
  }
689
736
  });
690
- if (update2.docChanged && isPinned && !isThrottled) {
691
- const distanceFromBottom = calcDistance(update2.view.scrollDOM);
692
- if (distanceFromBottom >= overscroll) {
693
- isThrottled = true;
694
- requestAnimationFrame(() => {
695
- scrollToBottom(update2.view);
696
- });
697
- setTimeout(() => {
698
- isThrottled = false;
699
- scrollToBottom(update2.view);
700
- }, throttle2);
737
+ if (heightChanged && isPinned) {
738
+ const coords = view.coordsAtPos(view.state.doc.length);
739
+ const scrollerRect = view.scrollDOM.getBoundingClientRect();
740
+ const distanceFromBottom = coords ? scrollerRect.bottom - coords.bottom : 0;
741
+ if (autoScroll2 && distanceFromBottom < threshold) {
742
+ const shouldScroll = onAutoScroll?.({
743
+ view,
744
+ distanceFromBottom
745
+ }) ?? true;
746
+ if (shouldScroll) {
747
+ triggerUpdate(view);
748
+ }
749
+ } else if (distanceFromBottom < 0) {
750
+ setPinned(false);
701
751
  }
702
752
  }
703
753
  }),
704
754
  // Detect user scroll.
705
- // NOTE: Multiple scroll events are triggered during programmatic smooth scrolling.
706
- EditorView4.domEventHandlers({
755
+ EditorView5.domEventHandlers({
707
756
  scroll: (event, view) => {
708
- const scroller = view.scrollDOM;
709
- if (lastScrollTop > scroller.scrollTop) {
710
- scrollCounter++;
711
- }
712
- lastScrollTop = scroller.scrollTop;
713
- const distanceFromBottom = calcDistance(scroller);
714
- if (distanceFromBottom === 0) {
715
- isPinned = true;
716
- buttonContainer?.classList.add("opacity-0");
717
- scrollCounter = 0;
718
- } else if (scrollCounter > 3) {
719
- isPinned = false;
720
- buttonContainer?.classList.remove("opacity-0");
757
+ const currentScrollTop = view.scrollDOM.scrollTop;
758
+ const scrollingUp = currentScrollTop < lastScrollTop;
759
+ lastScrollTop = currentScrollTop;
760
+ if (scrollingUp) {
761
+ setPinned(false);
762
+ } else {
763
+ checkDistance(view);
721
764
  }
722
765
  }
723
766
  }),
724
767
  // Scroll button.
725
- ViewPlugin5.fromClass(class {
768
+ ViewPlugin6.fromClass(class {
726
769
  constructor(view) {
727
- const scroller = view.scrollDOM.parentElement;
728
770
  buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").children(Domino.of("button").classNames("dx-button bg-accentSurface").data("density", "fine").children(Domino.of("dx-icon").attributes({
729
771
  icon: "ph--arrow-down--regular"
730
772
  })).on("click", () => {
731
773
  scrollToBottom(view);
732
774
  })).build();
733
- scroller?.appendChild(buttonContainer);
775
+ view.scrollDOM.parentElement.appendChild(buttonContainer);
734
776
  }
735
777
  }),
736
778
  // Styles.
737
- EditorView4.theme({
779
+ EditorView5.theme({
738
780
  ".cm-scroller": {
739
- paddingBottom: `${overscroll}px`,
740
781
  scrollbarWidth: "thin"
741
782
  },
742
783
  ".cm-scroller.cm-hide-scrollbar": {
@@ -753,27 +794,20 @@ var autoScroll = ({ overscroll = 4 * lineHeight, throttle: throttle2 = 2e3 } = {
753
794
  })
754
795
  ];
755
796
  };
756
- var calcDistance = (scroller) => {
757
- const scrollTop = scroller.scrollTop;
758
- const scrollHeight = scroller.scrollHeight;
759
- const clientHeight = scroller.clientHeight;
760
- const distanceFromBottom = scrollHeight - (scrollTop + clientHeight);
761
- return distanceFromBottom;
762
- };
763
797
 
764
798
  // src/extensions/automerge/automerge.ts
765
799
  import { next as A3 } from "@automerge/automerge";
766
800
  import { StateField, Transaction as Transaction2 } from "@codemirror/state";
767
- import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
768
- import { DocAccessor } from "@dxos/react-client/echo";
801
+ import { EditorView as EditorView6, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
802
+ import { DocAccessor } from "@dxos/client/echo";
769
803
 
770
804
  // src/extensions/state.ts
771
805
  import { Transaction } from "@codemirror/state";
772
806
  var initialSync = Transaction.userEvent.of("initial.sync");
773
807
 
774
808
  // src/extensions/automerge/cursor.ts
809
+ import { fromCursor, toCursor } from "@dxos/client/echo";
775
810
  import { log as log2 } from "@dxos/log";
776
- import { fromCursor, toCursor } from "@dxos/react-client/echo";
777
811
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
778
812
  var cursorConverter = (accessor) => ({
779
813
  toCursor: (pos, assoc) => {
@@ -805,10 +839,10 @@ var cursorConverter = (accessor) => ({
805
839
  });
806
840
 
807
841
  // src/extensions/automerge/defs.ts
808
- import { Annotation, StateEffect as StateEffect2 } from "@codemirror/state";
842
+ import { Annotation, StateEffect as StateEffect3 } from "@codemirror/state";
809
843
  var getPath = (state, field) => state.field(field).path;
810
844
  var getLastHeads = (state, field) => state.field(field).lastHeads;
811
- var updateHeadsEffect = StateEffect2.define({});
845
+ var updateHeadsEffect = StateEffect3.define({});
812
846
  var updateHeads = (newHeads) => updateHeadsEffect.of({
813
847
  newHeads
814
848
  });
@@ -960,21 +994,16 @@ var charPath = (textPath, candidatePath) => {
960
994
  };
961
995
 
962
996
  // src/extensions/automerge/sync.ts
963
- function _define_property6(obj, key, value) {
964
- if (key in obj) {
965
- Object.defineProperty(obj, key, {
966
- value,
967
- enumerable: true,
968
- configurable: true,
969
- writable: true
970
- });
971
- } else {
972
- obj[key] = value;
973
- }
974
- return obj;
975
- }
976
997
  var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/sync.ts";
977
998
  var Syncer = class {
999
+ _handle;
1000
+ _state;
1001
+ _pending = false;
1002
+ // prettier-ignore
1003
+ constructor(_handle, _state) {
1004
+ this._handle = _handle;
1005
+ this._state = _state;
1006
+ }
978
1007
  reconcile(view, editor2) {
979
1008
  if (this._pending) {
980
1009
  return;
@@ -1021,31 +1050,9 @@ var Syncer = class {
1021
1050
  annotations: reconcileAnnotation.of(false)
1022
1051
  });
1023
1052
  }
1024
- // prettier-ignore
1025
- constructor(_handle, _state) {
1026
- _define_property6(this, "_handle", void 0);
1027
- _define_property6(this, "_state", void 0);
1028
- _define_property6(this, "_pending", void 0);
1029
- this._handle = _handle;
1030
- this._state = _state;
1031
- this._pending = false;
1032
- }
1033
1053
  };
1034
1054
 
1035
1055
  // src/extensions/automerge/automerge.ts
1036
- function _define_property7(obj, key, value) {
1037
- if (key in obj) {
1038
- Object.defineProperty(obj, key, {
1039
- value,
1040
- enumerable: true,
1041
- configurable: true,
1042
- writable: true
1043
- });
1044
- } else {
1045
- obj[key] = value;
1046
- }
1047
- return obj;
1048
- }
1049
1056
  var automerge = (accessor) => {
1050
1057
  const syncState = StateField.define({
1051
1058
  create: () => {
@@ -1084,17 +1091,10 @@ var automerge = (accessor) => {
1084
1091
  // Track heads.
1085
1092
  syncState,
1086
1093
  // Reconcile external updates.
1087
- ViewPlugin6.fromClass(class {
1088
- destroy() {
1089
- accessor.handle.removeListener("change", this._handleChange);
1090
- }
1094
+ ViewPlugin7.fromClass(class {
1095
+ _view;
1091
1096
  constructor(_view) {
1092
- _define_property7(this, "_view", void 0);
1093
- _define_property7(this, "_handleChange", void 0);
1094
1097
  this._view = _view;
1095
- this._handleChange = () => {
1096
- syncer.reconcile(this._view, false);
1097
- };
1098
1098
  accessor.handle.addListener("change", this._handleChange);
1099
1099
  requestAnimationFrame(() => {
1100
1100
  const value = DocAccessor.getValue(accessor);
@@ -1103,9 +1103,15 @@ var automerge = (accessor) => {
1103
1103
  }
1104
1104
  });
1105
1105
  }
1106
+ destroy() {
1107
+ accessor.handle.removeListener("change", this._handleChange);
1108
+ }
1109
+ _handleChange = () => {
1110
+ syncer.reconcile(this._view, false);
1111
+ };
1106
1112
  }),
1107
1113
  // Reconcile local updates.
1108
- EditorView5.updateListener.of(({ view, changes, transactions }) => {
1114
+ EditorView6.updateListener.of(({ view, changes, transactions }) => {
1109
1115
  if (!changes.empty) {
1110
1116
  const isInitialSync = transactions.some((tr) => tr.annotation(Transaction2.userEvent) === initialSync.value);
1111
1117
  if (!isInitialSync) {
@@ -1118,22 +1124,9 @@ var automerge = (accessor) => {
1118
1124
 
1119
1125
  // src/extensions/awareness/awareness.ts
1120
1126
  import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
1121
- import { Decoration as Decoration5, EditorView as EditorView6, ViewPlugin as ViewPlugin7, WidgetType as WidgetType3 } from "@codemirror/view";
1127
+ import { Decoration as Decoration5, EditorView as EditorView7, ViewPlugin as ViewPlugin8, WidgetType as WidgetType3 } from "@codemirror/view";
1122
1128
  import { Event } from "@dxos/async";
1123
1129
  import { Context } from "@dxos/context";
1124
- function _define_property8(obj, key, value) {
1125
- if (key in obj) {
1126
- Object.defineProperty(obj, key, {
1127
- value,
1128
- enumerable: true,
1129
- configurable: true,
1130
- writable: true
1131
- });
1132
- } else {
1133
- obj[key] = value;
1134
- }
1135
- return obj;
1136
- }
1137
1130
  var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
1138
1131
  var dummyProvider = {
1139
1132
  remoteStateChange: new Event(),
@@ -1150,13 +1143,34 @@ var RemoteSelectionChangedAnnotation = Annotation2.define();
1150
1143
  var awareness = (provider = dummyProvider) => {
1151
1144
  return [
1152
1145
  awarenessProvider.of(provider),
1153
- ViewPlugin7.fromClass(RemoteSelectionsDecorator, {
1146
+ ViewPlugin8.fromClass(RemoteSelectionsDecorator, {
1154
1147
  decorations: (value) => value.decorations
1155
1148
  }),
1156
1149
  styles
1157
1150
  ];
1158
1151
  };
1159
1152
  var RemoteSelectionsDecorator = class {
1153
+ _ctx = new Context(void 0, {
1154
+ F: __dxlog_file4,
1155
+ L: 80
1156
+ });
1157
+ _cursorConverter;
1158
+ _provider;
1159
+ _lastAnchor;
1160
+ _lastHead;
1161
+ decorations = RangeSet.of([]);
1162
+ constructor(view) {
1163
+ this._cursorConverter = view.state.facet(Cursor.converter);
1164
+ this._provider = view.state.facet(awarenessProvider);
1165
+ this._provider.open();
1166
+ this._provider.remoteStateChange.on(this._ctx, () => {
1167
+ view.dispatch({
1168
+ annotations: [
1169
+ RemoteSelectionChangedAnnotation.of([])
1170
+ ]
1171
+ });
1172
+ });
1173
+ }
1160
1174
  destroy() {
1161
1175
  void this._ctx.dispose();
1162
1176
  this._provider.close();
@@ -1251,29 +1265,13 @@ var RemoteSelectionsDecorator = class {
1251
1265
  }
1252
1266
  this.decorations = Decoration5.set(decorations2, true);
1253
1267
  }
1254
- constructor(view) {
1255
- _define_property8(this, "_ctx", new Context(void 0, {
1256
- F: __dxlog_file4,
1257
- L: 80
1258
- }));
1259
- _define_property8(this, "_cursorConverter", void 0);
1260
- _define_property8(this, "_provider", void 0);
1261
- _define_property8(this, "_lastAnchor", void 0);
1262
- _define_property8(this, "_lastHead", void 0);
1263
- _define_property8(this, "decorations", RangeSet.of([]));
1264
- this._cursorConverter = view.state.facet(Cursor.converter);
1265
- this._provider = view.state.facet(awarenessProvider);
1266
- this._provider.open();
1267
- this._provider.remoteStateChange.on(this._ctx, () => {
1268
- view.dispatch({
1269
- annotations: [
1270
- RemoteSelectionChangedAnnotation.of([])
1271
- ]
1272
- });
1273
- });
1274
- }
1275
1268
  };
1276
1269
  var RemoteCaretWidget = class extends WidgetType3 {
1270
+ _name;
1271
+ _color;
1272
+ constructor(_name, _color) {
1273
+ super(), this._name = _name, this._color = _color;
1274
+ }
1277
1275
  toDOM() {
1278
1276
  const span = document.createElement("span");
1279
1277
  span.className = "cm-collab-selectionCaret";
@@ -1303,11 +1301,8 @@ var RemoteCaretWidget = class extends WidgetType3 {
1303
1301
  ignoreEvent() {
1304
1302
  return true;
1305
1303
  }
1306
- constructor(_name, _color) {
1307
- super(), _define_property8(this, "_name", void 0), _define_property8(this, "_color", void 0), this._name = _name, this._color = _color;
1308
- }
1309
1304
  };
1310
- var styles = EditorView6.theme({
1305
+ var styles = EditorView7.theme({
1311
1306
  ".cm-collab-selection": {},
1312
1307
  ".cm-collab-selectionLine": {
1313
1308
  padding: 0,
@@ -1370,22 +1365,24 @@ import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
1370
1365
  import { Context as Context2 } from "@dxos/context";
1371
1366
  import { invariant } from "@dxos/invariant";
1372
1367
  import { log as log4 } from "@dxos/log";
1373
- function _define_property9(obj, key, value) {
1374
- if (key in obj) {
1375
- Object.defineProperty(obj, key, {
1376
- value,
1377
- enumerable: true,
1378
- configurable: true,
1379
- writable: true
1380
- });
1381
- } else {
1382
- obj[key] = value;
1383
- }
1384
- return obj;
1385
- }
1386
1368
  var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness-provider.ts";
1387
1369
  var DEBOUNCE_INTERVAL = 100;
1388
1370
  var SpaceAwarenessProvider = class {
1371
+ _remoteStates = /* @__PURE__ */ new Map();
1372
+ _space;
1373
+ _channel;
1374
+ _peerId;
1375
+ _info;
1376
+ _ctx;
1377
+ _postTask;
1378
+ _localState;
1379
+ remoteStateChange = new Event2();
1380
+ constructor(params) {
1381
+ this._space = params.space;
1382
+ this._channel = params.channel;
1383
+ this._peerId = params.peerId;
1384
+ this._info = params.info;
1385
+ }
1389
1386
  open() {
1390
1387
  this._ctx = new Context2(void 0, {
1391
1388
  F: __dxlog_file5,
@@ -1475,41 +1472,13 @@ var SpaceAwarenessProvider = class {
1475
1472
  this._remoteStates.set(message.state.peerId, message.state);
1476
1473
  this.remoteStateChange.emit();
1477
1474
  }
1478
- constructor(params) {
1479
- _define_property9(this, "_remoteStates", /* @__PURE__ */ new Map());
1480
- _define_property9(this, "_space", void 0);
1481
- _define_property9(this, "_channel", void 0);
1482
- _define_property9(this, "_peerId", void 0);
1483
- _define_property9(this, "_info", void 0);
1484
- _define_property9(this, "_ctx", void 0);
1485
- _define_property9(this, "_postTask", void 0);
1486
- _define_property9(this, "_localState", void 0);
1487
- _define_property9(this, "remoteStateChange", new Event2());
1488
- this._space = params.space;
1489
- this._channel = params.channel;
1490
- this._peerId = params.peerId;
1491
- this._info = params.info;
1492
- }
1493
1475
  };
1494
1476
 
1495
1477
  // src/extensions/blast.ts
1496
- import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
1478
+ import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
1497
1479
  import defaultsDeep from "lodash.defaultsdeep";
1498
1480
  import { throttle } from "@dxos/async";
1499
1481
  import { invariant as invariant2 } from "@dxos/invariant";
1500
- function _define_property10(obj, key, value) {
1501
- if (key in obj) {
1502
- Object.defineProperty(obj, key, {
1503
- value,
1504
- enumerable: true,
1505
- configurable: true,
1506
- writable: true
1507
- });
1508
- } else {
1509
- obj[key] = value;
1510
- }
1511
- return obj;
1512
- }
1513
1482
  var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
1514
1483
  var defaultOptions = {
1515
1484
  effect: 2,
@@ -1555,7 +1524,7 @@ var blast = (options = defaultOptions) => {
1555
1524
  };
1556
1525
  return [
1557
1526
  // Cursor moved.
1558
- EditorView7.updateListener.of((update2) => {
1527
+ EditorView8.updateListener.of((update2) => {
1559
1528
  if (blaster?.node !== update2.view.scrollDOM) {
1560
1529
  if (blaster) {
1561
1530
  blaster.destroy();
@@ -1604,6 +1573,26 @@ var blast = (options = defaultOptions) => {
1604
1573
  ];
1605
1574
  };
1606
1575
  var Blaster = class {
1576
+ _node;
1577
+ _options;
1578
+ _effect;
1579
+ _canvas;
1580
+ _ctx;
1581
+ _running = false;
1582
+ _lastTime;
1583
+ _shakeTime = 0;
1584
+ _shakeTimeMax = 0;
1585
+ _particles = [];
1586
+ _particlePointer = 0;
1587
+ _lastPoint = {
1588
+ x: 0,
1589
+ y: 0
1590
+ };
1591
+ constructor(_node, _options) {
1592
+ this._node = _node;
1593
+ this._options = _options;
1594
+ this._effect = this._options.effect === 1 ? new Effect1(_options) : new Effect2(_options);
1595
+ }
1607
1596
  get node() {
1608
1597
  return this._node;
1609
1598
  }
@@ -1667,7 +1656,7 @@ var Blaster = class {
1667
1656
  }
1668
1657
  this._ctx.clearRect(0, 0, this._canvas.width ?? 0, this._canvas.height ?? 0);
1669
1658
  const now = (/* @__PURE__ */ new Date()).getTime();
1670
- this._lastTime ?? (this._lastTime = now);
1659
+ this._lastTime ??= now;
1671
1660
  const dt = (now - this._lastTime) / 1e3;
1672
1661
  this._lastTime = now;
1673
1662
  if (this._shakeTime > 0) {
@@ -1680,6 +1669,20 @@ var Blaster = class {
1680
1669
  this.drawParticles();
1681
1670
  requestAnimationFrame(this.loop.bind(this));
1682
1671
  }
1672
+ shake = throttle(({ time }) => {
1673
+ this._shakeTime = this._shakeTimeMax || time;
1674
+ this._shakeTimeMax = time;
1675
+ }, 100);
1676
+ spawn = throttle(({ element, point }) => {
1677
+ const color = getRGBComponents(element, this._options.color);
1678
+ const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
1679
+ const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
1680
+ this._lastPoint = point;
1681
+ for (let i = numParticles; i--; i > 0) {
1682
+ this._particles[this._particlePointer] = this._effect.create(point.x - dir * 16, point.y, color);
1683
+ this._particlePointer = (this._particlePointer + 1) % this._options.maxParticles;
1684
+ }
1685
+ }, 100);
1683
1686
  drawParticles() {
1684
1687
  for (let i = this._particles.length; i--; i > 0) {
1685
1688
  const particle = this._particles[i];
@@ -1692,52 +1695,10 @@ var Blaster = class {
1692
1695
  this._effect.update(this._ctx, particle);
1693
1696
  }
1694
1697
  }
1695
- constructor(_node, _options) {
1696
- _define_property10(this, "_node", void 0);
1697
- _define_property10(this, "_options", void 0);
1698
- _define_property10(this, "_effect", void 0);
1699
- _define_property10(this, "_canvas", void 0);
1700
- _define_property10(this, "_ctx", void 0);
1701
- _define_property10(this, "_running", void 0);
1702
- _define_property10(this, "_lastTime", void 0);
1703
- _define_property10(this, "_shakeTime", void 0);
1704
- _define_property10(this, "_shakeTimeMax", void 0);
1705
- _define_property10(this, "_particles", void 0);
1706
- _define_property10(this, "_particlePointer", void 0);
1707
- _define_property10(this, "_lastPoint", void 0);
1708
- _define_property10(this, "shake", void 0);
1709
- _define_property10(this, "spawn", void 0);
1710
- this._node = _node;
1711
- this._options = _options;
1712
- this._running = false;
1713
- this._shakeTime = 0;
1714
- this._shakeTimeMax = 0;
1715
- this._particles = [];
1716
- this._particlePointer = 0;
1717
- this._lastPoint = {
1718
- x: 0,
1719
- y: 0
1720
- };
1721
- this.shake = throttle(({ time }) => {
1722
- this._shakeTime = this._shakeTimeMax || time;
1723
- this._shakeTimeMax = time;
1724
- }, 100);
1725
- this.spawn = throttle(({ element, point }) => {
1726
- const color = getRGBComponents(element, this._options.color);
1727
- const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
1728
- const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
1729
- this._lastPoint = point;
1730
- for (let i = numParticles; i--; i > 0) {
1731
- this._particles[this._particlePointer] = this._effect.create(point.x - dir * 16, point.y, color);
1732
- this._particlePointer = (this._particlePointer + 1) % this._options.maxParticles;
1733
- }
1734
- }, 100);
1735
- this._effect = this._options.effect === 1 ? new Effect1(_options) : new Effect2(_options);
1736
- }
1737
1698
  };
1738
1699
  var Effect = class {
1700
+ _options;
1739
1701
  constructor(_options) {
1740
- _define_property10(this, "_options", void 0);
1741
1702
  this._options = _options;
1742
1703
  }
1743
1704
  };
@@ -1819,20 +1780,173 @@ var random = (min, max) => {
1819
1780
  return min + ~~(Math.random() * (max - min + 1));
1820
1781
  };
1821
1782
 
1822
- // src/extensions/comments.ts
1823
- import { invertedEffects } from "@codemirror/commands";
1824
- import { StateEffect as StateEffect3, StateField as StateField2 } from "@codemirror/state";
1825
- import { Decoration as Decoration6, EditorView as EditorView9, ViewPlugin as ViewPlugin8, hoverTooltip, keymap as keymap5 } from "@codemirror/view";
1826
- import sortBy from "lodash.sortby";
1827
- import { useEffect } from "react";
1828
- import { debounce as debounce2 } from "@dxos/async";
1829
- import { log as log5 } from "@dxos/log";
1830
- import { isNonNullable } from "@dxos/util";
1783
+ // src/extensions/blocks.ts
1784
+ import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
1785
+ import { Decoration as Decoration6, EditorView as EditorView9, ViewPlugin as ViewPlugin9 } from "@codemirror/view";
1786
+ import { mx } from "@dxos/react-ui-theme";
1787
+ var paragraphBlockPlugin = ViewPlugin9.fromClass(class {
1788
+ decorations;
1789
+ constructor(view) {
1790
+ this.decorations = this.build(view);
1791
+ }
1792
+ update(update2) {
1793
+ if (update2.docChanged || update2.viewportChanged) {
1794
+ this.decorations = this.build(update2.view);
1795
+ }
1796
+ }
1797
+ build({ state }) {
1798
+ const builder = new RangeSetBuilder3();
1799
+ const pushBlock = (fromLine, toLine) => {
1800
+ for (let lineNum = fromLine; lineNum <= toLine; lineNum++) {
1801
+ const line = state.doc.line(lineNum);
1802
+ builder.add(line.from, line.from, Decoration6.line({
1803
+ class: mx("block-line", fromLine === toLine && "block-single", lineNum === fromLine && "block-first", lineNum > fromLine && lineNum < toLine && "block-middle", lineNum === toLine && "block-last")
1804
+ }));
1805
+ }
1806
+ };
1807
+ let blockStart = null;
1808
+ let consecutiveBlankLines = 0;
1809
+ const totalLines = state.doc.lines;
1810
+ for (let i = 1; i <= totalLines; i++) {
1811
+ const line = state.doc.line(i);
1812
+ const isBlank = /^\s*$/.test(line.text);
1813
+ if (!isBlank) {
1814
+ consecutiveBlankLines = 0;
1815
+ if (blockStart === null) {
1816
+ blockStart = i;
1817
+ }
1818
+ } else {
1819
+ consecutiveBlankLines++;
1820
+ if (consecutiveBlankLines >= 2 && blockStart !== null) {
1821
+ pushBlock(blockStart, i - consecutiveBlankLines);
1822
+ blockStart = null;
1823
+ }
1824
+ }
1825
+ }
1826
+ if (blockStart !== null) {
1827
+ let lastNonBlankLine = totalLines;
1828
+ while (lastNonBlankLine >= blockStart) {
1829
+ const line = state.doc.line(lastNonBlankLine);
1830
+ if (!/^\s*$/.test(line.text)) {
1831
+ break;
1832
+ }
1833
+ lastNonBlankLine--;
1834
+ }
1835
+ if (lastNonBlankLine >= blockStart) {
1836
+ pushBlock(blockStart, lastNonBlankLine);
1837
+ }
1838
+ }
1839
+ return builder.finish();
1840
+ }
1841
+ }, {
1842
+ decorations: (v) => v.decorations
1843
+ });
1844
+ var blocks = () => [
1845
+ paragraphBlockPlugin,
1846
+ EditorView9.baseTheme({
1847
+ ".cm-line.block-line": {
1848
+ paddingLeft: "0.75rem",
1849
+ paddingRight: "0.75rem",
1850
+ borderLeft: "1px solid var(--dx-subduedSeparator)",
1851
+ borderRight: "1px solid var(--dx-subduedSeparator)"
1852
+ },
1853
+ ".cm-line.block-single": {
1854
+ border: "1px solid var(--dx-subduedSeparator)",
1855
+ borderRadius: "6px",
1856
+ paddingTop: "0.5rem",
1857
+ paddingBottom: "0.5rem",
1858
+ marginTop: "0.5rem",
1859
+ marginBottom: "0.5rem"
1860
+ },
1861
+ ".cm-line.block-first": {
1862
+ borderTop: "1px solid var(--dx-subduedSeparator)",
1863
+ borderTopLeftRadius: "6px",
1864
+ borderTopRightRadius: "6px",
1865
+ paddingTop: "0.5rem",
1866
+ marginTop: "0.5rem"
1867
+ },
1868
+ ".cm-line.block-middle": {},
1869
+ ".cm-line.block-last": {
1870
+ borderBottom: "1px solid var(--dx-subduedSeparator)",
1871
+ borderBottomLeftRadius: "6px",
1872
+ borderBottomRightRadius: "6px",
1873
+ paddingBottom: "0.5rem",
1874
+ marginBottom: "0.5rem"
1875
+ }
1876
+ })
1877
+ ];
1831
1878
 
1832
- // src/extensions/selection.ts
1833
- import { Transaction as Transaction3 } from "@codemirror/state";
1834
- import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
1835
- import { debounce } from "@dxos/async";
1879
+ // src/extensions/bookmarks.ts
1880
+ import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
1881
+ import { keymap as keymap4 } from "@codemirror/view";
1882
+ var addBookmark = StateEffect4.define();
1883
+ var removeBookmark = StateEffect4.define();
1884
+ var clearBookmarks = StateEffect4.define();
1885
+ var bookmarks = () => {
1886
+ return [
1887
+ bookmarksField,
1888
+ Prec3.highest(keymap4.of([
1889
+ {
1890
+ key: "Mod-ArrowUp",
1891
+ run: (view) => {
1892
+ const bookmarks2 = view.state.field(bookmarksField);
1893
+ console.log("up", bookmarks2);
1894
+ return true;
1895
+ }
1896
+ },
1897
+ {
1898
+ key: "Mod-ArrowDown",
1899
+ run: (view) => {
1900
+ const bookmarks2 = view.state.field(bookmarksField);
1901
+ console.log("down", bookmarks2);
1902
+ return true;
1903
+ }
1904
+ }
1905
+ ]))
1906
+ ];
1907
+ };
1908
+ var bookmarksField = StateField2.define({
1909
+ create: () => ({
1910
+ bookmarks: []
1911
+ }),
1912
+ update: (value, tr) => {
1913
+ let bookmarks2 = value.bookmarks.map((bookmark) => ({
1914
+ ...bookmark,
1915
+ pos: tr.changes.mapPos(bookmark.pos)
1916
+ }));
1917
+ for (const effect of tr.effects) {
1918
+ if (effect.is(addBookmark)) {
1919
+ bookmarks2 = [
1920
+ ...bookmarks2,
1921
+ effect.value
1922
+ ];
1923
+ } else if (effect.is(removeBookmark)) {
1924
+ bookmarks2 = bookmarks2.filter((b) => b.id !== effect.value);
1925
+ } else if (effect.is(clearBookmarks)) {
1926
+ bookmarks2 = [];
1927
+ }
1928
+ }
1929
+ bookmarks2.sort(({ pos: a }, { pos: b }) => a - b);
1930
+ return {
1931
+ bookmarks: bookmarks2
1932
+ };
1933
+ }
1934
+ });
1935
+
1936
+ // src/extensions/comments.ts
1937
+ import { invertedEffects } from "@codemirror/commands";
1938
+ import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
1939
+ import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
1940
+ import sortBy from "lodash.sortby";
1941
+ import { useEffect } from "react";
1942
+ import { debounce as debounce3 } from "@dxos/async";
1943
+ import { log as log5 } from "@dxos/log";
1944
+ import { isNonNullable } from "@dxos/util";
1945
+
1946
+ // src/extensions/selection.ts
1947
+ import { Transaction as Transaction3 } from "@codemirror/state";
1948
+ import { EditorView as EditorView10, keymap as keymap5 } from "@codemirror/view";
1949
+ import { debounce as debounce2 } from "@dxos/async";
1836
1950
  import { invariant as invariant3 } from "@dxos/invariant";
1837
1951
  import { isTruthy } from "@dxos/util";
1838
1952
  var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/selection.ts";
@@ -1842,7 +1956,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1842
1956
  return {
1843
1957
  selection,
1844
1958
  scrollIntoView: !scrollTo,
1845
- effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
1959
+ effects: scrollTo ? EditorView10.scrollIntoView(scrollTo, {
1846
1960
  yMargin: 96
1847
1961
  }) : void 0,
1848
1962
  annotations: Transaction3.userEvent.of(stateRestoreAnnotation)
@@ -1876,7 +1990,7 @@ var createEditorStateStore = (keyPrefix) => ({
1876
1990
  }
1877
1991
  });
1878
1992
  var selectionState = ({ getState, setState } = {}) => {
1879
- const setStateDebounced = debounce(setState, 1e3);
1993
+ const setStateDebounced = debounce2(setState, 1e3);
1880
1994
  return [
1881
1995
  // TODO(burdon): Track scrolling (currently only updates when cursor moves).
1882
1996
  // EditorView.domEventHandlers({
@@ -1884,7 +1998,7 @@ var selectionState = ({ getState, setState } = {}) => {
1884
1998
  // setStateDebounced(id, {});
1885
1999
  // },
1886
2000
  // }),
1887
- EditorView8.updateListener.of(({ view, transactions }) => {
2001
+ EditorView10.updateListener.of(({ view, transactions }) => {
1888
2002
  const id = view.state.facet(documentId);
1889
2003
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1890
2004
  return;
@@ -1907,9 +2021,9 @@ var selectionState = ({ getState, setState } = {}) => {
1907
2021
  }
1908
2022
  }
1909
2023
  }),
1910
- getState && keymap4.of([
2024
+ getState && keymap5.of([
1911
2025
  {
1912
- key: "ctrl-r",
2026
+ key: "Ctrl-r",
1913
2027
  run: (view) => {
1914
2028
  const state = getState(view.state.facet(documentId));
1915
2029
  if (state) {
@@ -1923,24 +2037,11 @@ var selectionState = ({ getState, setState } = {}) => {
1923
2037
  };
1924
2038
 
1925
2039
  // src/extensions/comments.ts
1926
- function _define_property11(obj, key, value) {
1927
- if (key in obj) {
1928
- Object.defineProperty(obj, key, {
1929
- value,
1930
- enumerable: true,
1931
- configurable: true,
1932
- writable: true
1933
- });
1934
- } else {
1935
- obj[key] = value;
1936
- }
1937
- return obj;
1938
- }
1939
2040
  var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
1940
- var setComments = StateEffect3.define();
1941
- var setSelection = StateEffect3.define();
1942
- var setCommentState = StateEffect3.define();
1943
- var commentsState = StateField2.define({
2041
+ var setComments = StateEffect5.define();
2042
+ var setSelection = StateEffect5.define();
2043
+ var setCommentState = StateEffect5.define();
2044
+ var commentsState = StateField3.define({
1944
2045
  create: (state) => ({
1945
2046
  id: state.facet(documentId),
1946
2047
  comments: [],
@@ -1978,27 +2079,28 @@ var commentsState = StateField2.define({
1978
2079
  return value;
1979
2080
  }
1980
2081
  });
1981
- var styles2 = EditorView9.theme({
2082
+ var styles2 = EditorView11.theme({
1982
2083
  ".cm-comment, .cm-comment-current": {
1983
2084
  padding: "3px 0",
2085
+ color: "var(--dx-cmCommentText)",
1984
2086
  backgroundColor: "var(--dx-cmCommentSurface)"
1985
2087
  },
1986
2088
  ".cm-comment > span, .cm-comment-current > span": {
1987
2089
  boxDecorationBreak: "clone",
1988
2090
  boxShadow: "0 0 1px 3px var(--dx-cmCommentSurface)",
1989
2091
  backgroundColor: "var(--dx-cmCommentSurface)",
1990
- color: "var(--dx-cmComment)",
2092
+ color: "var(--dx-cmCommentText)",
1991
2093
  cursor: "pointer"
1992
2094
  }
1993
2095
  });
1994
- var createCommentMark = (id, isCurrent) => Decoration6.mark({
2096
+ var createCommentMark = (id, isCurrent) => Decoration7.mark({
1995
2097
  class: isCurrent ? "cm-comment-current" : "cm-comment",
1996
2098
  attributes: {
1997
2099
  "data-testid": "cm-comment",
1998
2100
  "data-comment-id": id
1999
2101
  }
2000
2102
  });
2001
- var commentsDecorations = EditorView9.decorations.compute([
2103
+ var commentsDecorations = EditorView11.decorations.compute([
2002
2104
  commentsState
2003
2105
  ], (state) => {
2004
2106
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -2007,7 +2109,7 @@ var commentsDecorations = EditorView9.decorations.compute([
2007
2109
  if (!range) {
2008
2110
  log5.warn("Invalid range:", range, {
2009
2111
  F: __dxlog_file8,
2010
- L: 140,
2112
+ L: 141,
2011
2113
  S: void 0,
2012
2114
  C: (f, a) => f(...a)
2013
2115
  });
@@ -2018,10 +2120,10 @@ var commentsDecorations = EditorView9.decorations.compute([
2018
2120
  const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
2019
2121
  return mark.range(range.from, range.to);
2020
2122
  }).filter(isNonNullable);
2021
- return Decoration6.set(decorations2);
2123
+ return Decoration7.set(decorations2);
2022
2124
  });
2023
- var commentClickedEffect = StateEffect3.define();
2024
- var handleCommentClick = EditorView9.domEventHandlers({
2125
+ var commentClickedEffect = StateEffect5.define();
2126
+ var handleCommentClick = EditorView11.domEventHandlers({
2025
2127
  click: (event, view) => {
2026
2128
  let target = event.target;
2027
2129
  const editorRoot = view.dom;
@@ -2060,7 +2162,7 @@ var trackPastedComments = (onUpdate) => {
2060
2162
  }
2061
2163
  };
2062
2164
  return [
2063
- EditorView9.domEventHandlers({
2165
+ EditorView11.domEventHandlers({
2064
2166
  cut: handleTrack,
2065
2167
  copy: handleTrack
2066
2168
  }),
@@ -2082,7 +2184,7 @@ var trackPastedComments = (onUpdate) => {
2082
2184
  return effects;
2083
2185
  }),
2084
2186
  // Handle paste or the undo of comment deletion.
2085
- EditorView9.updateListener.of((update2) => {
2187
+ EditorView11.updateListener.of((update2) => {
2086
2188
  const restore = [];
2087
2189
  for (let i = 0; i < update2.transactions.length; i++) {
2088
2190
  const tr = update2.transactions[i];
@@ -2138,7 +2240,7 @@ var mapTrackedComment = (comment, changes) => ({
2138
2240
  from: changes.mapPos(comment.from, 1),
2139
2241
  to: changes.mapPos(comment.to, 1)
2140
2242
  });
2141
- var restoreCommentEffect = StateEffect3.define({
2243
+ var restoreCommentEffect = StateEffect5.define({
2142
2244
  map: mapTrackedComment
2143
2245
  });
2144
2246
  var createComment = (view) => {
@@ -2172,7 +2274,7 @@ var createComment = (view) => {
2172
2274
  var optionsFacet = singleValueFacet();
2173
2275
  var comments = (options = {}) => {
2174
2276
  const { key: shortcut = "meta-'" } = options;
2175
- const handleSelect = debounce2((state) => options.onSelect?.(state), 200);
2277
+ const handleSelect = debounce3((state) => options.onSelect?.(state), 200);
2176
2278
  return [
2177
2279
  optionsFacet.of(options),
2178
2280
  options.id ? documentId.of(options.id) : void 0,
@@ -2183,7 +2285,7 @@ var comments = (options = {}) => {
2183
2285
  //
2184
2286
  // Keymap.
2185
2287
  //
2186
- options.onCreate && keymap5.of([
2288
+ options.onCreate && keymap6.of([
2187
2289
  {
2188
2290
  key: shortcut,
2189
2291
  run: callbackWrapper(createComment)
@@ -2224,7 +2326,7 @@ var comments = (options = {}) => {
2224
2326
  //
2225
2327
  // Track deleted ranges and update ranges for decorations.
2226
2328
  //
2227
- EditorView9.updateListener.of(({ view, state, changes }) => {
2329
+ EditorView11.updateListener.of(({ view, state, changes }) => {
2228
2330
  let mod = false;
2229
2331
  const { comments: comments2, ...value } = state.field(commentsState);
2230
2332
  changes.iterChanges((from, to, from2, to2) => {
@@ -2256,7 +2358,7 @@ var comments = (options = {}) => {
2256
2358
  //
2257
2359
  // Track selection/proximity.
2258
2360
  //
2259
- EditorView9.updateListener.of(({ view, state }) => {
2361
+ EditorView11.updateListener.of(({ view, state }) => {
2260
2362
  let min = Infinity;
2261
2363
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2262
2364
  const { head } = state.selection.main;
@@ -2310,7 +2412,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
2310
2412
  anchor: range.from
2311
2413
  } : void 0,
2312
2414
  effects: [
2313
- needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
2415
+ needsScroll ? EditorView11.scrollIntoView(range.from, center ? {
2314
2416
  y: "center"
2315
2417
  } : void 0) : [],
2316
2418
  needsSelectionUpdate ? setSelection.of({
@@ -2322,11 +2424,8 @@ var scrollThreadIntoView = (view, id, center = true) => {
2322
2424
  }
2323
2425
  };
2324
2426
  var ExternalCommentSync = class {
2427
+ unsubscribe;
2325
2428
  constructor(view, id, subscribe, getComments) {
2326
- _define_property11(this, "unsubscribe", void 0);
2327
- _define_property11(this, "destroy", () => {
2328
- this.unsubscribe();
2329
- });
2330
2429
  const updateComments = () => {
2331
2430
  const comments2 = getComments();
2332
2431
  if (id === view.state.facet(documentId)) {
@@ -2340,8 +2439,11 @@ var ExternalCommentSync = class {
2340
2439
  };
2341
2440
  this.unsubscribe = subscribe(updateComments);
2342
2441
  }
2442
+ destroy = () => {
2443
+ this.unsubscribe();
2444
+ };
2343
2445
  };
2344
- var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin8.fromClass(class {
2446
+ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin10.fromClass(class {
2345
2447
  constructor(view) {
2346
2448
  return new ExternalCommentSync(view, id, subscribe, getComments);
2347
2449
  }
@@ -2363,20 +2465,20 @@ var useComments = (view, id, comments2) => {
2363
2465
 
2364
2466
  // src/extensions/debug.ts
2365
2467
  import { syntaxTree } from "@codemirror/language";
2366
- import { StateField as StateField3 } from "@codemirror/state";
2468
+ import { StateField as StateField4 } from "@codemirror/state";
2367
2469
  var debugNodeLogger = (log11 = console.log) => {
2368
2470
  const logTokens = (state) => syntaxTree(state).iterate({
2369
2471
  enter: (node) => log11(node.type)
2370
2472
  });
2371
- return StateField3.define({
2473
+ return StateField4.define({
2372
2474
  create: (state) => logTokens(state),
2373
2475
  update: (_, tr) => logTokens(tr.state)
2374
2476
  });
2375
2477
  };
2376
2478
 
2377
2479
  // src/extensions/dnd.ts
2378
- import { EditorView as EditorView10, dropCursor } from "@codemirror/view";
2379
- var styles3 = EditorView10.theme({
2480
+ import { EditorView as EditorView12, dropCursor } from "@codemirror/view";
2481
+ var styles3 = EditorView12.theme({
2380
2482
  ".cm-dropCursor": {
2381
2483
  borderLeft: "2px solid var(--dx-accentText)",
2382
2484
  color: "var(--dx-accentText)",
@@ -2390,7 +2492,7 @@ var dropFile = (options = {}) => {
2390
2492
  return [
2391
2493
  styles3,
2392
2494
  dropCursor(),
2393
- EditorView10.domEventHandlers({
2495
+ EditorView12.domEventHandlers({
2394
2496
  drop: (event, view) => {
2395
2497
  event.preventDefault();
2396
2498
  const files = event.dataTransfer?.files;
@@ -2416,7 +2518,7 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
2416
2518
  import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
2417
2519
  import { searchKeymap } from "@codemirror/search";
2418
2520
  import { EditorState } from "@codemirror/state";
2419
- import { EditorView as EditorView13, ViewPlugin as ViewPlugin9, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder as placeholder2, scrollPastEnd } from "@codemirror/view";
2521
+ import { EditorView as EditorView15, ViewPlugin as ViewPlugin11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2, scrollPastEnd } from "@codemirror/view";
2420
2522
  import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
2421
2523
  import defaultsDeep2 from "lodash.defaultsdeep";
2422
2524
  import merge from "lodash.merge";
@@ -2425,11 +2527,11 @@ import { log as log6 } from "@dxos/log";
2425
2527
  import { hexToHue, isTruthy as isTruthy2 } from "@dxos/util";
2426
2528
 
2427
2529
  // src/defaults.ts
2428
- import { EditorView as EditorView11 } from "@codemirror/view";
2429
- import { mx as mx2 } from "@dxos/react-ui-theme";
2530
+ import { EditorView as EditorView13 } from "@codemirror/view";
2531
+ import { mx as mx3 } from "@dxos/react-ui-theme";
2430
2532
 
2431
2533
  // src/styles/markdown.ts
2432
- import { mx } from "@dxos/react-ui-theme";
2534
+ import { mx as mx2 } from "@dxos/react-ui-theme";
2433
2535
  var headings = {
2434
2536
  1: "text-4xl",
2435
2537
  2: "text-3xl",
@@ -2443,7 +2545,7 @@ var theme = {
2443
2545
  codeMark: "font-mono text-primary-500",
2444
2546
  mark: "opacity-50",
2445
2547
  heading: (level) => {
2446
- return mx(headings[level], "dark:text-primary-400");
2548
+ return mx2(headings[level], "dark:text-neutral-400");
2447
2549
  }
2448
2550
  };
2449
2551
 
@@ -2491,7 +2593,8 @@ var defaultTheme = {
2491
2593
  ".cm-gutter": {},
2492
2594
  ".cm-gutter.cm-lineNumbers": {
2493
2595
  paddingRight: "4px",
2494
- borderRight: "1px solid var(--dx-subduedSeparator)"
2596
+ borderRight: "1px solid var(--dx-subduedSeparator)",
2597
+ color: "var(--dx-subduedText)"
2495
2598
  },
2496
2599
  ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2497
2600
  minWidth: "40px"
@@ -2681,7 +2784,7 @@ var editorSlots = {
2681
2784
  className: editorWidth
2682
2785
  }
2683
2786
  };
2684
- var editorGutter = EditorView11.theme({
2787
+ var editorGutter = EditorView13.theme({
2685
2788
  ".cm-gutters": {
2686
2789
  // NOTE: Color required to cover content if scrolling horizontally.
2687
2790
  // TODO(burdon): Non-transparent background clips the focus ring.
@@ -2689,19 +2792,19 @@ var editorGutter = EditorView11.theme({
2689
2792
  paddingRight: "1rem"
2690
2793
  }
2691
2794
  });
2692
- var editorMonospace = EditorView11.theme({
2795
+ var editorMonospace = EditorView13.theme({
2693
2796
  ".cm-content": {
2694
2797
  fontFamily: fontMono
2695
2798
  }
2696
2799
  });
2697
2800
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
2698
- var stackItemContentEditorClassNames = (role) => mx2("p-0.5 dx-focus-ring-inset attention-surface data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
2801
+ var stackItemContentEditorClassNames = (role) => mx3("p-0.5 dx-focus-ring-inset attention-surface data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
2699
2802
 
2700
2803
  // src/extensions/focus.ts
2701
- import { StateEffect as StateEffect4, StateField as StateField4 } from "@codemirror/state";
2702
- import { EditorView as EditorView12 } from "@codemirror/view";
2703
- var focusEffect = StateEffect4.define();
2704
- var focusField = StateField4.define({
2804
+ import { StateEffect as StateEffect6, StateField as StateField5 } from "@codemirror/state";
2805
+ import { EditorView as EditorView14 } from "@codemirror/view";
2806
+ var focusEffect = StateEffect6.define();
2807
+ var focusField = StateField5.define({
2705
2808
  create: () => false,
2706
2809
  update: (value, tr) => {
2707
2810
  for (const effect of tr.effects) {
@@ -2714,7 +2817,7 @@ var focusField = StateField4.define({
2714
2817
  });
2715
2818
  var focus = [
2716
2819
  focusField,
2717
- EditorView12.domEventHandlers({
2820
+ EditorView14.domEventHandlers({
2718
2821
  focus: (_event, view) => {
2719
2822
  requestAnimationFrame(() => view.dispatch({
2720
2823
  effects: focusEffect.of(true)
@@ -2778,10 +2881,10 @@ var createBasicExtensions = (_props) => {
2778
2881
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2779
2882
  return [
2780
2883
  // NOTE: Doesn't catch errors in keymap functions.
2781
- EditorView13.exceptionSink.of((err) => {
2884
+ EditorView15.exceptionSink.of((err) => {
2782
2885
  log6.catch(err, void 0, {
2783
2886
  F: __dxlog_file9,
2784
- L: 125,
2887
+ L: 124,
2785
2888
  S: void 0,
2786
2889
  C: (f, a) => f(...a)
2787
2890
  });
@@ -2793,7 +2896,7 @@ var createBasicExtensions = (_props) => {
2793
2896
  props.drawSelection && drawSelection({
2794
2897
  cursorBlinkRate: 1200
2795
2898
  }),
2796
- props.editable !== void 0 && EditorView13.editable.of(props.editable),
2899
+ props.editable !== void 0 && EditorView15.editable.of(props.editable),
2797
2900
  props.focus && focus,
2798
2901
  props.highlightActiveLine && highlightActiveLine(),
2799
2902
  props.history && history(),
@@ -2801,14 +2904,13 @@ var createBasicExtensions = (_props) => {
2801
2904
  lineNumbers(),
2802
2905
  editorGutter
2803
2906
  ],
2804
- props.lineWrapping && EditorView13.lineWrapping,
2805
- props.monospace && editorMonospace,
2907
+ props.lineWrapping && EditorView15.lineWrapping,
2806
2908
  props.placeholder && placeholder2(props.placeholder),
2807
2909
  props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
2808
2910
  props.scrollPastEnd && scrollPastEnd(),
2809
2911
  props.tabSize && EditorState.tabSize.of(props.tabSize),
2810
2912
  // https://codemirror.net/docs/ref/#view.KeyBinding
2811
- keymap6.of([
2913
+ keymap7.of([
2812
2914
  ...(props.keymap && keymaps[props.keymap]) ?? [],
2813
2915
  // NOTE: Tabs are also configured by markdown extension.
2814
2916
  // https://codemirror.net/docs/ref/#commands.indentWithTab
@@ -2846,19 +2948,20 @@ var defaultStyles = {
2846
2948
  dark: vscodeDarkStyle,
2847
2949
  light: vscodeLightStyle
2848
2950
  };
2849
- var createThemeExtensions = ({ themeMode, styles: styles4, syntaxHighlighting: syntaxHighlightingProp, slots: slotsParam } = {}) => {
2951
+ var createThemeExtensions = ({ themeMode, monospace, styles: styles4, syntaxHighlighting: syntaxHighlightingProp, slots: slotsParam } = {}) => {
2850
2952
  const slots = defaultsDeep2({}, slotsParam, defaultThemeSlots);
2851
2953
  return [
2852
- EditorView13.darkTheme.of(themeMode === "dark"),
2853
- EditorView13.baseTheme(styles4 ? merge({}, defaultTheme, styles4) : defaultTheme),
2954
+ EditorView15.darkTheme.of(themeMode === "dark"),
2955
+ EditorView15.baseTheme(styles4 ? merge({}, defaultTheme, styles4) : defaultTheme),
2956
+ monospace && editorMonospace,
2854
2957
  syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
2855
- slots.editor?.className && EditorView13.editorAttributes.of({
2958
+ slots.editor?.className && EditorView15.editorAttributes.of({
2856
2959
  class: slots.editor.className
2857
2960
  }),
2858
- slots.content?.className && EditorView13.contentAttributes.of({
2961
+ slots.content?.className && EditorView15.contentAttributes.of({
2859
2962
  class: slots.content.className
2860
2963
  }),
2861
- slots.scroll?.className && ViewPlugin9.fromClass(class {
2964
+ slots.scroll?.className && ViewPlugin11.fromClass(class {
2862
2965
  constructor(view) {
2863
2966
  view.scrollDOM.classList.add(...slots.scroll.className.split(/\s+/));
2864
2967
  }
@@ -2889,7 +2992,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2889
2992
 
2890
2993
  // src/extensions/folding.tsx
2891
2994
  import { codeFolding, foldGutter } from "@codemirror/language";
2892
- import { EditorView as EditorView14 } from "@codemirror/view";
2995
+ import { EditorView as EditorView16 } from "@codemirror/view";
2893
2996
  import React2 from "react";
2894
2997
  import { Domino as Domino2, Icon } from "@dxos/react-ui";
2895
2998
  var folding = (_props = {}) => [
@@ -2900,21 +3003,17 @@ var folding = (_props = {}) => [
2900
3003
  }),
2901
3004
  foldGutter({
2902
3005
  markerDOM: (open) => {
2903
- return renderRoot(
2904
- Domino2.of("div").classNames("flex h-full items-center").build(),
2905
- // TODO(burdon): Use sprite directly.
2906
- /* @__PURE__ */ React2.createElement(Icon, {
2907
- icon: "ph--caret-right--bold",
2908
- size: 3,
2909
- classNames: [
2910
- "mx-3 cursor-pointer",
2911
- open && "rotate-90"
2912
- ]
2913
- })
2914
- );
3006
+ return renderRoot(Domino2.of("div").classNames("flex bs-full items-center").build(), /* @__PURE__ */ React2.createElement(Icon, {
3007
+ icon: "ph--caret-right--bold",
3008
+ size: 3,
3009
+ classNames: [
3010
+ "mx-3 cursor-pointer",
3011
+ open && "rotate-90"
3012
+ ]
3013
+ }));
2915
3014
  }
2916
3015
  }),
2917
- EditorView14.theme({
3016
+ EditorView16.theme({
2918
3017
  ".cm-foldGutter": {
2919
3018
  opacity: 0.3,
2920
3019
  transition: "opacity 0.3s",
@@ -2927,54 +3026,42 @@ var folding = (_props = {}) => [
2927
3026
  ];
2928
3027
 
2929
3028
  // src/extensions/hashtag.tsx
2930
- import { Decoration as Decoration7, EditorView as EditorView15, MatchDecorator, ViewPlugin as ViewPlugin10, WidgetType as WidgetType4 } from "@codemirror/view";
2931
- import { getHashStyles, mx as mx3 } from "@dxos/react-ui-theme";
2932
- function _define_property12(obj, key, value) {
2933
- if (key in obj) {
2934
- Object.defineProperty(obj, key, {
2935
- value,
2936
- enumerable: true,
2937
- configurable: true,
2938
- writable: true
2939
- });
2940
- } else {
2941
- obj[key] = value;
2942
- }
2943
- return obj;
2944
- }
3029
+ import { Decoration as Decoration8, EditorView as EditorView17, MatchDecorator, ViewPlugin as ViewPlugin12, WidgetType as WidgetType4 } from "@codemirror/view";
3030
+ import { getHashStyles, mx as mx4 } from "@dxos/react-ui-theme";
2945
3031
  var TagWidget = class extends WidgetType4 {
3032
+ _text;
3033
+ constructor(_text) {
3034
+ super(), this._text = _text;
3035
+ }
2946
3036
  toDOM() {
2947
3037
  const span = document.createElement("span");
2948
- span.className = mx3("cm-tag", getHashStyles(this._text).surface);
3038
+ span.className = mx4("cm-tag", getHashStyles(this._text).surface);
2949
3039
  span.textContent = this._text;
2950
3040
  return span;
2951
3041
  }
2952
- constructor(_text) {
2953
- super(), _define_property12(this, "_text", void 0), this._text = _text;
2954
- }
2955
3042
  };
2956
3043
  var tagMatcher = new MatchDecorator({
2957
3044
  regexp: /#(\w+)\W/g,
2958
- decoration: (match) => Decoration7.replace({
3045
+ decoration: (match) => Decoration8.replace({
2959
3046
  widget: new TagWidget(match[1])
2960
3047
  })
2961
3048
  });
2962
3049
  var hashtag = () => [
2963
- ViewPlugin10.fromClass(class {
2964
- update(update2) {
2965
- this.tags = tagMatcher.updateDeco(update2, this.tags);
2966
- }
3050
+ ViewPlugin12.fromClass(class {
3051
+ tags;
2967
3052
  constructor(view) {
2968
- _define_property12(this, "tags", void 0);
2969
3053
  this.tags = tagMatcher.createDeco(view);
2970
3054
  }
3055
+ update(update2) {
3056
+ this.tags = tagMatcher.updateDeco(update2, this.tags);
3057
+ }
2971
3058
  }, {
2972
3059
  decorations: (instance) => instance.tags,
2973
- provide: (plugin) => EditorView15.atomicRanges.of((view) => {
2974
- return view.plugin(plugin)?.tags || Decoration7.none;
3060
+ provide: (plugin) => EditorView17.atomicRanges.of((view) => {
3061
+ return view.plugin(plugin)?.tags || Decoration8.none;
2975
3062
  })
2976
3063
  }),
2977
- EditorView15.theme({
3064
+ EditorView17.theme({
2978
3065
  ".cm-tag": {
2979
3066
  borderRadius: "4px",
2980
3067
  marginRight: "6px",
@@ -3029,25 +3116,33 @@ var schemaLinter = (validate) => (view) => {
3029
3116
  };
3030
3117
 
3031
3118
  // src/extensions/listener.ts
3032
- import { EditorView as EditorView16 } from "@codemirror/view";
3119
+ import { EditorView as EditorView18 } from "@codemirror/view";
3120
+ import { isNonNullable as isNonNullable2 } from "@dxos/util";
3033
3121
  var listener = ({ onFocus, onChange }) => {
3034
- const extensions = [];
3035
- onFocus && extensions.push(EditorView16.focusChangeEffect.of((_, focusing) => {
3036
- onFocus(focusing);
3037
- return null;
3038
- }));
3039
- onChange && extensions.push(EditorView16.updateListener.of((update2) => {
3040
- onChange(update2.state.doc.toString(), update2.state.facet(documentId));
3041
- }));
3042
- return extensions;
3122
+ return [
3123
+ onFocus && EditorView18.focusChangeEffect.of((state, focusing) => {
3124
+ onFocus({
3125
+ id: state.facet(documentId),
3126
+ focusing
3127
+ });
3128
+ return null;
3129
+ }),
3130
+ onChange && EditorView18.updateListener.of(({ state, docChanged }) => {
3131
+ if (docChanged) {
3132
+ onChange({
3133
+ id: state.facet(documentId),
3134
+ text: state.doc.toString()
3135
+ });
3136
+ }
3137
+ })
3138
+ ].filter(isNonNullable2);
3043
3139
  };
3044
3140
 
3045
3141
  // src/extensions/markdown/formatting.ts
3046
3142
  import { snippet } from "@codemirror/autocomplete";
3047
3143
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3048
3144
  import { EditorSelection as EditorSelection2 } from "@codemirror/state";
3049
- import { EditorView as EditorView17, keymap as keymap7 } from "@codemirror/view";
3050
- import { useCallback, useMemo } from "react";
3145
+ import { EditorView as EditorView19, keymap as keymap8 } from "@codemirror/view";
3051
3146
  import { debounceAndThrottle } from "@dxos/async";
3052
3147
  var formattingEquals = (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;
3053
3148
  var Inline = /* @__PURE__ */ (function(Inline2) {
@@ -3520,7 +3615,7 @@ var addList = (type) => {
3520
3615
  let counter = 1;
3521
3616
  let first = true;
3522
3617
  let parentColumn = null;
3523
- const blocks = [];
3618
+ const blocks2 = [];
3524
3619
  for (const { from, to } of state.selection.ranges) {
3525
3620
  syntaxTree2(state).iterate({
3526
3621
  from,
@@ -3551,7 +3646,7 @@ var addList = (type) => {
3551
3646
  return;
3552
3647
  }
3553
3648
  lastBlock = node.from;
3554
- blocks.push({
3649
+ blocks2.push({
3555
3650
  node: node.node,
3556
3651
  counter,
3557
3652
  parentColumn
@@ -3568,7 +3663,7 @@ var addList = (type) => {
3568
3663
  }
3569
3664
  });
3570
3665
  }
3571
- if (!blocks.length) {
3666
+ if (!blocks2.length) {
3572
3667
  const { from, to } = state.doc.lineAt(state.selection.main.anchor);
3573
3668
  if (from === to) {
3574
3669
  const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
@@ -3590,8 +3685,8 @@ var addList = (type) => {
3590
3685
  return false;
3591
3686
  }
3592
3687
  const changes = [];
3593
- for (let i = 0; i < blocks.length; i++) {
3594
- const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
3688
+ for (let i = 0; i < blocks2.length; i++) {
3689
+ const { node, counter: counter2, parentColumn: parentColumn2 } = blocks2[i];
3595
3690
  const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
3596
3691
  let padding = nodeFrom > 0 && !/\s/.test(state.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
3597
3692
  if (type === 0) {
@@ -3605,8 +3700,8 @@ var addList = (type) => {
3605
3700
  let mark;
3606
3701
  if (type === 0) {
3607
3702
  let max = counter2;
3608
- for (let j = i + 1; j < blocks.length; j++) {
3609
- if (blocks[j].counter !== max + 1) {
3703
+ for (let j = i + 1; j < blocks2.length; j++) {
3704
+ if (blocks2[j].counter !== max + 1) {
3610
3705
  break;
3611
3706
  }
3612
3707
  max++;
@@ -3631,7 +3726,7 @@ var addList = (type) => {
3631
3726
  }
3632
3727
  }
3633
3728
  if (type === 0) {
3634
- const last = blocks[blocks.length - 1];
3729
+ const last = blocks2[blocks2.length - 1];
3635
3730
  let next = last.node.nextSibling;
3636
3731
  while (next && /Mark$/.test(next.name)) {
3637
3732
  next = next.nextSibling;
@@ -3935,7 +4030,7 @@ var toggleCodeblock = (target) => {
3935
4030
  };
3936
4031
  var formattingKeymap = (_options = {}) => {
3937
4032
  return [
3938
- keymap7.of([
4033
+ keymap8.of([
3939
4034
  {
3940
4035
  key: "meta-b",
3941
4036
  run: toggleStrong
@@ -4135,19 +4230,18 @@ var getFormatting = (state) => {
4135
4230
  listStyle: listStyle || null
4136
4231
  };
4137
4232
  };
4138
- var useFormattingState = (state) => {
4139
- const handleUpdate = useCallback(debounceAndThrottle((update2) => {
4233
+ var formattingListener = (stateProvider, delay = 100) => {
4234
+ return EditorView19.updateListener.of(debounceAndThrottle((update2) => {
4140
4235
  if (update2.docChanged || update2.selectionSet) {
4236
+ const state = stateProvider();
4237
+ if (!state) {
4238
+ return;
4239
+ }
4141
4240
  Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
4142
4241
  state[key] = active;
4143
4242
  });
4144
4243
  }
4145
- }, 100), [
4146
- state
4147
- ]);
4148
- return useMemo(() => EditorView17.updateListener.of(handleUpdate), [
4149
- handleUpdate
4150
- ]);
4244
+ }, delay));
4151
4245
  };
4152
4246
 
4153
4247
  // src/extensions/markdown/action.ts
@@ -4202,10 +4296,12 @@ var processEditorPayload = (view, { type, data }) => {
4202
4296
  // src/extensions/markdown/bundle.ts
4203
4297
  import { completionKeymap } from "@codemirror/autocomplete";
4204
4298
  import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
4299
+ import { jsonLanguage } from "@codemirror/lang-json";
4205
4300
  import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
4206
- import { syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
4301
+ import { xml } from "@codemirror/lang-xml";
4302
+ import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
4207
4303
  import { languages } from "@codemirror/language-data";
4208
- import { keymap as keymap8 } from "@codemirror/view";
4304
+ import { keymap as keymap9 } from "@codemirror/view";
4209
4305
  import { isTruthy as isTruthy3 } from "@dxos/util";
4210
4306
 
4211
4307
  // src/extensions/markdown/highlight.ts
@@ -4319,7 +4415,8 @@ var markdownHighlightStyle = (_options = {}) => {
4319
4415
  // Fonts.
4320
4416
  {
4321
4417
  tag: [
4322
- tags.monospace
4418
+ tags.monospace,
4419
+ tags.comment
4323
4420
  ],
4324
4421
  class: "font-mono"
4325
4422
  },
@@ -4401,6 +4498,7 @@ var createMarkdownExtensions = (options = {}) => {
4401
4498
  // https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
4402
4499
  base: markdownLanguage2,
4403
4500
  // Languages for syntax highlighting fenced code blocks.
4501
+ defaultCodeLanguage: jsonLanguage,
4404
4502
  codeLanguages: languages,
4405
4503
  // Don't complete HTML tags.
4406
4504
  completeHTMLTags: false,
@@ -4413,7 +4511,7 @@ var createMarkdownExtensions = (options = {}) => {
4413
4511
  }),
4414
4512
  // Custom styles.
4415
4513
  syntaxHighlighting2(markdownHighlightStyle()),
4416
- keymap8.of([
4514
+ keymap9.of([
4417
4515
  // https://codemirror.net/docs/ref/#commands.indentWithTab
4418
4516
  options.indentWithTab !== false && indentWithTab2,
4419
4517
  // https://codemirror.net/docs/ref/#commands.defaultKeymap
@@ -4423,6 +4521,18 @@ var createMarkdownExtensions = (options = {}) => {
4423
4521
  ].filter(isTruthy3))
4424
4522
  ];
4425
4523
  };
4524
+ var xmlLanguageDesc = LanguageDescription.of({
4525
+ name: "xml",
4526
+ alias: [
4527
+ "html",
4528
+ "xhtml"
4529
+ ],
4530
+ extensions: [
4531
+ "xml",
4532
+ "xhtml"
4533
+ ],
4534
+ load: async () => xml()
4535
+ });
4426
4536
  var defaultExtensions = () => [
4427
4537
  noSetExtHeading,
4428
4538
  noHtml
@@ -4432,17 +4542,12 @@ var noSetExtHeading = {
4432
4542
  "SetextHeading"
4433
4543
  ]
4434
4544
  };
4435
- var noHtml = {
4436
- remove: [
4437
- "HTMLBlock",
4438
- "HTMLTag"
4439
- ]
4440
- };
4545
+ var noHtml = {};
4441
4546
 
4442
4547
  // src/extensions/markdown/debug.ts
4443
4548
  import { syntaxTree as syntaxTree3 } from "@codemirror/language";
4444
- import { StateField as StateField5 } from "@codemirror/state";
4445
- var debugTree = (cb) => StateField5.define({
4549
+ import { StateField as StateField6 } from "@codemirror/state";
4550
+ var debugTree = (cb) => StateField6.define({
4446
4551
  create: (state) => cb(convertTreeToJson(state)),
4447
4552
  update: (value, tr) => cb(convertTreeToJson(tr.state))
4448
4553
  });
@@ -4468,17 +4573,17 @@ var convertTreeToJson = (state) => {
4468
4573
 
4469
4574
  // src/extensions/markdown/decorate.ts
4470
4575
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4471
- import { Prec as Prec3, RangeSetBuilder as RangeSetBuilder4, StateEffect as StateEffect5 } from "@codemirror/state";
4472
- import { Decoration as Decoration10, EditorView as EditorView21, ViewPlugin as ViewPlugin12, WidgetType as WidgetType7 } from "@codemirror/view";
4576
+ import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
4577
+ import { Decoration as Decoration11, EditorView as EditorView23, ViewPlugin as ViewPlugin14, WidgetType as WidgetType7 } from "@codemirror/view";
4473
4578
  import { invariant as invariant4 } from "@dxos/invariant";
4474
- import { mx as mx4 } from "@dxos/react-ui-theme";
4579
+ import { mx as mx5 } from "@dxos/react-ui-theme";
4475
4580
 
4476
4581
  // src/extensions/markdown/changes.ts
4477
4582
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4478
4583
  import { Transaction as Transaction4 } from "@codemirror/state";
4479
- import { ViewPlugin as ViewPlugin11 } from "@codemirror/view";
4584
+ import { ViewPlugin as ViewPlugin13 } from "@codemirror/view";
4480
4585
  var adjustChanges = () => {
4481
- return ViewPlugin11.fromClass(class {
4586
+ return ViewPlugin13.fromClass(class {
4482
4587
  update(update2) {
4483
4588
  const tree = syntaxTree4(update2.state);
4484
4589
  const adjustments = [];
@@ -4619,26 +4724,13 @@ var getValidUrl = (str) => {
4619
4724
 
4620
4725
  // src/extensions/markdown/image.ts
4621
4726
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4622
- import { StateField as StateField6 } from "@codemirror/state";
4623
- import { Decoration as Decoration8, EditorView as EditorView18, WidgetType as WidgetType5 } from "@codemirror/view";
4624
- function _define_property13(obj, key, value) {
4625
- if (key in obj) {
4626
- Object.defineProperty(obj, key, {
4627
- value,
4628
- enumerable: true,
4629
- configurable: true,
4630
- writable: true
4631
- });
4632
- } else {
4633
- obj[key] = value;
4634
- }
4635
- return obj;
4636
- }
4727
+ import { StateField as StateField7 } from "@codemirror/state";
4728
+ import { Decoration as Decoration9, EditorView as EditorView20, WidgetType as WidgetType5 } from "@codemirror/view";
4637
4729
  var image = (_options = {}) => {
4638
4730
  return [
4639
- StateField6.define({
4731
+ StateField7.define({
4640
4732
  create: (state) => {
4641
- return Decoration8.set(buildDecorations(state, 0, state.doc.length));
4733
+ return Decoration9.set(buildDecorations(state, 0, state.doc.length));
4642
4734
  },
4643
4735
  update: (value, tr) => {
4644
4736
  if (!tr.docChanged && !tr.selection) {
@@ -4661,7 +4753,7 @@ var image = (_options = {}) => {
4661
4753
  add: buildDecorations(tr.state, from, to)
4662
4754
  });
4663
4755
  },
4664
- provide: (field) => EditorView18.decorations.from(field)
4756
+ provide: (field) => EditorView20.decorations.from(field)
4665
4757
  })
4666
4758
  ];
4667
4759
  };
@@ -4679,7 +4771,7 @@ var buildDecorations = (state, from, to) => {
4679
4771
  return;
4680
4772
  }
4681
4773
  preloadImage(url);
4682
- decorations2.push(Decoration8.replace({
4774
+ decorations2.push(Decoration9.replace({
4683
4775
  block: true,
4684
4776
  widget: new ImageWidget(url)
4685
4777
  }).range(hide2 ? node.from : node.to, node.to));
@@ -4700,6 +4792,10 @@ var preloadImage = (url) => {
4700
4792
  }
4701
4793
  };
4702
4794
  var ImageWidget = class extends WidgetType5 {
4795
+ _url;
4796
+ constructor(_url) {
4797
+ super(), this._url = _url;
4798
+ }
4703
4799
  eq(other) {
4704
4800
  return this._url === other._url;
4705
4801
  }
@@ -4714,16 +4810,13 @@ var ImageWidget = class extends WidgetType5 {
4714
4810
  }
4715
4811
  return img;
4716
4812
  }
4717
- constructor(_url) {
4718
- super(), _define_property13(this, "_url", void 0), this._url = _url;
4719
- }
4720
4813
  };
4721
4814
 
4722
4815
  // src/extensions/markdown/styles.ts
4723
- import { EditorView as EditorView19 } from "@codemirror/view";
4816
+ import { EditorView as EditorView21 } from "@codemirror/view";
4724
4817
  var bulletListIndentationWidth = 24;
4725
4818
  var orderedListIndentationWidth = 36;
4726
- var formattingStyles = EditorView19.theme({
4819
+ var formattingStyles = EditorView21.theme({
4727
4820
  /**
4728
4821
  * Horizontal rule.
4729
4822
  */
@@ -4844,30 +4937,17 @@ var formattingStyles = EditorView19.theme({
4844
4937
 
4845
4938
  // src/extensions/markdown/table.ts
4846
4939
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4847
- import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField7 } from "@codemirror/state";
4848
- import { Decoration as Decoration9, EditorView as EditorView20, WidgetType as WidgetType6 } from "@codemirror/view";
4849
- function _define_property14(obj, key, value) {
4850
- if (key in obj) {
4851
- Object.defineProperty(obj, key, {
4852
- value,
4853
- enumerable: true,
4854
- configurable: true,
4855
- writable: true
4856
- });
4857
- } else {
4858
- obj[key] = value;
4859
- }
4860
- return obj;
4861
- }
4940
+ import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
4941
+ import { Decoration as Decoration10, EditorView as EditorView22, WidgetType as WidgetType6 } from "@codemirror/view";
4862
4942
  var table = (options = {}) => {
4863
- return StateField7.define({
4943
+ return StateField8.define({
4864
4944
  create: (state) => update(state, options),
4865
4945
  update: (_, tr) => update(tr.state, options),
4866
- provide: (field) => EditorView20.decorations.from(field)
4946
+ provide: (field) => EditorView22.decorations.from(field)
4867
4947
  });
4868
4948
  };
4869
4949
  var update = (state, _options) => {
4870
- const builder = new RangeSetBuilder3();
4950
+ const builder = new RangeSetBuilder4();
4871
4951
  const cursor2 = state.selection.main.head;
4872
4952
  const tables = [];
4873
4953
  const getTable = () => tables[tables.length - 1];
@@ -4890,8 +4970,7 @@ var update = (state, _options) => {
4890
4970
  break;
4891
4971
  }
4892
4972
  case "TableRow": {
4893
- var _getTable;
4894
- ((_getTable = getTable()).rows ?? (_getTable.rows = [])).push([]);
4973
+ (getTable().rows ??= []).push([]);
4895
4974
  break;
4896
4975
  }
4897
4976
  case "TableCell": {
@@ -4909,12 +4988,12 @@ var update = (state, _options) => {
4909
4988
  tables.forEach((table2) => {
4910
4989
  const replace = state.readOnly || cursor2 < table2.from || cursor2 > table2.to;
4911
4990
  if (replace) {
4912
- builder.add(table2.from, table2.to, Decoration9.replace({
4991
+ builder.add(table2.from, table2.to, Decoration10.replace({
4913
4992
  block: true,
4914
4993
  widget: new TableWidget(table2)
4915
4994
  }));
4916
4995
  } else {
4917
- builder.add(table2.from, table2.to, Decoration9.mark({
4996
+ builder.add(table2.from, table2.to, Decoration10.mark({
4918
4997
  class: "cm-table"
4919
4998
  }));
4920
4999
  }
@@ -4922,10 +5001,17 @@ var update = (state, _options) => {
4922
5001
  return builder.finish();
4923
5002
  };
4924
5003
  var TableWidget = class extends WidgetType6 {
5004
+ _table;
5005
+ constructor(_table) {
5006
+ super(), this._table = _table;
5007
+ }
4925
5008
  eq(other) {
4926
5009
  return this._table.header?.join() === other._table.header?.join() && this._table.rows?.join() === other._table.rows?.join();
4927
5010
  }
4928
- toDOM(view) {
5011
+ ignoreEvent(e) {
5012
+ return !/^mouse/.test(e.type);
5013
+ }
5014
+ toDOM(_view) {
4929
5015
  const div = document.createElement("div");
4930
5016
  const table2 = div.appendChild(document.createElement("table"));
4931
5017
  const header = table2.appendChild(document.createElement("thead"));
@@ -4946,28 +5032,9 @@ var TableWidget = class extends WidgetType6 {
4946
5032
  });
4947
5033
  return div;
4948
5034
  }
4949
- ignoreEvent(e) {
4950
- return !/^mouse/.test(e.type);
4951
- }
4952
- constructor(_table) {
4953
- super(), _define_property14(this, "_table", void 0), this._table = _table;
4954
- }
4955
5035
  };
4956
5036
 
4957
5037
  // src/extensions/markdown/decorate.ts
4958
- function _define_property15(obj, key, value) {
4959
- if (key in obj) {
4960
- Object.defineProperty(obj, key, {
4961
- value,
4962
- enumerable: true,
4963
- configurable: true,
4964
- writable: true
4965
- });
4966
- } else {
4967
- obj[key] = value;
4968
- }
4969
- return obj;
4970
- }
4971
5038
  var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts";
4972
5039
  var Unicode = {
4973
5040
  emDash: "\u2014",
@@ -4983,6 +5050,11 @@ var HorizontalRuleWidget = class extends WidgetType7 {
4983
5050
  }
4984
5051
  };
4985
5052
  var LinkButton = class extends WidgetType7 {
5053
+ url;
5054
+ render;
5055
+ constructor(url, render) {
5056
+ super(), this.url = url, this.render = render;
5057
+ }
4986
5058
  eq(other) {
4987
5059
  return this.url === other.url;
4988
5060
  }
@@ -4994,14 +5066,18 @@ var LinkButton = class extends WidgetType7 {
4994
5066
  }, view);
4995
5067
  return el;
4996
5068
  }
4997
- constructor(url, render) {
4998
- super(), _define_property15(this, "url", void 0), _define_property15(this, "render", void 0), this.url = url, this.render = render;
4999
- }
5000
5069
  };
5001
5070
  var CheckboxWidget = class extends WidgetType7 {
5071
+ _checked;
5072
+ constructor(_checked) {
5073
+ super(), this._checked = _checked;
5074
+ }
5002
5075
  eq(other) {
5003
5076
  return this._checked === other._checked;
5004
5077
  }
5078
+ ignoreEvent() {
5079
+ return false;
5080
+ }
5005
5081
  toDOM(view) {
5006
5082
  const input = document.createElement("input");
5007
5083
  input.className = "cm-task-checkbox dx-checkbox";
@@ -5035,14 +5111,13 @@ var CheckboxWidget = class extends WidgetType7 {
5035
5111
  span.appendChild(input);
5036
5112
  return span;
5037
5113
  }
5038
- ignoreEvent() {
5039
- return false;
5040
- }
5041
- constructor(_checked) {
5042
- super(), _define_property15(this, "_checked", void 0), this._checked = _checked;
5043
- }
5044
5114
  };
5045
5115
  var TextWidget = class extends WidgetType7 {
5116
+ text;
5117
+ className;
5118
+ constructor(text, className) {
5119
+ super(), this.text = text, this.className = className;
5120
+ }
5046
5121
  toDOM() {
5047
5122
  const el = document.createElement("span");
5048
5123
  if (this.className) {
@@ -5051,33 +5126,30 @@ var TextWidget = class extends WidgetType7 {
5051
5126
  el.innerText = this.text;
5052
5127
  return el;
5053
5128
  }
5054
- constructor(text, className) {
5055
- super(), _define_property15(this, "text", void 0), _define_property15(this, "className", void 0), this.text = text, this.className = className;
5056
- }
5057
5129
  };
5058
- var hide = Decoration10.replace({});
5059
- var blockQuote = Decoration10.line({
5130
+ var hide = Decoration11.replace({});
5131
+ var blockQuote = Decoration11.line({
5060
5132
  class: "cm-blockquote"
5061
5133
  });
5062
- var fencedCodeLine = Decoration10.line({
5134
+ var fencedCodeLine = Decoration11.line({
5063
5135
  class: "cm-code cm-codeblock-line"
5064
5136
  });
5065
- var fencedCodeLineFirst = Decoration10.line({
5066
- class: mx4("cm-code cm-codeblock-line", "cm-codeblock-start")
5137
+ var fencedCodeLineFirst = Decoration11.line({
5138
+ class: mx5("cm-code cm-codeblock-line", "cm-codeblock-start")
5067
5139
  });
5068
- var fencedCodeLineLast = Decoration10.line({
5069
- class: mx4("cm-code cm-codeblock-line", "cm-codeblock-end")
5140
+ var fencedCodeLineLast = Decoration11.line({
5141
+ class: mx5("cm-code cm-codeblock-line", "cm-codeblock-end")
5070
5142
  });
5071
5143
  var commentBlockLine = fencedCodeLine;
5072
5144
  var commentBlockLineFirst = fencedCodeLineFirst;
5073
5145
  var commentBlockLineLast = fencedCodeLineLast;
5074
- var horizontalRule = Decoration10.replace({
5146
+ var horizontalRule = Decoration11.replace({
5075
5147
  widget: new HorizontalRuleWidget()
5076
5148
  });
5077
- var checkedTask = Decoration10.replace({
5149
+ var checkedTask = Decoration11.replace({
5078
5150
  widget: new CheckboxWidget(true)
5079
5151
  });
5080
- var uncheckedTask = Decoration10.replace({
5152
+ var uncheckedTask = Decoration11.replace({
5081
5153
  widget: new CheckboxWidget(false)
5082
5154
  });
5083
5155
  var editingRange = (state, range, focus2) => {
@@ -5093,8 +5165,8 @@ var autoHideTags = /* @__PURE__ */ new Set([
5093
5165
  "SuperscriptMark"
5094
5166
  ]);
5095
5167
  var buildDecorations2 = (view, options, focus2) => {
5096
- const deco = new RangeSetBuilder4();
5097
- const atomicDeco = new RangeSetBuilder4();
5168
+ const deco = new RangeSetBuilder5();
5169
+ const atomicDeco = new RangeSetBuilder5();
5098
5170
  const { state } = view;
5099
5171
  const headerLevels = [];
5100
5172
  const getHeaderLevels = (node, level) => {
@@ -5181,7 +5253,7 @@ var buildDecorations2 = (view, options, focus2) => {
5181
5253
  } else {
5182
5254
  const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
5183
5255
  if (num.length) {
5184
- atomicDeco.add(mark.from, mark.from + len, Decoration10.replace({
5256
+ atomicDeco.add(mark.from, mark.from + len, Decoration11.replace({
5185
5257
  widget: new TextWidget(num, theme.heading(level))
5186
5258
  }));
5187
5259
  }
@@ -5206,7 +5278,7 @@ var buildDecorations2 = (view, options, focus2) => {
5206
5278
  if (node.from === line.to - 1) {
5207
5279
  return false;
5208
5280
  }
5209
- deco.add(line.from, line.from, Decoration10.line({
5281
+ deco.add(line.from, line.from, Decoration11.line({
5210
5282
  class: "cm-list-item",
5211
5283
  attributes: {
5212
5284
  style: `padding-left: ${offset}px; text-indent: -${width}px;`
@@ -5223,7 +5295,7 @@ var buildDecorations2 = (view, options, focus2) => {
5223
5295
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
5224
5296
  const line = state.doc.lineAt(node.from);
5225
5297
  const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
5226
- atomicDeco.add(line.from, to, Decoration10.replace({
5298
+ atomicDeco.add(line.from, to, Decoration11.replace({
5227
5299
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
5228
5300
  }));
5229
5301
  break;
@@ -5316,7 +5388,7 @@ var buildDecorations2 = (view, options, focus2) => {
5316
5388
  if (!editing) {
5317
5389
  atomicDeco.add(node.from, marks[0].to, hide);
5318
5390
  }
5319
- deco.add(marks[0].to, marks[1].from, Decoration10.mark({
5391
+ deco.add(marks[0].to, marks[1].from, Decoration11.mark({
5320
5392
  tagName: "a",
5321
5393
  attributes: {
5322
5394
  class: "cm-link",
@@ -5326,7 +5398,7 @@ var buildDecorations2 = (view, options, focus2) => {
5326
5398
  }
5327
5399
  }));
5328
5400
  if (!editing) {
5329
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration10.replace({
5401
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration11.replace({
5330
5402
  widget: new LinkButton(url, options.renderLinkButton)
5331
5403
  }) : hide);
5332
5404
  }
@@ -5381,10 +5453,16 @@ var buildDecorations2 = (view, options, focus2) => {
5381
5453
  atomicDeco: atomicDeco.finish()
5382
5454
  };
5383
5455
  };
5384
- var forceUpdate = StateEffect5.define();
5456
+ var forceUpdate = StateEffect7.define();
5385
5457
  var decorateMarkdown = (options = {}) => {
5386
5458
  return [
5387
- ViewPlugin12.fromClass(class {
5459
+ ViewPlugin14.fromClass(class {
5460
+ deco;
5461
+ atomicDeco;
5462
+ pendingUpdate;
5463
+ constructor(view) {
5464
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
5465
+ }
5388
5466
  update(update2) {
5389
5467
  if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
5390
5468
  ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
@@ -5411,17 +5489,11 @@ var decorateMarkdown = (options = {}) => {
5411
5489
  destroy() {
5412
5490
  this.clearUpdate();
5413
5491
  }
5414
- constructor(view) {
5415
- _define_property15(this, "deco", void 0);
5416
- _define_property15(this, "atomicDeco", void 0);
5417
- _define_property15(this, "pendingUpdate", void 0);
5418
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
5419
- }
5420
5492
  }, {
5421
5493
  provide: (plugin) => [
5422
- Prec3.low(EditorView21.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration10.none)),
5423
- EditorView21.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration10.none),
5424
- EditorView21.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration10.none)
5494
+ Prec4.low(EditorView23.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
5495
+ EditorView23.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
5496
+ EditorView23.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
5425
5497
  ]
5426
5498
  }),
5427
5499
  image(),
@@ -5515,7 +5587,7 @@ var mention = ({ debug, onSearch }) => {
5515
5587
  };
5516
5588
 
5517
5589
  // src/extensions/modes.ts
5518
- import { keymap as keymap9 } from "@codemirror/view";
5590
+ import { keymap as keymap10 } from "@codemirror/view";
5519
5591
  import { vim } from "@replit/codemirror-vim";
5520
5592
  import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
5521
5593
  var editorInputMode = singleValueFacet({});
@@ -5526,7 +5598,7 @@ var InputModeExtensions = {
5526
5598
  editorInputMode.of({
5527
5599
  type: "vscode"
5528
5600
  }),
5529
- keymap9.of(vscodeKeymap)
5601
+ keymap10.of(vscodeKeymap)
5530
5602
  ],
5531
5603
  vim: [
5532
5604
  // https://github.com/replit/codemirror-vim
@@ -5535,7 +5607,7 @@ var InputModeExtensions = {
5535
5607
  type: "vim",
5536
5608
  ignoreEscape: true
5537
5609
  }),
5538
- keymap9.of([
5610
+ keymap10.of([
5539
5611
  {
5540
5612
  key: "Alt-Escape",
5541
5613
  run: (view) => {
@@ -5551,29 +5623,16 @@ var InputModeExtensions = {
5551
5623
  import { indentMore } from "@codemirror/commands";
5552
5624
  import { getIndentUnit } from "@codemirror/language";
5553
5625
  import { EditorSelection as EditorSelection3 } from "@codemirror/state";
5554
- import { keymap as keymap10 } from "@codemirror/view";
5626
+ import { keymap as keymap11 } from "@codemirror/view";
5555
5627
 
5556
5628
  // src/extensions/outliner/selection.ts
5557
5629
  import { Compartment, Facet as Facet3 } from "@codemirror/state";
5558
5630
 
5559
5631
  // src/extensions/outliner/tree.ts
5560
5632
  import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5561
- import { StateField as StateField8 } from "@codemirror/state";
5633
+ import { StateField as StateField9 } from "@codemirror/state";
5562
5634
  import { Facet as Facet2 } from "@codemirror/state";
5563
5635
  import { invariant as invariant5 } from "@dxos/invariant";
5564
- function _define_property16(obj, key, value) {
5565
- if (key in obj) {
5566
- Object.defineProperty(obj, key, {
5567
- value,
5568
- enumerable: true,
5569
- configurable: true,
5570
- writable: true
5571
- });
5572
- } else {
5573
- obj[key] = value;
5574
- }
5575
- return obj;
5576
- }
5577
5636
  var __dxlog_file12 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/outliner/tree.ts";
5578
5637
  var itemToJSON = ({ type, index, level, lineRange, contentRange, children }) => {
5579
5638
  return {
@@ -5586,6 +5645,21 @@ var itemToJSON = ({ type, index, level, lineRange, contentRange, children }) =>
5586
5645
  };
5587
5646
  };
5588
5647
  var Tree = class {
5648
+ type = "root";
5649
+ index = -1;
5650
+ level = -1;
5651
+ node;
5652
+ lineRange;
5653
+ contentRange;
5654
+ children = [];
5655
+ constructor(node) {
5656
+ this.node = node;
5657
+ this.lineRange = {
5658
+ from: node.from,
5659
+ to: node.to
5660
+ };
5661
+ this.contentRange = this.lineRange;
5662
+ }
5589
5663
  toJSON() {
5590
5664
  return itemToJSON(this);
5591
5665
  }
@@ -5635,21 +5709,6 @@ var Tree = class {
5635
5709
  lastDescendant(item) {
5636
5710
  return item.children.length > 0 ? this.lastDescendant(item.children.at(-1)) : item;
5637
5711
  }
5638
- constructor(node) {
5639
- _define_property16(this, "type", "root");
5640
- _define_property16(this, "index", -1);
5641
- _define_property16(this, "level", -1);
5642
- _define_property16(this, "node", void 0);
5643
- _define_property16(this, "lineRange", void 0);
5644
- _define_property16(this, "contentRange", void 0);
5645
- _define_property16(this, "children", []);
5646
- this.node = node;
5647
- this.lineRange = {
5648
- from: node.from,
5649
- to: node.to
5650
- };
5651
- this.contentRange = this.lineRange;
5652
- }
5653
5712
  };
5654
5713
  var getRange = (tree, item) => {
5655
5714
  const lastDescendant = tree.lastDescendant(item);
@@ -5856,7 +5915,7 @@ var outlinerTree = (_options = {}) => {
5856
5915
  return tree;
5857
5916
  };
5858
5917
  return [
5859
- StateField8.define({
5918
+ StateField9.define({
5860
5919
  create: (state) => {
5861
5920
  return buildTree(state);
5862
5921
  },
@@ -6030,7 +6089,7 @@ var toggleTask = (view) => {
6030
6089
  }
6031
6090
  return true;
6032
6091
  };
6033
- var commands = () => keymap10.of([
6092
+ var commands = () => keymap11.of([
6034
6093
  //
6035
6094
  // Indentation.
6036
6095
  //
@@ -6136,18 +6195,18 @@ var commands = () => keymap10.of([
6136
6195
  ]);
6137
6196
 
6138
6197
  // src/extensions/outliner/outliner.ts
6139
- import { Prec as Prec4 } from "@codemirror/state";
6140
- import { Decoration as Decoration11, EditorView as EditorView23, ViewPlugin as ViewPlugin15 } from "@codemirror/view";
6141
- import { mx as mx5 } from "@dxos/react-ui-theme";
6198
+ import { Prec as Prec5 } from "@codemirror/state";
6199
+ import { Decoration as Decoration12, EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
6200
+ import { mx as mx6 } from "@dxos/react-ui-theme";
6142
6201
 
6143
6202
  // src/extensions/outliner/editor.ts
6144
6203
  import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
6145
- import { ViewPlugin as ViewPlugin13 } from "@codemirror/view";
6204
+ import { ViewPlugin as ViewPlugin15 } from "@codemirror/view";
6146
6205
  import { log as log8 } from "@dxos/log";
6147
6206
  var __dxlog_file13 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/outliner/editor.ts";
6148
6207
  var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
6149
6208
  var initialize = () => {
6150
- return ViewPlugin13.fromClass(class {
6209
+ return ViewPlugin15.fromClass(class {
6151
6210
  constructor(view) {
6152
6211
  const first = view.state.doc.lineAt(0);
6153
6212
  const text = view.state.sliceDoc(first.from, first.to);
@@ -6330,23 +6389,32 @@ var editor = () => [
6330
6389
  ];
6331
6390
 
6332
6391
  // src/extensions/outliner/menu.ts
6333
- import { EditorView as EditorView22, ViewPlugin as ViewPlugin14 } from "@codemirror/view";
6392
+ import { EditorView as EditorView24, ViewPlugin as ViewPlugin16 } from "@codemirror/view";
6334
6393
  import { addEventListener } from "@dxos/async";
6335
- function _define_property17(obj, key, value) {
6336
- if (key in obj) {
6337
- Object.defineProperty(obj, key, {
6338
- value,
6339
- enumerable: true,
6340
- configurable: true,
6341
- writable: true
6342
- });
6343
- } else {
6344
- obj[key] = value;
6345
- }
6346
- return obj;
6347
- }
6348
6394
  var menu = (options = {}) => [
6349
- ViewPlugin14.fromClass(class {
6395
+ ViewPlugin16.fromClass(class {
6396
+ view;
6397
+ tag;
6398
+ rafId;
6399
+ cleanup;
6400
+ constructor(view) {
6401
+ this.view = view;
6402
+ const container = view.scrollDOM;
6403
+ if (getComputedStyle(container).position === "static") {
6404
+ container.style.position = "relative";
6405
+ }
6406
+ {
6407
+ const icon = document.createElement("dx-icon");
6408
+ icon.setAttribute("icon", options.icon ?? "ph--dots-three-vertical--regular");
6409
+ this.tag = document.createElement("dx-anchor");
6410
+ this.tag.classList.add("cm-popover-trigger");
6411
+ this.tag.appendChild(icon);
6412
+ }
6413
+ container.appendChild(this.tag);
6414
+ const handler = () => this.scheduleUpdate();
6415
+ this.cleanup = addEventListener(container, "scroll", handler);
6416
+ this.scheduleUpdate();
6417
+ }
6350
6418
  destroy() {
6351
6419
  this.cleanup?.();
6352
6420
  this.tag.remove();
@@ -6371,8 +6439,8 @@ var menu = (options = {}) => [
6371
6439
  if (!coords) {
6372
6440
  return;
6373
6441
  }
6374
- const lineHeight2 = coords.bottom - coords.top;
6375
- const dy = (lineHeight2 - (options.height ?? 32)) / 2;
6442
+ const lineHeight = coords.bottom - coords.top;
6443
+ const dy = (lineHeight - (options.height ?? 32)) / 2;
6376
6444
  const offsetTop = coords.top + dy;
6377
6445
  const offsetLeft = x + width + (options.padding ?? 8);
6378
6446
  this.tag.style.top = `${offsetTop}px`;
@@ -6385,30 +6453,8 @@ var menu = (options = {}) => [
6385
6453
  }
6386
6454
  this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
6387
6455
  }
6388
- constructor(view) {
6389
- _define_property17(this, "view", void 0);
6390
- _define_property17(this, "tag", void 0);
6391
- _define_property17(this, "rafId", void 0);
6392
- _define_property17(this, "cleanup", void 0);
6393
- this.view = view;
6394
- const container = view.scrollDOM;
6395
- if (getComputedStyle(container).position === "static") {
6396
- container.style.position = "relative";
6397
- }
6398
- {
6399
- const icon = document.createElement("dx-icon");
6400
- icon.setAttribute("icon", options.icon ?? "ph--dots-three-vertical--regular");
6401
- this.tag = document.createElement("dx-anchor");
6402
- this.tag.classList.add("cm-popover-trigger");
6403
- this.tag.appendChild(icon);
6404
- }
6405
- container.appendChild(this.tag);
6406
- const handler = () => this.scheduleUpdate();
6407
- this.cleanup = addEventListener(container, "scroll", handler);
6408
- this.scheduleUpdate();
6409
- }
6410
6456
  }),
6411
- EditorView22.theme({
6457
+ EditorView24.theme({
6412
6458
  ".cm-popover-trigger": {
6413
6459
  position: "fixed",
6414
6460
  padding: "0",
@@ -6426,22 +6472,9 @@ var menu = (options = {}) => [
6426
6472
  ];
6427
6473
 
6428
6474
  // src/extensions/outliner/outliner.ts
6429
- function _define_property18(obj, key, value) {
6430
- if (key in obj) {
6431
- Object.defineProperty(obj, key, {
6432
- value,
6433
- enumerable: true,
6434
- configurable: true,
6435
- writable: true
6436
- });
6437
- } else {
6438
- obj[key] = value;
6439
- }
6440
- return obj;
6441
- }
6442
6475
  var outliner = (_options = {}) => [
6443
6476
  // Commands.
6444
- Prec4.highest(commands()),
6477
+ Prec5.highest(commands()),
6445
6478
  // Selection.
6446
6479
  selectionCompartment.of(selectionFacet.of([])),
6447
6480
  // State.
@@ -6457,12 +6490,16 @@ var outliner = (_options = {}) => [
6457
6490
  listPaddingLeft: 8
6458
6491
  }),
6459
6492
  // Researve space for menu.
6460
- EditorView23.contentAttributes.of({
6493
+ EditorView25.contentAttributes.of({
6461
6494
  class: "is-full !mr-[3rem]"
6462
6495
  })
6463
6496
  ];
6464
6497
  var decorations = () => [
6465
- ViewPlugin15.fromClass(class {
6498
+ ViewPlugin17.fromClass(class {
6499
+ decorations = Decoration12.none;
6500
+ constructor(view) {
6501
+ this.updateDecorations(view.state, view);
6502
+ }
6466
6503
  update(update2) {
6467
6504
  const selectionChanged = !selectionEquals(update2.state.facet(selectionFacet), update2.startState.facet(selectionFacet));
6468
6505
  if (update2.focusChanged || update2.docChanged || update2.viewportChanged || update2.selectionSet || selectionChanged) {
@@ -6482,22 +6519,18 @@ var decorations = () => [
6482
6519
  const lineFrom = doc.lineAt(item.contentRange.from);
6483
6520
  const lineTo = doc.lineAt(item.contentRange.to);
6484
6521
  const isSelected = selection.includes(item.index) || item === current;
6485
- decorations2.push(Decoration11.line({
6486
- class: mx5("cm-list-item", lineFrom.number === line.number && "cm-list-item-start", lineTo.number === line.number && "cm-list-item-end", isSelected && (hasFocus ? "cm-list-item-focused" : "cm-list-item-selected"))
6522
+ decorations2.push(Decoration12.line({
6523
+ class: mx6("cm-list-item", lineFrom.number === line.number && "cm-list-item-start", lineTo.number === line.number && "cm-list-item-end", isSelected && (hasFocus ? "cm-list-item-focused" : "cm-list-item-selected"))
6487
6524
  }).range(line.from, line.from));
6488
6525
  }
6489
6526
  }
6490
- this.decorations = Decoration11.set(decorations2);
6491
- }
6492
- constructor(view) {
6493
- _define_property18(this, "decorations", Decoration11.none);
6494
- this.updateDecorations(view.state, view);
6527
+ this.decorations = Decoration12.set(decorations2);
6495
6528
  }
6496
6529
  }, {
6497
6530
  decorations: (v) => v.decorations
6498
6531
  }),
6499
6532
  // Theme.
6500
- EditorView23.theme(Object.assign({
6533
+ EditorView25.theme(Object.assign({
6501
6534
  ".cm-list-item": {
6502
6535
  borderLeftWidth: "1px",
6503
6536
  borderRightWidth: "1px",
@@ -6729,9 +6762,9 @@ var linkSlashCommands = {
6729
6762
  };
6730
6763
 
6731
6764
  // src/extensions/popover/modal.ts
6732
- import { StateEffect as StateEffect6, StateField as StateField9 } from "@codemirror/state";
6733
- var modalStateEffect = StateEffect6.define();
6734
- var modalStateField = StateField9.define({
6765
+ import { StateEffect as StateEffect8, StateField as StateField10 } from "@codemirror/state";
6766
+ var modalStateEffect = StateEffect8.define();
6767
+ var modalStateField = StateField10.define({
6735
6768
  create: () => false,
6736
6769
  update: (value, tr) => {
6737
6770
  let newValue = value;
@@ -6745,29 +6778,16 @@ var modalStateField = StateField9.define({
6745
6778
  });
6746
6779
 
6747
6780
  // src/extensions/popover/popover.ts
6748
- import { Prec as Prec5, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7, StateField as StateField10 } from "@codemirror/state";
6749
- import { Decoration as Decoration12, EditorView as EditorView24, ViewPlugin as ViewPlugin16, keymap as keymap11 } from "@codemirror/view";
6750
- import { isNonNullable as isNonNullable2, isTruthy as isTruthy4 } from "@dxos/util";
6751
- function _define_property19(obj, key, value) {
6752
- if (key in obj) {
6753
- Object.defineProperty(obj, key, {
6754
- value,
6755
- enumerable: true,
6756
- configurable: true,
6757
- writable: true
6758
- });
6759
- } else {
6760
- obj[key] = value;
6761
- }
6762
- return obj;
6763
- }
6781
+ import { Prec as Prec6, RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect9, StateField as StateField11 } from "@codemirror/state";
6782
+ import { Decoration as Decoration13, EditorView as EditorView26, ViewPlugin as ViewPlugin18, keymap as keymap12 } from "@codemirror/view";
6783
+ import { isNonNullable as isNonNullable3, isTruthy as isTruthy4 } from "@dxos/util";
6764
6784
  var DELIMITERS = [
6765
6785
  " ",
6766
6786
  ":"
6767
6787
  ];
6768
6788
  var popover = (options = {}) => {
6769
6789
  return [
6770
- Prec5.highest(popoverKeymap(options)),
6790
+ Prec6.highest(popoverKeymap(options)),
6771
6791
  popoverStateField,
6772
6792
  popoverTriggerListener(options),
6773
6793
  popoverAnchorDecoration(options),
@@ -6779,7 +6799,7 @@ var popover = (options = {}) => {
6779
6799
  })
6780
6800
  ].filter(isTruthy4);
6781
6801
  };
6782
- var popoverTriggerListener = (options) => EditorView24.updateListener.of(({ view, docChanged }) => {
6802
+ var popoverTriggerListener = (options) => EditorView26.updateListener.of(({ view, docChanged }) => {
6783
6803
  const { range: activeRange, trigger } = view.state.field(popoverStateField) ?? {};
6784
6804
  if (!activeRange) {
6785
6805
  return;
@@ -6815,9 +6835,9 @@ var popoverKeymap = (options) => {
6815
6835
  const triggers = Array.isArray(options.trigger) ? options.trigger : [
6816
6836
  options.trigger
6817
6837
  ];
6818
- return keymap11.of([
6838
+ return keymap12.of([
6819
6839
  // Prefix triggers.
6820
- ...triggers.filter(isNonNullable2).map((trigger) => ({
6840
+ ...triggers.filter(isNonNullable3).map((trigger) => ({
6821
6841
  key: trigger,
6822
6842
  run: (view) => {
6823
6843
  const selection = view.state.selection.main;
@@ -6859,7 +6879,6 @@ var popoverKeymap = (options) => {
6859
6879
  str = str.slice(idx + 1);
6860
6880
  }
6861
6881
  const from = line.from + idx;
6862
- console.log("effect", from + 1, selection.head);
6863
6882
  view.dispatch({
6864
6883
  effects: popoverRangeEffect.of({
6865
6884
  range: {
@@ -6928,17 +6947,21 @@ var popoverKeymap = (options) => {
6928
6947
  ].filter(isTruthy4));
6929
6948
  };
6930
6949
  var popoverAnchorDecoration = (options) => {
6931
- return ViewPlugin16.fromClass(class {
6950
+ return ViewPlugin18.fromClass(class {
6951
+ view;
6952
+ _decorations = Decoration13.none;
6953
+ constructor(view) {
6954
+ this.view = view;
6955
+ }
6932
6956
  // TODO(wittjosiah): The decorations are repainted on every update, this occasionally causes menu to flicker.
6933
6957
  update({ view, transactions }) {
6934
- const builder = new RangeSetBuilder5();
6958
+ const builder = new RangeSetBuilder6();
6935
6959
  const { range, trigger } = view.state.field(popoverStateField) ?? {};
6936
6960
  if (range) {
6937
6961
  const selection = view.state.selection.main;
6938
6962
  const showWidget = selection.head >= range.from && selection.head <= range.to;
6939
- console.log("update", showWidget, range.from, range.to + 1);
6940
6963
  if (showWidget) {
6941
- builder.add(range.from, range.to + 1, Decoration12.mark({
6964
+ builder.add(range.from, range.to + 1, Decoration13.mark({
6942
6965
  tagName: "dx-anchor",
6943
6966
  class: "cm-popover-trigger",
6944
6967
  attributes: {
@@ -6958,23 +6981,15 @@ var popoverAnchorDecoration = (options) => {
6958
6981
  trigger
6959
6982
  });
6960
6983
  }
6961
- } else {
6962
- console.log("remove");
6963
6984
  }
6964
6985
  this._decorations = builder.finish();
6965
6986
  }
6966
- constructor(view) {
6967
- _define_property19(this, "view", void 0);
6968
- _define_property19(this, "_decorations", void 0);
6969
- this.view = view;
6970
- this._decorations = Decoration12.none;
6971
- }
6972
6987
  }, {
6973
6988
  decorations: (v) => v._decorations
6974
6989
  });
6975
6990
  };
6976
- var popoverRangeEffect = StateEffect7.define();
6977
- var popoverStateField = StateField10.define({
6991
+ var popoverRangeEffect = StateEffect9.define();
6992
+ var popoverStateField = StateField11.define({
6978
6993
  create: () => null,
6979
6994
  update: (value, tr) => {
6980
6995
  let newValue = value;
@@ -6991,7 +7006,7 @@ var getLastIndexOf = (str, delimiters) => Math.max(...delimiters.map((delim) =>
6991
7006
  // src/extensions/popover/PopoverMenuProvider.tsx
6992
7007
  import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
6993
7008
  import { useControllableState } from "@radix-ui/react-use-controllable-state";
6994
- import React3, { Fragment, useCallback as useCallback2, useEffect as useEffect2, useRef, useState } from "react";
7009
+ import React3, { Fragment, useCallback, useEffect as useEffect2, useRef, useState } from "react";
6995
7010
  import { addEventListener as addEventListener2 } from "@dxos/async";
6996
7011
  import { invariant as invariant6 } from "@dxos/invariant";
6997
7012
  import { Icon as Icon2, Popover, toLocalizedString, useDynamicRef, useThemeContext, useTranslation } from "@dxos/react-ui";
@@ -7028,7 +7043,6 @@ var PopoverMenuProvider = ({ children, view, groups, currentItem, open: openPara
7028
7043
  }
7029
7044
  return addEventListener2(root, "dx-anchor-activate", (event) => {
7030
7045
  const { trigger, refId } = event;
7031
- console.log("update", trigger, refId);
7032
7046
  if (!refId) {
7033
7047
  triggerRef.current = trigger;
7034
7048
  if (onActivate) {
@@ -7048,10 +7062,10 @@ var PopoverMenuProvider = ({ children, view, groups, currentItem, open: openPara
7048
7062
  root,
7049
7063
  onActivate
7050
7064
  ]);
7051
- const handleSelect = useCallback2((item) => {
7065
+ const handleSelect = useCallback((item) => {
7052
7066
  invariant6(viewRef.current, void 0, {
7053
7067
  F: __dxlog_file14,
7054
- L: 101,
7068
+ L: 100,
7055
7069
  S: void 0,
7056
7070
  A: [
7057
7071
  "viewRef.current",
@@ -7066,7 +7080,7 @@ var PopoverMenuProvider = ({ children, view, groups, currentItem, open: openPara
7066
7080
  viewRef,
7067
7081
  onSelect
7068
7082
  ]);
7069
- const menuGroups = groups.filter((group) => group.items.length > 0);
7083
+ const menuGroups = groups?.filter((group) => group.items.length > 0) ?? [];
7070
7084
  return /* @__PURE__ */ React3.createElement(Popover.Root, {
7071
7085
  modal: false,
7072
7086
  open,
@@ -7158,7 +7172,7 @@ var MenuItem = ({ item, current, onSelect }) => {
7158
7172
  }, [
7159
7173
  current
7160
7174
  ]);
7161
- const handleSelect = useCallback2(() => onSelect?.(item), [
7175
+ const handleSelect = useCallback(() => onSelect?.(item), [
7162
7176
  item,
7163
7177
  onSelect
7164
7178
  ]);
@@ -7180,7 +7194,7 @@ var MenuItem = ({ item, current, onSelect }) => {
7180
7194
  };
7181
7195
 
7182
7196
  // src/extensions/popover/usePopoverMenu.ts
7183
- import { useCallback as useCallback3, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
7197
+ import { useCallback as useCallback2, useMemo, useRef as useRef2, useState as useState2 } from "react";
7184
7198
  import { invariant as invariant7 } from "@dxos/invariant";
7185
7199
  var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/popover/usePopoverMenu.ts";
7186
7200
  var usePopoverMenu = ({ trigger, triggerKey, placeholder: placeholder3, filter = true, getMenu }) => {
@@ -7189,7 +7203,7 @@ var usePopoverMenu = ({ trigger, triggerKey, placeholder: placeholder3, filter =
7189
7203
  const [currentItem, setCurrentItem] = useState2();
7190
7204
  const [open, setOpen] = useState2(false);
7191
7205
  const [_, refresh] = useState2({});
7192
- const getMenuOptions = useCallback3(async ({ text, trigger: trigger2, ...props }) => {
7206
+ const getMenuOptions = useCallback2(async ({ text, trigger: trigger2, ...props }) => {
7193
7207
  const groups = await getMenu?.({
7194
7208
  text,
7195
7209
  trigger: trigger2,
@@ -7200,7 +7214,7 @@ var usePopoverMenu = ({ trigger, triggerKey, placeholder: placeholder3, filter =
7200
7214
  getMenu,
7201
7215
  filter
7202
7216
  ]);
7203
- const handleOpenChange = useCallback3(async ({ view, open: open2 }) => {
7217
+ const handleOpenChange = useCallback2(async ({ view, open: open2 }) => {
7204
7218
  invariant7(view, void 0, {
7205
7219
  F: __dxlog_file15,
7206
7220
  L: 76,
@@ -7229,7 +7243,7 @@ var usePopoverMenu = ({ trigger, triggerKey, placeholder: placeholder3, filter =
7229
7243
  }, [
7230
7244
  getMenuOptions
7231
7245
  ]);
7232
- const handleActivate = useCallback3(async ({ view, trigger: trigger2 }) => {
7246
+ const handleActivate = useCallback2(async ({ view, trigger: trigger2 }) => {
7233
7247
  const item = getMenuItem(groupsRef.current, currentItem);
7234
7248
  if (item) {
7235
7249
  currentRef.current = item;
@@ -7245,10 +7259,10 @@ var usePopoverMenu = ({ trigger, triggerKey, placeholder: placeholder3, filter =
7245
7259
  open,
7246
7260
  handleOpenChange
7247
7261
  ]);
7248
- const handleSelect = useCallback3(({ view, item }) => {
7262
+ const handleSelect = useCallback2(({ view, item }) => {
7249
7263
  void item.onSelect?.(view, view.state.selection.main.head);
7250
7264
  }, []);
7251
- const handleCancel = useCallback3(({ view }) => {
7265
+ const handleCancel = useCallback2(({ view }) => {
7252
7266
  const { range, trigger: trigger2 } = view.state.field(popoverStateField) ?? {};
7253
7267
  if (range && trigger2) {
7254
7268
  view.dispatch({
@@ -7260,7 +7274,7 @@ var usePopoverMenu = ({ trigger, triggerKey, placeholder: placeholder3, filter =
7260
7274
  }
7261
7275
  }, []);
7262
7276
  const serializedTrigger = Array.isArray(trigger) ? trigger.join(",") : trigger;
7263
- const extension = useMemo2(() => {
7277
+ const extension = useMemo(() => {
7264
7278
  return popover({
7265
7279
  trigger,
7266
7280
  triggerKey,
@@ -7326,26 +7340,13 @@ var usePopoverMenu = ({ trigger, triggerKey, placeholder: placeholder3, filter =
7326
7340
 
7327
7341
  // src/extensions/preview/preview.ts
7328
7342
  import { syntaxTree as syntaxTree10 } from "@codemirror/language";
7329
- import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
7330
- import { Decoration as Decoration13, EditorView as EditorView25, WidgetType as WidgetType8 } from "@codemirror/view";
7331
- function _define_property20(obj, key, value) {
7332
- if (key in obj) {
7333
- Object.defineProperty(obj, key, {
7334
- value,
7335
- enumerable: true,
7336
- configurable: true,
7337
- writable: true
7338
- });
7339
- } else {
7340
- obj[key] = value;
7341
- }
7342
- return obj;
7343
- }
7343
+ import { RangeSetBuilder as RangeSetBuilder7, StateField as StateField12 } from "@codemirror/state";
7344
+ import { Decoration as Decoration14, EditorView as EditorView27, WidgetType as WidgetType8 } from "@codemirror/view";
7344
7345
  var preview = (options = {}) => {
7345
7346
  return [
7346
7347
  // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
7347
7348
  // "Block decorations may not be specified via plugins".
7348
- StateField11.define({
7349
+ StateField12.define({
7349
7350
  create: (state) => buildDecorations3(state, options),
7350
7351
  update: (decorations2, tr) => {
7351
7352
  if (tr.docChanged) {
@@ -7354,14 +7355,14 @@ var preview = (options = {}) => {
7354
7355
  return decorations2.map(tr.changes);
7355
7356
  },
7356
7357
  provide: (field) => [
7357
- EditorView25.decorations.from(field),
7358
- EditorView25.atomicRanges.of((view) => view.state.field(field))
7358
+ EditorView27.decorations.from(field),
7359
+ EditorView27.atomicRanges.of((view) => view.state.field(field))
7359
7360
  ]
7360
7361
  })
7361
7362
  ];
7362
7363
  };
7363
7364
  var buildDecorations3 = (state, options) => {
7364
- const builder = new RangeSetBuilder6();
7365
+ const builder = new RangeSetBuilder7();
7365
7366
  syntaxTree10(state).iterate({
7366
7367
  enter: (node) => {
7367
7368
  switch (node.name) {
@@ -7372,7 +7373,7 @@ var buildDecorations3 = (state, options) => {
7372
7373
  case "Link": {
7373
7374
  const link = getLinkRef(state, node.node);
7374
7375
  if (link) {
7375
- builder.add(node.from, node.to, Decoration13.replace({
7376
+ builder.add(node.from, node.to, Decoration14.replace({
7376
7377
  widget: new PreviewInlineWidget(options, link),
7377
7378
  side: 1
7378
7379
  }));
@@ -7387,7 +7388,7 @@ var buildDecorations3 = (state, options) => {
7387
7388
  if (options.addBlockContainer && options.removeBlockContainer) {
7388
7389
  const link = getLinkRef(state, node.node);
7389
7390
  if (link) {
7390
- builder.add(node.from, node.to, Decoration13.replace({
7391
+ builder.add(node.from, node.to, Decoration14.replace({
7391
7392
  block: true,
7392
7393
  widget: new PreviewBlockWidget(options, link)
7393
7394
  }));
@@ -7416,6 +7417,11 @@ var getLinkRef = (state, node) => {
7416
7417
  }
7417
7418
  };
7418
7419
  var PreviewInlineWidget = class extends WidgetType8 {
7420
+ _options;
7421
+ _link;
7422
+ constructor(_options, _link) {
7423
+ super(), this._options = _options, this._link = _link;
7424
+ }
7419
7425
  // override ignoreEvent() {
7420
7426
  // return false;
7421
7427
  // }
@@ -7429,11 +7435,13 @@ var PreviewInlineWidget = class extends WidgetType8 {
7429
7435
  root.setAttribute("refId", this._link.ref);
7430
7436
  return root;
7431
7437
  }
7432
- constructor(_options, _link) {
7433
- super(), _define_property20(this, "_options", void 0), _define_property20(this, "_link", void 0), this._options = _options, this._link = _link;
7434
- }
7435
7438
  };
7436
7439
  var PreviewBlockWidget = class extends WidgetType8 {
7440
+ _options;
7441
+ _link;
7442
+ constructor(_options, _link) {
7443
+ super(), this._options = _options, this._link = _link;
7444
+ }
7437
7445
  // override ignoreEvent() {
7438
7446
  // return true;
7439
7447
  // }
@@ -7443,18 +7451,119 @@ var PreviewBlockWidget = class extends WidgetType8 {
7443
7451
  toDOM(_view) {
7444
7452
  const root = document.createElement("div");
7445
7453
  root.classList.add("cm-preview-block", "density-coarse");
7446
- this._options.addBlockContainer?.(this._link, root);
7454
+ this._options.addBlockContainer?.({
7455
+ link: this._link,
7456
+ el: root
7457
+ });
7447
7458
  return root;
7448
7459
  }
7449
- destroy() {
7450
- this._options.removeBlockContainer?.(this._link);
7451
- }
7452
- constructor(_options, _link) {
7453
- super(), _define_property20(this, "_options", void 0), _define_property20(this, "_link", void 0), this._options = _options, this._link = _link;
7460
+ destroy(root) {
7461
+ this._options.removeBlockContainer?.({
7462
+ link: this._link,
7463
+ el: root
7464
+ });
7454
7465
  }
7455
7466
  };
7456
7467
 
7457
- // src/extensions/tags/extended-markdown.ts
7468
+ // src/extensions/replacer.ts
7469
+ import { EditorView as EditorView28 } from "@codemirror/view";
7470
+ var defaultReplacements = [
7471
+ {
7472
+ input: "--",
7473
+ output: "\u2014"
7474
+ },
7475
+ {
7476
+ input: "...",
7477
+ output: "\u2026"
7478
+ },
7479
+ {
7480
+ input: "->",
7481
+ output: "\u2192"
7482
+ },
7483
+ {
7484
+ input: "<-",
7485
+ output: "\u2190"
7486
+ },
7487
+ {
7488
+ input: "=>",
7489
+ output: "\u21D2"
7490
+ },
7491
+ {
7492
+ input: "<=>",
7493
+ output: "\u21D4"
7494
+ },
7495
+ {
7496
+ input: "+-",
7497
+ output: "\xB1"
7498
+ },
7499
+ {
7500
+ input: "!=",
7501
+ output: "\u2260"
7502
+ },
7503
+ {
7504
+ input: "<=",
7505
+ output: "\u2264"
7506
+ },
7507
+ {
7508
+ input: ">=",
7509
+ output: "\u2265"
7510
+ },
7511
+ {
7512
+ input: "(c)",
7513
+ output: "\xA9"
7514
+ },
7515
+ {
7516
+ input: "EUR",
7517
+ output: "\u20AC"
7518
+ },
7519
+ {
7520
+ input: "GBP",
7521
+ output: "\xA3"
7522
+ },
7523
+ {
7524
+ input: "BTC",
7525
+ output: "\u20BF"
7526
+ }
7527
+ ];
7528
+ var replacer = ({ replacements = defaultReplacements } = {}) => {
7529
+ const sortedReplacements = [
7530
+ ...replacements
7531
+ ].sort((a, b) => b.input.length - a.input.length);
7532
+ return EditorView28.inputHandler.of((view, from, to, insert) => {
7533
+ if (insert.length !== 1) {
7534
+ return false;
7535
+ }
7536
+ const state = view.state;
7537
+ const doc = state.doc;
7538
+ const lineStart = doc.lineAt(from).from;
7539
+ const textBefore = doc.sliceString(lineStart, from);
7540
+ const textWithInsert = textBefore + insert;
7541
+ for (const replacement of sortedReplacements) {
7542
+ if (textWithInsert.endsWith(replacement.input)) {
7543
+ const range = {
7544
+ from: from - replacement.input.length + 1,
7545
+ to: from
7546
+ };
7547
+ if (range.from < lineStart) {
7548
+ continue;
7549
+ }
7550
+ view.dispatch(state.update({
7551
+ changes: {
7552
+ ...range,
7553
+ insert: replacement.output
7554
+ },
7555
+ selection: {
7556
+ anchor: range.from + replacement.output.length
7557
+ }
7558
+ }));
7559
+ return true;
7560
+ }
7561
+ }
7562
+ return false;
7563
+ });
7564
+ };
7565
+
7566
+ // src/extensions/tags/extended-markdown.ts
7458
7567
  import { xmlLanguage } from "@codemirror/lang-xml";
7459
7568
  import { parseMixed } from "@lezer/common";
7460
7569
  var extendedMarkdown = ({ registry } = {}) => {
@@ -7509,23 +7618,10 @@ var mixedParser = (registry) => {
7509
7618
  };
7510
7619
 
7511
7620
  // src/extensions/tags/streamer.ts
7512
- import { StateEffect as StateEffect8, StateField as StateField12 } from "@codemirror/state";
7513
- import { Decoration as Decoration14, EditorView as EditorView26, ViewPlugin as ViewPlugin17, WidgetType as WidgetType9 } from "@codemirror/view";
7621
+ import { StateEffect as StateEffect10, StateField as StateField13 } from "@codemirror/state";
7622
+ import { Decoration as Decoration15, EditorView as EditorView29, ViewPlugin as ViewPlugin19, WidgetType as WidgetType9 } from "@codemirror/view";
7514
7623
  import { Domino as Domino3 } from "@dxos/react-ui";
7515
7624
  import { isTruthy as isTruthy5 } from "@dxos/util";
7516
- function _define_property21(obj, key, value) {
7517
- if (key in obj) {
7518
- Object.defineProperty(obj, key, {
7519
- value,
7520
- enumerable: true,
7521
- configurable: true,
7522
- writable: true
7523
- });
7524
- } else {
7525
- obj[key] = value;
7526
- }
7527
- return obj;
7528
- }
7529
7625
  var BLINK_RATE = 2e3;
7530
7626
  var streamer = (options = {}) => {
7531
7627
  return [
@@ -7534,8 +7630,8 @@ var streamer = (options = {}) => {
7534
7630
  ].filter(isTruthy5);
7535
7631
  };
7536
7632
  var cursor = () => {
7537
- const hideCursor = StateEffect8.define();
7538
- const showCursor = StateField12.define({
7633
+ const hideCursor = StateEffect10.define();
7634
+ const showCursor = StateField13.define({
7539
7635
  create: () => true,
7540
7636
  update: (value, tr) => {
7541
7637
  for (const effect of tr.effects) {
@@ -7549,7 +7645,12 @@ var cursor = () => {
7549
7645
  return value;
7550
7646
  }
7551
7647
  });
7552
- const timerPlugin = ViewPlugin17.fromClass(class {
7648
+ const timerPlugin = ViewPlugin19.fromClass(class {
7649
+ view;
7650
+ timer;
7651
+ constructor(view) {
7652
+ this.view = view;
7653
+ }
7553
7654
  update(update2) {
7554
7655
  if (update2.docChanged) {
7555
7656
  clearTimeout(this.timer);
@@ -7563,28 +7664,23 @@ var cursor = () => {
7563
7664
  destroy() {
7564
7665
  clearTimeout(this.timer);
7565
7666
  }
7566
- constructor(view) {
7567
- _define_property21(this, "view", void 0);
7568
- _define_property21(this, "timer", void 0);
7569
- this.view = view;
7570
- }
7571
7667
  });
7572
- const cursorDecoration = StateField12.define({
7573
- create: () => Decoration14.none,
7668
+ const cursorDecoration = StateField13.define({
7669
+ create: () => Decoration15.none,
7574
7670
  update: (_decorations, tr) => {
7575
7671
  const show = tr.state.field(showCursor);
7576
7672
  if (!show) {
7577
- return Decoration14.none;
7673
+ return Decoration15.none;
7578
7674
  }
7579
7675
  const endPos = tr.state.doc.length;
7580
- return Decoration14.set([
7581
- Decoration14.widget({
7676
+ return Decoration15.set([
7677
+ Decoration15.widget({
7582
7678
  widget: new CursorWidget(),
7583
7679
  side: 1
7584
7680
  }).range(endPos)
7585
7681
  ]);
7586
7682
  },
7587
- provide: (f) => EditorView26.decorations.from(f)
7683
+ provide: (f) => EditorView29.decorations.from(f)
7588
7684
  });
7589
7685
  return [
7590
7686
  showCursor,
@@ -7605,9 +7701,9 @@ var fadeIn = (options = {}) => {
7605
7701
  const FADE_IN_DURATION = 1e3;
7606
7702
  const DEFAULT_REMOVAL_DELAY = 5e3;
7607
7703
  const removalDelay = options.removalDelay ?? DEFAULT_REMOVAL_DELAY;
7608
- const removeDecoration = StateEffect8.define();
7609
- const fadeField = StateField12.define({
7610
- create: () => Decoration14.none,
7704
+ const removeDecoration = StateEffect10.define();
7705
+ const fadeField = StateField13.define({
7706
+ create: () => Decoration15.none,
7611
7707
  update: (decorations2, tr) => {
7612
7708
  let next = decorations2;
7613
7709
  for (const effect of tr.effects) {
@@ -7630,7 +7726,7 @@ var fadeIn = (options = {}) => {
7630
7726
  });
7631
7727
  }
7632
7728
  if (isReset) {
7633
- return Decoration14.none;
7729
+ return Decoration15.none;
7634
7730
  }
7635
7731
  const add = [];
7636
7732
  tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
@@ -7638,7 +7734,7 @@ var fadeIn = (options = {}) => {
7638
7734
  return;
7639
7735
  }
7640
7736
  if (toA === tr.startState.doc.length && inserted.length > 0) {
7641
- add.push(Decoration14.mark({
7737
+ add.push(Decoration15.mark({
7642
7738
  class: "cm-fade-in"
7643
7739
  }).range(fromB, toB));
7644
7740
  }
@@ -7647,9 +7743,15 @@ var fadeIn = (options = {}) => {
7647
7743
  add
7648
7744
  });
7649
7745
  },
7650
- provide: (f) => EditorView26.decorations.from(f)
7746
+ provide: (f) => EditorView29.decorations.from(f)
7651
7747
  });
7652
- const timerPlugin = ViewPlugin17.fromClass(class {
7748
+ const timerPlugin = ViewPlugin19.fromClass(class {
7749
+ view;
7750
+ // Map a simple key "from-to" to timer id.
7751
+ _timers = /* @__PURE__ */ new Map();
7752
+ constructor(view) {
7753
+ this.view = view;
7754
+ }
7653
7755
  update(update2) {
7654
7756
  if (!update2.docChanged) {
7655
7757
  return;
@@ -7681,17 +7783,11 @@ var fadeIn = (options = {}) => {
7681
7783
  }
7682
7784
  this._timers.clear();
7683
7785
  }
7684
- constructor(view) {
7685
- _define_property21(this, "view", void 0);
7686
- _define_property21(this, "_timers", void 0);
7687
- this.view = view;
7688
- this._timers = /* @__PURE__ */ new Map();
7689
- }
7690
7786
  });
7691
7787
  return [
7692
7788
  fadeField,
7693
7789
  timerPlugin,
7694
- EditorView26.theme({
7790
+ EditorView29.theme({
7695
7791
  ".cm-line > span": {
7696
7792
  opacity: "0.8"
7697
7793
  },
@@ -7715,8 +7811,10 @@ var fadeIn = (options = {}) => {
7715
7811
 
7716
7812
  // src/extensions/tags/xml-tags.ts
7717
7813
  import { syntaxTree as syntaxTree11 } from "@codemirror/language";
7718
- import { RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect9, StateField as StateField13, Transaction as Transaction5 } from "@codemirror/state";
7719
- import { Decoration as Decoration15, EditorView as EditorView27, WidgetType as WidgetType10 } from "@codemirror/view";
7814
+ import { Prec as Prec7 } from "@codemirror/state";
7815
+ import { RangeSetBuilder as RangeSetBuilder8, StateEffect as StateEffect11, StateField as StateField14 } from "@codemirror/state";
7816
+ import { keymap as keymap13 } from "@codemirror/view";
7817
+ import { Decoration as Decoration16, EditorView as EditorView30, ViewPlugin as ViewPlugin20, WidgetType as WidgetType10 } from "@codemirror/view";
7720
7818
  import { invariant as invariant9 } from "@dxos/invariant";
7721
7819
  import { log as log9 } from "@dxos/log";
7722
7820
 
@@ -7789,102 +7887,281 @@ var nodeToJson = (state, node) => {
7789
7887
  };
7790
7888
 
7791
7889
  // src/extensions/tags/xml-tags.ts
7792
- function _define_property22(obj, key, value) {
7793
- if (key in obj) {
7794
- Object.defineProperty(obj, key, {
7795
- value,
7796
- enumerable: true,
7797
- configurable: true,
7798
- writable: true
7799
- });
7800
- } else {
7801
- obj[key] = value;
7802
- }
7803
- return obj;
7804
- }
7805
7890
  var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/extensions/tags/xml-tags.ts";
7891
+ var navigatePreviousEffect = StateEffect11.define();
7892
+ var navigateNextEffect = StateEffect11.define();
7806
7893
  var getXmlTextChild = (children) => {
7807
7894
  const child = children?.[0];
7808
7895
  return typeof child === "string" ? child : null;
7809
7896
  };
7810
- var xmlTagContextEffect = StateEffect9.define();
7811
- var xmlTagUpdateEffect = StateEffect9.define();
7812
- var xmlTagResetEffect = StateEffect9.define();
7813
- var xmlTags = (options = {}) => {
7814
- const contextState = StateField13.define({
7815
- create: () => void 0,
7816
- update: (value, tr) => {
7817
- for (const effect of tr.effects) {
7818
- if (effect.is(xmlTagContextEffect)) {
7819
- return effect.value;
7820
- }
7897
+ var xmlTagContextEffect = StateEffect11.define();
7898
+ var xmlTagResetEffect = StateEffect11.define();
7899
+ var xmlTagUpdateEffect = StateEffect11.define();
7900
+ var widgetContextStateField = StateField14.define({
7901
+ create: () => void 0,
7902
+ update: (value, tr) => {
7903
+ for (const effect of tr.effects) {
7904
+ if (effect.is(xmlTagContextEffect)) {
7905
+ return effect.value;
7821
7906
  }
7822
- return value;
7823
7907
  }
7824
- });
7908
+ return value;
7909
+ }
7910
+ });
7911
+ var widgetStateMapStateField = StateField14.define({
7912
+ create: () => ({}),
7913
+ update: (map, tr) => {
7914
+ for (const effect of tr.effects) {
7915
+ if (effect.is(xmlTagResetEffect)) {
7916
+ return {};
7917
+ }
7918
+ if (effect.is(xmlTagUpdateEffect)) {
7919
+ const { id, value } = effect.value;
7920
+ log9("widget updated", {
7921
+ id,
7922
+ value
7923
+ }, {
7924
+ F: __dxlog_file17,
7925
+ L: 146,
7926
+ S: void 0,
7927
+ C: (f, a) => f(...a)
7928
+ });
7929
+ const state = typeof value === "function" ? value(map[id]) : value;
7930
+ return {
7931
+ ...map,
7932
+ [id]: state
7933
+ };
7934
+ }
7935
+ }
7936
+ return map;
7937
+ }
7938
+ });
7939
+ var xmlTags = ({ registry, setWidgets, bookmarks: bookmarks2 }) => {
7940
+ const notifier = createWidgetMap(setWidgets);
7941
+ const widgetDecorationsField = createWidgetDecorationsField(registry, notifier);
7942
+ return [
7943
+ widgetContextStateField,
7944
+ widgetStateMapStateField,
7945
+ widgetDecorationsField,
7946
+ createWidgetUpdatePlugin(widgetDecorationsField, notifier),
7947
+ createNavigationEffectPlugin(widgetDecorationsField, bookmarks2),
7948
+ bookmarks2?.length ? Prec7.highest(keyHandlers) : []
7949
+ ];
7950
+ };
7951
+ var createWidgetMap = (setWidgets) => {
7825
7952
  const widgets = /* @__PURE__ */ new Map();
7826
7953
  const notifier = {
7827
- mounted: (widget) => {
7828
- widgets.set(widget.id, widget);
7829
- options.setWidgets?.([
7954
+ mounted: (state) => {
7955
+ log9("widget mounted", {
7956
+ id: state.id,
7957
+ tag: state.props._tag
7958
+ }, {
7959
+ F: __dxlog_file17,
7960
+ L: 199,
7961
+ S: void 0,
7962
+ C: (f, a) => f(...a)
7963
+ });
7964
+ widgets.set(state.id, state);
7965
+ setWidgets?.([
7830
7966
  ...widgets.values()
7831
7967
  ]);
7832
7968
  },
7833
7969
  unmounted: (id) => {
7970
+ const state = widgets.get(id);
7971
+ log9("widget unmounted", {
7972
+ id,
7973
+ tag: state?.props._tag
7974
+ }, {
7975
+ F: __dxlog_file17,
7976
+ L: 205,
7977
+ S: void 0,
7978
+ C: (f, a) => f(...a)
7979
+ });
7834
7980
  widgets.delete(id);
7835
- options.setWidgets?.([
7981
+ setWidgets?.([
7836
7982
  ...widgets.values()
7837
7983
  ]);
7838
7984
  }
7839
7985
  };
7840
- const decorationsState = StateField13.define({
7841
- create: (state) => {
7842
- return buildDecorations4(state, 0, state.doc.length, state.field(contextState), state.field(widgetState), options, notifier);
7843
- },
7844
- update: ({ from, decorations: decorations2 }, tr) => {
7845
- for (const effect of tr.effects) {
7846
- if (effect.is(xmlTagResetEffect)) {
7847
- return {
7848
- from: 0,
7849
- decorations: Decoration15.none
7850
- };
7986
+ return notifier;
7987
+ };
7988
+ var keyHandlers = keymap13.of([
7989
+ {
7990
+ key: "Mod-ArrowUp",
7991
+ run: (view) => {
7992
+ view.dispatch({
7993
+ effects: navigatePreviousEffect.of()
7994
+ });
7995
+ return true;
7996
+ }
7997
+ },
7998
+ {
7999
+ key: "Mod-ArrowDown",
8000
+ run: (view) => {
8001
+ view.dispatch({
8002
+ effects: navigateNextEffect.of()
8003
+ });
8004
+ return true;
8005
+ }
8006
+ }
8007
+ ]);
8008
+ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
8009
+ return EditorView30.updateListener.of((update2) => {
8010
+ update2.transactions.forEach((transaction) => {
8011
+ for (const effect of transaction.effects) {
8012
+ if (effect.is(navigatePreviousEffect)) {
8013
+ const view = update2.view;
8014
+ const cursorPos = view.state.doc.lineAt(view.state.selection.main.head).from;
8015
+ let widget = null;
8016
+ const { decorations: decorations2 } = view.state.field(widgetDecorationsField);
8017
+ for (const range of decorationSetToArray(decorations2)) {
8018
+ if (range.from < cursorPos) {
8019
+ const tag = range.value.spec.tag;
8020
+ if (bookmarks2?.includes(tag)) {
8021
+ if (!widget || range.from > widget.from) {
8022
+ widget = {
8023
+ from: range.from,
8024
+ to: range.to,
8025
+ tag
8026
+ };
8027
+ }
8028
+ }
8029
+ }
8030
+ }
8031
+ const line = view.state.doc.lineAt(widget?.from ?? 0);
8032
+ view.dispatch({
8033
+ selection: {
8034
+ anchor: line.from,
8035
+ head: line.from
8036
+ },
8037
+ effects: scrollToLineEffect.of({
8038
+ line: line.number,
8039
+ options: {
8040
+ offset: -16
8041
+ }
8042
+ })
8043
+ });
8044
+ continue;
7851
8045
  }
7852
- }
7853
- const userEvent = tr.annotation(Transaction5.userEvent);
7854
- if (userEvent === "delete.backward" || userEvent === "delete.forward") {
7855
- const { state } = tr;
7856
- const decorationArray = decorationSetToArray(decorations2);
7857
- const filteredDecorations = [];
7858
- const cursorPos = state.selection.main.head;
7859
- for (const range of decorationArray) {
7860
- let shouldKeep = true;
7861
- if (userEvent === "delete.backward" && range.from === cursorPos) {
7862
- shouldKeep = false;
8046
+ if (effect.is(navigateNextEffect)) {
8047
+ const view = update2.view;
8048
+ const cursorPos = view.state.doc.lineAt(view.state.selection.main.head).to;
8049
+ let widget = null;
8050
+ const { decorations: decorations2 } = view.state.field(widgetDecorationsField);
8051
+ for (const range of decorationSetToArray(decorations2)) {
8052
+ if (range.from > cursorPos) {
8053
+ const tag = range.value.spec.tag;
8054
+ if (bookmarks2?.includes(tag)) {
8055
+ if (!widget || range.from < widget.from) {
8056
+ widget = {
8057
+ from: range.from,
8058
+ to: range.to,
8059
+ tag
8060
+ };
8061
+ }
8062
+ }
8063
+ }
7863
8064
  }
7864
- if (userEvent === "delete.forward" && range.to === cursorPos) {
7865
- shouldKeep = false;
8065
+ if (widget) {
8066
+ const line = view.state.doc.lineAt(widget?.from);
8067
+ view.dispatch({
8068
+ selection: {
8069
+ anchor: line.to,
8070
+ head: line.to
8071
+ },
8072
+ effects: scrollToLineEffect.of({
8073
+ line: line.number,
8074
+ options: {
8075
+ offset: -16
8076
+ }
8077
+ })
8078
+ });
8079
+ } else {
8080
+ const line = view.state.doc.lineAt(view.state.doc.length);
8081
+ view.dispatch({
8082
+ selection: {
8083
+ anchor: line.to,
8084
+ head: line.to
8085
+ },
8086
+ effects: scrollToLineEffect.of({
8087
+ line: line.number,
8088
+ options: {
8089
+ position: "end"
8090
+ }
8091
+ })
8092
+ });
7866
8093
  }
7867
- if (shouldKeep) {
7868
- const mappedFrom = tr.changes.mapPos(range.from, -1);
7869
- const mappedTo = tr.changes.mapPos(range.to, 1);
7870
- if (mappedFrom >= 0 && mappedTo >= mappedFrom && mappedTo <= state.doc.length) {
7871
- filteredDecorations.push({
7872
- from: mappedFrom,
7873
- to: mappedTo,
7874
- value: range.value
7875
- });
7876
- }
8094
+ continue;
8095
+ }
8096
+ }
8097
+ });
8098
+ });
8099
+ };
8100
+ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin20.fromClass(class {
8101
+ update(update2) {
8102
+ const widgetStateMap = update2.state.field(widgetStateMapStateField);
8103
+ const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
8104
+ for (const effect of update2.transactions.flatMap((tr) => tr.effects)) {
8105
+ if (effect.is(xmlTagUpdateEffect)) {
8106
+ const widgetState = widgetStateMap[effect.value.id];
8107
+ for (const range of decorationSetToArray(decorations2)) {
8108
+ const deco = range.value;
8109
+ const widget = deco?.spec?.widget;
8110
+ if (widget && widget instanceof PlaceholderWidget2 && widget.id === effect.value.id && widget.root) {
8111
+ const props = {
8112
+ ...widget.props,
8113
+ ...widgetState
8114
+ };
8115
+ notifier.mounted({
8116
+ id: widget.id,
8117
+ props,
8118
+ root: widget.root,
8119
+ Component: widget.Component
8120
+ });
7877
8121
  }
7878
8122
  }
8123
+ }
8124
+ }
8125
+ }
8126
+ });
8127
+ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
8128
+ create: (state) => {
8129
+ return buildDecorations4(state, {
8130
+ from: 0,
8131
+ to: state.doc.length
8132
+ }, registry, notifier);
8133
+ },
8134
+ update: ({ from, decorations: decorations2 }, tr) => {
8135
+ for (const effect of tr.effects) {
8136
+ if (effect.is(xmlTagResetEffect)) {
7879
8137
  return {
7880
- from,
7881
- decorations: Decoration15.set(filteredDecorations)
8138
+ from: 0,
8139
+ decorations: Decoration16.none
7882
8140
  };
7883
8141
  }
7884
- if (tr.docChanged) {
7885
- const { state } = tr;
7886
- const reset = tr.changes.touchesRange(0, from);
7887
- const result = buildDecorations4(state, reset ? 0 : from, state.doc.length, state.field(contextState), state.field(widgetState), options, notifier);
8142
+ }
8143
+ if (tr.docChanged) {
8144
+ const { state } = tr;
8145
+ const reset = tr.changes.touchesRange(0, from);
8146
+ if (reset) {
8147
+ log9("document reset", {
8148
+ from,
8149
+ to: state.doc.length
8150
+ }, {
8151
+ F: __dxlog_file17,
8152
+ L: 364,
8153
+ S: void 0,
8154
+ C: (f, a) => f(...a)
8155
+ });
8156
+ return buildDecorations4(state, {
8157
+ from: 0,
8158
+ to: state.doc.length
8159
+ }, registry, notifier);
8160
+ } else {
8161
+ const result = buildDecorations4(state, {
8162
+ from,
8163
+ to: state.doc.length
8164
+ }, registry, notifier);
7888
8165
  return {
7889
8166
  from: result.from,
7890
8167
  decorations: decorations2.update({
@@ -7892,104 +8169,70 @@ var xmlTags = (options = {}) => {
7892
8169
  })
7893
8170
  };
7894
8171
  }
7895
- return {
7896
- from,
7897
- decorations: decorations2
7898
- };
7899
- },
7900
- provide: (field) => [
7901
- EditorView27.decorations.from(field, (v) => v.decorations),
7902
- EditorView27.atomicRanges.of((view) => view.state.field(field).decorations || Decoration15.none)
7903
- ]
7904
- });
7905
- const widgetState = StateField13.define({
7906
- create: () => ({}),
7907
- update: (map, tr) => {
7908
- for (const effect of tr.effects) {
7909
- if (effect.is(xmlTagResetEffect)) {
7910
- return {};
7911
- }
7912
- if (effect.is(xmlTagUpdateEffect)) {
7913
- const { id, value } = effect.value;
7914
- const state = typeof value === "function" ? value(map[id]) : value;
7915
- const { decorations: decorations2 } = tr.state.field(decorationsState);
7916
- for (const range of decorationSetToArray(decorations2)) {
7917
- const deco = range.value;
7918
- const widget = deco?.spec?.widget;
7919
- if (widget && widget instanceof PlaceholderWidget2 && widget.id === effect.value.id && widget.root) {
7920
- const props = {
7921
- ...widget.props,
7922
- ...state
7923
- };
7924
- notifier.mounted({
7925
- id: widget.id,
7926
- props,
7927
- root: widget.root,
7928
- Component: widget.Component
7929
- });
7930
- }
7931
- }
7932
- return {
7933
- ...map,
7934
- [id]: state
7935
- };
7936
- }
7937
- }
7938
- return map;
7939
8172
  }
7940
- });
7941
- return [
7942
- contextState,
7943
- decorationsState,
7944
- widgetState
7945
- ];
7946
- };
7947
- var buildDecorations4 = (state, from, to, context, widgetState, options, notifier) => {
7948
- const builder = new RangeSetBuilder7();
8173
+ return {
8174
+ from,
8175
+ decorations: decorations2
8176
+ };
8177
+ },
8178
+ provide: (field) => [
8179
+ EditorView30.decorations.from(field, (v) => v.decorations),
8180
+ EditorView30.atomicRanges.of((view) => view.state.field(field).decorations || Decoration16.none)
8181
+ ]
8182
+ });
8183
+ var buildDecorations4 = (state, range, registry, notifier) => {
8184
+ const context = state.field(widgetContextStateField, false);
8185
+ const widgetStateMap = state.field(widgetStateMapStateField, false) ?? {};
8186
+ const builder = new RangeSetBuilder8();
7949
8187
  const tree = syntaxTree11(state);
7950
8188
  if (!tree || tree.type.name === "Program" && tree.length === 0) {
7951
8189
  return {
7952
- from,
7953
- decorations: Decoration15.none
8190
+ from: range.from,
8191
+ decorations: Decoration16.none
7954
8192
  };
7955
8193
  }
8194
+ let last = range.from;
7956
8195
  tree.iterate({
7957
- from,
7958
- to,
8196
+ from: range.from,
8197
+ to: range.to,
7959
8198
  enter: (node) => {
7960
8199
  switch (node.type.name) {
7961
8200
  // XML Element.
7962
8201
  case "Element": {
7963
8202
  try {
7964
- if (options.registry) {
7965
- const props = nodeToJson(state, node.node);
7966
- if (props) {
7967
- const def = options.registry[props._tag];
7968
- if (def) {
7969
- const { block, factory, Component } = def;
7970
- const state2 = props.id ? widgetState[props.id] : void 0;
7971
- const args = {
7972
- context,
7973
- ...props,
7974
- ...state2
7975
- };
7976
- const widget = factory ? factory(args) : Component ? props.id && new PlaceholderWidget2(props.id, Component, args, notifier) : void 0;
7977
- if (widget) {
7978
- from = node.node.to;
7979
- builder.add(node.node.from, node.node.to, Decoration15.replace({
7980
- widget,
7981
- block,
7982
- atomic: true,
7983
- inclusive: true
7984
- }));
7985
- }
8203
+ const args = nodeToJson(state, node.node);
8204
+ if (args) {
8205
+ const def = registry[args._tag];
8206
+ if (def) {
8207
+ const { block, factory, Component } = def;
8208
+ const widgetState = args.id ? widgetStateMap[args.id] : void 0;
8209
+ const nodeRange = {
8210
+ from: node.node.from,
8211
+ to: node.node.to
8212
+ };
8213
+ const props = {
8214
+ context,
8215
+ range: nodeRange,
8216
+ ...args,
8217
+ ...widgetState
8218
+ };
8219
+ const widget = factory ? factory(props) : Component ? args.id && new PlaceholderWidget2(args.id, Component, props, notifier) : void 0;
8220
+ if (widget) {
8221
+ builder.add(nodeRange.from, nodeRange.to, Decoration16.replace({
8222
+ widget,
8223
+ block,
8224
+ atomic: true,
8225
+ inclusive: true,
8226
+ tag: args._tag
8227
+ }));
8228
+ last = nodeRange.to - 1;
7986
8229
  }
7987
8230
  }
7988
8231
  }
7989
8232
  } catch (err) {
7990
8233
  log9.catch(err, void 0, {
7991
8234
  F: __dxlog_file17,
7992
- L: 343,
8235
+ L: 449,
7993
8236
  S: void 0,
7994
8237
  C: (f, a) => f(...a)
7995
8238
  });
@@ -8000,16 +8243,33 @@ var buildDecorations4 = (state, from, to, context, widgetState, options, notifie
8000
8243
  }
8001
8244
  });
8002
8245
  return {
8003
- from,
8246
+ from: last,
8004
8247
  decorations: builder.finish()
8005
8248
  };
8006
8249
  };
8007
- var PlaceholderWidget2 = class _PlaceholderWidget extends WidgetType10 {
8250
+ var PlaceholderWidget2 = class extends WidgetType10 {
8251
+ id;
8252
+ Component;
8253
+ props;
8254
+ notifier;
8255
+ _root = null;
8256
+ constructor(id, Component, props, notifier) {
8257
+ super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier;
8258
+ invariant9(id, void 0, {
8259
+ F: __dxlog_file17,
8260
+ L: 475,
8261
+ S: this,
8262
+ A: [
8263
+ "id",
8264
+ ""
8265
+ ]
8266
+ });
8267
+ }
8008
8268
  get root() {
8009
8269
  return this._root;
8010
8270
  }
8011
8271
  eq(other) {
8012
- return other instanceof _PlaceholderWidget && this.id === other.id;
8272
+ return this.id === other.id;
8013
8273
  }
8014
8274
  ignoreEvent() {
8015
8275
  return true;
@@ -8018,8 +8278,8 @@ var PlaceholderWidget2 = class _PlaceholderWidget extends WidgetType10 {
8018
8278
  this._root = document.createElement("span");
8019
8279
  this.notifier.mounted({
8020
8280
  id: this.id,
8021
- props: this.props,
8022
8281
  root: this._root,
8282
+ props: this.props,
8023
8283
  Component: this.Component
8024
8284
  });
8025
8285
  return this._root;
@@ -8028,22 +8288,10 @@ var PlaceholderWidget2 = class _PlaceholderWidget extends WidgetType10 {
8028
8288
  this.notifier.unmounted(this.id);
8029
8289
  this._root = null;
8030
8290
  }
8031
- constructor(id, Component, props, notifier) {
8032
- super(), _define_property22(this, "id", void 0), _define_property22(this, "Component", void 0), _define_property22(this, "props", void 0), _define_property22(this, "notifier", void 0), _define_property22(this, "_root", void 0), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this._root = null;
8033
- invariant9(id, void 0, {
8034
- F: __dxlog_file17,
8035
- L: 368,
8036
- S: this,
8037
- A: [
8038
- "id",
8039
- ""
8040
- ]
8041
- });
8042
- }
8043
8291
  };
8044
8292
 
8045
8293
  // src/extensions/typewriter.ts
8046
- import { keymap as keymap12 } from "@codemirror/view";
8294
+ import { keymap as keymap14 } from "@codemirror/view";
8047
8295
  var defaultItems = [
8048
8296
  "hello world!",
8049
8297
  "this is a test.",
@@ -8053,7 +8301,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
8053
8301
  let t;
8054
8302
  let idx = 0;
8055
8303
  return [
8056
- keymap12.of([
8304
+ keymap14.of([
8057
8305
  {
8058
8306
  // Reset.
8059
8307
  key: "alt-meta-'",
@@ -8066,7 +8314,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
8066
8314
  {
8067
8315
  // Next prompt.
8068
8316
  // TODO(burdon): Press 1-9 to select prompt?
8069
- key: "shift-meta-'",
8317
+ key: "Shift-Meta-'",
8070
8318
  run: (view) => {
8071
8319
  clearTimeout(t);
8072
8320
  const text = items[idx++];
@@ -8101,14 +8349,14 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
8101
8349
 
8102
8350
  // src/hooks/useTextEditor.ts
8103
8351
  import { EditorState as EditorState3 } from "@codemirror/state";
8104
- import { EditorView as EditorView28 } from "@codemirror/view";
8105
- import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
8352
+ import { EditorView as EditorView31 } from "@codemirror/view";
8353
+ import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as useState3 } from "react";
8106
8354
  import { log as log10 } from "@dxos/log";
8107
8355
  import { getProviderValue, isTruthy as isTruthy6 } from "@dxos/util";
8108
8356
  var __dxlog_file18 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
8109
8357
  var instanceCount = 0;
8110
8358
  var useTextEditor = (props = {}, deps = []) => {
8111
- const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo3(() => getProviderValue(props), deps ?? []);
8359
+ const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo2(() => getProviderValue(props), deps ?? []);
8112
8360
  const [instanceId] = useState3(() => `text-editor-${++instanceCount}`);
8113
8361
  const [view, setView] = useState3(null);
8114
8362
  const parentRef = useRef3(null);
@@ -8144,7 +8392,7 @@ var useTextEditor = (props = {}, deps = []) => {
8144
8392
  id && documentId.of(id),
8145
8393
  extensions,
8146
8394
  // NOTE: This doesn't catch errors in keymap functions.
8147
- EditorView28.exceptionSink.of((err) => {
8395
+ EditorView31.exceptionSink.of((err) => {
8148
8396
  log10.catch(err, void 0, {
8149
8397
  F: __dxlog_file18,
8150
8398
  L: 93,
@@ -8154,10 +8402,10 @@ var useTextEditor = (props = {}, deps = []) => {
8154
8402
  })
8155
8403
  ].filter(isTruthy6)
8156
8404
  });
8157
- view2 = new EditorView28({
8405
+ view2 = new EditorView31({
8158
8406
  parent: parentRef.current,
8159
8407
  state,
8160
- scrollTo: scrollTo ? EditorView28.scrollIntoView(scrollTo, {
8408
+ scrollTo: scrollTo ? EditorView31.scrollIntoView(scrollTo, {
8161
8409
  yMargin: 96
8162
8410
  }) : void 0,
8163
8411
  dispatchTransactions: debug ? debugDispatcher : void 0
@@ -8221,7 +8469,7 @@ var useTextEditor = (props = {}, deps = []) => {
8221
8469
  autoFocus,
8222
8470
  view
8223
8471
  ]);
8224
- const handleKeyDown = useCallback4((event) => {
8472
+ const handleKeyDown = useCallback3((event) => {
8225
8473
  const { key, target, currentTarget } = event;
8226
8474
  switch (key) {
8227
8475
  case "Escape": {
@@ -8262,8 +8510,8 @@ var Editor = /* @__PURE__ */ forwardRef(({ classNames, id, extensions, moveToEnd
8262
8510
  initialValue: value,
8263
8511
  extensions: [
8264
8512
  extensions ?? [],
8265
- EditorView29.updateListener.of(({ view: view2, docChanged, transactions }) => {
8266
- const isInitialSync = transactions.some((tr) => tr.annotation(Transaction6.userEvent) === initialSync.value);
8513
+ EditorView32.updateListener.of(({ view: view2, docChanged, transactions }) => {
8514
+ const isInitialSync = transactions.some((tr) => tr.annotation(Transaction5.userEvent) === initialSync.value);
8267
8515
  if (!isInitialSync && docChanged) {
8268
8516
  onChange?.(view2.state.doc.toString());
8269
8517
  }
@@ -8305,7 +8553,7 @@ var Editor = /* @__PURE__ */ forwardRef(({ classNames, id, extensions, moveToEnd
8305
8553
  ]);
8306
8554
  return /* @__PURE__ */ React4.createElement("div", {
8307
8555
  role: "none",
8308
- className: mx6("is-full", classNames),
8556
+ className: mx7("is-full", classNames),
8309
8557
  ...focusAttributes,
8310
8558
  ref: parentRef
8311
8559
  });
@@ -8316,18 +8564,18 @@ var Editor = /* @__PURE__ */ forwardRef(({ classNames, id, extensions, moveToEnd
8316
8564
 
8317
8565
  // src/components/EditorToolbar/EditorToolbar.tsx
8318
8566
  import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
8319
- import { Rx } from "@effect-rx/rx-react";
8320
- import React5, { memo, useMemo as useMemo5 } from "react";
8567
+ import { Atom } from "@effect-atom/atom-react";
8568
+ import React5, { memo, useMemo as useMemo4 } from "react";
8321
8569
  import { rxFromSignal } from "@dxos/app-graph";
8322
8570
  import { ElevationProvider } from "@dxos/react-ui";
8323
8571
  import { MenuProvider, ToolbarMenu, createGapSeparator, useMenuActions } from "@dxos/react-ui-menu";
8324
8572
 
8325
8573
  // src/components/EditorToolbar/util.ts
8326
- import { useMemo as useMemo4 } from "react";
8574
+ import { useMemo as useMemo3 } from "react";
8327
8575
  import { live } from "@dxos/live-object";
8328
8576
  import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
8329
8577
  var useEditorToolbarState = (initialState = {}) => {
8330
- return useMemo4(() => live(initialState), []);
8578
+ return useMemo3(() => live(initialState), []);
8331
8579
  };
8332
8580
  var createEditorAction = (id, props, invoke) => {
8333
8581
  const { label = [
@@ -8471,9 +8719,10 @@ var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
8471
8719
  variant: "dropdownMenu",
8472
8720
  applyActive: true,
8473
8721
  selectCardinality: "single",
8722
+ // TODO(wittjosiah): Remove? Not sure this does anything.
8474
8723
  value
8475
8724
  }, "ph--text-h--regular");
8476
- var createHeadingActions = (getView) => Object.entries({
8725
+ var createHeadingActions = (currentLevel, getView) => Object.entries({
8477
8726
  "0": "ph--paragraph--regular",
8478
8727
  "1": "ph--text-h-one--regular",
8479
8728
  "2": "ph--text-h-two--regular",
@@ -8491,18 +8740,19 @@ var createHeadingActions = (getView) => Object.entries({
8491
8740
  ns: translationKey
8492
8741
  }
8493
8742
  ],
8494
- icon
8743
+ icon,
8744
+ checked: levelStr === currentLevel
8495
8745
  }, () => setHeading(level)(getView()));
8496
8746
  });
8497
8747
  var computeHeadingValue = (state) => {
8498
8748
  const blockType = state ? state.blockType : "paragraph";
8499
- const header = blockType && /heading(\d)/.exec(blockType);
8500
- return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
8749
+ const heading = blockType && /heading(\d)/.exec(blockType);
8750
+ return heading ? heading[1] : blockType === "paragraph" || !blockType ? "0" : "";
8501
8751
  };
8502
8752
  var createHeadings = (state, getView) => {
8503
8753
  const headingValue = computeHeadingValue(state);
8504
8754
  const headingGroupAction = createHeadingGroupAction(headingValue);
8505
- const headingActions = createHeadingActions(getView);
8755
+ const headingActions = createHeadingActions(headingValue, getView);
8506
8756
  return {
8507
8757
  nodes: [
8508
8758
  headingGroupAction,
@@ -8654,87 +8904,7 @@ var createViewMode = (state, onViewModeChange) => {
8654
8904
  };
8655
8905
 
8656
8906
  // src/components/EditorToolbar/EditorToolbar.tsx
8657
- var createToolbarActions = ({ getView, state, customActions, ...features }) => {
8658
- return Rx.make((get2) => {
8659
- const graph = {
8660
- nodes: [],
8661
- edges: []
8662
- };
8663
- if (features.headings ?? true) {
8664
- const headings2 = get2(rxFromSignal(() => createHeadings(state, getView)));
8665
- graph.nodes.push(...headings2.nodes);
8666
- graph.edges.push(...headings2.edges);
8667
- }
8668
- if (features.formatting ?? true) {
8669
- const formatting = get2(rxFromSignal(() => createFormatting(state, getView)));
8670
- graph.nodes.push(...formatting.nodes);
8671
- graph.edges.push(...formatting.edges);
8672
- }
8673
- if (features.lists ?? true) {
8674
- const lists = get2(rxFromSignal(() => createLists(state, getView)));
8675
- graph.nodes.push(...lists.nodes);
8676
- graph.edges.push(...lists.edges);
8677
- }
8678
- if (features.blocks ?? true) {
8679
- const blocks = get2(rxFromSignal(() => createBlocks(state, getView)));
8680
- graph.nodes.push(...blocks.nodes);
8681
- graph.edges.push(...blocks.edges);
8682
- }
8683
- if (features.image) {
8684
- const image2 = get2(rxFromSignal(() => createImageUpload(features.image)));
8685
- graph.nodes.push(...image2.nodes);
8686
- graph.edges.push(...image2.edges);
8687
- }
8688
- {
8689
- const gap = createGapSeparator();
8690
- graph.nodes.push(...gap.nodes);
8691
- graph.edges.push(...gap.edges);
8692
- }
8693
- if (customActions) {
8694
- const custom = get2(customActions);
8695
- graph.nodes.push(...custom.nodes);
8696
- graph.edges.push(...custom.edges);
8697
- }
8698
- if (features.search ?? true) {
8699
- const search = get2(rxFromSignal(() => createSearch(getView)));
8700
- graph.nodes.push(...search.nodes);
8701
- graph.edges.push(...search.edges);
8702
- }
8703
- if (features.viewMode) {
8704
- const viewMode = get2(rxFromSignal(() => createViewMode(state, features.viewMode)));
8705
- graph.nodes.push(...viewMode.nodes);
8706
- graph.edges.push(...viewMode.edges);
8707
- }
8708
- return graph;
8709
- });
8710
- };
8711
- var useEditorToolbarActionGraph = (props) => {
8712
- const menuCreator = useMemo5(() => createToolbarActions({
8713
- getView: props.getView,
8714
- state: props.state,
8715
- customActions: props.customActions,
8716
- headings: props.headings,
8717
- formatting: props.formatting,
8718
- lists: props.lists,
8719
- blocks: props.blocks,
8720
- image: props.image,
8721
- search: props.search,
8722
- viewMode: props.viewMode
8723
- }), [
8724
- props.getView,
8725
- props.state,
8726
- props.customActions,
8727
- props.headings,
8728
- props.formatting,
8729
- props.lists,
8730
- props.blocks,
8731
- props.image,
8732
- props.search,
8733
- props.viewMode
8734
- ]);
8735
- return useMenuActions(menuCreator);
8736
- };
8737
- var EditorToolbar = /* @__PURE__ */ memo(({ classNames, attendableId, role, ...props }) => {
8907
+ var EditorToolbar = /* @__PURE__ */ memo(({ classNames, role, attendableId, ...props }) => {
8738
8908
  var _effect = _useSignals3();
8739
8909
  try {
8740
8910
  const menuProps = useEditorToolbarActionGraph(props);
@@ -8751,6 +8921,64 @@ var EditorToolbar = /* @__PURE__ */ memo(({ classNames, attendableId, role, ...p
8751
8921
  _effect.f();
8752
8922
  }
8753
8923
  });
8924
+ var useEditorToolbarActionGraph = ({ state, getView, customActions, ...features }) => {
8925
+ const menuCreator = useMemo4(() => createToolbarActions({
8926
+ state,
8927
+ getView,
8928
+ customActions,
8929
+ ...features
8930
+ }), [
8931
+ state,
8932
+ getView,
8933
+ customActions,
8934
+ features?.showHeadings,
8935
+ features?.showFormatting,
8936
+ features?.showLists,
8937
+ features?.showBlocks,
8938
+ features?.showSearch,
8939
+ features?.onImageUpload,
8940
+ features?.onViewModeChange
8941
+ ]);
8942
+ return useMenuActions(menuCreator);
8943
+ };
8944
+ var createToolbarActions = ({ state, getView, customActions, ...features }) => {
8945
+ return Atom.make((get2) => {
8946
+ const graph = {
8947
+ nodes: [],
8948
+ edges: []
8949
+ };
8950
+ const addSubGraph = (graph2, subGraph) => {
8951
+ graph2.nodes.push(...subGraph.nodes);
8952
+ graph2.edges.push(...subGraph.edges);
8953
+ };
8954
+ if (features?.showHeadings ?? true) {
8955
+ addSubGraph(graph, get2(rxFromSignal(() => createHeadings(state, getView))));
8956
+ }
8957
+ if (features?.showFormatting ?? true) {
8958
+ addSubGraph(graph, get2(rxFromSignal(() => createFormatting(state, getView))));
8959
+ }
8960
+ if (features?.showLists ?? true) {
8961
+ addSubGraph(graph, get2(rxFromSignal(() => createLists(state, getView))));
8962
+ }
8963
+ if (features?.showBlocks ?? true) {
8964
+ addSubGraph(graph, get2(rxFromSignal(() => createBlocks(state, getView))));
8965
+ }
8966
+ if (features?.onImageUpload) {
8967
+ addSubGraph(graph, get2(rxFromSignal(() => createImageUpload(features.onImageUpload))));
8968
+ }
8969
+ addSubGraph(graph, createGapSeparator());
8970
+ if (customActions) {
8971
+ addSubGraph(graph, get2(customActions));
8972
+ }
8973
+ if (features?.showSearch ?? true) {
8974
+ addSubGraph(graph, get2(rxFromSignal(() => createSearch(getView))));
8975
+ }
8976
+ if (features?.onViewModeChange) {
8977
+ addSubGraph(graph, get2(rxFromSignal(() => createViewMode(state, features.onViewModeChange))));
8978
+ }
8979
+ return graph;
8980
+ });
8981
+ };
8754
8982
  export {
8755
8983
  Cursor,
8756
8984
  Editor,
@@ -8758,7 +8986,7 @@ export {
8758
8986
  EditorInputModes,
8759
8987
  EditorState4 as EditorState,
8760
8988
  EditorToolbar,
8761
- EditorView30 as EditorView,
8989
+ EditorView33 as EditorView,
8762
8990
  EditorViewMode,
8763
8991
  EditorViewModes,
8764
8992
  Inline,
@@ -8771,6 +8999,7 @@ export {
8771
8999
  TextKind,
8772
9000
  Tree,
8773
9001
  addBlockquote,
9002
+ addBookmark,
8774
9003
  addCodeblock,
8775
9004
  addLink,
8776
9005
  addList,
@@ -8782,7 +9011,10 @@ export {
8782
9011
  awareness,
8783
9012
  awarenessProvider,
8784
9013
  blast,
9014
+ blocks,
9015
+ bookmarks,
8785
9016
  callbackWrapper,
9017
+ clearBookmarks,
8786
9018
  clientRectsFor,
8787
9019
  commands,
8788
9020
  commentClickedEffect,
@@ -8809,6 +9041,7 @@ export {
8809
9041
  decorationSetToArray,
8810
9042
  defaultExtensions,
8811
9043
  defaultOptions,
9044
+ defaultReplacements,
8812
9045
  defaultStyles,
8813
9046
  defaultThemeSlots,
8814
9047
  deleteItem,
@@ -8830,6 +9063,7 @@ export {
8830
9063
  formattingCommands,
8831
9064
  formattingEquals,
8832
9065
  formattingKeymap,
9066
+ formattingListener,
8833
9067
  fullWidth,
8834
9068
  getFormatting,
8835
9069
  getLinkRef,
@@ -8849,7 +9083,7 @@ export {
8849
9083
  insertAtLineStart,
8850
9084
  insertTable,
8851
9085
  itemToJSON,
8852
- keymap13 as keymap,
9086
+ keymap15 as keymap,
8853
9087
  linkSlashCommands,
8854
9088
  linkTooltip,
8855
9089
  listItemToString,
@@ -8864,6 +9098,8 @@ export {
8864
9098
  modalStateField,
8865
9099
  moveItemDown,
8866
9100
  moveItemUp,
9101
+ navigateNextEffect,
9102
+ navigatePreviousEffect,
8867
9103
  outliner,
8868
9104
  outlinerTree,
8869
9105
  overlap,
@@ -8874,13 +9110,17 @@ export {
8874
9110
  preview,
8875
9111
  processEditorPayload,
8876
9112
  removeBlockquote,
9113
+ removeBookmark,
8877
9114
  removeCodeblock,
8878
9115
  removeLink,
8879
9116
  removeList,
8880
9117
  removeStyle,
8881
9118
  renderRoot,
9119
+ replacer,
8882
9120
  scrollThreadIntoView,
8883
9121
  scrollToBottomEffect,
9122
+ scrollToLine,
9123
+ scrollToLineEffect,
8884
9124
  selectionState,
8885
9125
  setBlockquote,
8886
9126
  setComments,
@@ -8888,6 +9128,7 @@ export {
8888
9128
  setSelection,
8889
9129
  setStyle,
8890
9130
  singleValueFacet,
9131
+ smoothScroll,
8891
9132
  stackItemContentEditorClassNames,
8892
9133
  staticCompletion,
8893
9134
  streamer,
@@ -8910,7 +9151,6 @@ export {
8910
9151
  typewriter,
8911
9152
  useComments,
8912
9153
  useEditorToolbarState,
8913
- useFormattingState,
8914
9154
  usePopoverMenu,
8915
9155
  useTextEditor,
8916
9156
  wrapWithCatch,