@dxos/react-ui-editor 0.3.10-main.92d1f2c → 0.3.10-main.a0865c9

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 (51) hide show
  1. package/dist/lib/browser/index.mjs +383 -175
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +6 -3
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  7. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +3 -0
  8. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/TextEditor/extensions/basic.d.ts.map +1 -1
  10. package/dist/types/src/components/TextEditor/extensions/blast.d.ts +1 -1
  11. package/dist/types/src/components/TextEditor/extensions/blast.d.ts.map +1 -1
  12. package/dist/types/src/components/TextEditor/extensions/code.d.ts +2 -0
  13. package/dist/types/src/components/TextEditor/extensions/code.d.ts.map +1 -0
  14. package/dist/types/src/components/TextEditor/extensions/comments.d.ts +1 -1
  15. package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -1
  16. package/dist/types/src/components/TextEditor/extensions/highlight.d.ts +24 -0
  17. package/dist/types/src/components/TextEditor/extensions/highlight.d.ts.map +1 -0
  18. package/dist/types/src/components/TextEditor/extensions/index.d.ts +2 -0
  19. package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
  20. package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts +8 -0
  21. package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts.map +1 -1
  22. package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +1 -1
  23. package/dist/types/src/components/TextEditor/themes/default.d.ts.map +1 -1
  24. package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
  25. package/dist/types/src/hooks/useTextModel.d.ts +6 -0
  26. package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
  27. package/dist/types/src/hooks/yjs/yjs.stories.d.ts +1 -1
  28. package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +1 -1
  29. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  30. package/dist/types/src/testing/replicator.d.ts.map +1 -1
  31. package/package.json +23 -21
  32. package/src/components/TextEditor/MarkdownEditor.stories.tsx +41 -24
  33. package/src/components/TextEditor/TextEditor.stories.tsx +12 -1
  34. package/src/components/TextEditor/TextEditor.tsx +18 -1
  35. package/src/components/TextEditor/extensions/basic.ts +4 -3
  36. package/src/components/TextEditor/extensions/blast.ts +14 -28
  37. package/src/components/TextEditor/extensions/code.ts +99 -0
  38. package/src/components/TextEditor/extensions/comments.ts +9 -8
  39. package/src/components/TextEditor/extensions/experimental.tsx +1 -1
  40. package/src/components/TextEditor/extensions/highlight.ts +128 -0
  41. package/src/components/TextEditor/extensions/index.ts +2 -0
  42. package/src/components/TextEditor/extensions/markdown/bundle.ts +17 -17
  43. package/src/components/TextEditor/extensions/markdown/highlight.ts +1 -0
  44. package/src/components/TextEditor/extensions/table.ts +2 -5
  45. package/src/components/TextEditor/extensions/tasklist.ts +1 -1
  46. package/src/components/TextEditor/themes/default.ts +44 -2
  47. package/src/hooks/automerge/automerge.stories.tsx +1 -0
  48. package/src/hooks/useTextModel.ts +9 -0
  49. package/src/hooks/yjs/yjs.stories.tsx +1 -1
  50. package/src/styles/markdown.ts +5 -4
  51. package/src/testing/replicator.ts +1 -0
@@ -42,20 +42,20 @@ var autocomplete = ({ onSearch }) => {
42
42
  import { closeBrackets } from "@codemirror/autocomplete";
43
43
  import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
44
44
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
45
- import { EditorView, placeholder } from "@codemirror/view";
45
+ import { drawSelection, EditorView, placeholder } from "@codemirror/view";
46
46
  var basicBundle = ({ readonly, themeMode, placeholder: _placeholder }) => [
47
+ EditorView.lineWrapping,
47
48
  // TODO(burdon): Compare with minimalSetup.
48
49
  // https://codemirror.net/docs/ref/#codemirror.minimalSetup
49
50
  bracketMatching(),
50
51
  closeBrackets(),
51
- EditorView.lineWrapping,
52
+ drawSelection(),
52
53
  _placeholder && placeholder(_placeholder),
53
54
  // TODO(burdon): Is this required?
54
55
  themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
55
56
  ].filter(Boolean);
56
57
 
57
58
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts
58
- import { StateField } from "@codemirror/state";
59
59
  import { EditorView as EditorView2, keymap as keymap2 } from "@codemirror/view";
60
60
  import defaultsDeep from "lodash.defaultsdeep";
61
61
  import { invariant } from "@dxos/invariant";
@@ -86,7 +86,7 @@ var defaultOptions = {
86
86
  particleShrinkRate: 0.95,
87
87
  shakeIntensity: 5
88
88
  };
89
- var blast = (options) => {
89
+ var blast = (options = defaultOptions) => {
90
90
  let blaster;
91
91
  let last = 0;
92
92
  const getPoint = (view, pos) => {
@@ -123,10 +123,10 @@ var blast = (options) => {
123
123
  } else {
124
124
  blaster.resize();
125
125
  }
126
- const current = update4.view.state.selection.main.head;
126
+ const current = update4.state.selection.main.head;
127
127
  if (current !== last) {
128
128
  last = current;
129
- const { element, point } = getPoint(update4.view, current);
129
+ const { element, point } = getPoint(update4.view, current - 1);
130
130
  if (element && point) {
131
131
  blaster.spawn({
132
132
  element,
@@ -135,30 +135,16 @@ var blast = (options) => {
135
135
  }
136
136
  }
137
137
  }),
138
- // Document changed.
139
- StateField.define({
140
- create: () => null,
141
- update: (_value, transaction) => {
142
- if (blaster && transaction.docChanged) {
143
- const view = EditorView2.findFromDOM(blaster.node);
144
- const { element, point } = getPoint(view, transaction.selection.main.head);
145
- if (element && point) {
146
- blaster.spawn({
147
- element,
148
- point
149
- });
150
- }
151
- }
152
- return null;
153
- }
154
- }),
155
138
  keymap2.of([
156
139
  {
157
- any: (view, event) => {
158
- if (blaster && event.key === "Enter" && event.shiftKey) {
159
- blaster.shake({
160
- time: 0.4
161
- });
140
+ any: (_, event) => {
141
+ if (blaster) {
142
+ if (event.key === "Enter" && event.shiftKey) {
143
+ blaster.shake({
144
+ time: 0.8
145
+ });
146
+ return true;
147
+ }
162
148
  }
163
149
  return false;
164
150
  }
@@ -180,7 +166,7 @@ var Blaster = class {
180
166
  y: 0
181
167
  };
182
168
  this.shake = throttle(({ time }) => {
183
- this._shakeTime = this._shakeTimeMax;
169
+ this._shakeTime = this._shakeTimeMax || time;
184
170
  this._shakeTimeMax = time;
185
171
  }, 100);
186
172
  this.spawn = throttle(({ element, point }) => {
@@ -201,7 +187,7 @@ var Blaster = class {
201
187
  initialize() {
202
188
  invariant(!this._canvas && !this._ctx, void 0, {
203
189
  F: __dxlog_file,
204
- L: 152,
190
+ L: 138,
205
191
  S: this,
206
192
  A: [
207
193
  "!this._canvas && !this._ctx",
@@ -238,7 +224,7 @@ var Blaster = class {
238
224
  start() {
239
225
  invariant(this._canvas && this._ctx, void 0, {
240
226
  F: __dxlog_file,
241
- L: 191,
227
+ L: 177,
242
228
  S: this,
243
229
  A: [
244
230
  "this._canvas && this._ctx",
@@ -379,6 +365,126 @@ var random = (min, max) => {
379
365
  return min + ~~(Math.random() * (max - min + 1));
380
366
  };
381
367
 
368
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/code.ts
369
+ import { ViewPlugin, EditorView as EditorView3, Decoration } from "@codemirror/view";
370
+ import get from "lodash.get";
371
+ import { mx as mx2 } from "@dxos/react-ui-theme";
372
+
373
+ // packages/ui/react-ui-editor/src/styles/markdown.ts
374
+ import { mx } from "@dxos/react-ui-theme";
375
+ var headings = {
376
+ 1: [
377
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
378
+ "-ml-[10px]"
379
+ ],
380
+ 2: [
381
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
382
+ "-ml-[8px]"
383
+ ],
384
+ 3: [
385
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
386
+ "-ml-[7px]"
387
+ ],
388
+ 4: [
389
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
390
+ "-ml-[6px]"
391
+ ],
392
+ 5: [
393
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
394
+ "-ml-[5px]"
395
+ ],
396
+ 6: [
397
+ "mbs-4 mbe-2 font-medium text-inherit no-underline",
398
+ "-ml-[4px]"
399
+ ]
400
+ };
401
+ var heading = (level, readonly) => {
402
+ const [style, offset] = headings[level];
403
+ return mx(style, readonly && offset);
404
+ };
405
+ var light = "text-neutral-200 dark:text-neutral-800";
406
+ var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
407
+ var bold = "font-bold";
408
+ var italic = "italic";
409
+ var strikethrough = "line-through";
410
+ var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
411
+ var codeMark = "font-mono text-primary-500";
412
+ var inlineUrl = mx(code, "px-1");
413
+ var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
414
+ var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
415
+
416
+ // packages/ui/react-ui-editor/src/styles/tokens.ts
417
+ import { tailwindConfig } from "@dxos/react-ui-theme";
418
+ var tokens = tailwindConfig({}).theme;
419
+
420
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/code.ts
421
+ var CODE_REGEX = /```[\s\S]*?```/gs;
422
+ var styles = EditorView3.baseTheme({
423
+ "& .cm-code-block": {
424
+ display: "block",
425
+ paddingInline: "4px !important"
426
+ },
427
+ "&light .cm-code-block": {
428
+ background: get(tokens, "extend.colors.neutral.50")
429
+ },
430
+ "&dark .cm-code-block": {
431
+ background: get(tokens, "extend.colors.neutral.850")
432
+ },
433
+ "& .cm-code-block-first": {
434
+ paddingTop: "4px !important",
435
+ borderTopLeftRadius: "4px",
436
+ borderTopRightRadius: "4px"
437
+ },
438
+ "& .cm-code-block-last": {
439
+ paddingBottom: "4px !important",
440
+ borderBottomLeftRadius: "4px",
441
+ borderBottomRightRadius: "4px"
442
+ }
443
+ });
444
+ var getLineRange = (lines, from, to) => {
445
+ const start = lines.findIndex((line) => line.from >= from);
446
+ const end = lines.findIndex((line) => line.to >= to);
447
+ return [
448
+ start,
449
+ end
450
+ ];
451
+ };
452
+ var code2 = () => {
453
+ const getDecorations = (view) => {
454
+ const decorations = [];
455
+ if (view.state.readOnly) {
456
+ const text = view.state.doc.sliceString(0);
457
+ const matches = text.matchAll(CODE_REGEX);
458
+ const blocks = view.viewportLineBlocks;
459
+ for (const match of matches) {
460
+ const range = getLineRange(blocks, match.index, match.index + match[0].length);
461
+ for (let i = range[0]; i <= range[1]; i++) {
462
+ const block = blocks[i];
463
+ decorations.push(Decoration.line({
464
+ class: mx2("cm-code-block", i === range[0] && "cm-code-block-first", i === range[1] && "cm-code-block-last")
465
+ }).range(block.from));
466
+ }
467
+ }
468
+ }
469
+ return Decoration.set(decorations);
470
+ };
471
+ return [
472
+ ViewPlugin.fromClass(class {
473
+ constructor(view) {
474
+ this.decorations = getDecorations(view);
475
+ }
476
+ update(update4) {
477
+ if (update4.docChanged || update4.viewportChanged) {
478
+ this.decorations = getDecorations(update4.view);
479
+ }
480
+ }
481
+ }, {
482
+ decorations: (value) => value.decorations
483
+ }),
484
+ styles
485
+ ];
486
+ };
487
+
382
488
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/demo.ts
383
489
  import { keymap as keymap3 } from "@codemirror/view";
384
490
  var defaultItems = [
@@ -437,11 +543,11 @@ var demo = ({ delay = 75, items = defaultItems } = {}) => {
437
543
  };
438
544
 
439
545
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts
440
- import { keymap as keymap4, Decoration, EditorView as EditorView3, MatchDecorator, ViewPlugin, WidgetType } from "@codemirror/view";
546
+ import { keymap as keymap4, Decoration as Decoration2, EditorView as EditorView4, MatchDecorator, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
441
547
  import { debounce } from "@dxos/async";
442
548
  import { invariant as invariant2 } from "@dxos/invariant";
443
549
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts";
444
- var styles = EditorView3.baseTheme({
550
+ var styles2 = EditorView4.baseTheme({
445
551
  "& .cm-bookmark": {
446
552
  cursor: "pointer",
447
553
  margin: "4px",
@@ -485,7 +591,7 @@ var comments = (options = {}) => {
485
591
  regexp: /\[\^(\w+)\]/g,
486
592
  decoration: (match, view, pos) => {
487
593
  const id = match[1];
488
- return Decoration.replace({
594
+ return Decoration2.replace({
489
595
  id,
490
596
  widget: new BookmarkWidget(pos, id, () => handleUpdate({
491
597
  active: id
@@ -493,7 +599,7 @@ var comments = (options = {}) => {
493
599
  });
494
600
  }
495
601
  });
496
- const bookmarks = ViewPlugin.fromClass(class {
602
+ const bookmarks = ViewPlugin2.fromClass(class {
497
603
  constructor(view) {
498
604
  this.bookmarks = bookmarkMatcher.createDeco(view);
499
605
  }
@@ -502,8 +608,8 @@ var comments = (options = {}) => {
502
608
  }
503
609
  }, {
504
610
  decorations: (instance) => instance.bookmarks,
505
- provide: (plugin) => EditorView3.atomicRanges.of((view) => {
506
- return view.plugin(plugin)?.bookmarks || Decoration.none;
611
+ provide: (plugin) => EditorView4.atomicRanges.of((view) => {
612
+ return view.plugin(plugin)?.bookmarks || Decoration2.none;
507
613
  })
508
614
  });
509
615
  const handleUpdate = debounce((data) => {
@@ -514,17 +620,17 @@ var comments = (options = {}) => {
514
620
  {
515
621
  key: options?.key ?? "shift-meta-c",
516
622
  run: (view) => {
517
- const id = options.onCreate?.();
623
+ const { from, to, head } = view.state.selection.main;
624
+ const id = options.onCreate?.(from, to);
518
625
  if (id) {
519
- const pos = view.state.selection.main.head;
520
626
  const tag = `[^${id}]`;
521
627
  view.dispatch({
522
628
  changes: {
523
- from: pos,
629
+ from: head,
524
630
  insert: tag
525
631
  },
526
632
  selection: {
527
- anchor: pos + tag.length
633
+ anchor: head + tag.length
528
634
  }
529
635
  });
530
636
  return true;
@@ -535,13 +641,13 @@ var comments = (options = {}) => {
535
641
  ]),
536
642
  bookmarks,
537
643
  // Monitor cursor movement.
538
- EditorView3.updateListener.of((update4) => {
644
+ EditorView4.updateListener.of((update4) => {
539
645
  active = void 0;
540
646
  if (!options.onUpdate) {
541
647
  return;
542
648
  }
543
- const view = update4.view;
544
- const pos = view.state.selection.main.head;
649
+ const { view, state } = update4;
650
+ const pos = state.selection.main.head;
545
651
  const decorations = [];
546
652
  const rangeSet = view.plugin(bookmarks)?.bookmarks;
547
653
  let closest = Infinity;
@@ -549,7 +655,7 @@ var comments = (options = {}) => {
549
655
  /* view.visibleRanges?.[0] ?? */
550
656
  {
551
657
  from: 0,
552
- to: view.state.doc.length
658
+ to: state.doc.length
553
659
  }
554
660
  );
555
661
  rangeSet?.between(from, to, (from2, to2, value) => {
@@ -575,19 +681,121 @@ var comments = (options = {}) => {
575
681
  });
576
682
  }
577
683
  }),
578
- styles
684
+ styles2
685
+ ];
686
+ };
687
+
688
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/highlight.ts
689
+ import { StateEffect, StateField } from "@codemirror/state";
690
+ import { Decoration as Decoration3, EditorView as EditorView5 } from "@codemirror/view";
691
+ import sortBy from "lodash.sortby";
692
+ import { useEffect } from "react";
693
+ var styles3 = EditorView5.baseTheme({
694
+ "& .cm-highlight": {
695
+ backgroundColor: "yellow"
696
+ },
697
+ "& .cm-highlight::before": {
698
+ content: "]"
699
+ },
700
+ "& .cm-highlight-active": {
701
+ backgroundColor: "lime"
702
+ }
703
+ });
704
+ var marks = {
705
+ highlight: Decoration3.mark({
706
+ class: "cm-highlight"
707
+ }),
708
+ HighlightActive: Decoration3.mark({
709
+ class: "cm-highlight-active"
710
+ })
711
+ };
712
+ var setHighlights = StateEffect.define();
713
+ var useHighlights = (view, ranges = []) => {
714
+ useEffect(() => {
715
+ view?.dispatch({
716
+ effects: setHighlights.of(ranges)
717
+ });
718
+ }, [
719
+ view,
720
+ ranges
721
+ ]);
722
+ };
723
+ var highlightStateField = StateField.define({
724
+ create: () => [],
725
+ update: (threads, tr) => {
726
+ for (const effect of tr.effects) {
727
+ if (effect.is(setHighlights)) {
728
+ return effect.value;
729
+ }
730
+ }
731
+ return threads;
732
+ }
733
+ });
734
+ var highlightDecorations = EditorView5.decorations.compute([
735
+ highlightStateField
736
+ ], (state) => {
737
+ const selectionRanges = state.field(highlightStateField);
738
+ const decorations = sortBy(selectionRanges ?? [], (selection) => selection.from)?.flatMap((selection) => {
739
+ const range = {
740
+ from: selection.from,
741
+ to: selection.to + 1
742
+ };
743
+ if (selection.to > selection.from) {
744
+ if (selection.active) {
745
+ return marks.HighlightActive.range(range.from, range.to);
746
+ } else {
747
+ return marks.highlight.range(range.from, range.to);
748
+ }
749
+ } else {
750
+ return [];
751
+ }
752
+ }) ?? [];
753
+ return Decoration3.set(decorations);
754
+ });
755
+ var listener = (options) => {
756
+ return EditorView5.updateListener.of((update4) => {
757
+ const { view, state } = update4;
758
+ const { head } = state.selection.main;
759
+ const ranges = state.field(highlightStateField);
760
+ let mod = false;
761
+ const newRanges = ranges.map((range) => {
762
+ const active = head >= range.from && head <= range.to;
763
+ if (active !== range.active) {
764
+ mod = true;
765
+ return {
766
+ ...range,
767
+ active
768
+ };
769
+ } else {
770
+ return range;
771
+ }
772
+ });
773
+ if (mod) {
774
+ view.dispatch({
775
+ effects: setHighlights.of(newRanges)
776
+ });
777
+ options?.onChange?.(newRanges.find((range) => range.active)?.id);
778
+ }
779
+ });
780
+ };
781
+ var highlight = (options = {}) => {
782
+ return [
783
+ highlightStateField,
784
+ highlightDecorations,
785
+ listener(options),
786
+ styles3
579
787
  ];
580
788
  };
581
789
 
582
790
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/image.ts
583
791
  import { syntaxTree } from "@codemirror/language";
584
792
  import { RangeSetBuilder, StateField as StateField2 } from "@codemirror/state";
585
- import { Decoration as Decoration2, EditorView as EditorView4, WidgetType as WidgetType2 } from "@codemirror/view";
793
+ import { Decoration as Decoration4, EditorView as EditorView6, WidgetType as WidgetType2 } from "@codemirror/view";
586
794
  var image = (options = {}) => {
587
795
  return StateField2.define({
588
796
  create: (state) => update(state, options),
589
797
  update: (_, tr) => update(tr.state, options),
590
- provide: (field) => EditorView4.decorations.from(field)
798
+ provide: (field) => EditorView6.decorations.from(field)
591
799
  });
592
800
  };
593
801
  var update = (state, options) => {
@@ -600,7 +808,7 @@ var update = (state, options) => {
600
808
  if (urlNode) {
601
809
  const hide = state.readOnly || cursor < node.from || cursor > node.to;
602
810
  const url = state.sliceDoc(urlNode.from, urlNode.to);
603
- builder.add(hide ? node.from : node.to, node.to, Decoration2.replace({
811
+ builder.add(hide ? node.from : node.to, node.to, Decoration4.replace({
604
812
  widget: new ImageWidget(url)
605
813
  }));
606
814
  }
@@ -628,12 +836,12 @@ var ImageWidget = class extends WidgetType2 {
628
836
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/link.ts
629
837
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
630
838
  import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField3 } from "@codemirror/state";
631
- import { Decoration as Decoration3, EditorView as EditorView5, WidgetType as WidgetType3 } from "@codemirror/view";
839
+ import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as WidgetType3 } from "@codemirror/view";
632
840
  var link = (options = {}) => {
633
841
  return StateField3.define({
634
842
  create: (state) => update2(state, options),
635
843
  update: (_, tr) => update2(tr.state, options),
636
- provide: (field) => EditorView5.decorations.from(field)
844
+ provide: (field) => EditorView7.decorations.from(field)
637
845
  });
638
846
  };
639
847
  var LinkButton = class extends WidgetType3 {
@@ -688,20 +896,20 @@ var update2 = (state, options) => {
688
896
  syntaxTree2(state).iterate({
689
897
  enter: (node) => {
690
898
  if (node.name === "Link") {
691
- const marks = node.node.getChildren("LinkMark");
692
- const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
899
+ const marks2 = node.node.getChildren("LinkMark");
900
+ const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
693
901
  const urlNode = node.node.getChild("URL");
694
902
  const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
695
903
  if (!url) {
696
904
  return false;
697
905
  }
698
906
  if (state.readOnly || cursor < node.from || cursor > node.to) {
699
- builder.add(node.from, node.to, Decoration3.replace({
907
+ builder.add(node.from, node.to, Decoration5.replace({
700
908
  widget: new LinkText(node.from, text, options.link ? url : void 0)
701
909
  }));
702
910
  }
703
911
  if (options.onRender) {
704
- builder.add(node.to, node.to, Decoration3.replace({
912
+ builder.add(node.to, node.to, Decoration5.replace({
705
913
  widget: new LinkButton(node.from, url, options.onRender)
706
914
  }));
707
915
  }
@@ -714,7 +922,7 @@ var update2 = (state, options) => {
714
922
 
715
923
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/listener.ts
716
924
  import { StateField as StateField4 } from "@codemirror/state";
717
- var listener = ({ onChange }) => {
925
+ var listener2 = ({ onChange }) => {
718
926
  return StateField4.define({
719
927
  create: () => null,
720
928
  update: (_value, transaction) => {
@@ -732,67 +940,18 @@ import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirr
732
940
  import { markdownLanguage as markdownLanguage2, markdown } from "@codemirror/lang-markdown";
733
941
  import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
734
942
  import { languages } from "@codemirror/language-data";
735
- import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
943
+ import { searchKeymap } from "@codemirror/search";
736
944
  import { EditorState } from "@codemirror/state";
737
945
  import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
738
- import { crosshairCursor, drawSelection, dropCursor, EditorView as EditorView6, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap as keymap5, placeholder as placeholder2, rectangularSelection } from "@codemirror/view";
946
+ import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView8, highlightActiveLine, keymap as keymap5, placeholder as placeholder2 } from "@codemirror/view";
739
947
 
740
948
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
741
949
  import { markdownLanguage } from "@codemirror/lang-markdown";
742
950
  import { HighlightStyle } from "@codemirror/language";
743
951
  import { tags, styleTags, Tag } from "@lezer/highlight";
744
952
  import { Table } from "@lezer/markdown";
745
- import get from "lodash.get";
746
- import { mx as mx2 } from "@dxos/react-ui-theme";
747
-
748
- // packages/ui/react-ui-editor/src/styles/markdown.ts
749
- import { mx } from "@dxos/react-ui-theme";
750
- var headings = {
751
- 1: [
752
- "mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
753
- "-ml-1.5"
754
- ],
755
- 2: [
756
- "mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
757
- "-ml-1.5"
758
- ],
759
- 3: [
760
- "mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
761
- "-ml-1.5"
762
- ],
763
- 4: [
764
- "mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
765
- "-ml-[5px]"
766
- ],
767
- 5: [
768
- "mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
769
- "-ml-[5px]"
770
- ],
771
- 6: [
772
- "mbs-4 mbe-2 font-medium text-inherit no-underline",
773
- "-ml-[4px]"
774
- ]
775
- };
776
- var heading = (level, readonly) => {
777
- const [style, offset] = headings[level];
778
- return mx(style, readonly && offset);
779
- };
780
- var light = "text-neutral-200 dark:text-neutral-800";
781
- var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
782
- var bold = "font-bold";
783
- var italic = "italic";
784
- var strikethrough = "line-through";
785
- var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
786
- var codeMark = "font-mono text-primary-500";
787
- var inlineUrl = mx(code, "px-1");
788
- var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
789
- var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
790
-
791
- // packages/ui/react-ui-editor/src/styles/tokens.ts
792
- import { tailwindConfig } from "@dxos/react-ui-theme";
793
- var tokens = tailwindConfig({}).theme;
794
-
795
- // packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
953
+ import get2 from "lodash.get";
954
+ import { mx as mx3 } from "@dxos/react-ui-theme";
796
955
  var markdownTags = {
797
956
  Blockquote: Tag.define(),
798
957
  CodeMark: Tag.define(),
@@ -963,11 +1122,12 @@ var markdownHighlightStyle = (readonly) => {
963
1122
  ],
964
1123
  class: blockquote
965
1124
  },
1125
+ // TODO(burdon): Replace with extension.
966
1126
  {
967
1127
  tag: [
968
1128
  markdownTags.HorizontalRule
969
1129
  ],
970
- class: mx2(horizontalRule, readonly && "-indent-[100rem]")
1130
+ class: mx3(horizontalRule, readonly && "-indent-[100rem]")
971
1131
  },
972
1132
  // TODO(burdon): Only if being edited.
973
1133
  {
@@ -979,7 +1139,7 @@ var markdownHighlightStyle = (readonly) => {
979
1139
  ], {
980
1140
  scope: markdownLanguage,
981
1141
  all: {
982
- fontFamily: get(tokens, "fontFamily.body", []).join(",")
1142
+ fontFamily: get2(tokens, "fontFamily.body", []).join(",")
983
1143
  }
984
1144
  });
985
1145
  };
@@ -987,22 +1147,19 @@ var markdownHighlightStyle = (readonly) => {
987
1147
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
988
1148
  var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
989
1149
  return [
1150
+ EditorState.allowMultipleSelections.of(true),
1151
+ EditorState.tabSize.of(2),
1152
+ EditorView8.lineWrapping,
1153
+ customKeymap(),
990
1154
  bracketMatching2(),
991
1155
  closeBrackets2(),
992
- _placeholder && placeholder2(_placeholder),
993
- EditorState.allowMultipleSelections.of(true),
994
- EditorView6.lineWrapping,
995
1156
  crosshairCursor(),
996
1157
  dropCursor(),
997
- drawSelection(),
1158
+ drawSelection2(),
998
1159
  highlightActiveLine(),
999
- highlightActiveLineGutter(),
1000
- highlightSelectionMatches(),
1001
- highlightSpecialChars(),
1002
1160
  history(),
1003
1161
  indentOnInput(),
1004
- rectangularSelection(),
1005
- customkeymap(),
1162
+ _placeholder && placeholder2(_placeholder),
1006
1163
  // Main extension.
1007
1164
  // https://github.com/codemirror/lang-markdown
1008
1165
  // https://codemirror.net/5/mode/markdown/index.html (demo).
@@ -1027,7 +1184,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
1027
1184
  syntaxHighlighting2(markdownHighlightStyle(readonly))
1028
1185
  ].filter(Boolean);
1029
1186
  };
1030
- var customkeymap = () => keymap5.of([
1187
+ var customKeymap = () => keymap5.of([
1031
1188
  // https://codemirror.net/docs/ref/#commands.indentWithTab
1032
1189
  indentWithTab,
1033
1190
  // https://codemirror.net/docs/ref/#commands.standardKeymap
@@ -1066,12 +1223,12 @@ var mention = ({ onSearch }) => {
1066
1223
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/table.ts
1067
1224
  import { syntaxTree as syntaxTree3 } from "@codemirror/language";
1068
1225
  import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField5 } from "@codemirror/state";
1069
- import { Decoration as Decoration4, EditorView as EditorView7, WidgetType as WidgetType4 } from "@codemirror/view";
1226
+ import { Decoration as Decoration6, EditorView as EditorView9, WidgetType as WidgetType4 } from "@codemirror/view";
1070
1227
  var table = (options = {}) => {
1071
1228
  return StateField5.define({
1072
1229
  create: (state) => update3(state, options),
1073
1230
  update: (_, tr) => update3(tr.state, options),
1074
- provide: (field) => EditorView7.decorations.from(field)
1231
+ provide: (field) => EditorView9.decorations.from(field)
1075
1232
  });
1076
1233
  };
1077
1234
  var update3 = (state, options) => {
@@ -1115,9 +1272,12 @@ var update3 = (state, options) => {
1115
1272
  });
1116
1273
  tables.forEach((table2) => {
1117
1274
  const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
1118
- hide && builder.add(table2.from, table2.to, Decoration4.replace({
1275
+ hide && builder.add(table2.from, table2.to, Decoration6.replace({
1119
1276
  widget: new TableWidget(table2)
1120
1277
  }));
1278
+ builder.add(table2.from, table2.to, Decoration6.mark({
1279
+ class: "cm-table"
1280
+ }));
1121
1281
  });
1122
1282
  return builder.finish();
1123
1283
  };
@@ -1156,8 +1316,8 @@ var TableWidget = class extends WidgetType4 {
1156
1316
  };
1157
1317
 
1158
1318
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/tasklist.ts
1159
- import { EditorView as EditorView8, Decoration as Decoration5, WidgetType as WidgetType5, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin2 } from "@codemirror/view";
1160
- var styles2 = EditorView8.baseTheme({
1319
+ import { EditorView as EditorView10, Decoration as Decoration7, WidgetType as WidgetType5, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin3 } from "@codemirror/view";
1320
+ var styles4 = EditorView10.baseTheme({
1161
1321
  "& .cm-task-item": {
1162
1322
  paddingLeft: "4px",
1163
1323
  paddingRight: "8px"
@@ -1203,7 +1363,7 @@ var tasklist = (options = {}) => {
1203
1363
  decoration: (match, view, pos) => {
1204
1364
  const indent = Math.floor(match[1].length / 2);
1205
1365
  const checked = match[2] === "x" || match[2] === "X";
1206
- return Decoration5.replace({
1366
+ return Decoration7.replace({
1207
1367
  widget: new CheckboxWidget(pos, checked, indent, view.state.readOnly ? void 0 : (checked2) => {
1208
1368
  const idx = pos + match[0].indexOf("[") + 1;
1209
1369
  view.dispatch({
@@ -1221,7 +1381,7 @@ var tasklist = (options = {}) => {
1221
1381
  });
1222
1382
  }
1223
1383
  });
1224
- const tasks = ViewPlugin2.fromClass(class {
1384
+ const tasks = ViewPlugin3.fromClass(class {
1225
1385
  constructor(view) {
1226
1386
  this.tasks = taskMatcher.createDeco(view);
1227
1387
  }
@@ -1229,14 +1389,14 @@ var tasklist = (options = {}) => {
1229
1389
  this.tasks = taskMatcher.updateDeco(update4, this.tasks);
1230
1390
  }
1231
1391
  }, {
1232
- decorations: (instance) => instance.tasks,
1233
- provide: (plugin) => EditorView8.atomicRanges.of((view) => {
1234
- return view.plugin(plugin)?.tasks || Decoration5.none;
1392
+ decorations: (value) => value.tasks,
1393
+ provide: (plugin) => EditorView10.atomicRanges.of((view) => {
1394
+ return view.plugin(plugin)?.tasks || Decoration7.none;
1235
1395
  })
1236
1396
  });
1237
1397
  return [
1238
1398
  tasks,
1239
- styles2
1399
+ styles4
1240
1400
  ];
1241
1401
  };
1242
1402
 
@@ -1285,7 +1445,7 @@ var tooltip = ({ onHover, regexp = markdownLinkRegexp }) => hoverTooltip((view,
1285
1445
  });
1286
1446
 
1287
1447
  // packages/ui/react-ui-editor/src/components/TextEditor/themes/default.ts
1288
- import get2 from "lodash.get";
1448
+ import get3 from "lodash.get";
1289
1449
  var defaultTheme = {
1290
1450
  //
1291
1451
  // Main layout:
@@ -1302,7 +1462,8 @@ var defaultTheme = {
1302
1462
  outline: "none"
1303
1463
  },
1304
1464
  "& .cm-scroller": {
1305
- overflow: "visible"
1465
+ overflow: "visible",
1466
+ fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
1306
1467
  },
1307
1468
  "& .cm-content": {
1308
1469
  padding: 0,
@@ -1310,20 +1471,20 @@ var defaultTheme = {
1310
1471
  fontSize: "16px"
1311
1472
  },
1312
1473
  "&light .cm-content": {
1313
- color: get2(tokens, "extend.colors.neutral.900", "black"),
1474
+ color: get3(tokens, "extend.colors.neutral.900", "black"),
1314
1475
  caretColor: "black"
1315
1476
  },
1316
1477
  "&dark .cm-content": {
1317
- color: get2(tokens, "extend.colors.neutral.100", "white"),
1478
+ color: get3(tokens, "extend.colors.neutral.100", "white"),
1318
1479
  caretColor: "white"
1319
1480
  },
1320
1481
  //
1321
1482
  // Cursor
1322
1483
  //
1323
- "&light .cm-cursor": {
1484
+ "&light .cm-cursor, &light .cm-dropCursor": {
1324
1485
  borderLeft: "2px solid black"
1325
1486
  },
1326
- "&dark .cm-cursor": {
1487
+ "&dark .cm-cursor, &dark .cm-dropCursor": {
1327
1488
  borderLeft: "2px solid white"
1328
1489
  },
1329
1490
  "& .cm-placeholder": {
@@ -1343,16 +1504,16 @@ var defaultTheme = {
1343
1504
  // selection
1344
1505
  //
1345
1506
  "&light .cm-selectionBackground, &light.cm-focused .cm-selectionBackground": {
1346
- background: get2(tokens, "extend.colors.primary.150", "#00ffff")
1507
+ background: get3(tokens, "extend.colors.primary.150", "#00ffff")
1347
1508
  },
1348
1509
  "&dark .cm-selectionBackground, &dark.cm-focused .cm-selectionBackground": {
1349
- background: get2(tokens, "extend.colors.primary.850", "#00ffff")
1510
+ background: get3(tokens, "extend.colors.primary.850", "#00ffff")
1350
1511
  },
1351
1512
  "&light .cm-selectionMatch": {
1352
- background: get2(tokens, "extend.colors.primary.250", "#00ffff") + "44"
1513
+ background: get3(tokens, "extend.colors.primary.250", "#00ffff") + "44"
1353
1514
  },
1354
1515
  "&dark .cm-selectionMatch": {
1355
- background: get2(tokens, "extend.colors.primary.600", "#00ffff") + "44"
1516
+ background: get3(tokens, "extend.colors.primary.600", "#00ffff") + "44"
1356
1517
  },
1357
1518
  //
1358
1519
  // collaboration
@@ -1385,12 +1546,12 @@ var defaultTheme = {
1385
1546
  // link
1386
1547
  //
1387
1548
  "& .cm-link": {
1388
- color: get2(tokens, "extend.colors.primary.500"),
1549
+ color: get3(tokens, "extend.colors.primary.500"),
1389
1550
  textDecorationLine: "underline",
1390
1551
  textDecorationThickness: "1px",
1391
1552
  textUnderlineOffset: "2px",
1392
1553
  borderRadius: ".125rem",
1393
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1554
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1394
1555
  },
1395
1556
  //
1396
1557
  // tooltip
@@ -1412,7 +1573,7 @@ var defaultTheme = {
1412
1573
  display: "none"
1413
1574
  },
1414
1575
  "& .cm-completionLabel": {
1415
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1576
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1416
1577
  },
1417
1578
  "& .cm-completionMatchedText": {
1418
1579
  textDecoration: "none"
@@ -1427,12 +1588,16 @@ var defaultTheme = {
1427
1588
  //
1428
1589
  // table
1429
1590
  //
1591
+ "& .cm-table *": {
1592
+ fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
1593
+ textDecoration: "none !important"
1594
+ },
1430
1595
  "& .cm-table-head": {
1431
1596
  padding: "2px 16px 2px 0px",
1432
- borderBottom: `1px solid ${get2(tokens, "extend.colors.neutral.500")}`,
1597
+ borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
1433
1598
  fontWeight: 100,
1434
1599
  textAlign: "left",
1435
- color: get2(tokens, "extend.colors.neutral.500")
1600
+ color: get3(tokens, "extend.colors.neutral.500")
1436
1601
  },
1437
1602
  "& .cm-table-cell": {
1438
1603
  padding: "2px 16px 2px 0px"
@@ -1447,8 +1612,8 @@ var defaultTheme = {
1447
1612
  // font size
1448
1613
  // TODO(thure): This appears to be the best or only way to set selection caret heights, but it's far more verbose than it needs to be.
1449
1614
  //
1450
- ...Object.keys(get2(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
1451
- const height = get2(tokens, [
1615
+ ...Object.keys(get3(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
1616
+ const height = get3(tokens, [
1452
1617
  "extend",
1453
1618
  "fontSize",
1454
1619
  fontSize,
@@ -1465,41 +1630,76 @@ var defaultTheme = {
1465
1630
  height
1466
1631
  };
1467
1632
  return acc;
1468
- }, {})
1633
+ }, {}),
1634
+ /**
1635
+ * Panels
1636
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
1637
+ *
1638
+ * Find/replace panel.
1639
+ * <div class="cm-announced">...</div>
1640
+ * <div class="cm-scroller">...</div>
1641
+ * <div class="cm-panels cm-panels-bottom">
1642
+ * <div class="cm-search cm-panel">
1643
+ * <input class="cm-textfield" />
1644
+ * <button class="cm-button">...</button>
1645
+ * <label><input type="checkbox" />...</label>
1646
+ * </div>
1647
+ * </div
1648
+ */
1649
+ "& .cm-panels": {
1650
+ border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`,
1651
+ borderBottom: "none"
1652
+ },
1653
+ "& .cm-panel": {
1654
+ background: get3(tokens, "extend.colors.neutral.50"),
1655
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1656
+ },
1657
+ "& .cm-button": {
1658
+ margin: "4px",
1659
+ fontFamily: get3(tokens, "fontFamily.body", []).join(","),
1660
+ background: get3(tokens, "extend.colors.neutral.100"),
1661
+ border: "none"
1662
+ },
1663
+ "& .cm-searchMatch": {
1664
+ backgroundColor: get3(tokens, "extend.colors.yellow.100")
1665
+ },
1666
+ "& .cm-searchMatch.cm-searchMatch-selected": {
1667
+ backgroundColor: get3(tokens, "extend.colors.primary.100")
1668
+ }
1469
1669
  };
1470
1670
  var textTheme = {
1471
1671
  "& .cm-scroller": {
1472
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1672
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1473
1673
  },
1474
1674
  "& .cm-placeholder": {
1475
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1675
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1476
1676
  }
1477
1677
  };
1478
1678
  var markdownTheme = {
1479
1679
  // NOTE: Must leave base font family as is (i.e., monospace) due to fenced code blocks.
1480
1680
  "& .cm-placeholder": {
1481
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1681
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1482
1682
  }
1483
1683
  };
1484
1684
  var codeTheme = {
1485
1685
  "& .cm-scroller": {
1486
- fontFamily: get2(tokens, "fontFamily.mono", []).join(",")
1686
+ fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
1487
1687
  },
1488
1688
  "& .cm-placeholder": {
1489
- fontFamily: get2(tokens, "fontFamily.mono", []).join(",")
1689
+ fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
1490
1690
  }
1491
1691
  };
1492
1692
 
1493
1693
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
1494
1694
  import { EditorState as EditorState2 } from "@codemirror/state";
1495
- import { EditorView as EditorView9 } from "@codemirror/view";
1695
+ import { EditorView as EditorView11 } from "@codemirror/view";
1496
1696
  import { useFocusableGroup } from "@fluentui/react-tabster";
1497
1697
  import { vim } from "@replit/codemirror-vim";
1498
1698
  import defaultsDeep2 from "lodash.defaultsdeep";
1499
- import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
1699
+ import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useState } from "react";
1500
1700
  import { generateName } from "@dxos/display-name";
1501
1701
  import { useThemeContext } from "@dxos/react-ui";
1502
- import { getColorForValue, inputSurface, mx as mx3 } from "@dxos/react-ui-theme";
1702
+ import { getColorForValue, inputSurface, mx as mx4 } from "@dxos/react-ui-theme";
1503
1703
  var EditorModes = [
1504
1704
  "default",
1505
1705
  "vim"
@@ -1522,7 +1722,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
1522
1722
  root
1523
1723
  ]);
1524
1724
  const { awareness, peer } = model;
1525
- useEffect(() => {
1725
+ useEffect2(() => {
1526
1726
  if (awareness && peer) {
1527
1727
  awareness.setLocalStateField("user", {
1528
1728
  name: peer.name ?? generateName(peer.id),
@@ -1542,7 +1742,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
1542
1742
  peer,
1543
1743
  themeMode
1544
1744
  ]);
1545
- useEffect(() => {
1745
+ useEffect2(() => {
1546
1746
  if (!root) {
1547
1747
  return;
1548
1748
  }
@@ -1553,10 +1753,11 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
1553
1753
  // TODO(burdon): Factor out VIM mode?
1554
1754
  editorMode === "vim" && vim(),
1555
1755
  // Theme.
1556
- EditorView9.baseTheme(defaultTheme),
1557
- EditorView9.theme(slots?.editor?.theme ?? {}),
1756
+ // TODO(burdon): Make optional.
1757
+ EditorView11.baseTheme(defaultTheme),
1758
+ EditorView11.theme(slots?.editor?.theme ?? {}),
1558
1759
  // TODO(burdon): themeMode doesn't change in storybooks.
1559
- EditorView9.darkTheme.of(themeMode === "dark"),
1760
+ EditorView11.darkTheme.of(themeMode === "dark"),
1560
1761
  // Storage and replication.
1561
1762
  model.extension,
1562
1763
  // Custom.
@@ -1564,7 +1765,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
1564
1765
  ].filter(Boolean)
1565
1766
  });
1566
1767
  view?.destroy();
1567
- setView(new EditorView9({
1768
+ setView(new EditorView11({
1568
1769
  state: state2,
1569
1770
  parent: root
1570
1771
  }));
@@ -1644,7 +1845,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
1644
1845
  });
1645
1846
  var defaultSlots = {
1646
1847
  root: {
1647
- className: mx3("p-2", inputSurface)
1848
+ className: mx4("p-2", inputSurface)
1648
1849
  }
1649
1850
  };
1650
1851
  var defaultTextSlots = {
@@ -1661,15 +1862,15 @@ var defaultMarkdownSlots = {
1661
1862
  };
1662
1863
 
1663
1864
  // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
1664
- import get3 from "lodash.get";
1665
- import { useEffect as useEffect2, useState as useState2 } from "react";
1865
+ import get4 from "lodash.get";
1866
+ import { useEffect as useEffect3, useState as useState2 } from "react";
1666
1867
  import { yCollab } from "y-codemirror.next";
1667
1868
  import { invariant as invariant3 } from "@dxos/invariant";
1668
1869
  import { getRawDoc, isActualAutomergeObject } from "@dxos/react-client/echo";
1669
1870
 
1670
1871
  // packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
1671
- import { Annotation, Facet, StateEffect, StateField as StateField6 } from "@codemirror/state";
1672
- import { ViewPlugin as ViewPlugin3 } from "@codemirror/view";
1872
+ import { Annotation, Facet, StateEffect as StateEffect2, StateField as StateField6 } from "@codemirror/state";
1873
+ import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1673
1874
  import * as automerge2 from "@dxos/automerge/automerge";
1674
1875
 
1675
1876
  // packages/ui/react-ui-editor/src/hooks/automerge/PatchSemaphore.ts
@@ -1847,7 +2048,7 @@ var PatchSemaphore = class {
1847
2048
  };
1848
2049
 
1849
2050
  // packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
1850
- var effectType = StateEffect.define({});
2051
+ var effectType = StateEffect2.define({});
1851
2052
  var updateHeads = (newHeads) => effectType.of({
1852
2053
  newHeads
1853
2054
  });
@@ -1887,7 +2088,7 @@ var automergePlugin = (handle, path) => {
1887
2088
  }
1888
2089
  });
1889
2090
  const semaphore = new PatchSemaphore(stateField);
1890
- const viewPlugin = ViewPlugin3.fromClass(class AutomergeCodemirrorViewPlugin {
2091
+ const viewPlugin = ViewPlugin4.fromClass(class AutomergeCodemirrorViewPlugin {
1891
2092
  constructor(view) {
1892
2093
  this._handleChange = () => {
1893
2094
  this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
@@ -2063,7 +2264,7 @@ var useTextModel = ({ identity, space, text }) => {
2063
2264
  space,
2064
2265
  text
2065
2266
  }));
2066
- useEffect2(() => {
2267
+ useEffect3(() => {
2067
2268
  setModel(createModel({
2068
2269
  identity,
2069
2270
  space,
@@ -2090,7 +2291,7 @@ var createModel = (options) => {
2090
2291
  var createYjsModel = ({ identity, space, text }) => {
2091
2292
  invariant3(text?.doc && text?.content, void 0, {
2092
2293
  F: __dxlog_file4,
2093
- L: 74,
2294
+ L: 81,
2094
2295
  S: void 0,
2095
2296
  A: [
2096
2297
  "text?.doc && text?.content",
@@ -2106,6 +2307,7 @@ var createYjsModel = ({ identity, space, text }) => {
2106
2307
  id: text.doc.guid,
2107
2308
  content: text.content,
2108
2309
  text: () => text.content.toString(),
2310
+ ranges: [],
2109
2311
  extension: yCollab(text.content, provider?.awareness),
2110
2312
  awareness: provider?.awareness,
2111
2313
  peer: identity ? {
@@ -2122,7 +2324,8 @@ var createAutomergeModel = ({ identity, text }) => {
2122
2324
  return {
2123
2325
  id: obj.id,
2124
2326
  content: doc,
2125
- text: () => get3(doc.handle.docSync(), doc.path),
2327
+ text: () => get4(doc.handle.docSync(), doc.path),
2328
+ ranges: [],
2126
2329
  extension: automergePlugin(doc.handle, doc.path),
2127
2330
  peer: identity ? {
2128
2331
  id: identity.identityKey.toHex(),
@@ -2143,6 +2346,7 @@ export {
2143
2346
  autocomplete,
2144
2347
  basicBundle,
2145
2348
  blast,
2349
+ code2 as code,
2146
2350
  codeTheme,
2147
2351
  comments,
2148
2352
  cursorColor,
@@ -2152,9 +2356,12 @@ export {
2152
2356
  defaultTextSlots,
2153
2357
  defaultTheme,
2154
2358
  demo,
2359
+ highlight,
2360
+ highlightDecorations,
2361
+ highlightStateField,
2155
2362
  image,
2156
2363
  link,
2157
- listener,
2364
+ listener2 as listener,
2158
2365
  markdownBundle,
2159
2366
  markdownHighlightStyle,
2160
2367
  markdownTags,
@@ -2166,6 +2373,7 @@ export {
2166
2373
  tasklist,
2167
2374
  textTheme,
2168
2375
  tooltip,
2376
+ useHighlights,
2169
2377
  useTextModel
2170
2378
  };
2171
2379
  //# sourceMappingURL=index.mjs.map