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