@dxos/ui-editor 0.8.4-main.9735255 → 0.8.4-main.bcb3aa67d6

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 (76) hide show
  1. package/dist/lib/browser/index.mjs +711 -521
  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 +711 -521
  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/defaults.d.ts +3 -10
  8. package/dist/types/src/defaults.d.ts.map +1 -1
  9. package/dist/types/src/extensions/auto-scroll.d.ts +6 -0
  10. package/dist/types/src/extensions/auto-scroll.d.ts.map +1 -0
  11. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  12. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  13. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  14. package/dist/types/src/extensions/index.d.ts +3 -2
  15. package/dist/types/src/extensions/index.d.ts.map +1 -1
  16. package/dist/types/src/extensions/markdown/bundle.d.ts +3 -0
  17. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  18. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  19. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  20. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  21. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  22. package/dist/types/src/extensions/preview/preview.d.ts +3 -1
  23. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
  24. package/dist/types/src/extensions/scroll-past-end.d.ts +3 -0
  25. package/dist/types/src/extensions/scroll-past-end.d.ts.map +1 -0
  26. package/dist/types/src/extensions/scroller.d.ts +66 -0
  27. package/dist/types/src/extensions/scroller.d.ts.map +1 -0
  28. package/dist/types/src/extensions/tags/streamer.d.ts +1 -1
  29. package/dist/types/src/styles/index.d.ts +0 -2
  30. package/dist/types/src/styles/index.d.ts.map +1 -1
  31. package/dist/types/src/styles/theme.d.ts +15 -0
  32. package/dist/types/src/styles/theme.d.ts.map +1 -1
  33. package/dist/types/src/util/cursor.d.ts +1 -1
  34. package/dist/types/src/util/cursor.d.ts.map +1 -1
  35. package/dist/types/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +32 -32
  37. package/src/defaults.ts +19 -21
  38. package/src/extensions/annotations.ts +1 -1
  39. package/src/extensions/auto-scroll.ts +129 -0
  40. package/src/extensions/automerge/automerge.test.tsx +2 -2
  41. package/src/extensions/automerge/automerge.ts +6 -5
  42. package/src/extensions/blocks.ts +5 -5
  43. package/src/extensions/comments.ts +5 -5
  44. package/src/extensions/dnd.ts +2 -2
  45. package/src/extensions/factories.ts +7 -8
  46. package/src/extensions/folding.ts +3 -20
  47. package/src/extensions/index.ts +3 -2
  48. package/src/extensions/markdown/bundle.ts +23 -9
  49. package/src/extensions/markdown/decorate.ts +15 -11
  50. package/src/extensions/markdown/highlight.ts +15 -7
  51. package/src/extensions/markdown/link.ts +27 -33
  52. package/src/extensions/markdown/parser.test.ts +0 -1
  53. package/src/extensions/markdown/styles.ts +36 -9
  54. package/src/extensions/markdown/table.ts +24 -2
  55. package/src/extensions/outliner/outliner.ts +3 -3
  56. package/src/extensions/preview/preview.ts +62 -15
  57. package/src/extensions/scroll-past-end.ts +32 -0
  58. package/src/extensions/scroller.ts +233 -0
  59. package/src/extensions/selection.ts +1 -1
  60. package/src/extensions/tags/streamer.ts +2 -2
  61. package/src/extensions/tags/xml-tags.ts +7 -4
  62. package/src/styles/index.ts +0 -2
  63. package/src/styles/theme.ts +116 -34
  64. package/src/util/cursor.ts +1 -1
  65. package/dist/types/src/extensions/autoscroll.d.ts +0 -20
  66. package/dist/types/src/extensions/autoscroll.d.ts.map +0 -1
  67. package/dist/types/src/extensions/scrolling.d.ts +0 -78
  68. package/dist/types/src/extensions/scrolling.d.ts.map +0 -1
  69. package/dist/types/src/styles/markdown.d.ts +0 -8
  70. package/dist/types/src/styles/markdown.d.ts.map +0 -1
  71. package/dist/types/src/styles/tokens.d.ts +0 -3
  72. package/dist/types/src/styles/tokens.d.ts.map +0 -1
  73. package/src/extensions/autoscroll.ts +0 -165
  74. package/src/extensions/scrolling.ts +0 -189
  75. package/src/styles/markdown.ts +0 -26
  76. package/src/styles/tokens.ts +0 -17
@@ -7,23 +7,29 @@ import {
7
7
 
8
8
  // src/index.ts
9
9
  import { EditorState as EditorState3 } from "@codemirror/state";
10
- import { EditorView as EditorView30, keymap as keymap15 } from "@codemirror/view";
10
+ import { EditorView as EditorView31, keymap as keymap15 } from "@codemirror/view";
11
11
  import { tags as tags2 } from "@lezer/highlight";
12
12
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
13
13
 
14
14
  // src/defaults.ts
15
15
  import { mx } from "@dxos/ui-theme";
16
- var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
17
- var editorSlots = {
18
- scroll: {
19
- className: "pbs-2"
20
- },
16
+ var editorClassNames = (role) => mx("dx-attention-surface p-0.5 data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
17
+ var documentSlots = {
18
+ content: {
19
+ /**
20
+ * CodeMirror content width.
21
+ * 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
22
+ * 50rem = 800px. Maximum content width for solo mode.
23
+ * NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
24
+ */
25
+ className: "mx-auto! w-full pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]"
26
+ }
27
+ };
28
+ var compactSlots = {
21
29
  content: {
22
- className: editorWidth
30
+ className: "mx-2! w-full"
23
31
  }
24
32
  };
25
- var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
26
- var stackItemContentEditorClassNames = (role) => mx("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");
27
33
 
28
34
  // src/extensions/annotations.ts
29
35
  import { RangeSetBuilder } from "@codemirror/state";
@@ -58,7 +64,7 @@ var annotations = ({ match } = {}) => {
58
64
  ".cm-annotation": {
59
65
  textDecoration: "underline",
60
66
  textDecorationStyle: "wavy",
61
- textDecorationColor: "var(--dx-errorText)"
67
+ textDecorationColor: "var(--color-error-text)"
62
68
  }
63
69
  })
64
70
  ];
@@ -501,228 +507,245 @@ var typeahead = ({ onComplete } = {}) => {
501
507
  ];
502
508
  };
503
509
 
504
- // src/extensions/autoscroll.ts
505
- import { StateEffect as StateEffect2 } from "@codemirror/state";
510
+ // src/extensions/auto-scroll.ts
506
511
  import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
507
- import { debounce } from "@dxos/async";
512
+ import { addEventListener, combine, throttle } from "@dxos/async";
508
513
  import { Domino } from "@dxos/ui";
509
514
 
510
- // src/extensions/scrolling.ts
515
+ // src/extensions/scroller.ts
511
516
  import { StateEffect } from "@codemirror/state";
512
517
  import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
513
- var scrollToLineEffect = StateEffect.define();
514
- var smoothScroll = ({ offset = 0, position = "start" } = {}) => {
515
- const scrollPlugin = ViewPlugin5.fromClass(class SmoothScrollPlugin {
518
+ import { log as log2 } from "@dxos/log";
519
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
520
+ var scrollerLineEffect = StateEffect.define();
521
+ var scrollerCrawlEffect = StateEffect.define();
522
+ var scrollToLine = (view, options) => {
523
+ view.dispatch({
524
+ effects: scrollerLineEffect.of(options)
525
+ });
526
+ };
527
+ var scroller = ({ overScroll = 0 } = {}) => {
528
+ const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
516
529
  view;
530
+ crawler;
517
531
  constructor(view) {
518
532
  this.view = view;
533
+ this.crawler = createCrawler(this.view);
519
534
  }
520
535
  // No-op.
521
536
  destroy() {
537
+ this.crawler.cancel();
522
538
  }
523
- /**
524
- * Perform smooth scroll to the specified line.
525
- */
526
- scrollToLine(lineNumber, options) {
527
- const { offset: animOffset = 0, position: animPosition, behavior } = options;
528
- const doc = this.view.state.doc;
529
- const scroller = this.view.scrollDOM;
530
- const targetLine = Math.max(0, lineNumber - 1);
531
- if (behavior === "instant") {
532
- requestAnimationFrame(() => {
533
- this.view.dispatch({
534
- selection: {
535
- anchor: doc.line(targetLine + 1).from
536
- },
537
- scrollIntoView: true
538
- });
539
- });
540
- return;
541
- }
542
- if (targetLine >= doc.lines) {
543
- const targetScrollTop2 = scroller.scrollHeight - scroller.clientHeight + (animOffset || 0);
544
- this.animateScroll(scroller, targetScrollTop2);
545
- return;
546
- }
547
- const lineStart = doc.line(targetLine + 1).from;
548
- const coords = this.view.coordsAtPos(lineStart);
549
- if (!coords) {
550
- return;
551
- }
552
- const currentScrollTop = scroller.scrollTop;
553
- const scrollerRect = scroller.getBoundingClientRect();
554
- const maxScrollTop = scroller.scrollHeight - scroller.clientHeight;
555
- let targetScrollTop;
556
- if (animPosition === "end") {
557
- targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + animOffset;
539
+ cancel() {
540
+ this.crawler.cancel();
541
+ }
542
+ crawl(start = false) {
543
+ if (start) {
544
+ this.crawler.scroll();
558
545
  } else {
559
- targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + animOffset;
546
+ this.crawler.cancel();
560
547
  }
561
- const clampedScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
562
- this.animateScroll(scroller, clampedScrollTop);
563
548
  }
564
- /**
565
- * Animate scroll using browser's built-in smooth scrolling.
566
- */
567
- animateScroll(element, targetScrollTop) {
568
- if (Math.abs(targetScrollTop - element.scrollTop) < 1) {
569
- return;
549
+ scroll({ line, offset = 0, position, behavior = "instant" }) {
550
+ const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
551
+ const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
552
+ const doc = this.view.state.doc;
553
+ let targetScrollTop = scrollHeight - clientHeight + offset;
554
+ if (line >= 0 && line <= doc.lines - 1) {
555
+ const lineStart = doc.line(line + 1).from;
556
+ const coords = this.view.coordsAtPos(lineStart);
557
+ if (coords) {
558
+ const currentScrollTop = scrollTop;
559
+ const maxScrollTop = scrollHeight - clientHeight;
560
+ if (position === "end") {
561
+ targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
562
+ } else {
563
+ targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
564
+ }
565
+ targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
566
+ }
570
567
  }
571
- element.scrollTo({
572
- top: targetScrollTop,
573
- behavior: "smooth"
568
+ requestAnimationFrame(() => {
569
+ this.view.scrollDOM.scrollTo({
570
+ top: targetScrollTop
571
+ });
574
572
  });
575
573
  }
576
574
  });
577
575
  return [
578
576
  scrollPlugin,
579
- // Update listener to handle scroll effects.
577
+ // Listen for effect.s
580
578
  EditorView4.updateListener.of((update2) => {
581
579
  update2.transactions.forEach((transaction) => {
582
- for (const effect of transaction.effects) {
583
- if (effect.is(scrollToLineEffect)) {
584
- const { line, options = {} } = effect.value;
585
- const plugin = update2.view.plugin(scrollPlugin);
586
- if (plugin) {
587
- plugin.scrollToLine(line, {
588
- offset,
589
- position,
590
- ...options
591
- });
580
+ try {
581
+ const plugin = update2.view.plugin(scrollPlugin);
582
+ if (plugin) {
583
+ for (const effect of transaction.effects) {
584
+ if (effect.is(scrollerCrawlEffect)) {
585
+ plugin.crawl(effect.value);
586
+ } else if (effect.is(scrollerLineEffect)) {
587
+ plugin.scroll(effect.value);
588
+ }
592
589
  }
593
590
  }
591
+ } catch (err) {
592
+ log2.catch(err, void 0, {
593
+ F: __dxlog_file2,
594
+ L: 146,
595
+ S: void 0,
596
+ C: (f, a) => f(...a)
597
+ });
594
598
  }
595
599
  });
600
+ }),
601
+ // Styles.
602
+ EditorView4.theme({
603
+ ".cm-content": {
604
+ paddingBottom: `${overScroll}px`
605
+ },
606
+ ".cm-scroller": {
607
+ overflowAnchor: "none",
608
+ paddingBottom: "0"
609
+ },
610
+ ".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
611
+ display: "none"
612
+ },
613
+ ".cm-scroller::-webkit-scrollbar-thumb": {
614
+ background: "transparent",
615
+ transition: "background 0.15s"
616
+ },
617
+ "&:hover .cm-scroller::-webkit-scrollbar-thumb": {
618
+ background: "var(--color-scrollbar-thumb)"
619
+ },
620
+ ".cm-scroll-button": {
621
+ position: "absolute",
622
+ bottom: "0.5rem",
623
+ right: "1rem"
624
+ }
596
625
  })
597
626
  ];
598
627
  };
599
- var scrollToLine = (view, line, options) => {
600
- view.dispatch({
601
- effects: scrollToLineEffect.of({
602
- line,
603
- options
604
- })
605
- });
606
- };
628
+ function createCrawler(view, k = 0.3, maxStep = 2, targetDelta = 0.5) {
629
+ const el = view.scrollDOM;
630
+ let currentTop = 0;
631
+ let rafId = null;
632
+ function frame() {
633
+ const targetTop = el.scrollHeight - el.clientHeight;
634
+ const delta = targetTop - currentTop;
635
+ const absDelta = Math.abs(delta);
636
+ if (absDelta < targetDelta) {
637
+ el.scrollTop = targetTop;
638
+ currentTop = targetTop;
639
+ rafId = null;
640
+ return;
641
+ }
642
+ const step = Math.sign(delta) * Math.min(absDelta, Math.max(1, Math.min(absDelta * k, maxStep)));
643
+ currentTop += step;
644
+ el.scrollTop = currentTop;
645
+ rafId = requestAnimationFrame(frame);
646
+ }
647
+ return {
648
+ scroll: () => {
649
+ if (rafId === null) {
650
+ currentTop = el.scrollTop;
651
+ rafId = requestAnimationFrame(frame);
652
+ }
653
+ },
654
+ cancel: () => {
655
+ if (rafId !== null) {
656
+ cancelAnimationFrame(rafId);
657
+ rafId = null;
658
+ }
659
+ }
660
+ };
661
+ }
607
662
 
608
- // src/extensions/autoscroll.ts
609
- var scrollToBottomEffect = StateEffect2.define();
610
- var autoScroll = ({ autoScroll: autoScroll2 = true, threshold = 100, throttleDelay = 1e3, onAutoScroll } = {}) => {
663
+ // src/extensions/auto-scroll.ts
664
+ import { getSize } from "@dxos/ui-theme";
665
+ var autoScroll = (_ = {}) => {
611
666
  let buttonContainer;
612
- let hideTimeout;
613
- let lastScrollTop = 0;
614
667
  let isPinned = true;
615
- const setPinned = (pin) => {
616
- isPinned = pin;
617
- buttonContainer?.classList.toggle("opacity-0", pin);
618
- };
619
- const hideScrollbar = (view) => {
620
- view.scrollDOM.classList.add("cm-hide-scrollbar");
621
- clearTimeout(hideTimeout);
622
- hideTimeout = setTimeout(() => {
623
- view.scrollDOM.classList.remove("cm-hide-scrollbar");
624
- }, 1e3);
625
- };
626
- const scrollToBottom = (view, behavior) => {
627
- setPinned(true);
628
- hideScrollbar(view);
629
- const line = view.state.doc.lineAt(view.state.doc.length);
630
- view.dispatch({
631
- selection: {
632
- anchor: line.to,
633
- head: line.to
634
- },
635
- effects: scrollToLineEffect.of({
636
- line: line.number,
637
- options: {
638
- position: "end",
639
- offset: threshold,
640
- behavior
641
- }
642
- })
643
- });
668
+ const setPinned = (pinned) => {
669
+ buttonContainer?.classList.toggle("opacity-0", pinned);
670
+ isPinned = pinned;
644
671
  };
645
- const checkDistance = debounce((view) => {
646
- const scrollerRect = view.scrollDOM.getBoundingClientRect();
647
- const coords = view.coordsAtPos(view.state.doc.length);
648
- const distanceFromBottom = coords ? coords.bottom - scrollerRect.bottom : 0;
649
- setPinned(distanceFromBottom < 0);
650
- }, 1e3);
651
- const triggerUpdate = debounce((view) => scrollToBottom(view), throttleDelay);
652
672
  return [
653
673
  // Update listener for logging when scrolling is needed.
654
- EditorView5.updateListener.of(({ view, transactions, heightChanged }) => {
655
- transactions.forEach((transaction) => {
656
- for (const effect of transaction.effects) {
657
- if (effect.is(scrollToBottomEffect)) {
658
- scrollToBottom(view, effect.value);
674
+ EditorView5.updateListener.of(({ view, heightChanged, state }) => {
675
+ if (heightChanged) {
676
+ if (isPinned) {
677
+ const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
678
+ const delta = scrollHeight - scrollTop - clientHeight;
679
+ if (delta > 0 && scrollTop > 0) {
680
+ setPinned(true);
681
+ view.dispatch({
682
+ effects: scrollerCrawlEffect.of(true)
683
+ });
684
+ } else if (delta < 0) {
685
+ setPinned(false);
659
686
  }
660
- }
661
- });
662
- if (heightChanged && isPinned) {
663
- const coords = view.coordsAtPos(view.state.doc.length);
664
- const scrollerRect = view.scrollDOM.getBoundingClientRect();
665
- const distanceFromBottom = coords ? scrollerRect.bottom - coords.bottom : 0;
666
- if (autoScroll2 && distanceFromBottom < threshold) {
667
- const shouldScroll = onAutoScroll?.({
668
- view,
669
- distanceFromBottom
670
- }) ?? true;
671
- if (shouldScroll) {
672
- triggerUpdate(view);
687
+ } else {
688
+ if (state.doc.length === 0) {
689
+ setPinned(true);
673
690
  }
674
- } else if (distanceFromBottom < 0) {
675
- setPinned(false);
676
691
  }
677
692
  }
678
693
  }),
679
- // Detect user scroll.
680
- EditorView5.domEventHandlers({
681
- scroll: (event, view) => {
682
- const currentScrollTop = view.scrollDOM.scrollTop;
683
- const scrollingUp = currentScrollTop < lastScrollTop;
684
- lastScrollTop = currentScrollTop;
685
- if (scrollingUp) {
686
- setPinned(false);
687
- } else {
688
- checkDistance(view);
689
- }
694
+ // Detect user scroll and unpin (or re-pin if scrolled to the bottom).
695
+ ViewPlugin6.fromClass(class {
696
+ cleanup;
697
+ constructor(view) {
698
+ this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
699
+ requestAnimationFrame(() => {
700
+ const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
701
+ const delta = scrollHeight - scrollTop - clientHeight;
702
+ const pinned = delta === 0;
703
+ setPinned(pinned);
704
+ if (!pinned) {
705
+ view.dispatch({
706
+ effects: scrollerCrawlEffect.of(false)
707
+ });
708
+ }
709
+ });
710
+ }, 500));
711
+ }
712
+ destroy() {
713
+ this.cleanup();
690
714
  }
691
715
  }),
692
716
  // Scroll button.
693
717
  ViewPlugin6.fromClass(class {
694
718
  constructor(view) {
695
- const icon = Domino.of("dx-icon").attributes({
719
+ const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
696
720
  icon: "ph--arrow-down--regular"
697
721
  });
698
- const button = Domino.of("button").classNames("dx-button bg-accentSurface").attributes({
722
+ const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
699
723
  "data-density": "fine"
700
724
  }).children(icon).on("click", () => {
701
- scrollToBottom(view);
725
+ setPinned(true);
726
+ view.dispatch({
727
+ effects: scrollerLineEffect.of({
728
+ line: -1,
729
+ position: "end",
730
+ behavior: "smooth"
731
+ })
732
+ });
702
733
  });
703
734
  buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").children(button).root;
704
735
  view.scrollDOM.parentElement.appendChild(buttonContainer);
705
736
  }
706
- }),
707
- // Styles.
708
- EditorView5.theme({
709
- ".cm-scroller": {
710
- scrollbarWidth: "thin"
711
- },
712
- ".cm-scroller.cm-hide-scrollbar": {
713
- scrollbarWidth: "none"
714
- },
715
- ".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
716
- display: "none"
717
- },
718
- ".cm-scroll-button": {
719
- position: "absolute",
720
- bottom: "0.5rem",
721
- right: "1rem"
722
- }
723
737
  })
724
738
  ];
725
739
  };
740
+ function createUserScrollDetector(element, onUserScroll) {
741
+ return combine(addEventListener(element, "wheel", () => onUserScroll(), {
742
+ passive: true
743
+ }), addEventListener(element, "pointerdown", (event) => {
744
+ if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
745
+ onUserScroll();
746
+ }
747
+ }));
748
+ }
726
749
 
727
750
  // src/extensions/automerge/automerge.ts
728
751
  import { next as A3 } from "@automerge/automerge";
@@ -736,15 +759,15 @@ var initialSync = Transaction.userEvent.of("initial.sync");
736
759
 
737
760
  // src/extensions/automerge/cursor.ts
738
761
  import { fromCursor, toCursor } from "@dxos/echo-db";
739
- import { log as log2 } from "@dxos/log";
740
- var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
762
+ import { log as log3 } from "@dxos/log";
763
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
741
764
  var cursorConverter = (accessor) => ({
742
765
  toCursor: (pos, assoc) => {
743
766
  try {
744
767
  return toCursor(accessor, pos, assoc);
745
768
  } catch (err) {
746
- log2.catch(err, void 0, {
747
- F: __dxlog_file2,
769
+ log3.catch(err, void 0, {
770
+ F: __dxlog_file3,
748
771
  L: 15,
749
772
  S: void 0,
750
773
  C: (f, a) => f(...a)
@@ -756,8 +779,8 @@ var cursorConverter = (accessor) => ({
756
779
  try {
757
780
  return fromCursor(accessor, cursor2);
758
781
  } catch (err) {
759
- log2.catch(err, void 0, {
760
- F: __dxlog_file2,
782
+ log3.catch(err, void 0, {
783
+ F: __dxlog_file3,
761
784
  L: 24,
762
785
  S: void 0,
763
786
  C: (f, a) => f(...a)
@@ -768,10 +791,10 @@ var cursorConverter = (accessor) => ({
768
791
  });
769
792
 
770
793
  // src/extensions/automerge/defs.ts
771
- import { Annotation, StateEffect as StateEffect3 } from "@codemirror/state";
794
+ import { Annotation, StateEffect as StateEffect2 } from "@codemirror/state";
772
795
  var getPath = (state, field) => state.field(field).path;
773
796
  var getLastHeads = (state, field) => state.field(field).lastHeads;
774
- var updateHeadsEffect = StateEffect3.define({});
797
+ var updateHeadsEffect = StateEffect2.define({});
775
798
  var updateHeads = (newHeads) => updateHeadsEffect.of({
776
799
  newHeads
777
800
  });
@@ -782,7 +805,7 @@ var isReconcile = (tr) => {
782
805
 
783
806
  // src/extensions/automerge/sync.ts
784
807
  import { next as A2 } from "@automerge/automerge";
785
- import { log as log3 } from "@dxos/log";
808
+ import { log as log4 } from "@dxos/log";
786
809
 
787
810
  // src/extensions/automerge/update-automerge.ts
788
811
  import { next as A } from "@automerge/automerge";
@@ -923,7 +946,7 @@ var charPath = (textPath, candidatePath) => {
923
946
  };
924
947
 
925
948
  // src/extensions/automerge/sync.ts
926
- var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
949
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
927
950
  var Syncer = class {
928
951
  _handle;
929
952
  _state;
@@ -946,8 +969,8 @@ var Syncer = class {
946
969
  this._pending = false;
947
970
  }
948
971
  onEditorChange(view) {
949
- log3("onEditorChange", void 0, {
950
- F: __dxlog_file3,
972
+ log4("onEditorChange", void 0, {
973
+ F: __dxlog_file4,
951
974
  L: 45,
952
975
  S: this,
953
976
  C: (f, a) => f(...a)
@@ -962,8 +985,8 @@ var Syncer = class {
962
985
  }
963
986
  }
964
987
  onAutomergeChange(view) {
965
- log3("onAutomergeChange", void 0, {
966
- F: __dxlog_file3,
988
+ log4("onAutomergeChange", void 0, {
989
+ F: __dxlog_file4,
967
990
  L: 60,
968
991
  S: this,
969
992
  C: (f, a) => f(...a)
@@ -1029,6 +1052,15 @@ var automerge = (accessor) => {
1029
1052
  const value = DocAccessor.getValue(accessor);
1030
1053
  const current = this._view.state.doc.toString();
1031
1054
  if (value !== current) {
1055
+ console.warn("ENABLING INITIAL SYNC -- THIS MAY BE A REGRESSION");
1056
+ this._view.dispatch({
1057
+ changes: {
1058
+ from: 0,
1059
+ to: this._view.state.doc.length,
1060
+ insert: value
1061
+ },
1062
+ annotations: initialSync
1063
+ });
1032
1064
  }
1033
1065
  });
1034
1066
  }
@@ -1056,7 +1088,7 @@ import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
1056
1088
  import { Decoration as Decoration5, EditorView as EditorView7, ViewPlugin as ViewPlugin8, WidgetType as WidgetType3 } from "@codemirror/view";
1057
1089
  import { Event } from "@dxos/async";
1058
1090
  import { Context } from "@dxos/context";
1059
- var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
1091
+ var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
1060
1092
  var dummyProvider = {
1061
1093
  remoteStateChange: new Event(),
1062
1094
  open: () => {
@@ -1080,7 +1112,7 @@ var awareness = (provider = dummyProvider) => {
1080
1112
  };
1081
1113
  var RemoteSelectionsDecorator = class {
1082
1114
  _ctx = new Context(void 0, {
1083
- F: __dxlog_file4,
1115
+ F: __dxlog_file5,
1084
1116
  L: 80
1085
1117
  });
1086
1118
  _cursorConverter;
@@ -1293,8 +1325,8 @@ var styles = EditorView7.theme({
1293
1325
  import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
1294
1326
  import { Context as Context2 } from "@dxos/context";
1295
1327
  import { invariant } from "@dxos/invariant";
1296
- import { log as log4 } from "@dxos/log";
1297
- var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
1328
+ import { log as log5 } from "@dxos/log";
1329
+ var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
1298
1330
  var DEBOUNCE_INTERVAL = 100;
1299
1331
  var SpaceAwarenessProvider = class {
1300
1332
  _remoteStates = /* @__PURE__ */ new Map();
@@ -1314,7 +1346,7 @@ var SpaceAwarenessProvider = class {
1314
1346
  }
1315
1347
  open() {
1316
1348
  this._ctx = new Context2(void 0, {
1317
- F: __dxlog_file5,
1349
+ F: __dxlog_file6,
1318
1350
  L: 57
1319
1351
  });
1320
1352
  this._postTask = new DeferredTask(this._ctx, async () => {
@@ -1341,10 +1373,10 @@ var SpaceAwarenessProvider = class {
1341
1373
  void this._messenger.postMessage(this._channel, {
1342
1374
  kind: "query"
1343
1375
  }).catch((err) => {
1344
- log4.debug("failed to query awareness", {
1376
+ log5.debug("failed to query awareness", {
1345
1377
  err
1346
1378
  }, {
1347
- F: __dxlog_file5,
1379
+ F: __dxlog_file6,
1348
1380
  L: 91,
1349
1381
  S: this,
1350
1382
  C: (f, a) => f(...a)
@@ -1361,7 +1393,7 @@ var SpaceAwarenessProvider = class {
1361
1393
  }
1362
1394
  update(position) {
1363
1395
  invariant(this._postTask, void 0, {
1364
- F: __dxlog_file5,
1396
+ F: __dxlog_file6,
1365
1397
  L: 106,
1366
1398
  S: this,
1367
1399
  A: [
@@ -1378,7 +1410,7 @@ var SpaceAwarenessProvider = class {
1378
1410
  }
1379
1411
  _handleQueryMessage() {
1380
1412
  invariant(this._postTask, void 0, {
1381
- F: __dxlog_file5,
1413
+ F: __dxlog_file6,
1382
1414
  L: 117,
1383
1415
  S: this,
1384
1416
  A: [
@@ -1390,7 +1422,7 @@ var SpaceAwarenessProvider = class {
1390
1422
  }
1391
1423
  _handlePostMessage(message) {
1392
1424
  invariant(message.kind === "post", void 0, {
1393
- F: __dxlog_file5,
1425
+ F: __dxlog_file6,
1394
1426
  L: 122,
1395
1427
  S: this,
1396
1428
  A: [
@@ -1406,9 +1438,9 @@ var SpaceAwarenessProvider = class {
1406
1438
  // src/extensions/blast.ts
1407
1439
  import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
1408
1440
  import defaultsDeep from "lodash.defaultsdeep";
1409
- import { throttle } from "@dxos/async";
1441
+ import { throttle as throttle2 } from "@dxos/async";
1410
1442
  import { invariant as invariant2 } from "@dxos/invariant";
1411
- var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
1443
+ var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
1412
1444
  var defaultOptions = {
1413
1445
  effect: 2,
1414
1446
  maxParticles: 200,
@@ -1527,7 +1559,7 @@ var Blaster = class {
1527
1559
  }
1528
1560
  initialize() {
1529
1561
  invariant2(!this._canvas && !this._ctx, void 0, {
1530
- F: __dxlog_file6,
1562
+ F: __dxlog_file7,
1531
1563
  L: 142,
1532
1564
  S: this,
1533
1565
  A: [
@@ -1564,7 +1596,7 @@ var Blaster = class {
1564
1596
  }
1565
1597
  start() {
1566
1598
  invariant2(this._canvas && this._ctx, void 0, {
1567
- F: __dxlog_file6,
1599
+ F: __dxlog_file7,
1568
1600
  L: 181,
1569
1601
  S: this,
1570
1602
  A: [
@@ -1598,11 +1630,11 @@ var Blaster = class {
1598
1630
  this.drawParticles();
1599
1631
  requestAnimationFrame(this.loop.bind(this));
1600
1632
  }
1601
- shake = throttle(({ time }) => {
1633
+ shake = throttle2(({ time }) => {
1602
1634
  this._shakeTime = this._shakeTimeMax || time;
1603
1635
  this._shakeTimeMax = time;
1604
1636
  }, 100);
1605
- spawn = throttle(({ element, point }) => {
1637
+ spawn = throttle2(({ element, point }) => {
1606
1638
  const color = getRGBComponents(element, this._options.color);
1607
1639
  const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
1608
1640
  const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
@@ -1776,11 +1808,11 @@ var blocks = () => [
1776
1808
  ".cm-line.block-line": {
1777
1809
  paddingLeft: "0.75rem",
1778
1810
  paddingRight: "0.75rem",
1779
- borderLeft: "1px solid var(--dx-subduedSeparator)",
1780
- borderRight: "1px solid var(--dx-subduedSeparator)"
1811
+ borderLeft: "1px solid var(--color-subdued-separator)",
1812
+ borderRight: "1px solid var(--color-subdued-separator)"
1781
1813
  },
1782
1814
  ".cm-line.block-single": {
1783
- border: "1px solid var(--dx-subduedSeparator)",
1815
+ border: "1px solid var(--color-subdued-separator)",
1784
1816
  borderRadius: "6px",
1785
1817
  paddingTop: "0.5rem",
1786
1818
  paddingBottom: "0.5rem",
@@ -1788,7 +1820,7 @@ var blocks = () => [
1788
1820
  marginBottom: "0.5rem"
1789
1821
  },
1790
1822
  ".cm-line.block-first": {
1791
- borderTop: "1px solid var(--dx-subduedSeparator)",
1823
+ borderTop: "1px solid var(--color-subdued-separator)",
1792
1824
  borderTopLeftRadius: "6px",
1793
1825
  borderTopRightRadius: "6px",
1794
1826
  paddingTop: "0.5rem",
@@ -1796,7 +1828,7 @@ var blocks = () => [
1796
1828
  },
1797
1829
  ".cm-line.block-middle": {},
1798
1830
  ".cm-line.block-last": {
1799
- borderBottom: "1px solid var(--dx-subduedSeparator)",
1831
+ borderBottom: "1px solid var(--color-subdued-separator)",
1800
1832
  borderBottomLeftRadius: "6px",
1801
1833
  borderBottomRightRadius: "6px",
1802
1834
  paddingBottom: "0.5rem",
@@ -1806,13 +1838,13 @@ var blocks = () => [
1806
1838
  ];
1807
1839
 
1808
1840
  // src/extensions/bookmarks.ts
1809
- import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
1841
+ import { Prec as Prec3, StateEffect as StateEffect3, StateField as StateField2 } from "@codemirror/state";
1810
1842
  import { keymap as keymap4 } from "@codemirror/view";
1811
- import { log as log5 } from "@dxos/log";
1812
- var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
1813
- var addBookmark = StateEffect4.define();
1814
- var removeBookmark = StateEffect4.define();
1815
- var clearBookmarks = StateEffect4.define();
1843
+ import { log as log6 } from "@dxos/log";
1844
+ var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
1845
+ var addBookmark = StateEffect3.define();
1846
+ var removeBookmark = StateEffect3.define();
1847
+ var clearBookmarks = StateEffect3.define();
1816
1848
  var bookmarks = () => {
1817
1849
  return [
1818
1850
  bookmarksField,
@@ -1821,8 +1853,8 @@ var bookmarks = () => {
1821
1853
  key: "Mod-ArrowUp",
1822
1854
  run: (view) => {
1823
1855
  const bookmarks2 = view.state.field(bookmarksField);
1824
- log5("up", bookmarks2, {
1825
- F: __dxlog_file7,
1856
+ log6("up", bookmarks2, {
1857
+ F: __dxlog_file8,
1826
1858
  L: 29,
1827
1859
  S: void 0,
1828
1860
  C: (f, a) => f(...a)
@@ -1834,8 +1866,8 @@ var bookmarks = () => {
1834
1866
  key: "Mod-ArrowDown",
1835
1867
  run: (view) => {
1836
1868
  const bookmarks2 = view.state.field(bookmarksField);
1837
- log5("down", bookmarks2, {
1838
- F: __dxlog_file7,
1869
+ log6("down", bookmarks2, {
1870
+ F: __dxlog_file8,
1839
1871
  L: 37,
1840
1872
  S: void 0,
1841
1873
  C: (f, a) => f(...a)
@@ -1876,22 +1908,22 @@ var bookmarksField = StateField2.define({
1876
1908
 
1877
1909
  // src/extensions/comments.ts
1878
1910
  import { invertedEffects } from "@codemirror/commands";
1879
- import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
1911
+ import { StateEffect as StateEffect4, StateField as StateField3 } from "@codemirror/state";
1880
1912
  import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
1881
1913
  import sortBy from "lodash.sortby";
1882
- import { debounce as debounce3 } from "@dxos/async";
1883
- import { log as log6 } from "@dxos/log";
1914
+ import { debounce as debounce2 } from "@dxos/async";
1915
+ import { log as log7 } from "@dxos/log";
1884
1916
  import { isNonNullable } from "@dxos/util";
1885
1917
 
1886
1918
  // src/extensions/selection.ts
1887
1919
  import { Transaction as Transaction3 } from "@codemirror/state";
1888
1920
  import { EditorView as EditorView10, keymap as keymap5 } from "@codemirror/view";
1889
- import { debounce as debounce2 } from "@dxos/async";
1921
+ import { debounce } from "@dxos/async";
1890
1922
  import { invariant as invariant3 } from "@dxos/invariant";
1891
1923
  import { isTruthy } from "@dxos/util";
1892
- var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
1924
+ var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
1893
1925
  var documentId = singleValueFacet();
1894
- var stateRestoreAnnotation = "dxos.org/cm/state-restore";
1926
+ var stateRestoreAnnotation = "org.dxos.cm.state-restore";
1895
1927
  var createEditorStateTransaction = ({ scrollTo, selection }) => {
1896
1928
  return {
1897
1929
  selection,
@@ -1905,7 +1937,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1905
1937
  var createEditorStateStore = (keyPrefix) => ({
1906
1938
  getState: (id) => {
1907
1939
  invariant3(id, void 0, {
1908
- F: __dxlog_file8,
1940
+ F: __dxlog_file9,
1909
1941
  L: 47,
1910
1942
  S: void 0,
1911
1943
  A: [
@@ -1918,7 +1950,7 @@ var createEditorStateStore = (keyPrefix) => ({
1918
1950
  },
1919
1951
  setState: (id, state) => {
1920
1952
  invariant3(id, void 0, {
1921
- F: __dxlog_file8,
1953
+ F: __dxlog_file9,
1922
1954
  L: 53,
1923
1955
  S: void 0,
1924
1956
  A: [
@@ -1930,7 +1962,7 @@ var createEditorStateStore = (keyPrefix) => ({
1930
1962
  }
1931
1963
  });
1932
1964
  var selectionState = ({ getState, setState } = {}) => {
1933
- const setStateDebounced = debounce2(setState, 1e3);
1965
+ const setStateDebounced = debounce(setState, 1e3);
1934
1966
  return [
1935
1967
  // TODO(burdon): Track scrolling (currently only updates when cursor moves).
1936
1968
  // EditorView.domEventHandlers({
@@ -1977,10 +2009,10 @@ var selectionState = ({ getState, setState } = {}) => {
1977
2009
  };
1978
2010
 
1979
2011
  // src/extensions/comments.ts
1980
- var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
1981
- var setComments = StateEffect5.define();
1982
- var setSelection = StateEffect5.define();
1983
- var setCommentState = StateEffect5.define();
2012
+ var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
2013
+ var setComments = StateEffect4.define();
2014
+ var setSelection = StateEffect4.define();
2015
+ var setCommentState = StateEffect4.define();
1984
2016
  var commentsState = StateField3.define({
1985
2017
  create: (state) => ({
1986
2018
  id: state.facet(documentId),
@@ -2022,14 +2054,14 @@ var commentsState = StateField3.define({
2022
2054
  var styles2 = EditorView11.theme({
2023
2055
  ".cm-comment, .cm-comment-current": {
2024
2056
  padding: "3px 0",
2025
- color: "var(--dx-cmCommentText)",
2026
- backgroundColor: "var(--dx-cmCommentSurface)"
2057
+ color: "var(--color-cm-comment-text)",
2058
+ backgroundColor: "var(--color-cm-comment-surface)"
2027
2059
  },
2028
2060
  ".cm-comment > span, .cm-comment-current > span": {
2029
2061
  boxDecorationBreak: "clone",
2030
- boxShadow: "0 0 1px 3px var(--dx-cmCommentSurface)",
2031
- backgroundColor: "var(--dx-cmCommentSurface)",
2032
- color: "var(--dx-cmCommentText)",
2062
+ boxShadow: "0 0 1px 3px var(--color-cm-comment-surface)",
2063
+ backgroundColor: "var(--color-cm-comment-surface)",
2064
+ color: "var(--color-cm-comment-text)",
2033
2065
  cursor: "pointer"
2034
2066
  }
2035
2067
  });
@@ -2047,8 +2079,8 @@ var commentsDecorations = EditorView11.decorations.compute([
2047
2079
  const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
2048
2080
  const range = comment.range;
2049
2081
  if (!range) {
2050
- log6.warn("Invalid range:", range, {
2051
- F: __dxlog_file9,
2082
+ log7.warn("Invalid range:", range, {
2083
+ F: __dxlog_file10,
2052
2084
  L: 140,
2053
2085
  S: void 0,
2054
2086
  C: (f, a) => f(...a)
@@ -2062,7 +2094,7 @@ var commentsDecorations = EditorView11.decorations.compute([
2062
2094
  }).filter(isNonNullable);
2063
2095
  return Decoration7.set(decorations2);
2064
2096
  });
2065
- var commentClickedEffect = StateEffect5.define();
2097
+ var commentClickedEffect = StateEffect4.define();
2066
2098
  var handleCommentClick = EditorView11.domEventHandlers({
2067
2099
  click: (event, view) => {
2068
2100
  let target = event.target;
@@ -2180,7 +2212,7 @@ var mapTrackedComment = (comment, changes) => ({
2180
2212
  from: changes.mapPos(comment.from, 1),
2181
2213
  to: changes.mapPos(comment.to, 1)
2182
2214
  });
2183
- var restoreCommentEffect = StateEffect5.define({
2215
+ var restoreCommentEffect = StateEffect4.define({
2184
2216
  map: mapTrackedComment
2185
2217
  });
2186
2218
  var createComment = (view) => {
@@ -2214,7 +2246,7 @@ var createComment = (view) => {
2214
2246
  var optionsFacet = singleValueFacet();
2215
2247
  var comments = (options = {}) => {
2216
2248
  const { key: shortcut = "meta-'" } = options;
2217
- const handleSelect = debounce3((state) => options.onSelect?.(state), 200);
2249
+ const handleSelect = debounce2((state) => options.onSelect?.(state), 200);
2218
2250
  return [
2219
2251
  optionsFacet.of(options),
2220
2252
  options.id ? documentId.of(options.id) : void 0,
@@ -2392,9 +2424,9 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin10.fro
2392
2424
  // src/extensions/debug.ts
2393
2425
  import { syntaxTree } from "@codemirror/language";
2394
2426
  import { StateField as StateField4 } from "@codemirror/state";
2395
- var debugNodeLogger = (log11 = console.log) => {
2427
+ var debugNodeLogger = (log12 = console.log) => {
2396
2428
  const logTokens = (state) => syntaxTree(state).iterate({
2397
- enter: (node) => log11(node.type)
2429
+ enter: (node) => log12(node.type)
2398
2430
  });
2399
2431
  return StateField4.define({
2400
2432
  create: (state) => logTokens(state),
@@ -2429,8 +2461,8 @@ var dropFile = (options = {}) => {
2429
2461
  };
2430
2462
  var styles3 = EditorView12.theme({
2431
2463
  ".cm-dropCursor": {
2432
- borderLeft: "2px solid var(--dx-accentText)",
2433
- color: "var(--dx-accentText)",
2464
+ borderLeft: "2px solid var(--color-accent-text)",
2465
+ color: "var(--color-accent-text)",
2434
2466
  padding: "0 4px"
2435
2467
  },
2436
2468
  ".cm-dropCursor:after": {
@@ -2444,47 +2476,66 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
2444
2476
  import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
2445
2477
  import { searchKeymap } from "@codemirror/search";
2446
2478
  import { EditorState } from "@codemirror/state";
2447
- import { EditorView as EditorView15, ViewPlugin as ViewPlugin11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2, scrollPastEnd } from "@codemirror/view";
2479
+ import { EditorView as EditorView16, ViewPlugin as ViewPlugin12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
2448
2480
  import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
2449
2481
  import defaultsDeep2 from "lodash.defaultsdeep";
2450
2482
  import { generateName } from "@dxos/display-name";
2451
- import { log as log7 } from "@dxos/log";
2483
+ import { log as log8 } from "@dxos/log";
2452
2484
  import { hexToHue, isTruthy as isTruthy2 } from "@dxos/util";
2453
2485
 
2454
- // src/styles/markdown.ts
2486
+ // src/styles/theme.ts
2487
+ import { EditorView as EditorView13 } from "@codemirror/view";
2455
2488
  import { mx as mx3 } from "@dxos/ui-theme";
2456
2489
  var headings = {
2457
- 1: "text-4xl",
2458
- 2: "text-3xl",
2459
- 3: "text-2xl",
2460
- 4: "text-xl",
2461
- 5: "text-lg",
2462
- 6: ""
2490
+ 1: {
2491
+ className: "text-3xl",
2492
+ fontSize: "var(--text-3xl)",
2493
+ lineHeight: "var(--text-4xl--line-height)"
2494
+ },
2495
+ 2: {
2496
+ className: "text-2xl",
2497
+ fontSize: "var(--text-2xl)",
2498
+ lineHeight: "var(--text-3xl--line-height)"
2499
+ },
2500
+ 3: {
2501
+ className: "text-xl",
2502
+ fontSize: "var(--text-xl)",
2503
+ lineHeight: "var(--text-2xl--line-height)"
2504
+ },
2505
+ 4: {
2506
+ className: "text-lg",
2507
+ fontSize: "var(--text-lg)",
2508
+ lineHeight: "var(--text-xl--line-height)"
2509
+ },
2510
+ 5: {
2511
+ className: "text-base",
2512
+ fontSize: "var(--text-base)",
2513
+ lineHeight: "var(--text-lg--line-height)"
2514
+ },
2515
+ 6: {
2516
+ className: "text-base",
2517
+ fontSize: "var(--text-base)",
2518
+ lineHeight: "var(--text-base--line-height)"
2519
+ }
2463
2520
  };
2521
+ var fontBody = '"Inter Variable", ui-sans-serif, system-ui, sans-serif';
2522
+ var fontMono = '"JetBrains Mono Variable", ui-monospace, "Cascadia Code", "Source Code Pro", monospace';
2464
2523
  var markdownTheme = {
2465
- code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
2466
- codeMark: "font-mono text-primary-500",
2467
- mark: "opacity-50",
2468
- heading: (level) => {
2469
- return mx3(headings[level], "dark:text-neutral-400");
2470
- }
2524
+ code: "font-mono! cm-code-inline",
2525
+ codeMark: "font-mono! cm-code-mark",
2526
+ mark: "font-mono!",
2527
+ heading: (level) => ({
2528
+ className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
2529
+ color: "var(--color-cm-heading) !important",
2530
+ lineHeight: headings[level].lineHeight,
2531
+ fontSize: headings[level].fontSize,
2532
+ fontWeight: "100 !important"
2533
+ })
2471
2534
  };
2472
-
2473
- // src/styles/theme.ts
2474
- import { EditorView as EditorView13 } from "@codemirror/view";
2475
-
2476
- // src/styles/tokens.ts
2477
- import { tokens } from "@dxos/ui-theme";
2478
- import { get } from "@dxos/util";
2479
- var getToken = (path, defaultValue) => {
2480
- const value = get(tokens, path, defaultValue);
2481
- return value?.toString() ?? "";
2482
- };
2483
- var fontBody = getToken("fontFamily.body");
2484
- var fontMono = getToken("fontFamily.mono");
2485
-
2486
- // src/styles/theme.ts
2487
2535
  var baseTheme = EditorView13.baseTheme({
2536
+ /**
2537
+ * Outer frame.
2538
+ */
2488
2539
  "&": {},
2489
2540
  "&.cm-focused": {
2490
2541
  outline: "none"
@@ -2493,7 +2544,18 @@ var baseTheme = EditorView13.baseTheme({
2493
2544
  * Scroller
2494
2545
  */
2495
2546
  ".cm-scroller": {
2496
- overflowY: "auto"
2547
+ overflowAnchor: "none"
2548
+ },
2549
+ ".cm-scroller::-webkit-scrollbar": {
2550
+ width: "8px"
2551
+ },
2552
+ ".cm-scroller::-webkit-scrollbar-track": {},
2553
+ ".cm-scroller::-webkit-scrollbar-thumb": {
2554
+ background: "transparent",
2555
+ transition: "background 0.15s"
2556
+ },
2557
+ "&:hover .cm-scroller::-webkit-scrollbar-thumb": {
2558
+ background: "var(--color-scrollbar-thumb)"
2497
2559
  },
2498
2560
  /**
2499
2561
  * Content
@@ -2501,7 +2563,6 @@ var baseTheme = EditorView13.baseTheme({
2501
2563
  */
2502
2564
  ".cm-content": {
2503
2565
  padding: "unset",
2504
- lineHeight: "24px",
2505
2566
  color: "unset"
2506
2567
  },
2507
2568
  /**
@@ -2515,8 +2576,8 @@ var baseTheme = EditorView13.baseTheme({
2515
2576
  ".cm-gutter": {},
2516
2577
  ".cm-gutter.cm-lineNumbers": {
2517
2578
  paddingRight: "4px",
2518
- borderRight: "1px solid var(--dx-subduedSeparator)",
2519
- color: "var(--dx-subduedText)"
2579
+ borderRight: "1px solid var(--color-subdued-separator)",
2580
+ color: "var(--color-subdued)"
2520
2581
  },
2521
2582
  ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2522
2583
  minWidth: "40px"
@@ -2525,36 +2586,43 @@ var baseTheme = EditorView13.baseTheme({
2525
2586
  * Height is set to match the corresponding line (which may have wrapped).
2526
2587
  */
2527
2588
  ".cm-gutterElement": {
2528
- lineHeight: "24px",
2589
+ lineHeight: 1.5,
2529
2590
  fontSize: "12px"
2530
2591
  },
2531
2592
  /**
2532
2593
  * Line.
2533
2594
  */
2534
2595
  ".cm-line": {
2535
- lineHeight: "24px",
2596
+ lineHeight: 1.5,
2536
2597
  paddingInline: 0
2537
2598
  },
2599
+ /**
2600
+ * Force all inline children to inherit line-height to prevent monospace font metrics
2601
+ * (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.
2602
+ */
2603
+ ".cm-line *": {
2604
+ lineHeight: "inherit"
2605
+ },
2538
2606
  ".cm-activeLine": {
2539
- background: "var(--dx-cmActiveLine)"
2607
+ background: "var(--color-cm-active-line)"
2540
2608
  },
2541
2609
  /**
2542
2610
  * Cursor (layer).
2543
2611
  */
2544
2612
  ".cm-cursor, .cm-dropCursor": {
2545
- borderLeft: "2px solid var(--dx-cmCursor)"
2613
+ borderLeft: "2px solid var(--color-cm-cursor)"
2546
2614
  },
2547
2615
  ".cm-placeholder": {
2548
- color: "var(--dx-placeholder)"
2616
+ color: "var(--color-placeholder)"
2549
2617
  },
2550
2618
  /**
2551
2619
  * Selection (layer).
2552
2620
  */
2553
2621
  ".cm-selectionBackground": {
2554
- background: "var(--dx-cmSelection)"
2622
+ background: "var(--color-cm-selection)"
2555
2623
  },
2556
2624
  "&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
2557
- background: "var(--dx-cmFocusedSelection)"
2625
+ background: "var(--color-cm-focused-selection)"
2558
2626
  },
2559
2627
  /**
2560
2628
  * Search.
@@ -2564,8 +2632,8 @@ var baseTheme = EditorView13.baseTheme({
2564
2632
  margin: "0 -3px",
2565
2633
  padding: "3px",
2566
2634
  borderRadius: "3px",
2567
- background: "var(--dx-cmHighlightSurface)",
2568
- color: "var(--dx-cmHighlight)"
2635
+ background: "var(--color-cm-highlight-surface)",
2636
+ color: "var(--color-cm-highlight)"
2569
2637
  },
2570
2638
  ".cm-searchMatch-selected": {
2571
2639
  textDecoration: "underline"
@@ -2576,20 +2644,29 @@ var baseTheme = EditorView13.baseTheme({
2576
2644
  ".cm-link": {
2577
2645
  textDecorationLine: "underline",
2578
2646
  textDecorationThickness: "1px",
2579
- textDecorationColor: "var(--dx-separator)",
2647
+ textDecorationColor: "var(--color-separator)",
2580
2648
  textUnderlineOffset: "2px",
2581
2649
  borderRadius: ".125rem"
2582
2650
  },
2583
2651
  ".cm-link > span": {
2584
- color: "var(--dx-accentText)"
2652
+ color: "var(--color-accent-text)"
2653
+ },
2654
+ ".cm-link > span:hover": {
2655
+ color: "var(--color-accent-text-hover)"
2585
2656
  },
2586
2657
  /**
2587
2658
  * Tooltip.
2588
2659
  */
2589
2660
  ".cm-tooltip": {
2590
- background: "var(--dx-baseSurface)"
2661
+ background: "var(--color-modal-surface)"
2591
2662
  },
2592
2663
  ".cm-tooltip-below": {},
2664
+ ".cm-tooltip-hover": {
2665
+ background: "var(--color-modal-surface)",
2666
+ border: "1px solid var(--color-separator)",
2667
+ borderRadius: "4px",
2668
+ overflow: "hidden"
2669
+ },
2593
2670
  /**
2594
2671
  * Autocomplete.
2595
2672
  * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
@@ -2597,7 +2674,7 @@ var baseTheme = EditorView13.baseTheme({
2597
2674
  ".cm-tooltip.cm-tooltip-autocomplete": {
2598
2675
  marginTop: "6px",
2599
2676
  marginLeft: "-10px",
2600
- border: "2px solid var(--dx-separator)",
2677
+ border: "2px solid var(--color-separator)",
2601
2678
  borderRadius: "4px"
2602
2679
  },
2603
2680
  ".cm-tooltip.cm-tooltip-autocomplete > ul": {
@@ -2607,12 +2684,12 @@ var baseTheme = EditorView13.baseTheme({
2607
2684
  padding: "4px"
2608
2685
  },
2609
2686
  ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
2610
- background: "var(--dx-activeSurface)",
2611
- color: "var(--dx-activeSurfaceText)"
2687
+ background: "var(--color-active-surface)",
2688
+ color: "var(--color-base-surface-text)"
2612
2689
  },
2613
2690
  ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2614
2691
  paddingLeft: "4px !important",
2615
- color: "var(--dx-hoverSurfaceText)"
2692
+ color: "var(--color-base-surface-text)"
2616
2693
  },
2617
2694
  /**
2618
2695
  * Completion info.
@@ -2621,17 +2698,17 @@ var baseTheme = EditorView13.baseTheme({
2621
2698
  width: "360px !important",
2622
2699
  margin: "-10px 1px 0 1px",
2623
2700
  padding: "8px !important",
2624
- borderColor: "var(--dx-separator)"
2701
+ borderColor: "var(--color-separator)"
2625
2702
  },
2626
2703
  ".cm-completionIcon": {
2627
2704
  display: "none"
2628
2705
  },
2629
2706
  ".cm-completionLabel": {
2630
- color: "var(--dx-description)",
2707
+ color: "var(--color-description)",
2631
2708
  padding: "0 4px"
2632
2709
  },
2633
2710
  ".cm-completionMatchedText": {
2634
- color: "var(--dx-baseText)",
2711
+ color: "var(--color-base-surface-text)",
2635
2712
  textDecoration: "none !important"
2636
2713
  },
2637
2714
  /**
@@ -2655,7 +2732,7 @@ var baseTheme = EditorView13.baseTheme({
2655
2732
  backgroundColor: "var(--surface-bg)"
2656
2733
  },
2657
2734
  ".cm-panel input, .cm-panel button, .cm-panel label": {
2658
- color: "var(--dx-subdued)",
2735
+ color: "var(--color-subdued)",
2659
2736
  fontSize: "14px",
2660
2737
  all: "unset",
2661
2738
  margin: "3px !important",
@@ -2663,10 +2740,10 @@ var baseTheme = EditorView13.baseTheme({
2663
2740
  outline: "1px solid transparent"
2664
2741
  },
2665
2742
  ".cm-panel input, .cm-panel button": {
2666
- backgroundColor: "var(--dx-inputSurface)"
2743
+ backgroundColor: "var(--color-input-surface)"
2667
2744
  },
2668
2745
  ".cm-panel input:focus, .cm-panel button:focus": {
2669
- outline: "1px solid var(--dx-neutralFocusIndicator)"
2746
+ outline: "1px solid var(--color-neutral-focus-indicator)"
2670
2747
  },
2671
2748
  ".cm-panel label": {
2672
2749
  display: "inline-flex",
@@ -2679,33 +2756,33 @@ var baseTheme = EditorView13.baseTheme({
2679
2756
  height: "8px",
2680
2757
  marginRight: "6px !important",
2681
2758
  padding: "2px !important",
2682
- color: "var(--dx-neutralFocusIndicator)"
2759
+ color: "var(--color-neutral-focus-indicator)"
2683
2760
  },
2684
2761
  ".cm-panel button": {
2685
2762
  "&:hover": {
2686
- backgroundColor: "var(--dx-accentSurfaceHover) !important"
2763
+ // TODO(burdon): Replace with layer and @apply bg-accent-surface-hover
2764
+ backgroundColor: "var(--color-accent-surface-hover) !important"
2687
2765
  },
2688
2766
  "&:active": {
2689
- backgroundColor: "var(--dx-accentSurfaceHover)"
2767
+ backgroundColor: "var(--color-accent-surface-hover)"
2690
2768
  }
2691
2769
  },
2692
2770
  ".cm-panel.cm-search": {
2693
2771
  padding: "4px",
2694
- borderTop: "1px solid var(--dx-separator)"
2772
+ borderTop: "1px solid var(--color-separator)"
2695
2773
  }
2696
2774
  });
2697
2775
  var editorGutter = EditorView13.theme({
2698
2776
  ".cm-gutters": {
2699
2777
  // NOTE: Non-transparent background required to cover content if scrolling horizontally.
2700
- background: "var(--dx-baseSurface) !important",
2778
+ background: "var(--color-base-surface) !important",
2701
2779
  paddingRight: "1rem"
2702
2780
  }
2703
2781
  });
2704
2782
  var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
2705
- // Set metrics on the scroller (this is often what CM uses for layout).
2783
+ // Main content.
2706
2784
  ".cm-scroller": {
2707
- fontFamily: monospace ? fontMono : fontBody,
2708
- fontSize: "16px"
2785
+ fontFamily: monospace ? fontMono : fontBody
2709
2786
  },
2710
2787
  // Maintain defaults for UI components.
2711
2788
  ".cm-content, .cm-gutters, .cm-panel": {
@@ -2715,9 +2792,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
2715
2792
  });
2716
2793
 
2717
2794
  // src/extensions/focus.ts
2718
- import { StateEffect as StateEffect6, StateField as StateField5 } from "@codemirror/state";
2795
+ import { StateEffect as StateEffect5, StateField as StateField5 } from "@codemirror/state";
2719
2796
  import { EditorView as EditorView14 } from "@codemirror/view";
2720
- var focusEffect = StateEffect6.define();
2797
+ var focusEffect = StateEffect5.define();
2721
2798
  var focusField = StateField5.define({
2722
2799
  create: () => false,
2723
2800
  update: (value, tr) => {
@@ -2745,9 +2822,32 @@ var focus = [
2745
2822
  })
2746
2823
  ];
2747
2824
 
2825
+ // src/extensions/scroll-past-end.ts
2826
+ import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
2827
+ var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
2828
+ height = 1e3;
2829
+ attrs = {
2830
+ style: "padding-bottom: 1000px"
2831
+ };
2832
+ update({ view }) {
2833
+ const lastLineBlock = view.lineBlockAt(view.state.doc.length);
2834
+ const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
2835
+ if (height >= 0 && height !== this.height) {
2836
+ this.height = height;
2837
+ this.attrs = {
2838
+ style: `padding-bottom: ${height}px`
2839
+ };
2840
+ }
2841
+ }
2842
+ });
2843
+ var scrollPastEnd = () => [
2844
+ scrollPastEndPlugin,
2845
+ EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.attrs ?? null)
2846
+ ];
2847
+
2748
2848
  // src/extensions/factories.ts
2749
- var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
2750
- var tabbable = EditorView15.contentAttributes.of({
2849
+ var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
2850
+ var tabbable = EditorView16.contentAttributes.of({
2751
2851
  tabindex: "0"
2752
2852
  });
2753
2853
  var filterChars = (chars) => {
@@ -2800,10 +2900,10 @@ var createBasicExtensions = (propsProp) => {
2800
2900
  const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
2801
2901
  return [
2802
2902
  // NOTE: Doesn't catch errors in keymap functions.
2803
- EditorView15.exceptionSink.of((err) => {
2804
- log7.catch(err, void 0, {
2805
- F: __dxlog_file10,
2806
- L: 132,
2903
+ EditorView16.exceptionSink.of((err) => {
2904
+ log8.catch(err, void 0, {
2905
+ F: __dxlog_file11,
2906
+ L: 131,
2807
2907
  S: void 0,
2808
2908
  C: (f, a) => f(...a)
2809
2909
  });
@@ -2815,7 +2915,7 @@ var createBasicExtensions = (propsProp) => {
2815
2915
  props.drawSelection && drawSelection({
2816
2916
  cursorBlinkRate: 1200
2817
2917
  }),
2818
- props.editable !== void 0 && EditorView15.editable.of(props.editable),
2918
+ props.editable !== void 0 && EditorView16.editable.of(props.editable),
2819
2919
  props.focus && focus,
2820
2920
  props.highlightActiveLine && highlightActiveLine(),
2821
2921
  props.history && history(),
@@ -2823,7 +2923,7 @@ var createBasicExtensions = (propsProp) => {
2823
2923
  lineNumbers(),
2824
2924
  editorGutter
2825
2925
  ],
2826
- props.lineWrapping && EditorView15.lineWrapping,
2926
+ props.lineWrapping && EditorView16.lineWrapping,
2827
2927
  props.placeholder && placeholder2(props.placeholder),
2828
2928
  props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
2829
2929
  props.scrollPastEnd && scrollPastEnd(),
@@ -2855,12 +2955,12 @@ var createBasicExtensions = (propsProp) => {
2855
2955
  };
2856
2956
  var grow = {
2857
2957
  editor: {
2858
- className: "bs-full is-full"
2958
+ className: "h-full w-full"
2859
2959
  }
2860
2960
  };
2861
2961
  var fullWidth = {
2862
2962
  editor: {
2863
- className: "is-full"
2963
+ className: "w-full"
2864
2964
  }
2865
2965
  };
2866
2966
  var defaultThemeSlots = grow;
@@ -2872,18 +2972,18 @@ var createThemeExtensions = ({ monospace, themeMode, slots: slotsProp, syntaxHig
2872
2972
  const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
2873
2973
  return [
2874
2974
  baseTheme,
2875
- EditorView15.darkTheme.of(themeMode === "dark"),
2975
+ EditorView16.darkTheme.of(themeMode === "dark"),
2876
2976
  createFontTheme({
2877
2977
  monospace
2878
2978
  }),
2879
2979
  syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
2880
- slots.editor?.className && EditorView15.editorAttributes.of({
2980
+ slots.editor?.className && EditorView16.editorAttributes.of({
2881
2981
  class: slots.editor.className
2882
2982
  }),
2883
- slots.content?.className && EditorView15.contentAttributes.of({
2983
+ slots.content?.className && EditorView16.contentAttributes.of({
2884
2984
  class: slots.content.className
2885
2985
  }),
2886
- slots.scroll?.className && ViewPlugin11.fromClass(class {
2986
+ slots.scroll?.className && ViewPlugin12.fromClass(class {
2887
2987
  constructor(view) {
2888
2988
  view.scrollDOM.classList.add(...slots.scroll.className.split(/\s+/));
2889
2989
  }
@@ -2903,8 +3003,8 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
2903
3003
  channel: `awareness.${id}`,
2904
3004
  peerId: identity.identityKey.toHex(),
2905
3005
  info: {
2906
- darkColor: `var(--dx-${hue}Cursor)`,
2907
- lightColor: `var(--dx-${hue}Cursor)`,
3006
+ darkColor: `var(--color-${hue}-border)`,
3007
+ lightColor: `var(--color-${hue}-border)`,
2908
3008
  displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex())
2909
3009
  }
2910
3010
  })));
@@ -2914,7 +3014,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
2914
3014
 
2915
3015
  // src/extensions/folding.ts
2916
3016
  import { codeFolding, foldGutter } from "@codemirror/language";
2917
- import { EditorView as EditorView16 } from "@codemirror/view";
3017
+ import { EditorView as EditorView17 } from "@codemirror/view";
2918
3018
  import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
2919
3019
  var folding = () => {
2920
3020
  return [
@@ -2922,13 +3022,14 @@ var folding = () => {
2922
3022
  placeholderDOM: () => Domino2.of("span").root
2923
3023
  }),
2924
3024
  foldGutter({
3025
+ // NOTE: We can't animate since the element is remounted on state change.
2925
3026
  markerDOM: (open) => {
2926
- return Domino2.of("div").classNames("flex bs-full justify-center items-center").children(Domino2.of("svg", Domino2.SVG).classNames(mx4("is-4 bs-4 cursor-pointer", open && "rotate-90")).children(Domino2.of("use", Domino2.SVG).attributes({
3027
+ return Domino2.of("div").classNames("flex h-full justify-center items-center").children(Domino2.of("svg", Domino2.SVG).classNames(mx4("w-4 h-4 cursor-pointer", open && "rotate-90")).children(Domino2.of("use", Domino2.SVG).attributes({
2927
3028
  href: Domino2.icon("ph--caret-right--regular")
2928
3029
  }))).root;
2929
3030
  }
2930
3031
  }),
2931
- EditorView16.theme({
3032
+ EditorView17.theme({
2932
3033
  ".cm-foldGutter": {
2933
3034
  opacity: 0.3,
2934
3035
  transition: "opacity 0.3s",
@@ -2942,7 +3043,7 @@ var folding = () => {
2942
3043
  };
2943
3044
 
2944
3045
  // src/extensions/hashtag.ts
2945
- import { Decoration as Decoration8, EditorView as EditorView17, MatchDecorator, ViewPlugin as ViewPlugin12, WidgetType as WidgetType4 } from "@codemirror/view";
3046
+ import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
2946
3047
  import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
2947
3048
  var TagWidget = class extends WidgetType4 {
2948
3049
  _text;
@@ -2963,7 +3064,7 @@ var tagMatcher = new MatchDecorator({
2963
3064
  })
2964
3065
  });
2965
3066
  var hashtag = () => [
2966
- ViewPlugin12.fromClass(class {
3067
+ ViewPlugin13.fromClass(class {
2967
3068
  tags;
2968
3069
  constructor(view) {
2969
3070
  this.tags = tagMatcher.createDeco(view);
@@ -2973,11 +3074,11 @@ var hashtag = () => [
2973
3074
  }
2974
3075
  }, {
2975
3076
  decorations: (instance) => instance.tags,
2976
- provide: (plugin) => EditorView17.atomicRanges.of((view) => {
3077
+ provide: (plugin) => EditorView18.atomicRanges.of((view) => {
2977
3078
  return view.plugin(plugin)?.tags || Decoration8.none;
2978
3079
  })
2979
3080
  }),
2980
- EditorView17.theme({
3081
+ EditorView18.theme({
2981
3082
  ".cm-tag": {
2982
3083
  borderRadius: "4px",
2983
3084
  marginRight: "6px",
@@ -3032,18 +3133,18 @@ var schemaLinter = (validate) => (view) => {
3032
3133
  };
3033
3134
 
3034
3135
  // src/extensions/listener.ts
3035
- import { EditorView as EditorView18 } from "@codemirror/view";
3136
+ import { EditorView as EditorView19 } from "@codemirror/view";
3036
3137
  import { isNonNullable as isNonNullable2 } from "@dxos/util";
3037
3138
  var listener = ({ onFocus, onChange }) => {
3038
3139
  return [
3039
- onFocus && EditorView18.focusChangeEffect.of((state, focusing) => {
3140
+ onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
3040
3141
  onFocus({
3041
3142
  id: state.facet(documentId),
3042
3143
  focusing
3043
3144
  });
3044
3145
  return null;
3045
3146
  }),
3046
- onChange && EditorView18.updateListener.of(({ state, docChanged }) => {
3147
+ onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
3047
3148
  if (docChanged) {
3048
3149
  onChange({
3049
3150
  id: state.facet(documentId),
@@ -3058,7 +3159,7 @@ var listener = ({ onFocus, onChange }) => {
3058
3159
  import { snippet } from "@codemirror/autocomplete";
3059
3160
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3060
3161
  import { EditorSelection as EditorSelection2 } from "@codemirror/state";
3061
- import { EditorView as EditorView19, keymap as keymap8 } from "@codemirror/view";
3162
+ import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
3062
3163
  import { debounceAndThrottle } from "@dxos/async";
3063
3164
  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;
3064
3165
  var Inline = /* @__PURE__ */ (function(Inline2) {
@@ -4147,7 +4248,7 @@ var getFormatting = (state) => {
4147
4248
  };
4148
4249
  };
4149
4250
  var formattingListener = (onStateChange, delay = 100) => {
4150
- return EditorView19.updateListener.of(debounceAndThrottle((update2) => {
4251
+ return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
4151
4252
  if (update2.docChanged || update2.selectionSet) {
4152
4253
  onStateChange(getFormatting(update2.state));
4153
4254
  }
@@ -4208,8 +4309,7 @@ import { completionKeymap } from "@codemirror/autocomplete";
4208
4309
  import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
4209
4310
  import { jsonLanguage } from "@codemirror/lang-json";
4210
4311
  import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
4211
- import { xml } from "@codemirror/lang-xml";
4212
- import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
4312
+ import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
4213
4313
  import { languages } from "@codemirror/language-data";
4214
4314
  import { keymap as keymap9 } from "@codemirror/view";
4215
4315
  import { isTruthy as isTruthy3 } from "@dxos/util";
@@ -4330,30 +4430,38 @@ var markdownHighlightStyle = (_options = {}) => {
4330
4430
  ],
4331
4431
  class: "font-mono"
4332
4432
  },
4333
- // Headings.
4433
+ // Headings — use CSS properties only (no class:) so CodeMirror generates scoped CSS via
4434
+ // StyleModule that overrides vscodeDarkStyle's t.heading rule. When class: is present,
4435
+ // HighlightStyle silently ignores all other CSS properties (they're mutually exclusive).
4436
+ // Font sizes use Tailwind v4 CSS variables so nothing is hardcoded.
4437
+ {
4438
+ tag: tags.heading,
4439
+ color: "var(--color-cm-heading) !important",
4440
+ fontWeight: "300"
4441
+ },
4334
4442
  {
4335
4443
  tag: tags.heading1,
4336
- class: markdownTheme.heading(1)
4444
+ ...markdownTheme.heading(1)
4337
4445
  },
4338
4446
  {
4339
4447
  tag: tags.heading2,
4340
- class: markdownTheme.heading(2)
4448
+ ...markdownTheme.heading(2)
4341
4449
  },
4342
4450
  {
4343
4451
  tag: tags.heading3,
4344
- class: markdownTheme.heading(3)
4452
+ ...markdownTheme.heading(3)
4345
4453
  },
4346
4454
  {
4347
4455
  tag: tags.heading4,
4348
- class: markdownTheme.heading(4)
4456
+ ...markdownTheme.heading(4)
4349
4457
  },
4350
4458
  {
4351
4459
  tag: tags.heading5,
4352
- class: markdownTheme.heading(5)
4460
+ ...markdownTheme.heading(5)
4353
4461
  },
4354
4462
  {
4355
4463
  tag: tags.heading6,
4356
- class: markdownTheme.heading(6)
4464
+ ...markdownTheme.heading(6)
4357
4465
  },
4358
4466
  // Emphasis.
4359
4467
  {
@@ -4408,15 +4516,23 @@ var createMarkdownExtensions = (options = {}) => {
4408
4516
  // https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
4409
4517
  base: markdownLanguage2,
4410
4518
  // Languages for syntax highlighting fenced code blocks.
4519
+ // Caller-supplied languages are checked first so they can override defaults.
4411
4520
  defaultCodeLanguage: jsonLanguage,
4412
- codeLanguages: languages,
4521
+ codeLanguages: [
4522
+ ...options.codeLanguages ?? [],
4523
+ ...languages
4524
+ ],
4413
4525
  // Don't complete HTML tags.
4414
4526
  completeHTMLTags: false,
4415
4527
  // Parser extensions.
4416
4528
  extensions: [
4417
4529
  // GFM provided by default.
4418
4530
  markdownTagsExtensions,
4419
- ...options.extensions ?? defaultExtensions()
4531
+ ...options.extensions ?? defaultExtensions(),
4532
+ // Disable folding for fenced code blocks by overriding foldNodeProp.
4533
+ // Note: returning null from foldService does not prevent syntaxFolding fallback,
4534
+ // so we must override the node prop directly on the FencedCode node type.
4535
+ noFencedCodeFolding
4420
4536
  ]
4421
4537
  }),
4422
4538
  // Custom styles.
@@ -4431,18 +4547,13 @@ var createMarkdownExtensions = (options = {}) => {
4431
4547
  ].filter(isTruthy3))
4432
4548
  ];
4433
4549
  };
4434
- var xmlLanguageDesc = LanguageDescription.of({
4435
- name: "xml",
4436
- alias: [
4437
- "html",
4438
- "xhtml"
4439
- ],
4440
- extensions: [
4441
- "xml",
4442
- "xhtml"
4443
- ],
4444
- load: async () => xml()
4445
- });
4550
+ var noFencedCodeFolding = {
4551
+ props: [
4552
+ foldNodeProp.add({
4553
+ FencedCode: () => null
4554
+ })
4555
+ ]
4556
+ };
4446
4557
  var defaultExtensions = () => [
4447
4558
  noSetExtHeading,
4448
4559
  noHtml
@@ -4483,17 +4594,16 @@ var convertTreeToJson = (state) => {
4483
4594
 
4484
4595
  // src/extensions/markdown/decorate.ts
4485
4596
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4486
- import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
4487
- import { Decoration as Decoration11, EditorView as EditorView23, ViewPlugin as ViewPlugin14, WidgetType as WidgetType7 } from "@codemirror/view";
4597
+ import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect6 } from "@codemirror/state";
4598
+ import { Decoration as Decoration11, EditorView as EditorView24, ViewPlugin as ViewPlugin15, WidgetType as WidgetType7 } from "@codemirror/view";
4488
4599
  import { invariant as invariant4 } from "@dxos/invariant";
4489
- import { mx as mx6 } from "@dxos/ui-theme";
4490
4600
 
4491
4601
  // src/extensions/markdown/changes.ts
4492
4602
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4493
4603
  import { Transaction as Transaction4 } from "@codemirror/state";
4494
- import { ViewPlugin as ViewPlugin13 } from "@codemirror/view";
4604
+ import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
4495
4605
  var adjustChanges = () => {
4496
- return ViewPlugin13.fromClass(class {
4606
+ return ViewPlugin14.fromClass(class {
4497
4607
  update(update2) {
4498
4608
  const tree = syntaxTree4(update2.state);
4499
4609
  const adjustments = [];
@@ -4635,7 +4745,7 @@ var getValidUrl = (str) => {
4635
4745
  // src/extensions/markdown/image.ts
4636
4746
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4637
4747
  import { StateField as StateField7 } from "@codemirror/state";
4638
- import { Decoration as Decoration9, EditorView as EditorView20, WidgetType as WidgetType5 } from "@codemirror/view";
4748
+ import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
4639
4749
  var image = (_options = {}) => {
4640
4750
  return [
4641
4751
  StateField7.define({
@@ -4663,7 +4773,7 @@ var image = (_options = {}) => {
4663
4773
  add: buildDecorations(tr.state, from, to)
4664
4774
  });
4665
4775
  },
4666
- provide: (field) => EditorView20.decorations.from(field)
4776
+ provide: (field) => EditorView21.decorations.from(field)
4667
4777
  })
4668
4778
  ];
4669
4779
  };
@@ -4723,10 +4833,10 @@ var ImageWidget = class extends WidgetType5 {
4723
4833
  };
4724
4834
 
4725
4835
  // src/extensions/markdown/styles.ts
4726
- import { EditorView as EditorView21 } from "@codemirror/view";
4836
+ import { EditorView as EditorView22 } from "@codemirror/view";
4727
4837
  var bulletListIndentationWidth = 24;
4728
4838
  var orderedListIndentationWidth = 36;
4729
- var formattingStyles = EditorView21.theme({
4839
+ var formattingStyles = EditorView22.theme({
4730
4840
  /**
4731
4841
  * Horizontal rule.
4732
4842
  */
@@ -4735,7 +4845,7 @@ var formattingStyles = EditorView21.theme({
4735
4845
  width: "100%",
4736
4846
  height: "0",
4737
4847
  verticalAlign: "middle",
4738
- borderTop: "1px solid var(--dx-cmSeparator)",
4848
+ borderTop: "1px solid var(--color-cm-separator)",
4739
4849
  opacity: 0.5
4740
4850
  },
4741
4851
  /**
@@ -4758,19 +4868,44 @@ var formattingStyles = EditorView21.theme({
4758
4868
  * Blockquote.
4759
4869
  */
4760
4870
  "& .cm-blockquote": {
4761
- background: "var(--dx-cmCodeblock)",
4762
- borderLeft: "2px solid var(--dx-cmSeparator)",
4871
+ background: "var(--color-cm-codeblock)",
4872
+ borderLeft: "2px solid var(--color-cm-separator)",
4763
4873
  paddingLeft: "1rem",
4764
- margin: "0"
4874
+ margin: 0
4765
4875
  },
4766
4876
  /**
4767
4877
  * Code and codeblocks.
4768
4878
  */
4879
+ "& code": {
4880
+ fontFamily: fontMono,
4881
+ whiteSpace: "nowrap",
4882
+ color: "var(--color-cm-code)"
4883
+ },
4769
4884
  "& .cm-code": {
4770
- fontFamily: fontMono
4885
+ fontFamily: fontMono,
4886
+ whiteSpace: "nowrap",
4887
+ color: "var(--color-cm-code)"
4888
+ },
4889
+ // Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.
4890
+ // Different monospace font metrics can slightly overflow the fixed CodeMirror line box,
4891
+ // so constrain them to the target 24px height.
4892
+ "& .cm-code-inline": {
4893
+ fontFamily: fontMono,
4894
+ height: "24px",
4895
+ display: "inline-flex",
4896
+ alignItems: "center",
4897
+ overflow: "hidden",
4898
+ color: "var(--color-cm-code)"
4899
+ },
4900
+ "& .cm-code-mark": {
4901
+ fontFamily: fontMono,
4902
+ height: "24px",
4903
+ display: "inline-flex",
4904
+ alignItems: "center",
4905
+ overflow: "hidden"
4771
4906
  },
4772
4907
  "& .cm-codeblock-line": {
4773
- background: "var(--dx-cmCodeblock)",
4908
+ background: "var(--color-cm-codeblock)",
4774
4909
  paddingInline: "1rem !important"
4775
4910
  },
4776
4911
  "& .cm-codeblock-start": {
@@ -4799,16 +4934,18 @@ var formattingStyles = EditorView21.theme({
4799
4934
  */
4800
4935
  ".cm-table *": {
4801
4936
  fontFamily: fontMono,
4937
+ lineHeight: 1.5,
4802
4938
  textDecoration: "none !important"
4803
4939
  },
4804
4940
  ".cm-table-head": {
4805
4941
  padding: "2px 16px 2px 0px",
4806
4942
  textAlign: "left",
4807
- borderBottom: "1px solid var(--dx-cmSeparator)",
4808
- color: "var(--dx-subdued)"
4943
+ borderBottom: "1px solid var(--color-cm-separator)",
4944
+ color: "var(--color-subdued)"
4809
4945
  },
4810
4946
  ".cm-table-cell": {
4811
- padding: "2px 16px 2px 0px"
4947
+ padding: "2px 16px 2px 0px",
4948
+ verticalAlign: "top"
4812
4949
  },
4813
4950
  /**
4814
4951
  * Image.
@@ -4824,12 +4961,12 @@ var formattingStyles = EditorView21.theme({
4824
4961
  },
4825
4962
  ".cm-image-with-loader": {
4826
4963
  display: "block",
4827
- opacity: "0",
4964
+ opacity: 0,
4828
4965
  transitionDuration: "350ms",
4829
4966
  transitionProperty: "opacity"
4830
4967
  },
4831
4968
  ".cm-image-with-loader.cm-loaded-image": {
4832
- opacity: "1"
4969
+ opacity: 1
4833
4970
  },
4834
4971
  ".cm-image-wrapper": {
4835
4972
  "grid-template-columns": "1fr",
@@ -4848,12 +4985,12 @@ var formattingStyles = EditorView21.theme({
4848
4985
  // src/extensions/markdown/table.ts
4849
4986
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4850
4987
  import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
4851
- import { Decoration as Decoration10, EditorView as EditorView22, WidgetType as WidgetType6 } from "@codemirror/view";
4988
+ import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
4852
4989
  var table = (options = {}) => {
4853
4990
  return StateField8.define({
4854
4991
  create: (state) => update(state, options),
4855
4992
  update: (_, tr) => update(tr.state, options),
4856
- provide: (field) => EditorView22.decorations.from(field)
4993
+ provide: (field) => EditorView23.decorations.from(field)
4857
4994
  });
4858
4995
  };
4859
4996
  var update = (state, _options) => {
@@ -4910,6 +5047,26 @@ var update = (state, _options) => {
4910
5047
  });
4911
5048
  return builder.finish();
4912
5049
  };
5050
+ var renderCellContent = (el, text) => {
5051
+ const parts = text.split(/(`[^`\n]+`|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/);
5052
+ for (const part of parts) {
5053
+ if (part.length > 2 && part.startsWith("`") && part.endsWith("`")) {
5054
+ const code = document.createElement("code");
5055
+ code.textContent = part.slice(1, -1);
5056
+ el.appendChild(code);
5057
+ } else if (part.startsWith("**") && part.endsWith("**") || part.startsWith("__") && part.endsWith("__")) {
5058
+ const strong = document.createElement("strong");
5059
+ strong.textContent = part.slice(2, -2);
5060
+ el.appendChild(strong);
5061
+ } else if (part.startsWith("*") && part.endsWith("*") || part.startsWith("_") && part.endsWith("_")) {
5062
+ const em = document.createElement("em");
5063
+ em.textContent = part.slice(1, -1);
5064
+ el.appendChild(em);
5065
+ } else {
5066
+ el.appendChild(document.createTextNode(part));
5067
+ }
5068
+ }
5069
+ };
4913
5070
  var TableWidget = class extends WidgetType6 {
4914
5071
  _table;
4915
5072
  constructor(_table) {
@@ -4929,7 +5086,7 @@ var TableWidget = class extends WidgetType6 {
4929
5086
  this._table.header?.forEach((cell) => {
4930
5087
  const th = document.createElement("th");
4931
5088
  th.setAttribute("class", "cm-table-head");
4932
- tr.appendChild(th).textContent = cell;
5089
+ renderCellContent(tr.appendChild(th), cell);
4933
5090
  });
4934
5091
  const body = table2.appendChild(document.createElement("tbody"));
4935
5092
  this._table.rows?.forEach((row) => {
@@ -4937,7 +5094,7 @@ var TableWidget = class extends WidgetType6 {
4937
5094
  row.forEach((cell) => {
4938
5095
  const td = document.createElement("td");
4939
5096
  td.setAttribute("class", "cm-table-cell");
4940
- tr2.appendChild(td).textContent = cell;
5097
+ renderCellContent(tr2.appendChild(td), cell);
4941
5098
  });
4942
5099
  });
4943
5100
  return div;
@@ -4945,7 +5102,7 @@ var TableWidget = class extends WidgetType6 {
4945
5102
  };
4946
5103
 
4947
5104
  // src/extensions/markdown/decorate.ts
4948
- var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/markdown/decorate.ts";
5105
+ var __dxlog_file12 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/markdown/decorate.ts";
4949
5106
  var Unicode = {
4950
5107
  emDash: "\u2014",
4951
5108
  bullet: "\u2022",
@@ -4968,7 +5125,6 @@ var LinkButton = class extends WidgetType7 {
4968
5125
  eq(other) {
4969
5126
  return this.url === other.url;
4970
5127
  }
4971
- // TODO(burdon): Create icon and link directly without react?
4972
5128
  toDOM(view) {
4973
5129
  const el = document.createElement("span");
4974
5130
  this.render(el, {
@@ -5045,10 +5201,10 @@ var fencedCodeLine = Decoration11.line({
5045
5201
  class: "cm-code cm-codeblock-line"
5046
5202
  });
5047
5203
  var fencedCodeLineFirst = Decoration11.line({
5048
- class: mx6("cm-code cm-codeblock-line", "cm-codeblock-start")
5204
+ class: "cm-code cm-codeblock-line cm-codeblock-start"
5049
5205
  });
5050
5206
  var fencedCodeLineLast = Decoration11.line({
5051
- class: mx6("cm-code cm-codeblock-line", "cm-codeblock-end")
5207
+ class: "cm-code cm-codeblock-line cm-codeblock-end"
5052
5208
  });
5053
5209
  var commentBlockLine = fencedCodeLine;
5054
5210
  var commentBlockLineFirst = fencedCodeLineFirst;
@@ -5081,8 +5237,8 @@ var buildDecorations2 = (view, options, focus2) => {
5081
5237
  const headerLevels = [];
5082
5238
  const getHeaderLevels = (node, level) => {
5083
5239
  invariant4(level > 0, void 0, {
5084
- F: __dxlog_file11,
5085
- L: 180,
5240
+ F: __dxlog_file12,
5241
+ L: 178,
5086
5242
  S: void 0,
5087
5243
  A: [
5088
5244
  "level > 0",
@@ -5120,8 +5276,8 @@ var buildDecorations2 = (view, options, focus2) => {
5120
5276
  };
5121
5277
  const getCurrentListLevel = () => {
5122
5278
  invariant4(listLevels.length, void 0, {
5123
- F: __dxlog_file11,
5124
- L: 202,
5279
+ F: __dxlog_file12,
5280
+ L: 200,
5125
5281
  S: void 0,
5126
5282
  A: [
5127
5283
  "listLevels.length",
@@ -5165,13 +5321,13 @@ var buildDecorations2 = (view, options, focus2) => {
5165
5321
  deco: hide
5166
5322
  });
5167
5323
  } else {
5168
- const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
5324
+ const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + "). ";
5169
5325
  if (num.length) {
5170
5326
  atomicDecoRanges.push({
5171
5327
  from: mark.from,
5172
5328
  to: mark.from + len,
5173
5329
  deco: Decoration11.replace({
5174
- widget: new TextWidget(num, markdownTheme.heading(level))
5330
+ widget: new TextWidget(num, markdownTheme.heading(level).className)
5175
5331
  })
5176
5332
  });
5177
5333
  }
@@ -5348,11 +5504,11 @@ var buildDecorations2 = (view, options, focus2) => {
5348
5504
  }
5349
5505
  decoRanges.push({
5350
5506
  from: marks[0].to,
5351
- to: marks[1].from,
5507
+ to: !editing && options.renderLinkButton ? node.to : marks[1].from,
5352
5508
  deco: Decoration11.mark({
5353
5509
  tagName: "a",
5354
5510
  attributes: {
5355
- class: "cm-link",
5511
+ class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
5356
5512
  href: url,
5357
5513
  rel: "noreferrer",
5358
5514
  target: "_blank"
@@ -5430,18 +5586,21 @@ var buildDecorations2 = (view, options, focus2) => {
5430
5586
  deco.add(from, to, d);
5431
5587
  }
5432
5588
  const atomicDeco = new RangeSetBuilder5();
5433
- for (const { from, to, deco: d } of atomicDecoRanges) {
5434
- atomicDeco.add(from, to, d);
5589
+ for (const { from, to, deco: deco2 } of atomicDecoRanges) {
5590
+ if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {
5591
+ continue;
5592
+ }
5593
+ atomicDeco.add(from, to, deco2);
5435
5594
  }
5436
5595
  return {
5437
5596
  deco: deco.finish(),
5438
5597
  atomicDeco: atomicDeco.finish()
5439
5598
  };
5440
5599
  };
5441
- var forceUpdate = StateEffect7.define();
5600
+ var forceUpdate = StateEffect6.define();
5442
5601
  var decorateMarkdown = (options = {}) => {
5443
5602
  return [
5444
- ViewPlugin14.fromClass(class {
5603
+ ViewPlugin15.fromClass(class {
5445
5604
  deco;
5446
5605
  atomicDeco;
5447
5606
  pendingUpdate;
@@ -5476,9 +5635,9 @@ var decorateMarkdown = (options = {}) => {
5476
5635
  }
5477
5636
  }, {
5478
5637
  provide: (plugin) => [
5479
- Prec4.low(EditorView23.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
5480
- EditorView23.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
5481
- EditorView23.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
5638
+ Prec4.low(EditorView24.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
5639
+ EditorView24.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
5640
+ EditorView24.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
5482
5641
  ]
5483
5642
  }),
5484
5643
  image(),
@@ -5510,8 +5669,7 @@ var linkTooltip = (renderTooltip) => {
5510
5669
  return {
5511
5670
  pos: link.from,
5512
5671
  end: link.to,
5513
- // NOTE: Forcing above causes the tooltip to flicker.
5514
- // above: true,
5672
+ above: true,
5515
5673
  create: () => {
5516
5674
  const el = document.createElement("div");
5517
5675
  el.className = tooltipContent({});
@@ -5527,16 +5685,13 @@ var linkTooltip = (renderTooltip) => {
5527
5685
  };
5528
5686
  }
5529
5687
  };
5530
- }, {
5531
- // NOTE: 0 = default of 300ms.
5532
- hoverTime: 1
5533
5688
  });
5534
5689
  };
5535
5690
 
5536
5691
  // src/extensions/mention.ts
5537
5692
  import { autocompletion } from "@codemirror/autocomplete";
5538
- import { log as log8 } from "@dxos/log";
5539
- var __dxlog_file12 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/mention.ts";
5693
+ import { log as log9 } from "@dxos/log";
5694
+ var __dxlog_file13 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/mention.ts";
5540
5695
  var mention = ({ debug, onSearch }) => {
5541
5696
  return autocompletion({
5542
5697
  // TODO(burdon): Not working.
@@ -5548,10 +5703,10 @@ var mention = ({ debug, onSearch }) => {
5548
5703
  icons: false,
5549
5704
  override: [
5550
5705
  (context) => {
5551
- log8.info("completion context", {
5706
+ log9.info("completion context", {
5552
5707
  context
5553
5708
  }, {
5554
- F: __dxlog_file12,
5709
+ F: __dxlog_file13,
5555
5710
  L: 27,
5556
5711
  S: void 0,
5557
5712
  C: (f, a) => f(...a)
@@ -5572,8 +5727,8 @@ var mention = ({ debug, onSearch }) => {
5572
5727
  };
5573
5728
 
5574
5729
  // src/extensions/modal.ts
5575
- import { StateEffect as StateEffect8, StateField as StateField9 } from "@codemirror/state";
5576
- var modalStateEffect = StateEffect8.define();
5730
+ import { StateEffect as StateEffect7, StateField as StateField9 } from "@codemirror/state";
5731
+ var modalStateEffect = StateEffect7.define();
5577
5732
  var modalStateField = StateField9.define({
5578
5733
  create: () => false,
5579
5734
  update: (value, tr) => {
@@ -5634,7 +5789,7 @@ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5634
5789
  import { StateField as StateField10 } from "@codemirror/state";
5635
5790
  import { Facet as Facet2 } from "@codemirror/state";
5636
5791
  import { invariant as invariant5 } from "@dxos/invariant";
5637
- var __dxlog_file13 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/tree.ts";
5792
+ var __dxlog_file14 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/tree.ts";
5638
5793
  var itemToJSON = ({ type, index, level, lineRange, contentRange, children }) => {
5639
5794
  return {
5640
5795
  type,
@@ -5789,7 +5944,7 @@ var outlinerTree = (_options = {}) => {
5789
5944
  }
5790
5945
  case "BulletList": {
5791
5946
  invariant5(current, void 0, {
5792
- F: __dxlog_file13,
5947
+ F: __dxlog_file14,
5793
5948
  L: 219,
5794
5949
  S: void 0,
5795
5950
  A: [
@@ -5806,7 +5961,7 @@ var outlinerTree = (_options = {}) => {
5806
5961
  }
5807
5962
  case "ListItem": {
5808
5963
  invariant5(parent, void 0, {
5809
- F: __dxlog_file13,
5964
+ F: __dxlog_file14,
5810
5965
  L: 228,
5811
5966
  S: void 0,
5812
5967
  A: [
@@ -5848,7 +6003,7 @@ var outlinerTree = (_options = {}) => {
5848
6003
  }
5849
6004
  case "ListMark": {
5850
6005
  invariant5(current, void 0, {
5851
- F: __dxlog_file13,
6006
+ F: __dxlog_file14,
5852
6007
  L: 272,
5853
6008
  S: void 0,
5854
6009
  A: [
@@ -5862,7 +6017,7 @@ var outlinerTree = (_options = {}) => {
5862
6017
  }
5863
6018
  case "Task": {
5864
6019
  invariant5(current, void 0, {
5865
- F: __dxlog_file13,
6020
+ F: __dxlog_file14,
5866
6021
  L: 278,
5867
6022
  S: void 0,
5868
6023
  A: [
@@ -5875,7 +6030,7 @@ var outlinerTree = (_options = {}) => {
5875
6030
  }
5876
6031
  case "TaskMarker": {
5877
6032
  invariant5(current, void 0, {
5878
- F: __dxlog_file13,
6033
+ F: __dxlog_file14,
5879
6034
  L: 283,
5880
6035
  S: void 0,
5881
6036
  A: [
@@ -5891,7 +6046,7 @@ var outlinerTree = (_options = {}) => {
5891
6046
  leave: (node) => {
5892
6047
  if (node.name === "BulletList") {
5893
6048
  invariant5(parent, void 0, {
5894
- F: __dxlog_file13,
6049
+ F: __dxlog_file14,
5895
6050
  L: 291,
5896
6051
  S: void 0,
5897
6052
  A: [
@@ -5905,7 +6060,7 @@ var outlinerTree = (_options = {}) => {
5905
6060
  }
5906
6061
  });
5907
6062
  invariant5(tree, void 0, {
5908
- F: __dxlog_file13,
6063
+ F: __dxlog_file14,
5909
6064
  L: 298,
5910
6065
  S: void 0,
5911
6066
  A: [
@@ -6197,17 +6352,17 @@ var commands = () => keymap11.of([
6197
6352
 
6198
6353
  // src/extensions/outliner/outliner.ts
6199
6354
  import { Prec as Prec5 } from "@codemirror/state";
6200
- import { Decoration as Decoration12, EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
6201
- import { mx as mx7 } from "@dxos/ui-theme";
6355
+ import { Decoration as Decoration12, EditorView as EditorView26, ViewPlugin as ViewPlugin18 } from "@codemirror/view";
6356
+ import { mx as mx6 } from "@dxos/ui-theme";
6202
6357
 
6203
6358
  // src/extensions/outliner/editor.ts
6204
6359
  import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
6205
- import { ViewPlugin as ViewPlugin15 } from "@codemirror/view";
6206
- import { log as log9 } from "@dxos/log";
6207
- var __dxlog_file14 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
6360
+ import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
6361
+ import { log as log10 } from "@dxos/log";
6362
+ var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
6208
6363
  var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
6209
6364
  var initialize = () => {
6210
- return ViewPlugin15.fromClass(class {
6365
+ return ViewPlugin16.fromClass(class {
6211
6366
  constructor(view) {
6212
6367
  const first = view.state.doc.lineAt(0);
6213
6368
  const text = view.state.sliceDoc(first.from, first.to);
@@ -6336,7 +6491,7 @@ var editor = () => [
6336
6491
  cancel = true;
6337
6492
  return;
6338
6493
  }
6339
- log9("change", {
6494
+ log10("change", {
6340
6495
  item,
6341
6496
  line: {
6342
6497
  from: line.from,
@@ -6355,7 +6510,7 @@ var editor = () => [
6355
6510
  length: insert.length
6356
6511
  }
6357
6512
  }, {
6358
- F: __dxlog_file14,
6513
+ F: __dxlog_file15,
6359
6514
  L: 164,
6360
6515
  S: void 0,
6361
6516
  C: (f, a) => f(...a)
@@ -6363,10 +6518,10 @@ var editor = () => [
6363
6518
  }
6364
6519
  });
6365
6520
  if (changes.length > 0) {
6366
- log9("modified,", {
6521
+ log10("modified,", {
6367
6522
  changes
6368
6523
  }, {
6369
- F: __dxlog_file14,
6524
+ F: __dxlog_file15,
6370
6525
  L: 175,
6371
6526
  S: void 0,
6372
6527
  C: (f, a) => f(...a)
@@ -6377,8 +6532,8 @@ var editor = () => [
6377
6532
  }
6378
6533
  ];
6379
6534
  } else if (cancel) {
6380
- log9("cancel", void 0, {
6381
- F: __dxlog_file14,
6535
+ log10("cancel", void 0, {
6536
+ F: __dxlog_file15,
6382
6537
  L: 178,
6383
6538
  S: void 0,
6384
6539
  C: (f, a) => f(...a)
@@ -6390,10 +6545,10 @@ var editor = () => [
6390
6545
  ];
6391
6546
 
6392
6547
  // src/extensions/outliner/menu.ts
6393
- import { EditorView as EditorView24, ViewPlugin as ViewPlugin16 } from "@codemirror/view";
6394
- import { addEventListener } from "@dxos/async";
6548
+ import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
6549
+ import { addEventListener as addEventListener2 } from "@dxos/async";
6395
6550
  var menu = (options = {}) => [
6396
- ViewPlugin16.fromClass(class {
6551
+ ViewPlugin17.fromClass(class {
6397
6552
  view;
6398
6553
  tag;
6399
6554
  rafId;
@@ -6413,7 +6568,7 @@ var menu = (options = {}) => [
6413
6568
  }
6414
6569
  container.appendChild(this.tag);
6415
6570
  const handler = () => this.scheduleUpdate();
6416
- this.cleanup = addEventListener(container, "scroll", handler);
6571
+ this.cleanup = addEventListener2(container, "scroll", handler);
6417
6572
  this.scheduleUpdate();
6418
6573
  }
6419
6574
  destroy() {
@@ -6455,7 +6610,7 @@ var menu = (options = {}) => [
6455
6610
  this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
6456
6611
  }
6457
6612
  }),
6458
- EditorView24.theme({
6613
+ EditorView25.theme({
6459
6614
  ".cm-popover-trigger": {
6460
6615
  position: "fixed",
6461
6616
  padding: "0",
@@ -6491,12 +6646,12 @@ var outliner = (_options = {}) => [
6491
6646
  listPaddingLeft: 8
6492
6647
  }),
6493
6648
  // Researve space for menu.
6494
- EditorView25.contentAttributes.of({
6495
- class: "is-full !mr-[3rem]"
6649
+ EditorView26.contentAttributes.of({
6650
+ class: "w-full !mr-[3rem]"
6496
6651
  })
6497
6652
  ];
6498
6653
  var decorations = () => [
6499
- ViewPlugin17.fromClass(class {
6654
+ ViewPlugin18.fromClass(class {
6500
6655
  decorations = Decoration12.none;
6501
6656
  constructor(view) {
6502
6657
  this.updateDecorations(view.state, view);
@@ -6521,7 +6676,7 @@ var decorations = () => [
6521
6676
  const lineTo = doc.lineAt(item.contentRange.to);
6522
6677
  const isSelected = selection.includes(item.index) || item === current;
6523
6678
  decorations2.push(Decoration12.line({
6524
- class: mx7("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"))
6679
+ 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"))
6525
6680
  }).range(line.from, line.from));
6526
6681
  }
6527
6682
  }
@@ -6531,7 +6686,7 @@ var decorations = () => [
6531
6686
  decorations: (v) => v.decorations
6532
6687
  }),
6533
6688
  // Theme.
6534
- EditorView25.theme(Object.assign({
6689
+ EditorView26.theme(Object.assign({
6535
6690
  ".cm-list-item": {
6536
6691
  borderLeftWidth: "1px",
6537
6692
  borderRightWidth: "1px",
@@ -6556,38 +6711,67 @@ var decorations = () => [
6556
6711
  marginBottom: "2px"
6557
6712
  },
6558
6713
  ".cm-list-item-focused": {
6559
- borderColor: "var(--dx-neutralFocusIndicator)"
6714
+ borderColor: "var(--color-neutral-focus-indicator)"
6560
6715
  },
6561
6716
  "&:focus-within .cm-list-item-selected": {
6562
- borderColor: "var(--dx-separator)"
6717
+ borderColor: "var(--color-separator)"
6563
6718
  }
6564
6719
  }))
6565
6720
  ];
6566
6721
 
6567
6722
  // src/extensions/preview/preview.ts
6568
6723
  import { syntaxTree as syntaxTree10 } from "@codemirror/language";
6569
- import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
6570
- import { Decoration as Decoration13, EditorView as EditorView26, WidgetType as WidgetType8 } from "@codemirror/view";
6724
+ import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect8, StateField as StateField11 } from "@codemirror/state";
6725
+ import { Decoration as Decoration13, EditorView as EditorView27, ViewPlugin as ViewPlugin19, WidgetType as WidgetType8 } from "@codemirror/view";
6726
+ import { DXN, Entity } from "@dxos/echo";
6727
+ var labelResolvedEffect = StateEffect8.define();
6571
6728
  var preview = (options = {}) => {
6729
+ const viewRef = {
6730
+ current: void 0
6731
+ };
6572
6732
  return [
6573
6733
  // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
6574
6734
  // "Block decorations may not be specified via plugins".
6575
6735
  StateField11.define({
6576
- create: (state) => buildDecorations3(state, options),
6736
+ create: (state) => buildDecorations3(state, options, viewRef),
6577
6737
  update: (decorations2, tr) => {
6578
- if (tr.docChanged) {
6579
- return buildDecorations3(tr.state, options);
6738
+ if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
6739
+ return buildDecorations3(tr.state, options, viewRef);
6580
6740
  }
6581
6741
  return decorations2.map(tr.changes);
6582
6742
  },
6583
6743
  provide: (field) => [
6584
- EditorView26.decorations.from(field),
6585
- EditorView26.atomicRanges.of((view) => view.state.field(field))
6744
+ EditorView27.decorations.from(field),
6745
+ EditorView27.atomicRanges.of((view) => view.state.field(field))
6586
6746
  ]
6747
+ }),
6748
+ ViewPlugin19.define((view) => {
6749
+ viewRef.current = view;
6750
+ return {
6751
+ destroy() {
6752
+ viewRef.current = void 0;
6753
+ }
6754
+ };
6587
6755
  })
6588
6756
  ];
6589
6757
  };
6590
- var buildDecorations3 = (state, options) => {
6758
+ var resolveLabel = (db, dxnStr, viewRef) => {
6759
+ const dxn = DXN.tryParse(dxnStr);
6760
+ if (!dxn) {
6761
+ return;
6762
+ }
6763
+ const ref = db.makeRef(dxn);
6764
+ const target = ref.target;
6765
+ if (target) {
6766
+ return Entity.getLabel(target);
6767
+ }
6768
+ void ref.tryLoad().then(() => {
6769
+ viewRef.current?.dispatch({
6770
+ effects: labelResolvedEffect.of(void 0)
6771
+ });
6772
+ });
6773
+ };
6774
+ var buildDecorations3 = (state, options, viewRef) => {
6591
6775
  const builder = new RangeSetBuilder6();
6592
6776
  syntaxTree10(state).iterate({
6593
6777
  enter: (node) => {
@@ -6599,8 +6783,13 @@ var buildDecorations3 = (state, options) => {
6599
6783
  case "Link": {
6600
6784
  const link = getLinkRef(state, node.node);
6601
6785
  if (link) {
6786
+ const resolved = options.db ? resolveLabel(options.db, link.dxn, viewRef) : void 0;
6787
+ const displayLink = resolved ? {
6788
+ ...link,
6789
+ label: resolved
6790
+ } : link;
6602
6791
  builder.add(node.from, node.to, Decoration13.replace({
6603
- widget: new PreviewInlineWidget(options, link),
6792
+ widget: new PreviewInlineWidget(options, displayLink),
6604
6793
  side: 1
6605
6794
  }));
6606
6795
  }
@@ -6631,13 +6820,13 @@ var getLinkRef = (state, node) => {
6631
6820
  const mark = node.getChildren("LinkMark");
6632
6821
  const urlNode = node.getChild("URL");
6633
6822
  if (mark && urlNode) {
6634
- const url = state.sliceDoc(urlNode.from, urlNode.to);
6635
- if (url.startsWith("dxn:")) {
6823
+ const dxn = state.sliceDoc(urlNode.from, urlNode.to);
6824
+ if (dxn.startsWith("dxn:")) {
6636
6825
  const label = state.sliceDoc(mark[0].to, mark[1].from);
6637
6826
  return {
6638
6827
  block: state.sliceDoc(mark[0].from, mark[0].from + 1) === "!",
6639
6828
  label,
6640
- ref: url
6829
+ dxn
6641
6830
  };
6642
6831
  }
6643
6832
  }
@@ -6652,13 +6841,13 @@ var PreviewInlineWidget = class extends WidgetType8 {
6652
6841
  // return false;
6653
6842
  // }
6654
6843
  eq(other) {
6655
- return this._link.ref === other._link.ref && this._link.label === other._link.label;
6844
+ return this._link.dxn === other._link.dxn && this._link.label === other._link.label;
6656
6845
  }
6657
6846
  toDOM(_view) {
6658
6847
  const root = document.createElement("dx-anchor");
6659
6848
  root.classList.add("dx-tag--anchor");
6660
6849
  root.textContent = this._link.label;
6661
- root.setAttribute("refId", this._link.ref);
6850
+ root.setAttribute("dxn", this._link.dxn);
6662
6851
  return root;
6663
6852
  }
6664
6853
  };
@@ -6672,11 +6861,11 @@ var PreviewBlockWidget = class extends WidgetType8 {
6672
6861
  // return true;
6673
6862
  // }
6674
6863
  eq(other) {
6675
- return this._link.ref === other._link.ref;
6864
+ return this._link.dxn === other._link.dxn;
6676
6865
  }
6677
6866
  toDOM(_view) {
6678
6867
  const root = document.createElement("div");
6679
- root.classList.add("cm-preview-block", "density-fine");
6868
+ root.classList.add("cm-preview-block", "dx-density-fine");
6680
6869
  this._options.addBlockContainer?.({
6681
6870
  link: this._link,
6682
6871
  el: root
@@ -6692,7 +6881,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
6692
6881
  };
6693
6882
 
6694
6883
  // src/extensions/replacer.ts
6695
- import { EditorView as EditorView27 } from "@codemirror/view";
6884
+ import { EditorView as EditorView28 } from "@codemirror/view";
6696
6885
  var defaultReplacements = [
6697
6886
  {
6698
6887
  input: "--",
@@ -6755,7 +6944,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
6755
6944
  const sortedReplacements = [
6756
6945
  ...replacements
6757
6946
  ].sort((a, b) => b.input.length - a.input.length);
6758
- return EditorView27.inputHandler.of((view, from, to, insert) => {
6947
+ return EditorView28.inputHandler.of((view, from, to, insert) => {
6759
6948
  if (insert.length !== 1) {
6760
6949
  return false;
6761
6950
  }
@@ -6892,7 +7081,7 @@ var mixedParser = (registry) => {
6892
7081
 
6893
7082
  // src/extensions/tags/streamer.ts
6894
7083
  import { StateEffect as StateEffect9, StateField as StateField12 } from "@codemirror/state";
6895
- import { Decoration as Decoration14, EditorView as EditorView28, ViewPlugin as ViewPlugin18, WidgetType as WidgetType9 } from "@codemirror/view";
7084
+ import { Decoration as Decoration14, EditorView as EditorView29, ViewPlugin as ViewPlugin20, WidgetType as WidgetType9 } from "@codemirror/view";
6896
7085
  import { Domino as Domino3 } from "@dxos/ui";
6897
7086
  import { isTruthy as isTruthy4 } from "@dxos/util";
6898
7087
  var BLINK_RATE = 2e3;
@@ -6918,7 +7107,7 @@ var cursor = () => {
6918
7107
  return value;
6919
7108
  }
6920
7109
  });
6921
- const timerPlugin = ViewPlugin18.fromClass(class {
7110
+ const timerPlugin = ViewPlugin20.fromClass(class {
6922
7111
  view;
6923
7112
  timer;
6924
7113
  constructor(view) {
@@ -6953,7 +7142,7 @@ var cursor = () => {
6953
7142
  }).range(endPos)
6954
7143
  ]);
6955
7144
  },
6956
- provide: (f) => EditorView28.decorations.from(f)
7145
+ provide: (f) => EditorView29.decorations.from(f)
6957
7146
  });
6958
7147
  return [
6959
7148
  showCursor,
@@ -6973,7 +7162,7 @@ var CursorWidget = class extends WidgetType9 {
6973
7162
  };
6974
7163
  var fadeIn = (options = {}) => {
6975
7164
  const FADE_IN_DURATION = 1e3;
6976
- const DEFAULT_REMOVAL_DELAY = 5e3;
7165
+ const DEFAULT_REMOVAL_DELAY = 3e3;
6977
7166
  const removalDelay = options.removalDelay ?? DEFAULT_REMOVAL_DELAY;
6978
7167
  const removeDecoration = StateEffect9.define();
6979
7168
  const fadeField = StateField12.define({
@@ -7017,9 +7206,9 @@ var fadeIn = (options = {}) => {
7017
7206
  add
7018
7207
  });
7019
7208
  },
7020
- provide: (f) => EditorView28.decorations.from(f)
7209
+ provide: (f) => EditorView29.decorations.from(f)
7021
7210
  });
7022
- const timerPlugin = ViewPlugin18.fromClass(class {
7211
+ const timerPlugin = ViewPlugin20.fromClass(class {
7023
7212
  view;
7024
7213
  // Map a simple key "from-to" to timer id.
7025
7214
  _timers = /* @__PURE__ */ new Map();
@@ -7061,7 +7250,7 @@ var fadeIn = (options = {}) => {
7061
7250
  return [
7062
7251
  fadeField,
7063
7252
  timerPlugin,
7064
- EditorView28.theme({
7253
+ EditorView29.theme({
7065
7254
  ".cm-line > span": {
7066
7255
  opacity: "0.8"
7067
7256
  },
@@ -7086,16 +7275,16 @@ var fadeIn = (options = {}) => {
7086
7275
  // src/extensions/tags/xml-tags.ts
7087
7276
  import { syntaxTree as syntaxTree11 } from "@codemirror/language";
7088
7277
  import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect10, StateField as StateField13 } from "@codemirror/state";
7089
- import { Decoration as Decoration15, EditorView as EditorView29, ViewPlugin as ViewPlugin19, WidgetType as WidgetType10, keymap as keymap13 } from "@codemirror/view";
7278
+ import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType10, keymap as keymap13 } from "@codemirror/view";
7090
7279
  import { invariant as invariant7 } from "@dxos/invariant";
7091
- import { log as log10 } from "@dxos/log";
7280
+ import { log as log11 } from "@dxos/log";
7092
7281
 
7093
7282
  // src/extensions/tags/xml-util.ts
7094
7283
  import { invariant as invariant6 } from "@dxos/invariant";
7095
- var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
7284
+ var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
7096
7285
  var nodeToJson = (state, node) => {
7097
7286
  invariant6(node.type.name === "Element", "Node is not an Element", {
7098
- F: __dxlog_file15,
7287
+ F: __dxlog_file16,
7099
7288
  L: 18,
7100
7289
  S: void 0,
7101
7290
  A: [
@@ -7159,7 +7348,7 @@ var nodeToJson = (state, node) => {
7159
7348
  };
7160
7349
 
7161
7350
  // src/extensions/tags/xml-tags.ts
7162
- var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
7351
+ var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
7163
7352
  var navigatePreviousEffect = StateEffect10.define();
7164
7353
  var navigateNextEffect = StateEffect10.define();
7165
7354
  var getXmlTextChild = (children) => {
@@ -7189,11 +7378,11 @@ var widgetStateMapStateField = StateField13.define({
7189
7378
  }
7190
7379
  if (effect.is(xmlTagUpdateEffect)) {
7191
7380
  const { id, value } = effect.value;
7192
- log10("widget updated", {
7381
+ log11("widget updated", {
7193
7382
  id,
7194
7383
  value
7195
7384
  }, {
7196
- F: __dxlog_file16,
7385
+ F: __dxlog_file17,
7197
7386
  L: 153,
7198
7387
  S: void 0,
7199
7388
  C: (f, a) => f(...a)
@@ -7224,11 +7413,11 @@ var createWidgetMap = (setWidgets) => {
7224
7413
  const widgets = /* @__PURE__ */ new Map();
7225
7414
  const notifier = {
7226
7415
  mounted: (state) => {
7227
- log10("widget mounted", {
7416
+ log11("widget mounted", {
7228
7417
  id: state.id,
7229
7418
  tag: state.props._tag
7230
7419
  }, {
7231
- F: __dxlog_file16,
7420
+ F: __dxlog_file17,
7232
7421
  L: 206,
7233
7422
  S: void 0,
7234
7423
  C: (f, a) => f(...a)
@@ -7240,11 +7429,11 @@ var createWidgetMap = (setWidgets) => {
7240
7429
  },
7241
7430
  unmounted: (id) => {
7242
7431
  const state = widgets.get(id);
7243
- log10("widget unmounted", {
7432
+ log11("widget unmounted", {
7244
7433
  id,
7245
7434
  tag: state?.props._tag
7246
7435
  }, {
7247
- F: __dxlog_file16,
7436
+ F: __dxlog_file17,
7248
7437
  L: 212,
7249
7438
  S: void 0,
7250
7439
  C: (f, a) => f(...a)
@@ -7278,7 +7467,7 @@ var keyHandlers = keymap13.of([
7278
7467
  }
7279
7468
  ]);
7280
7469
  var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
7281
- return EditorView29.updateListener.of((update2) => {
7470
+ return EditorView30.updateListener.of((update2) => {
7282
7471
  update2.transactions.forEach((transaction) => {
7283
7472
  for (const effect of transaction.effects) {
7284
7473
  if (effect.is(navigatePreviousEffect)) {
@@ -7306,11 +7495,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
7306
7495
  anchor: line.from,
7307
7496
  head: line.from
7308
7497
  },
7309
- effects: scrollToLineEffect.of({
7310
- line: line.number,
7311
- options: {
7312
- offset: -16
7313
- }
7498
+ effects: scrollerLineEffect.of({
7499
+ line: line.number - 1,
7500
+ offset: -16
7314
7501
  })
7315
7502
  });
7316
7503
  continue;
@@ -7341,11 +7528,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
7341
7528
  anchor: line.to,
7342
7529
  head: line.to
7343
7530
  },
7344
- effects: scrollToLineEffect.of({
7345
- line: line.number,
7346
- options: {
7347
- offset: -16
7348
- }
7531
+ effects: scrollerLineEffect.of({
7532
+ line: line.number - 1,
7533
+ offset: -16
7349
7534
  })
7350
7535
  });
7351
7536
  } else {
@@ -7355,11 +7540,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
7355
7540
  anchor: line.to,
7356
7541
  head: line.to
7357
7542
  },
7358
- effects: scrollToLineEffect.of({
7359
- line: line.number,
7360
- options: {
7361
- position: "end"
7362
- }
7543
+ effects: scrollerLineEffect.of({
7544
+ line: line.number - 1,
7545
+ position: "end"
7363
7546
  })
7364
7547
  });
7365
7548
  }
@@ -7369,7 +7552,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
7369
7552
  });
7370
7553
  });
7371
7554
  };
7372
- var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin19.fromClass(class {
7555
+ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin21.fromClass(class {
7373
7556
  update(update2) {
7374
7557
  const widgetStateMap = update2.state.field(widgetStateMapStateField);
7375
7558
  const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
@@ -7406,6 +7589,12 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
7406
7589
  update: ({ from, decorations: decorations2 }, tr) => {
7407
7590
  for (const effect of tr.effects) {
7408
7591
  if (effect.is(xmlTagResetEffect)) {
7592
+ if (tr.docChanged) {
7593
+ return buildDecorations4(tr.state, {
7594
+ from: 0,
7595
+ to: tr.state.doc.length
7596
+ }, registry, notifier);
7597
+ }
7409
7598
  return {
7410
7599
  from: 0,
7411
7600
  decorations: Decoration15.none
@@ -7416,12 +7605,12 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
7416
7605
  const { state } = tr;
7417
7606
  const reset = tr.changes.touchesRange(0, from);
7418
7607
  if (reset) {
7419
- log10("document reset", {
7608
+ log11("document reset", {
7420
7609
  from,
7421
7610
  to: state.doc.length
7422
7611
  }, {
7423
- F: __dxlog_file16,
7424
- L: 371,
7612
+ F: __dxlog_file17,
7613
+ L: 374,
7425
7614
  S: void 0,
7426
7615
  C: (f, a) => f(...a)
7427
7616
  });
@@ -7448,8 +7637,8 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
7448
7637
  };
7449
7638
  },
7450
7639
  provide: (field) => [
7451
- EditorView29.decorations.from(field, (v) => v.decorations),
7452
- EditorView29.atomicRanges.of((view) => view.state.field(field).decorations || Decoration15.none)
7640
+ EditorView30.decorations.from(field, (v) => v.decorations),
7641
+ EditorView30.atomicRanges.of((view) => view.state.field(field).decorations || Decoration15.none)
7453
7642
  ]
7454
7643
  });
7455
7644
  var buildDecorations4 = (state, range, registry, notifier) => {
@@ -7502,9 +7691,9 @@ var buildDecorations4 = (state, range, registry, notifier) => {
7502
7691
  }
7503
7692
  }
7504
7693
  } catch (err) {
7505
- log10.catch(err, void 0, {
7506
- F: __dxlog_file16,
7507
- L: 456,
7694
+ log11.catch(err, void 0, {
7695
+ F: __dxlog_file17,
7696
+ L: 459,
7508
7697
  S: void 0,
7509
7698
  C: (f, a) => f(...a)
7510
7699
  });
@@ -7528,8 +7717,8 @@ var PlaceholderWidget2 = class extends WidgetType10 {
7528
7717
  constructor(id, Component, props, notifier) {
7529
7718
  super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier;
7530
7719
  invariant7(id, void 0, {
7531
- F: __dxlog_file16,
7532
- L: 482,
7720
+ F: __dxlog_file17,
7721
+ L: 485,
7533
7722
  S: this,
7534
7723
  A: [
7535
7724
  "id",
@@ -7623,7 +7812,7 @@ export {
7623
7812
  EditorInputMode,
7624
7813
  EditorInputModes,
7625
7814
  EditorState3 as EditorState,
7626
- EditorView30 as EditorView,
7815
+ EditorView31 as EditorView,
7627
7816
  EditorViewMode,
7628
7817
  EditorViewModes,
7629
7818
  Inline,
@@ -7655,9 +7844,11 @@ export {
7655
7844
  commentClickedEffect,
7656
7845
  comments,
7657
7846
  commentsState,
7847
+ compactSlots,
7658
7848
  convertTreeToJson,
7659
7849
  createBasicExtensions,
7660
7850
  createComment,
7851
+ createCrawler,
7661
7852
  createDataExtensions,
7662
7853
  createEditorStateStore,
7663
7854
  createEditorStateTransaction,
@@ -7677,11 +7868,10 @@ export {
7677
7868
  defaultThemeSlots,
7678
7869
  deleteItem,
7679
7870
  documentId,
7871
+ documentSlots,
7680
7872
  dropFile,
7873
+ editorClassNames,
7681
7874
  editorInputMode,
7682
- editorSlots,
7683
- editorWidth,
7684
- editorWithToolbarLayout,
7685
7875
  extendedMarkdown,
7686
7876
  filterChars,
7687
7877
  flattenRect,
@@ -7737,10 +7927,12 @@ export {
7737
7927
  removeList,
7738
7928
  removeStyle,
7739
7929
  replacer,
7930
+ scrollPastEnd,
7740
7931
  scrollThreadIntoView,
7741
- scrollToBottomEffect,
7742
7932
  scrollToLine,
7743
- scrollToLineEffect,
7933
+ scroller,
7934
+ scrollerCrawlEffect,
7935
+ scrollerLineEffect,
7744
7936
  selectionState,
7745
7937
  setBlockquote,
7746
7938
  setComments,
@@ -7748,8 +7940,6 @@ export {
7748
7940
  setSelection,
7749
7941
  setStyle,
7750
7942
  singleValueFacet,
7751
- smoothScroll,
7752
- stackItemContentEditorClassNames,
7753
7943
  staticCompletion,
7754
7944
  streamer,
7755
7945
  submit,