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

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 +381 -174
  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 +22 -20
  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 +43 -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:
@@ -1310,20 +1470,20 @@ var defaultTheme = {
1310
1470
  fontSize: "16px"
1311
1471
  },
1312
1472
  "&light .cm-content": {
1313
- color: get2(tokens, "extend.colors.neutral.900", "black"),
1473
+ color: get3(tokens, "extend.colors.neutral.900", "black"),
1314
1474
  caretColor: "black"
1315
1475
  },
1316
1476
  "&dark .cm-content": {
1317
- color: get2(tokens, "extend.colors.neutral.100", "white"),
1477
+ color: get3(tokens, "extend.colors.neutral.100", "white"),
1318
1478
  caretColor: "white"
1319
1479
  },
1320
1480
  //
1321
1481
  // Cursor
1322
1482
  //
1323
- "&light .cm-cursor": {
1483
+ "&light .cm-cursor, &light .cm-dropCursor": {
1324
1484
  borderLeft: "2px solid black"
1325
1485
  },
1326
- "&dark .cm-cursor": {
1486
+ "&dark .cm-cursor, &dark .cm-dropCursor": {
1327
1487
  borderLeft: "2px solid white"
1328
1488
  },
1329
1489
  "& .cm-placeholder": {
@@ -1343,16 +1503,16 @@ var defaultTheme = {
1343
1503
  // selection
1344
1504
  //
1345
1505
  "&light .cm-selectionBackground, &light.cm-focused .cm-selectionBackground": {
1346
- background: get2(tokens, "extend.colors.primary.150", "#00ffff")
1506
+ background: get3(tokens, "extend.colors.primary.150", "#00ffff")
1347
1507
  },
1348
1508
  "&dark .cm-selectionBackground, &dark.cm-focused .cm-selectionBackground": {
1349
- background: get2(tokens, "extend.colors.primary.850", "#00ffff")
1509
+ background: get3(tokens, "extend.colors.primary.850", "#00ffff")
1350
1510
  },
1351
1511
  "&light .cm-selectionMatch": {
1352
- background: get2(tokens, "extend.colors.primary.250", "#00ffff") + "44"
1512
+ background: get3(tokens, "extend.colors.primary.250", "#00ffff") + "44"
1353
1513
  },
1354
1514
  "&dark .cm-selectionMatch": {
1355
- background: get2(tokens, "extend.colors.primary.600", "#00ffff") + "44"
1515
+ background: get3(tokens, "extend.colors.primary.600", "#00ffff") + "44"
1356
1516
  },
1357
1517
  //
1358
1518
  // collaboration
@@ -1385,12 +1545,12 @@ var defaultTheme = {
1385
1545
  // link
1386
1546
  //
1387
1547
  "& .cm-link": {
1388
- color: get2(tokens, "extend.colors.primary.500"),
1548
+ color: get3(tokens, "extend.colors.primary.500"),
1389
1549
  textDecorationLine: "underline",
1390
1550
  textDecorationThickness: "1px",
1391
1551
  textUnderlineOffset: "2px",
1392
1552
  borderRadius: ".125rem",
1393
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1553
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1394
1554
  },
1395
1555
  //
1396
1556
  // tooltip
@@ -1412,7 +1572,7 @@ var defaultTheme = {
1412
1572
  display: "none"
1413
1573
  },
1414
1574
  "& .cm-completionLabel": {
1415
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1575
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1416
1576
  },
1417
1577
  "& .cm-completionMatchedText": {
1418
1578
  textDecoration: "none"
@@ -1427,12 +1587,16 @@ var defaultTheme = {
1427
1587
  //
1428
1588
  // table
1429
1589
  //
1590
+ "& .cm-table *": {
1591
+ fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
1592
+ textDecoration: "none !important"
1593
+ },
1430
1594
  "& .cm-table-head": {
1431
1595
  padding: "2px 16px 2px 0px",
1432
- borderBottom: `1px solid ${get2(tokens, "extend.colors.neutral.500")}`,
1596
+ borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
1433
1597
  fontWeight: 100,
1434
1598
  textAlign: "left",
1435
- color: get2(tokens, "extend.colors.neutral.500")
1599
+ color: get3(tokens, "extend.colors.neutral.500")
1436
1600
  },
1437
1601
  "& .cm-table-cell": {
1438
1602
  padding: "2px 16px 2px 0px"
@@ -1447,8 +1611,8 @@ var defaultTheme = {
1447
1611
  // font size
1448
1612
  // 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
1613
  //
1450
- ...Object.keys(get2(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
1451
- const height = get2(tokens, [
1614
+ ...Object.keys(get3(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
1615
+ const height = get3(tokens, [
1452
1616
  "extend",
1453
1617
  "fontSize",
1454
1618
  fontSize,
@@ -1465,41 +1629,76 @@ var defaultTheme = {
1465
1629
  height
1466
1630
  };
1467
1631
  return acc;
1468
- }, {})
1632
+ }, {}),
1633
+ /**
1634
+ * Panels
1635
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
1636
+ *
1637
+ * Find/replace panel.
1638
+ * <div class="cm-announced">...</div>
1639
+ * <div class="cm-scroller">...</div>
1640
+ * <div class="cm-panels cm-panels-bottom">
1641
+ * <div class="cm-search cm-panel">
1642
+ * <input class="cm-textfield" />
1643
+ * <button class="cm-button">...</button>
1644
+ * <label><input type="checkbox" />...</label>
1645
+ * </div>
1646
+ * </div
1647
+ */
1648
+ "& .cm-panels": {
1649
+ border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`,
1650
+ borderBottom: "none"
1651
+ },
1652
+ "& .cm-panel": {
1653
+ background: get3(tokens, "extend.colors.neutral.50"),
1654
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1655
+ },
1656
+ "& .cm-button": {
1657
+ margin: "4px",
1658
+ fontFamily: get3(tokens, "fontFamily.body", []).join(","),
1659
+ background: get3(tokens, "extend.colors.neutral.100"),
1660
+ border: "none"
1661
+ },
1662
+ "& .cm-searchMatch": {
1663
+ backgroundColor: get3(tokens, "extend.colors.yellow.100")
1664
+ },
1665
+ "& .cm-searchMatch.cm-searchMatch-selected": {
1666
+ backgroundColor: get3(tokens, "extend.colors.primary.100")
1667
+ }
1469
1668
  };
1470
1669
  var textTheme = {
1471
1670
  "& .cm-scroller": {
1472
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1671
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1473
1672
  },
1474
1673
  "& .cm-placeholder": {
1475
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1674
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1476
1675
  }
1477
1676
  };
1478
1677
  var markdownTheme = {
1479
1678
  // NOTE: Must leave base font family as is (i.e., monospace) due to fenced code blocks.
1480
1679
  "& .cm-placeholder": {
1481
- fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1680
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
1482
1681
  }
1483
1682
  };
1484
1683
  var codeTheme = {
1485
1684
  "& .cm-scroller": {
1486
- fontFamily: get2(tokens, "fontFamily.mono", []).join(",")
1685
+ fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
1487
1686
  },
1488
1687
  "& .cm-placeholder": {
1489
- fontFamily: get2(tokens, "fontFamily.mono", []).join(",")
1688
+ fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
1490
1689
  }
1491
1690
  };
1492
1691
 
1493
1692
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
1494
1693
  import { EditorState as EditorState2 } from "@codemirror/state";
1495
- import { EditorView as EditorView9 } from "@codemirror/view";
1694
+ import { EditorView as EditorView11 } from "@codemirror/view";
1496
1695
  import { useFocusableGroup } from "@fluentui/react-tabster";
1497
1696
  import { vim } from "@replit/codemirror-vim";
1498
1697
  import defaultsDeep2 from "lodash.defaultsdeep";
1499
- import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
1698
+ import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useState } from "react";
1500
1699
  import { generateName } from "@dxos/display-name";
1501
1700
  import { useThemeContext } from "@dxos/react-ui";
1502
- import { getColorForValue, inputSurface, mx as mx3 } from "@dxos/react-ui-theme";
1701
+ import { getColorForValue, inputSurface, mx as mx4 } from "@dxos/react-ui-theme";
1503
1702
  var EditorModes = [
1504
1703
  "default",
1505
1704
  "vim"
@@ -1522,7 +1721,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
1522
1721
  root
1523
1722
  ]);
1524
1723
  const { awareness, peer } = model;
1525
- useEffect(() => {
1724
+ useEffect2(() => {
1526
1725
  if (awareness && peer) {
1527
1726
  awareness.setLocalStateField("user", {
1528
1727
  name: peer.name ?? generateName(peer.id),
@@ -1542,7 +1741,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
1542
1741
  peer,
1543
1742
  themeMode
1544
1743
  ]);
1545
- useEffect(() => {
1744
+ useEffect2(() => {
1546
1745
  if (!root) {
1547
1746
  return;
1548
1747
  }
@@ -1553,10 +1752,11 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
1553
1752
  // TODO(burdon): Factor out VIM mode?
1554
1753
  editorMode === "vim" && vim(),
1555
1754
  // Theme.
1556
- EditorView9.baseTheme(defaultTheme),
1557
- EditorView9.theme(slots?.editor?.theme ?? {}),
1755
+ // TODO(burdon): Make optional.
1756
+ EditorView11.baseTheme(defaultTheme),
1757
+ EditorView11.theme(slots?.editor?.theme ?? {}),
1558
1758
  // TODO(burdon): themeMode doesn't change in storybooks.
1559
- EditorView9.darkTheme.of(themeMode === "dark"),
1759
+ EditorView11.darkTheme.of(themeMode === "dark"),
1560
1760
  // Storage and replication.
1561
1761
  model.extension,
1562
1762
  // Custom.
@@ -1564,7 +1764,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
1564
1764
  ].filter(Boolean)
1565
1765
  });
1566
1766
  view?.destroy();
1567
- setView(new EditorView9({
1767
+ setView(new EditorView11({
1568
1768
  state: state2,
1569
1769
  parent: root
1570
1770
  }));
@@ -1644,7 +1844,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
1644
1844
  });
1645
1845
  var defaultSlots = {
1646
1846
  root: {
1647
- className: mx3("p-2", inputSurface)
1847
+ className: mx4("p-2", inputSurface)
1648
1848
  }
1649
1849
  };
1650
1850
  var defaultTextSlots = {
@@ -1661,15 +1861,15 @@ var defaultMarkdownSlots = {
1661
1861
  };
1662
1862
 
1663
1863
  // 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";
1864
+ import get4 from "lodash.get";
1865
+ import { useEffect as useEffect3, useState as useState2 } from "react";
1666
1866
  import { yCollab } from "y-codemirror.next";
1667
1867
  import { invariant as invariant3 } from "@dxos/invariant";
1668
1868
  import { getRawDoc, isActualAutomergeObject } from "@dxos/react-client/echo";
1669
1869
 
1670
1870
  // 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";
1871
+ import { Annotation, Facet, StateEffect as StateEffect2, StateField as StateField6 } from "@codemirror/state";
1872
+ import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1673
1873
  import * as automerge2 from "@dxos/automerge/automerge";
1674
1874
 
1675
1875
  // packages/ui/react-ui-editor/src/hooks/automerge/PatchSemaphore.ts
@@ -1847,7 +2047,7 @@ var PatchSemaphore = class {
1847
2047
  };
1848
2048
 
1849
2049
  // packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
1850
- var effectType = StateEffect.define({});
2050
+ var effectType = StateEffect2.define({});
1851
2051
  var updateHeads = (newHeads) => effectType.of({
1852
2052
  newHeads
1853
2053
  });
@@ -1887,7 +2087,7 @@ var automergePlugin = (handle, path) => {
1887
2087
  }
1888
2088
  });
1889
2089
  const semaphore = new PatchSemaphore(stateField);
1890
- const viewPlugin = ViewPlugin3.fromClass(class AutomergeCodemirrorViewPlugin {
2090
+ const viewPlugin = ViewPlugin4.fromClass(class AutomergeCodemirrorViewPlugin {
1891
2091
  constructor(view) {
1892
2092
  this._handleChange = () => {
1893
2093
  this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
@@ -2063,7 +2263,7 @@ var useTextModel = ({ identity, space, text }) => {
2063
2263
  space,
2064
2264
  text
2065
2265
  }));
2066
- useEffect2(() => {
2266
+ useEffect3(() => {
2067
2267
  setModel(createModel({
2068
2268
  identity,
2069
2269
  space,
@@ -2090,7 +2290,7 @@ var createModel = (options) => {
2090
2290
  var createYjsModel = ({ identity, space, text }) => {
2091
2291
  invariant3(text?.doc && text?.content, void 0, {
2092
2292
  F: __dxlog_file4,
2093
- L: 74,
2293
+ L: 81,
2094
2294
  S: void 0,
2095
2295
  A: [
2096
2296
  "text?.doc && text?.content",
@@ -2106,6 +2306,7 @@ var createYjsModel = ({ identity, space, text }) => {
2106
2306
  id: text.doc.guid,
2107
2307
  content: text.content,
2108
2308
  text: () => text.content.toString(),
2309
+ ranges: [],
2109
2310
  extension: yCollab(text.content, provider?.awareness),
2110
2311
  awareness: provider?.awareness,
2111
2312
  peer: identity ? {
@@ -2122,7 +2323,8 @@ var createAutomergeModel = ({ identity, text }) => {
2122
2323
  return {
2123
2324
  id: obj.id,
2124
2325
  content: doc,
2125
- text: () => get3(doc.handle.docSync(), doc.path),
2326
+ text: () => get4(doc.handle.docSync(), doc.path),
2327
+ ranges: [],
2126
2328
  extension: automergePlugin(doc.handle, doc.path),
2127
2329
  peer: identity ? {
2128
2330
  id: identity.identityKey.toHex(),
@@ -2143,6 +2345,7 @@ export {
2143
2345
  autocomplete,
2144
2346
  basicBundle,
2145
2347
  blast,
2348
+ code2 as code,
2146
2349
  codeTheme,
2147
2350
  comments,
2148
2351
  cursorColor,
@@ -2152,9 +2355,12 @@ export {
2152
2355
  defaultTextSlots,
2153
2356
  defaultTheme,
2154
2357
  demo,
2358
+ highlight,
2359
+ highlightDecorations,
2360
+ highlightStateField,
2155
2361
  image,
2156
2362
  link,
2157
- listener,
2363
+ listener2 as listener,
2158
2364
  markdownBundle,
2159
2365
  markdownHighlightStyle,
2160
2366
  markdownTags,
@@ -2166,6 +2372,7 @@ export {
2166
2372
  tasklist,
2167
2373
  textTheme,
2168
2374
  tooltip,
2375
+ useHighlights,
2169
2376
  useTextModel
2170
2377
  };
2171
2378
  //# sourceMappingURL=index.mjs.map