@dxos/ui-editor 0.8.4-main.d05539e30a → 0.8.4-main.d9fc60f731

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 (34) hide show
  1. package/dist/lib/browser/index.mjs +253 -132
  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 +253 -132
  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.map +1 -1
  8. package/dist/types/src/extensions/markdown/image.d.ts +13 -2
  9. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  10. package/dist/types/src/extensions/markdown/image.test.d.ts +2 -0
  11. package/dist/types/src/extensions/markdown/image.test.d.ts.map +1 -0
  12. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  13. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
  14. package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -1
  15. package/dist/types/src/extensions/scrolling/crawler.d.ts +11 -3
  16. package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -1
  17. package/dist/types/src/extensions/scrolling/index.d.ts +1 -0
  18. package/dist/types/src/extensions/scrolling/index.d.ts.map +1 -1
  19. package/dist/types/src/extensions/scrolling/scrollbar-autohide.d.ts +15 -0
  20. package/dist/types/src/extensions/scrolling/scrollbar-autohide.d.ts.map +1 -0
  21. package/dist/types/tsconfig.tsbuildinfo +1 -1
  22. package/package.json +53 -52
  23. package/src/defaults.ts +1 -2
  24. package/src/extensions/comments.ts +1 -1
  25. package/src/extensions/markdown/decorate.ts +1 -1
  26. package/src/extensions/markdown/image.test.ts +54 -0
  27. package/src/extensions/markdown/image.ts +70 -9
  28. package/src/extensions/markdown/link.ts +7 -2
  29. package/src/extensions/preview/preview.ts +7 -5
  30. package/src/extensions/scrolling/auto-scroll.ts +27 -10
  31. package/src/extensions/scrolling/crawler.ts +29 -6
  32. package/src/extensions/scrolling/index.ts +1 -0
  33. package/src/extensions/scrolling/scrollbar-autohide.ts +56 -0
  34. package/src/styles/theme.ts +6 -6
@@ -1,12 +1,12 @@
1
1
  // src/index.ts
2
2
  import { EditorState as EditorState4 } from "@codemirror/state";
3
- import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
3
+ import { EditorView as EditorView34, keymap as keymap15 } from "@codemirror/view";
4
4
  import { tags as tags2 } from "@lezer/highlight";
5
5
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
6
6
 
7
7
  // src/defaults.ts
8
8
  import { mx } from "@dxos/ui-theme";
9
- 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");
9
+ var editorClassNames = (role) => mx("dx-attention-surface data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
10
10
  var documentSlots = {
11
11
  content: {
12
12
  /**
@@ -1728,7 +1728,7 @@ var styles2 = EditorView9.theme({
1728
1728
  },
1729
1729
  ".cm-comment > span, .cm-comment-current > span": {
1730
1730
  boxDecorationBreak: "clone",
1731
- boxShadow: "0 0 1px 3px var(--color-cm-comment-surface)",
1731
+ boxShadow: "0 0 0 3px var(--color-cm-comment-surface)",
1732
1732
  backgroundColor: "var(--color-cm-comment-surface)",
1733
1733
  color: "var(--color-cm-comment-text)",
1734
1734
  cursor: "pointer"
@@ -2140,7 +2140,7 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
2140
2140
  import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
2141
2141
  import { searchKeymap } from "@codemirror/search";
2142
2142
  import { EditorState } from "@codemirror/state";
2143
- import { EditorView as EditorView16, ViewPlugin as ViewPlugin12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
2143
+ import { EditorView as EditorView17, ViewPlugin as ViewPlugin13, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
2144
2144
  import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
2145
2145
  import defaultsDeep2 from "lodash.defaultsdeep";
2146
2146
  import { generateName } from "@dxos/display-name";
@@ -2359,11 +2359,11 @@ var baseTheme = EditorView11.baseTheme({
2359
2359
  },
2360
2360
  ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
2361
2361
  background: "var(--color-current-surface)",
2362
- color: "var(--color-base-foreground)"
2362
+ color: "var(--color-base-fg)"
2363
2363
  },
2364
2364
  ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2365
2365
  paddingLeft: "4px !important",
2366
- color: "var(--color-base-foreground)"
2366
+ color: "var(--color-base-fg)"
2367
2367
  },
2368
2368
  /**
2369
2369
  * Completion info.
@@ -2382,7 +2382,7 @@ var baseTheme = EditorView11.baseTheme({
2382
2382
  padding: "0 4px"
2383
2383
  },
2384
2384
  ".cm-completionMatchedText": {
2385
- color: "var(--color-base-foreground)",
2385
+ color: "var(--color-base-fg)",
2386
2386
  textDecoration: "none !important"
2387
2387
  },
2388
2388
  /**
@@ -2434,11 +2434,11 @@ var baseTheme = EditorView11.baseTheme({
2434
2434
  },
2435
2435
  ".cm-panel button": {
2436
2436
  "&:hover": {
2437
- // TODO(burdon): Replace with layer and @apply bg-accent-surface-hover
2438
- backgroundColor: "var(--color-accent-surface-hover) !important"
2437
+ // TODO(burdon): Replace with layer and @apply bg-accent-bg-hover
2438
+ backgroundColor: "var(--color-accent-bg-hover) !important"
2439
2439
  },
2440
2440
  "&:active": {
2441
- backgroundColor: "var(--color-accent-surface-hover)"
2441
+ backgroundColor: "var(--color-accent-bg-hover)"
2442
2442
  }
2443
2443
  },
2444
2444
  ".cm-panel.cm-search": {
@@ -2530,9 +2530,11 @@ var crawler = ({ overScroll = 0 } = {}) => {
2530
2530
  cancel() {
2531
2531
  this.crawler.cancel();
2532
2532
  }
2533
- crawl(start = false) {
2534
- if (start) {
2535
- this.crawler.scroll();
2533
+ crawl({ active, instant } = {
2534
+ active: false
2535
+ }) {
2536
+ if (active) {
2537
+ this.crawler.scroll(instant);
2536
2538
  } else {
2537
2539
  this.crawler.cancel();
2538
2540
  }
@@ -2580,7 +2582,7 @@ var crawler = ({ overScroll = 0 } = {}) => {
2580
2582
  }
2581
2583
  }
2582
2584
  } catch (err) {
2583
- log7.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 98, S: void 0 });
2585
+ log7.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 105, S: void 0 });
2584
2586
  }
2585
2587
  });
2586
2588
  }),
@@ -2628,11 +2630,24 @@ function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
2628
2630
  let velocity = 0;
2629
2631
  let rafId = null;
2630
2632
  let lastTime = 0;
2633
+ let instant = false;
2631
2634
  function frame(now) {
2632
2635
  const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
2633
2636
  lastTime = now;
2634
2637
  const targetTop = el.scrollHeight - el.clientHeight;
2635
2638
  const delta = targetTop - currentTop;
2639
+ if (instant) {
2640
+ el.scrollTop = targetTop;
2641
+ currentTop = targetTop;
2642
+ velocity = 0;
2643
+ if (Math.abs(delta) < snapThreshold) {
2644
+ rafId = null;
2645
+ lastTime = 0;
2646
+ return;
2647
+ }
2648
+ rafId = requestAnimationFrame(frame);
2649
+ return;
2650
+ }
2636
2651
  if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
2637
2652
  el.scrollTop = targetTop;
2638
2653
  currentTop = targetTop;
@@ -2648,7 +2663,8 @@ function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
2648
2663
  rafId = requestAnimationFrame(frame);
2649
2664
  }
2650
2665
  return {
2651
- scroll: () => {
2666
+ scroll: (useInstant = false) => {
2667
+ instant = useInstant;
2652
2668
  if (rafId === null) {
2653
2669
  currentTop = el.scrollTop;
2654
2670
  lastTime = 0;
@@ -2674,6 +2690,7 @@ var autoScroll = ({ scrollOnResize = true } = {}) => {
2674
2690
  let jumpPending = false;
2675
2691
  let enabled = true;
2676
2692
  let firstUpdate = true;
2693
+ let streamed = false;
2677
2694
  const setPinned = (pinned) => {
2678
2695
  buttonContainer?.classList.toggle("opacity-0", pinned);
2679
2696
  isPinned = pinned;
@@ -2689,11 +2706,15 @@ var autoScroll = ({ scrollOnResize = true } = {}) => {
2689
2706
  if (enabled) {
2690
2707
  setPinned(true);
2691
2708
  view.dispatch({
2692
- effects: crawlerActiveEffect.of(true)
2709
+ effects: crawlerActiveEffect.of({
2710
+ active: true
2711
+ })
2693
2712
  });
2694
2713
  } else {
2695
2714
  view.dispatch({
2696
- effects: crawlerActiveEffect.of(false)
2715
+ effects: crawlerActiveEffect.of({
2716
+ active: false
2717
+ })
2697
2718
  });
2698
2719
  }
2699
2720
  }
@@ -2719,10 +2740,16 @@ var autoScroll = ({ scrollOnResize = true } = {}) => {
2719
2740
  if (isPinned) {
2720
2741
  const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
2721
2742
  const delta = scrollHeight - scrollTop - clientHeight;
2743
+ if (update2.docChanged) {
2744
+ streamed = true;
2745
+ }
2722
2746
  if (delta > 0) {
2723
2747
  setPinned(true);
2724
2748
  view.dispatch({
2725
- effects: crawlerActiveEffect.of(true)
2749
+ effects: crawlerActiveEffect.of({
2750
+ active: true,
2751
+ instant: !streamed
2752
+ })
2726
2753
  });
2727
2754
  } else if (delta < -1) {
2728
2755
  setPinned(false);
@@ -2756,7 +2783,9 @@ var autoScroll = ({ scrollOnResize = true } = {}) => {
2756
2783
  behavior: "instant"
2757
2784
  });
2758
2785
  view.dispatch({
2759
- effects: crawlerActiveEffect.of(false)
2786
+ effects: crawlerActiveEffect.of({
2787
+ active: false
2788
+ })
2760
2789
  });
2761
2790
  });
2762
2791
  }, 50);
@@ -2786,7 +2815,9 @@ var autoScroll = ({ scrollOnResize = true } = {}) => {
2786
2815
  setPinned(pinned);
2787
2816
  if (!pinned) {
2788
2817
  view.dispatch({
2789
- effects: crawlerActiveEffect.of(false)
2818
+ effects: crawlerActiveEffect.of({
2819
+ active: false
2820
+ })
2790
2821
  });
2791
2822
  }
2792
2823
  });
@@ -2795,7 +2826,9 @@ var autoScroll = ({ scrollOnResize = true } = {}) => {
2795
2826
  if (isPinned) {
2796
2827
  setPinned(false);
2797
2828
  view.dispatch({
2798
- effects: crawlerActiveEffect.of(false)
2829
+ effects: crawlerActiveEffect.of({
2830
+ active: false
2831
+ })
2799
2832
  });
2800
2833
  }
2801
2834
  onUserScroll();
@@ -2811,19 +2844,27 @@ var autoScroll = ({ scrollOnResize = true } = {}) => {
2811
2844
  const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
2812
2845
  icon: "ph--arrow-down--regular"
2813
2846
  });
2814
- const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
2815
- "data-density": "fine"
2847
+ const button = Domino.of("button").classNames("dx-button bg-accent-bg").attributes({
2848
+ "data-density": "md"
2816
2849
  }).append(icon).on("click", () => {
2817
2850
  setPinned(true);
2818
2851
  view.dispatch({
2819
- effects: crawlerLineEffect.of({
2820
- line: -1,
2821
- position: "end",
2822
- behavior: "smooth"
2823
- })
2852
+ effects: [
2853
+ crawlerLineEffect.of({
2854
+ line: -1,
2855
+ position: "end",
2856
+ behavior: "smooth"
2857
+ }),
2858
+ // Re-engage the follower so it keeps tracking the bottom as content continues
2859
+ // to stream after the catch-up jump.
2860
+ crawlerActiveEffect.of({
2861
+ active: true,
2862
+ instant: !streamed
2863
+ })
2864
+ ]
2824
2865
  });
2825
2866
  });
2826
- buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
2867
+ buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0 z-1").append(button).root;
2827
2868
  view.scrollDOM.parentElement.appendChild(buttonContainer);
2828
2869
  }
2829
2870
  })
@@ -2862,6 +2903,42 @@ var scrollPastEnd = () => [
2862
2903
  EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?._attrs ?? null)
2863
2904
  ];
2864
2905
 
2906
+ // src/extensions/scrolling/scrollbar-autohide.ts
2907
+ import { EditorView as EditorView16, ViewPlugin as ViewPlugin12 } from "@codemirror/view";
2908
+ var scrollbarAutohide = ({ timeout = 800 } = {}) => [
2909
+ ViewPlugin12.fromClass(class {
2910
+ #scroller;
2911
+ #timer;
2912
+ constructor(view) {
2913
+ this.#scroller = view.scrollDOM;
2914
+ this.#scroller.addEventListener("scroll", this.#handleScroll, {
2915
+ passive: true
2916
+ });
2917
+ }
2918
+ destroy() {
2919
+ this.#scroller.removeEventListener("scroll", this.#handleScroll);
2920
+ clearTimeout(this.#timer);
2921
+ }
2922
+ // Show the thumb while scrolling; remove the class once scrolling has been idle for `timeout`.
2923
+ #handleScroll = () => {
2924
+ this.#scroller.classList.add("cm-scrolling");
2925
+ clearTimeout(this.#timer);
2926
+ this.#timer = setTimeout(() => this.#scroller.classList.remove("cm-scrolling"), timeout);
2927
+ };
2928
+ }),
2929
+ EditorView16.theme({
2930
+ // Reveal the thumb only while actively scrolling.
2931
+ ".cm-scroller.cm-scrolling::-webkit-scrollbar-thumb": {
2932
+ background: "var(--color-scrollbar-thumb)"
2933
+ },
2934
+ // Suppress the base theme's hover-reveal (higher specificity via `:not(.cm-scrolling)`), so a
2935
+ // hovered/focused-but-idle editor keeps the thumb hidden.
2936
+ "&:hover .cm-scroller:not(.cm-scrolling)::-webkit-scrollbar-thumb": {
2937
+ background: "transparent"
2938
+ }
2939
+ })
2940
+ ];
2941
+
2865
2942
  // src/extensions/scrolling/scroller.ts
2866
2943
  import { isTruthy as isTruthy2 } from "@dxos/util";
2867
2944
  var scroller = ({ overScroll, scrollOnResize, autoScroll: autoScroll2 = true } = {}) => {
@@ -2877,7 +2954,7 @@ var scroller = ({ overScroll, scrollOnResize, autoScroll: autoScroll2 = true } =
2877
2954
 
2878
2955
  // src/extensions/factories.ts
2879
2956
  var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
2880
- var tabbable = EditorView16.contentAttributes.of({
2957
+ var tabbable = EditorView17.contentAttributes.of({
2881
2958
  tabindex: "0"
2882
2959
  });
2883
2960
  var filterChars = (chars) => {
@@ -2930,7 +3007,7 @@ var createBasicExtensions = (propsProp) => {
2930
3007
  const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
2931
3008
  return [
2932
3009
  // NOTE: Doesn't catch errors in keymap functions.
2933
- EditorView16.exceptionSink.of((err) => {
3010
+ EditorView17.exceptionSink.of((err) => {
2934
3011
  log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
2935
3012
  }),
2936
3013
  props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
@@ -2940,7 +3017,7 @@ var createBasicExtensions = (propsProp) => {
2940
3017
  props.drawSelection && drawSelection({
2941
3018
  cursorBlinkRate: 1200
2942
3019
  }),
2943
- props.editable !== void 0 && EditorView16.editable.of(props.editable),
3020
+ props.editable !== void 0 && EditorView17.editable.of(props.editable),
2944
3021
  props.focus && focus,
2945
3022
  props.highlightActiveLine && highlightActiveLine(),
2946
3023
  props.history && history(),
@@ -2948,7 +3025,7 @@ var createBasicExtensions = (propsProp) => {
2948
3025
  lineNumbers(),
2949
3026
  editorGutter
2950
3027
  ],
2951
- props.lineWrapping && EditorView16.lineWrapping,
3028
+ props.lineWrapping && EditorView17.lineWrapping,
2952
3029
  props.placeholder && placeholder2(props.placeholder),
2953
3030
  props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
2954
3031
  // `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
@@ -3004,18 +3081,18 @@ var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, synta
3004
3081
  const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
3005
3082
  return [
3006
3083
  baseTheme,
3007
- EditorView16.darkTheme.of(themeMode === "dark"),
3084
+ EditorView17.darkTheme.of(themeMode === "dark"),
3008
3085
  createFontTheme({
3009
3086
  monospace
3010
3087
  }),
3011
3088
  syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
3012
- slots.editor?.className && EditorView16.editorAttributes.of({
3089
+ slots.editor?.className && EditorView17.editorAttributes.of({
3013
3090
  class: slots.editor.className
3014
3091
  }),
3015
- slots.content?.className && EditorView16.contentAttributes.of({
3092
+ slots.content?.className && EditorView17.contentAttributes.of({
3016
3093
  class: slots.content.className
3017
3094
  }),
3018
- (slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
3095
+ (slots.scroller?.className || scrollbarThin) && ViewPlugin13.fromClass(class {
3019
3096
  constructor(view) {
3020
3097
  if (slots.scroller?.className) {
3021
3098
  view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
@@ -3051,7 +3128,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
3051
3128
 
3052
3129
  // src/extensions/folding.ts
3053
3130
  import { codeFolding, foldGutter } from "@codemirror/language";
3054
- import { EditorView as EditorView17 } from "@codemirror/view";
3131
+ import { EditorView as EditorView18 } from "@codemirror/view";
3055
3132
  import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
3056
3133
  var folding = () => {
3057
3134
  return [
@@ -3066,7 +3143,7 @@ var folding = () => {
3066
3143
  }))).root;
3067
3144
  }
3068
3145
  }),
3069
- EditorView17.theme({
3146
+ EditorView18.theme({
3070
3147
  ".cm-foldGutter": {
3071
3148
  opacity: 0.3,
3072
3149
  transition: "opacity 0.3s",
@@ -3080,7 +3157,7 @@ var folding = () => {
3080
3157
  };
3081
3158
 
3082
3159
  // src/extensions/hashtag.ts
3083
- import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
3160
+ import { Decoration as Decoration8, EditorView as EditorView19, MatchDecorator, ViewPlugin as ViewPlugin14, WidgetType as WidgetType4 } from "@codemirror/view";
3084
3161
  import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
3085
3162
  var TagWidget = class extends WidgetType4 {
3086
3163
  _text;
@@ -3101,7 +3178,7 @@ var tagMatcher = new MatchDecorator({
3101
3178
  })
3102
3179
  });
3103
3180
  var hashtag = () => [
3104
- ViewPlugin13.fromClass(class {
3181
+ ViewPlugin14.fromClass(class {
3105
3182
  tags;
3106
3183
  constructor(view) {
3107
3184
  this.tags = tagMatcher.createDeco(view);
@@ -3111,11 +3188,11 @@ var hashtag = () => [
3111
3188
  }
3112
3189
  }, {
3113
3190
  decorations: (instance) => instance.tags,
3114
- provide: (plugin) => EditorView18.atomicRanges.of((view) => {
3191
+ provide: (plugin) => EditorView19.atomicRanges.of((view) => {
3115
3192
  return view.plugin(plugin)?.tags || Decoration8.none;
3116
3193
  })
3117
3194
  }),
3118
- EditorView18.theme({
3195
+ EditorView19.theme({
3119
3196
  ".cm-tag": {
3120
3197
  borderRadius: "4px",
3121
3198
  marginRight: "6px",
@@ -3170,18 +3247,18 @@ var schemaLinter = (validate) => (view) => {
3170
3247
  };
3171
3248
 
3172
3249
  // src/extensions/listener.ts
3173
- import { EditorView as EditorView19 } from "@codemirror/view";
3250
+ import { EditorView as EditorView20 } from "@codemirror/view";
3174
3251
  import { isNonNullable as isNonNullable2 } from "@dxos/util";
3175
3252
  var listener = ({ onFocus, onChange }) => {
3176
3253
  return [
3177
- onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
3254
+ onFocus && EditorView20.focusChangeEffect.of((state, focusing) => {
3178
3255
  onFocus({
3179
3256
  id: state.facet(documentId),
3180
3257
  focusing
3181
3258
  });
3182
3259
  return null;
3183
3260
  }),
3184
- onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
3261
+ onChange && EditorView20.updateListener.of(({ state, docChanged }) => {
3185
3262
  if (docChanged) {
3186
3263
  onChange({
3187
3264
  id: state.facet(documentId),
@@ -3196,7 +3273,7 @@ var listener = ({ onFocus, onChange }) => {
3196
3273
  import { snippet } from "@codemirror/autocomplete";
3197
3274
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3198
3275
  import { EditorSelection as EditorSelection2 } from "@codemirror/state";
3199
- import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
3276
+ import { EditorView as EditorView21, keymap as keymap8 } from "@codemirror/view";
3200
3277
  import { debounceAndThrottle } from "@dxos/async";
3201
3278
  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;
3202
3279
  var Inline = /* @__PURE__ */ (function(Inline2) {
@@ -4285,7 +4362,7 @@ var getFormatting = (state) => {
4285
4362
  };
4286
4363
  };
4287
4364
  var formattingListener = (onStateChange, delay = 100) => {
4288
- return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
4365
+ return EditorView21.updateListener.of(debounceAndThrottle((update2) => {
4289
4366
  if (update2.docChanged || update2.selectionSet) {
4290
4367
  onStateChange(getFormatting(update2.state));
4291
4368
  }
@@ -4631,16 +4708,16 @@ var convertTreeToJson = (state) => {
4631
4708
 
4632
4709
  // src/extensions/markdown/decorate.ts
4633
4710
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4634
- import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
4635
- import { Decoration as Decoration11, EditorView as EditorView24, ViewPlugin as ViewPlugin15, WidgetType as WidgetType7 } from "@codemirror/view";
4711
+ import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect8 } from "@codemirror/state";
4712
+ import { Decoration as Decoration11, EditorView as EditorView25, ViewPlugin as ViewPlugin17, WidgetType as WidgetType7 } from "@codemirror/view";
4636
4713
  import { invariant as invariant4 } from "@dxos/invariant";
4637
4714
 
4638
4715
  // src/extensions/markdown/changes.ts
4639
4716
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4640
4717
  import { Transaction as Transaction4 } from "@codemirror/state";
4641
- import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
4718
+ import { ViewPlugin as ViewPlugin15 } from "@codemirror/view";
4642
4719
  var adjustChanges = () => {
4643
- return ViewPlugin14.fromClass(class {
4720
+ return ViewPlugin15.fromClass(class {
4644
4721
  update(update2) {
4645
4722
  const tree = syntaxTree4(update2.state);
4646
4723
  const adjustments = [];
@@ -4781,15 +4858,19 @@ var getValidUrl = (str) => {
4781
4858
 
4782
4859
  // src/extensions/markdown/image.ts
4783
4860
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4784
- import { StateField as StateField7 } from "@codemirror/state";
4785
- import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
4786
- var image = (_options = {}) => {
4861
+ import { StateEffect as StateEffect7, StateField as StateField7 } from "@codemirror/state";
4862
+ import { Decoration as Decoration9, EditorView as EditorView22, ViewPlugin as ViewPlugin16, WidgetType as WidgetType5 } from "@codemirror/view";
4863
+ var rebuildEffect = StateEffect7.define();
4864
+ var image = (options = {}) => {
4787
4865
  return [
4788
4866
  StateField7.define({
4789
4867
  create: (state) => {
4790
- return Decoration9.set(buildDecorations(state, 0, state.doc.length));
4868
+ return Decoration9.set(buildDecorations(state, 0, state.doc.length, options));
4791
4869
  },
4792
4870
  update: (value, tr) => {
4871
+ if (tr.effects.some((effect) => effect.is(rebuildEffect))) {
4872
+ return Decoration9.set(buildDecorations(tr.state, 0, tr.state.doc.length, options));
4873
+ }
4793
4874
  if (!tr.docChanged && !tr.selection) {
4794
4875
  return value;
4795
4876
  }
@@ -4807,14 +4888,26 @@ var image = (_options = {}) => {
4807
4888
  filterFrom: from,
4808
4889
  filterTo: to,
4809
4890
  filter: () => false,
4810
- add: buildDecorations(tr.state, from, to)
4891
+ add: buildDecorations(tr.state, from, to, options)
4811
4892
  });
4812
4893
  },
4813
- provide: (field) => EditorView21.decorations.from(field)
4814
- })
4894
+ provide: (field) => EditorView22.decorations.from(field)
4895
+ }),
4896
+ // Block-replace decorations have to live in a state field, but viewport changes are only
4897
+ // observable from a view plugin. Bridge the two by dispatching a rebuild effect whenever
4898
+ // the viewport extends so newly-parsed image nodes get widgetized without requiring focus.
4899
+ ViewPlugin16.define((view) => ({
4900
+ update: (update2) => {
4901
+ if (update2.viewportChanged) {
4902
+ queueMicrotask(() => view.dispatch({
4903
+ effects: rebuildEffect.of(void 0)
4904
+ }));
4905
+ }
4906
+ }
4907
+ }))
4815
4908
  ];
4816
4909
  };
4817
- var buildDecorations = (state, from, to) => {
4910
+ var buildDecorations = (state, from, to, options = {}) => {
4818
4911
  const decorations2 = [];
4819
4912
  const cursor = state.selection.main.head;
4820
4913
  syntaxTree5(state).iterate({
@@ -4827,6 +4920,12 @@ var buildDecorations = (state, from, to) => {
4827
4920
  if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
4828
4921
  return;
4829
4922
  }
4923
+ if (options.skip?.({
4924
+ name: "Image",
4925
+ url
4926
+ })) {
4927
+ return;
4928
+ }
4830
4929
  preloadImage(url);
4831
4930
  decorations2.push(Decoration9.replace({
4832
4931
  block: true,
@@ -4860,20 +4959,34 @@ var ImageWidget = class extends WidgetType5 {
4860
4959
  const img = document.createElement("img");
4861
4960
  img.setAttribute("src", this._url);
4862
4961
  img.setAttribute("class", "cm-image");
4863
- if (view.state.field(focusField)) {
4864
- img.onload = () => img.classList.add("cm-loaded-image");
4962
+ const focused = view.state.field(focusField);
4963
+ if (focused) {
4964
+ img.onload = () => {
4965
+ img.classList.add("cm-loaded-image");
4966
+ collapseIfTrackingPixel(img);
4967
+ };
4865
4968
  } else {
4866
4969
  img.classList.add("cm-loaded-image");
4970
+ img.onload = () => collapseIfTrackingPixel(img);
4867
4971
  }
4972
+ img.onerror = () => collapseLine(img);
4868
4973
  return img;
4869
4974
  }
4870
4975
  };
4976
+ var collapseIfTrackingPixel = (img) => {
4977
+ if (img.naturalWidth <= 1 && img.naturalHeight <= 1) {
4978
+ collapseLine(img);
4979
+ }
4980
+ };
4981
+ var collapseLine = (img) => {
4982
+ img.style.display = "none";
4983
+ };
4871
4984
 
4872
4985
  // src/extensions/markdown/styles.ts
4873
- import { EditorView as EditorView22 } from "@codemirror/view";
4986
+ import { EditorView as EditorView23 } from "@codemirror/view";
4874
4987
  var bulletListIndentationWidth = 24;
4875
4988
  var orderedListIndentationWidth = 36;
4876
- var formattingStyles = EditorView22.theme({
4989
+ var formattingStyles = EditorView23.theme({
4877
4990
  /**
4878
4991
  * Horizontal rule.
4879
4992
  */
@@ -5028,12 +5141,12 @@ var formattingStyles = EditorView22.theme({
5028
5141
  // src/extensions/markdown/table.ts
5029
5142
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
5030
5143
  import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
5031
- import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
5144
+ import { Decoration as Decoration10, EditorView as EditorView24, WidgetType as WidgetType6 } from "@codemirror/view";
5032
5145
  var table = (options = {}) => {
5033
5146
  return StateField8.define({
5034
5147
  create: (state) => update(state, options),
5035
5148
  update: (_, tr) => update(tr.state, options),
5036
- provide: (field) => EditorView23.decorations.from(field)
5149
+ provide: (field) => EditorView24.decorations.from(field)
5037
5150
  });
5038
5151
  };
5039
5152
  var update = (state, _options) => {
@@ -5624,10 +5737,10 @@ var buildDecorations2 = (view, options, focus2) => {
5624
5737
  atomicDeco: atomicDeco.finish()
5625
5738
  };
5626
5739
  };
5627
- var forceUpdate = StateEffect7.define();
5740
+ var forceUpdate = StateEffect8.define();
5628
5741
  var decorateMarkdown = (options = {}) => {
5629
5742
  return [
5630
- ViewPlugin15.fromClass(class {
5743
+ ViewPlugin17.fromClass(class {
5631
5744
  deco;
5632
5745
  atomicDeco;
5633
5746
  pendingUpdate;
@@ -5662,12 +5775,14 @@ var decorateMarkdown = (options = {}) => {
5662
5775
  }
5663
5776
  }, {
5664
5777
  provide: (plugin) => [
5665
- Prec4.low(EditorView24.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
5666
- EditorView24.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
5667
- EditorView24.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
5778
+ Prec4.low(EditorView25.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
5779
+ EditorView25.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
5780
+ EditorView25.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
5668
5781
  ]
5669
5782
  }),
5670
- image(),
5783
+ image({
5784
+ skip: options.skip ? (node) => !!options.skip?.(node) : void 0
5785
+ }),
5671
5786
  table(),
5672
5787
  adjustChanges(),
5673
5788
  formattingStyles
@@ -5677,7 +5792,10 @@ var decorateMarkdown = (options = {}) => {
5677
5792
  // src/extensions/markdown/link.ts
5678
5793
  import { syntaxTree as syntaxTree8 } from "@codemirror/language";
5679
5794
  import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
5680
- import { tooltipContent } from "@dxos/ui-theme";
5795
+ import { mx as mx6, surfaceShadow } from "@dxos/ui-theme";
5796
+ var tooltipClassName = mx6("inline-flex items-center p-1 max-w-64 text-sm bg-inverse-surface text-inverse-fg rounded-sm", surfaceShadow({
5797
+ elevation: "positioned"
5798
+ }));
5681
5799
  var linkTooltip = (renderTooltip) => {
5682
5800
  return hoverTooltip2((view, pos, side) => {
5683
5801
  const syntax = syntaxTree8(view.state).resolveInner(pos, side);
@@ -5699,7 +5817,7 @@ var linkTooltip = (renderTooltip) => {
5699
5817
  above: true,
5700
5818
  create: () => {
5701
5819
  const el = document.createElement("div");
5702
- el.className = tooltipContent({});
5820
+ el.className = tooltipClassName;
5703
5821
  renderTooltip(el, {
5704
5822
  url: urlText
5705
5823
  }, view);
@@ -5749,8 +5867,8 @@ var mention = ({ debug, onSearch }) => {
5749
5867
  };
5750
5868
 
5751
5869
  // src/extensions/modal.ts
5752
- import { StateEffect as StateEffect8, StateField as StateField9 } from "@codemirror/state";
5753
- var modalStateEffect = StateEffect8.define();
5870
+ import { StateEffect as StateEffect9, StateField as StateField9 } from "@codemirror/state";
5871
+ var modalStateEffect = StateEffect9.define();
5754
5872
  var modalStateField = StateField9.define({
5755
5873
  create: () => false,
5756
5874
  update: (value, tr) => {
@@ -6318,17 +6436,17 @@ var commands = () => keymap11.of([
6318
6436
 
6319
6437
  // src/extensions/outliner/outliner.ts
6320
6438
  import { Prec as Prec5 } from "@codemirror/state";
6321
- import { Decoration as Decoration12, EditorView as EditorView26, ViewPlugin as ViewPlugin18 } from "@codemirror/view";
6322
- import { mx as mx6 } from "@dxos/ui-theme";
6439
+ import { Decoration as Decoration12, EditorView as EditorView27, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
6440
+ import { mx as mx7 } from "@dxos/ui-theme";
6323
6441
 
6324
6442
  // src/extensions/outliner/editor.ts
6325
6443
  import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
6326
- import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
6444
+ import { ViewPlugin as ViewPlugin18 } from "@codemirror/view";
6327
6445
  import { log as log10 } from "@dxos/log";
6328
6446
  var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
6329
6447
  var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
6330
6448
  var initialize = () => {
6331
- return ViewPlugin16.fromClass(class {
6449
+ return ViewPlugin18.fromClass(class {
6332
6450
  constructor(view) {
6333
6451
  const first = view.state.doc.lineAt(0);
6334
6452
  const text = view.state.sliceDoc(first.from, first.to);
@@ -6496,10 +6614,10 @@ var editor = () => [
6496
6614
  ];
6497
6615
 
6498
6616
  // src/extensions/outliner/menu.ts
6499
- import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
6617
+ import { EditorView as EditorView26, ViewPlugin as ViewPlugin19 } from "@codemirror/view";
6500
6618
  import { addEventListener as addEventListener2 } from "@dxos/async";
6501
6619
  var menu = (options = {}) => [
6502
- ViewPlugin17.fromClass(class {
6620
+ ViewPlugin19.fromClass(class {
6503
6621
  view;
6504
6622
  tag;
6505
6623
  rafId;
@@ -6561,7 +6679,7 @@ var menu = (options = {}) => [
6561
6679
  this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
6562
6680
  }
6563
6681
  }),
6564
- EditorView25.theme({
6682
+ EditorView26.theme({
6565
6683
  ".cm-popover-trigger": {
6566
6684
  position: "fixed",
6567
6685
  padding: "0",
@@ -6597,12 +6715,12 @@ var outliner = (_options = {}) => [
6597
6715
  listPaddingLeft: 8
6598
6716
  }),
6599
6717
  // Researve space for menu.
6600
- EditorView26.contentAttributes.of({
6718
+ EditorView27.contentAttributes.of({
6601
6719
  class: "w-full !mr-[3rem]"
6602
6720
  })
6603
6721
  ];
6604
6722
  var decorations = () => [
6605
- ViewPlugin18.fromClass(class {
6723
+ ViewPlugin20.fromClass(class {
6606
6724
  decorations = Decoration12.none;
6607
6725
  constructor(view) {
6608
6726
  this.updateDecorations(view.state, view);
@@ -6627,7 +6745,7 @@ var decorations = () => [
6627
6745
  const lineTo = doc.lineAt(item.contentRange.to);
6628
6746
  const isSelected = selection.includes(item.index) || item === current;
6629
6747
  decorations2.push(Decoration12.line({
6630
- 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"))
6748
+ 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"))
6631
6749
  }).range(line.from, line.from));
6632
6750
  }
6633
6751
  }
@@ -6637,7 +6755,7 @@ var decorations = () => [
6637
6755
  decorations: (v) => v.decorations
6638
6756
  }),
6639
6757
  // Theme.
6640
- EditorView26.theme(Object.assign({
6758
+ EditorView27.theme(Object.assign({
6641
6759
  ".cm-list-item": {
6642
6760
  borderLeftWidth: "1px",
6643
6761
  borderRightWidth: "1px",
@@ -6672,10 +6790,11 @@ var decorations = () => [
6672
6790
 
6673
6791
  // src/extensions/preview/preview.ts
6674
6792
  import { syntaxTree as syntaxTree10 } from "@codemirror/language";
6675
- import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect9, StateField as StateField11 } from "@codemirror/state";
6676
- import { Decoration as Decoration13, EditorView as EditorView27, ViewPlugin as ViewPlugin19, WidgetType as WidgetType8 } from "@codemirror/view";
6677
- import { DXN, Entity } from "@dxos/echo";
6678
- var labelResolvedEffect = StateEffect9.define();
6793
+ import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect10, StateField as StateField11 } from "@codemirror/state";
6794
+ import { Decoration as Decoration13, EditorView as EditorView28, ViewPlugin as ViewPlugin21, WidgetType as WidgetType8 } from "@codemirror/view";
6795
+ import { Entity } from "@dxos/echo";
6796
+ import { EID, URI } from "@dxos/keys";
6797
+ var labelResolvedEffect = StateEffect10.define();
6679
6798
  var preview = (options = {}) => {
6680
6799
  const viewRef = {
6681
6800
  current: void 0
@@ -6692,11 +6811,11 @@ var preview = (options = {}) => {
6692
6811
  return decorations2.map(tr.changes);
6693
6812
  },
6694
6813
  provide: (field) => [
6695
- EditorView27.decorations.from(field),
6696
- EditorView27.atomicRanges.of((view) => view.state.field(field))
6814
+ EditorView28.decorations.from(field),
6815
+ EditorView28.atomicRanges.of((view) => view.state.field(field))
6697
6816
  ]
6698
6817
  }),
6699
- ViewPlugin19.define((view) => {
6818
+ ViewPlugin21.define((view) => {
6700
6819
  viewRef.current = view;
6701
6820
  return {
6702
6821
  destroy() {
@@ -6707,11 +6826,12 @@ var preview = (options = {}) => {
6707
6826
  ];
6708
6827
  };
6709
6828
  var resolveLabel = (db, dxnStr, viewRef) => {
6710
- const dxn = DXN.tryParse(dxnStr);
6711
- if (!dxn) {
6829
+ const echoUri = EID.tryParse(dxnStr);
6830
+ const dxnRef = echoUri ?? (dxnStr.startsWith("dxn:") ? URI.make(dxnStr) : void 0);
6831
+ if (!dxnRef) {
6712
6832
  return;
6713
6833
  }
6714
- const ref = db.makeRef(dxn);
6834
+ const ref = db.makeRef(dxnRef);
6715
6835
  const target = ref.target;
6716
6836
  if (target) {
6717
6837
  return Entity.getLabel(target);
@@ -6816,7 +6936,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
6816
6936
  }
6817
6937
  toDOM(_view) {
6818
6938
  const root = document.createElement("div");
6819
- root.classList.add("cm-preview-block", "dx-density-fine");
6939
+ root.classList.add("cm-preview-block", "dx-density-md");
6820
6940
  this._options.addBlockContainer?.({
6821
6941
  link: this._link,
6822
6942
  el: root
@@ -6832,7 +6952,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
6832
6952
  };
6833
6953
 
6834
6954
  // src/extensions/replacer.ts
6835
- import { EditorView as EditorView28 } from "@codemirror/view";
6955
+ import { EditorView as EditorView29 } from "@codemirror/view";
6836
6956
  var defaultReplacements = [
6837
6957
  {
6838
6958
  input: "--",
@@ -6895,7 +7015,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
6895
7015
  const sortedReplacements = [
6896
7016
  ...replacements
6897
7017
  ].sort((a, b) => b.input.length - a.input.length);
6898
- return EditorView28.inputHandler.of((view, from, to, insert) => {
7018
+ return EditorView29.inputHandler.of((view, from, to, insert) => {
6899
7019
  if (insert.length !== 1) {
6900
7020
  return false;
6901
7021
  }
@@ -7141,8 +7261,8 @@ var mixedParser = (registry) => {
7141
7261
  };
7142
7262
 
7143
7263
  // src/extensions/tags/fader.ts
7144
- import { StateEffect as StateEffect10, StateField as StateField12 } from "@codemirror/state";
7145
- import { Decoration as Decoration14, EditorView as EditorView29, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
7264
+ import { StateEffect as StateEffect11, StateField as StateField12 } from "@codemirror/state";
7265
+ import { Decoration as Decoration14, EditorView as EditorView30, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
7146
7266
  var DEFAULT_REMOVAL_DELAY = 5e3;
7147
7267
  var DEFAULT_COALESCE_WINDOW = 100;
7148
7268
  var CLEANUP_INTERVAL = 1e3;
@@ -7155,7 +7275,7 @@ var fader = (options = {}) => {
7155
7275
  lastCount = expiries.length;
7156
7276
  }
7157
7277
  };
7158
- const dequeue = StateEffect10.define();
7278
+ const dequeue = StateEffect11.define();
7159
7279
  const fadeField = StateField12.define({
7160
7280
  create: () => ({
7161
7281
  decorations: Decoration14.none,
@@ -7266,9 +7386,9 @@ var fader = (options = {}) => {
7266
7386
  batchStart
7267
7387
  };
7268
7388
  },
7269
- provide: (f) => EditorView29.decorations.from(f, (value) => value.decorations)
7389
+ provide: (f) => EditorView30.decorations.from(f, (value) => value.decorations)
7270
7390
  });
7271
- const cleanup = ViewPlugin20.fromClass(class {
7391
+ const cleanup = ViewPlugin22.fromClass(class {
7272
7392
  view;
7273
7393
  #timer;
7274
7394
  constructor(view) {
@@ -7303,7 +7423,7 @@ var fader = (options = {}) => {
7303
7423
  return [
7304
7424
  fadeField,
7305
7425
  cleanup,
7306
- EditorView29.theme({
7426
+ EditorView30.theme({
7307
7427
  ".cm-fader": {
7308
7428
  animation: "fader 1s ease-out forwards"
7309
7429
  },
@@ -7318,11 +7438,11 @@ var fader = (options = {}) => {
7318
7438
  };
7319
7439
 
7320
7440
  // src/extensions/tags/typewriter.ts
7321
- import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
7322
- import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
7441
+ import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect12, StateField as StateField13 } from "@codemirror/state";
7442
+ import { Decoration as Decoration15, EditorView as EditorView31, ViewPlugin as ViewPlugin23, WidgetType as WidgetType9 } from "@codemirror/view";
7323
7443
  import { Domino as Domino3 } from "@dxos/ui";
7324
7444
  var typewriterBypass = Annotation3.define();
7325
- var typewriterDrainingEffect = StateEffect11.define();
7445
+ var typewriterDrainingEffect = StateEffect12.define();
7326
7446
  var CURSOR_LINGER = 3e3;
7327
7447
  var FRAME_BUDGET_MS = 4;
7328
7448
  var CHARS_PER_FRAME = 5;
@@ -7333,8 +7453,8 @@ var typewriter = (options = {}) => {
7333
7453
  const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
7334
7454
  const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
7335
7455
  const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
7336
- const suppressAppend = StateEffect11.define();
7337
- const insertChunk = StateEffect11.define();
7456
+ const suppressAppend = StateEffect12.define();
7457
+ const insertChunk = StateEffect12.define();
7338
7458
  const bufferField = StateField13.define({
7339
7459
  create: () => ({
7340
7460
  text: "",
@@ -7417,7 +7537,7 @@ var typewriter = (options = {}) => {
7417
7537
  })
7418
7538
  };
7419
7539
  });
7420
- const drainPlugin = ViewPlugin21.fromClass(class {
7540
+ const drainPlugin = ViewPlugin23.fromClass(class {
7421
7541
  view;
7422
7542
  _raf;
7423
7543
  _activeStreamTag = null;
@@ -7522,7 +7642,7 @@ var typewriter = (options = {}) => {
7522
7642
  ].filter(Boolean);
7523
7643
  };
7524
7644
  var typewriterCursor = (bufferField) => {
7525
- const hideCursor = StateEffect11.define();
7645
+ const hideCursor = StateEffect12.define();
7526
7646
  const visibilityField = StateField13.define({
7527
7647
  create: () => ({
7528
7648
  visible: false,
@@ -7576,9 +7696,9 @@ var typewriterCursor = (bufferField) => {
7576
7696
  }).range(pos)
7577
7697
  ]);
7578
7698
  },
7579
- provide: (field) => EditorView30.decorations.from(field)
7699
+ provide: (field) => EditorView31.decorations.from(field)
7580
7700
  });
7581
- const timerPlugin = ViewPlugin21.fromClass(class {
7701
+ const timerPlugin = ViewPlugin23.fromClass(class {
7582
7702
  view;
7583
7703
  _timer;
7584
7704
  constructor(view) {
@@ -7750,7 +7870,7 @@ var linkLength = (buffer, start, bracketAt) => {
7750
7870
 
7751
7871
  // src/extensions/tags/xml-block-decoration.ts
7752
7872
  import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
7753
- import { Decoration as Decoration16, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
7873
+ import { Decoration as Decoration16, ViewPlugin as ViewPlugin24 } from "@codemirror/view";
7754
7874
  var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
7755
7875
  const lineDecoration = lineClass ? Decoration16.line({
7756
7876
  class: lineClass
@@ -7806,7 +7926,7 @@ var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
7806
7926
  });
7807
7927
  return Decoration16.set(ranges, true);
7808
7928
  };
7809
- return ViewPlugin22.fromClass(class {
7929
+ return ViewPlugin24.fromClass(class {
7810
7930
  decorations;
7811
7931
  constructor(view) {
7812
7932
  this.decorations = buildDecorations5(view);
@@ -7823,7 +7943,7 @@ var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
7823
7943
 
7824
7944
  // src/extensions/tags/xml-formatting.ts
7825
7945
  import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
7826
- import { Decoration as Decoration17, EditorView as EditorView31, ViewPlugin as ViewPlugin23 } from "@codemirror/view";
7946
+ import { Decoration as Decoration17, EditorView as EditorView32, ViewPlugin as ViewPlugin25 } from "@codemirror/view";
7827
7947
  var XML_TAG_NODES = /* @__PURE__ */ new Set([
7828
7948
  "OpenTag",
7829
7949
  "CloseTag",
@@ -7886,7 +8006,7 @@ var xmlFormatting = ({ skip } = {}) => {
7886
8006
  return Decoration17.set(ranges, true);
7887
8007
  };
7888
8008
  return [
7889
- ViewPlugin23.fromClass(class {
8009
+ ViewPlugin25.fromClass(class {
7890
8010
  decorations;
7891
8011
  constructor(view) {
7892
8012
  this.decorations = buildDecorations5(view);
@@ -7899,7 +8019,7 @@ var xmlFormatting = ({ skip } = {}) => {
7899
8019
  }, {
7900
8020
  decorations: (instance) => instance.decorations
7901
8021
  }),
7902
- EditorView31.baseTheme({
8022
+ EditorView32.baseTheme({
7903
8023
  ".cm-xml-element": {
7904
8024
  backgroundColor: "var(--color-current-surface)",
7905
8025
  borderRadius: "0.25rem",
@@ -7916,8 +8036,8 @@ var xmlFormatting = ({ skip } = {}) => {
7916
8036
 
7917
8037
  // src/extensions/tags/xml-tags.ts
7918
8038
  import { syntaxTree as syntaxTree11 } from "@codemirror/language";
7919
- import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect12, StateField as StateField14 } from "@codemirror/state";
7920
- import { Decoration as Decoration18, EditorView as EditorView32, ViewPlugin as ViewPlugin24, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
8039
+ import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect13, StateField as StateField14 } from "@codemirror/state";
8040
+ import { Decoration as Decoration18, EditorView as EditorView33, ViewPlugin as ViewPlugin26, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
7921
8041
  import { invariant as invariant7 } from "@dxos/invariant";
7922
8042
  import { log as log11 } from "@dxos/log";
7923
8043
  import { Domino as Domino4 } from "@dxos/ui";
@@ -8029,17 +8149,17 @@ var decodeXmlEntity = (raw) => {
8029
8149
 
8030
8150
  // src/extensions/tags/xml-tags.ts
8031
8151
  var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
8032
- var navigatePreviousEffect = StateEffect12.define();
8033
- var navigateNextEffect = StateEffect12.define();
8152
+ var navigatePreviousEffect = StateEffect13.define();
8153
+ var navigateNextEffect = StateEffect13.define();
8034
8154
  var getXmlTextChild = (children) => {
8035
8155
  const child = children?.[0];
8036
8156
  return typeof child === "string" ? child : null;
8037
8157
  };
8038
8158
  var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
8039
8159
  var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8040
- var xmlTagContextEffect = StateEffect12.define();
8041
- var xmlTagResetEffect = StateEffect12.define();
8042
- var xmlTagUpdateEffect = StateEffect12.define();
8160
+ var xmlTagContextEffect = StateEffect13.define();
8161
+ var xmlTagResetEffect = StateEffect13.define();
8162
+ var xmlTagUpdateEffect = StateEffect13.define();
8043
8163
  var widgetContextStateField = StateField14.define({
8044
8164
  create: () => void 0,
8045
8165
  update: (value, tr) => {
@@ -8134,7 +8254,7 @@ var keyHandlers = keymap14.of([
8134
8254
  }
8135
8255
  ]);
8136
8256
  var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
8137
- return EditorView32.updateListener.of((update2) => {
8257
+ return EditorView33.updateListener.of((update2) => {
8138
8258
  update2.transactions.forEach((transaction) => {
8139
8259
  for (const effect of transaction.effects) {
8140
8260
  if (effect.is(navigatePreviousEffect)) {
@@ -8219,7 +8339,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
8219
8339
  });
8220
8340
  });
8221
8341
  };
8222
- var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
8342
+ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin26.fromClass(class {
8223
8343
  update(update2) {
8224
8344
  const widgetStateMap = update2.state.field(widgetStateMapStateField);
8225
8345
  const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
@@ -8304,8 +8424,8 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
8304
8424
  };
8305
8425
  },
8306
8426
  provide: (field) => [
8307
- EditorView32.decorations.from(field, (v) => v.decorations),
8308
- EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
8427
+ EditorView33.decorations.from(field, (v) => v.decorations),
8428
+ EditorView33.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
8309
8429
  ]
8310
8430
  });
8311
8431
  var buildDecorations4 = (state, range, registry, notifier) => {
@@ -8493,7 +8613,7 @@ var PlaceholderWidget2 = class extends WidgetType10 {
8493
8613
  export {
8494
8614
  Cursor,
8495
8615
  EditorState4 as EditorState,
8496
- EditorView33 as EditorView,
8616
+ EditorView34 as EditorView,
8497
8617
  Inline,
8498
8618
  InputModeExtensions,
8499
8619
  List,
@@ -8615,6 +8735,7 @@ export {
8615
8735
  scrollPastEnd,
8616
8736
  scrollThreadIntoView,
8617
8737
  scrollToLine,
8738
+ scrollbarAutohide,
8618
8739
  scroller,
8619
8740
  selectionState,
8620
8741
  setBlockquote,