@dxos/react-ui-editor 0.3.11-main.2e39ec4 → 0.3.11-main.3649358

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 (41) hide show
  1. package/dist/lib/browser/index.mjs +259 -231
  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 +3 -3
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  7. package/dist/types/src/extensions/automerge/index.d.ts +1 -0
  8. package/dist/types/src/extensions/automerge/index.d.ts.map +1 -1
  9. package/dist/types/src/extensions/code.d.ts.map +1 -1
  10. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  11. package/dist/types/src/extensions/hr.d.ts.map +1 -1
  12. package/dist/types/src/extensions/image.d.ts.map +1 -1
  13. package/dist/types/src/extensions/index.d.ts +0 -1
  14. package/dist/types/src/extensions/index.d.ts.map +1 -1
  15. package/dist/types/src/extensions/link.d.ts.map +1 -1
  16. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  17. package/dist/types/src/extensions/tasklist.d.ts.map +1 -1
  18. package/dist/types/src/index.d.ts +2 -0
  19. package/dist/types/src/index.d.ts.map +1 -1
  20. package/dist/types/src/styles/tokens.d.ts +1 -0
  21. package/dist/types/src/styles/tokens.d.ts.map +1 -1
  22. package/dist/types/src/themes/default.d.ts.map +1 -1
  23. package/package.json +22 -22
  24. package/src/components/TextEditor/MarkdownEditor.stories.tsx +6 -7
  25. package/src/extensions/autocomplete.ts +18 -17
  26. package/src/extensions/automerge/index.ts +1 -0
  27. package/src/extensions/code.ts +4 -5
  28. package/src/extensions/comments.ts +4 -5
  29. package/src/extensions/hr.ts +2 -3
  30. package/src/extensions/image.ts +38 -20
  31. package/src/extensions/index.ts +0 -1
  32. package/src/extensions/link.ts +82 -84
  33. package/src/extensions/markdown/highlight.ts +3 -4
  34. package/src/extensions/table.ts +9 -3
  35. package/src/extensions/tasklist.ts +1 -3
  36. package/src/index.ts +2 -0
  37. package/src/styles/tokens.ts +3 -0
  38. package/src/themes/default.ts +39 -33
  39. package/dist/types/src/extensions/mermaid.d.ts +0 -3
  40. package/dist/types/src/extensions/mermaid.d.ts.map +0 -1
  41. package/src/extensions/mermaid.ts +0 -11
@@ -7,7 +7,7 @@ import { tags as tags2 } from "@lezer/highlight";
7
7
 
8
8
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
9
9
  import { EditorState as EditorState2 } from "@codemirror/state";
10
- import { EditorView as EditorView13 } from "@codemirror/view";
10
+ import { EditorView as EditorView12 } from "@codemirror/view";
11
11
  import { useFocusableGroup } from "@fluentui/react-tabster";
12
12
  import { vim } from "@replit/codemirror-vim";
13
13
  import defaultsDeep2 from "lodash.defaultsdeep";
@@ -18,33 +18,34 @@ import { getColorForValue, inputSurface, mx as mx3 } from "@dxos/react-ui-theme"
18
18
 
19
19
  // packages/ui/react-ui-editor/src/extensions/autocomplete.ts
20
20
  import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
21
+ import { markdownLanguage } from "@codemirror/lang-markdown";
21
22
  import { keymap } from "@codemirror/view";
22
23
  var autocomplete = ({ onSearch }) => {
23
24
  return [
24
25
  // https://codemirror.net/docs/ref/#view.keymap
25
26
  // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
27
+ // TODO(burdon): Set custom keymap.
26
28
  keymap.of(completionKeymap),
27
29
  // https://codemirror.net/examples/autocompletion
28
30
  // https://codemirror.net/docs/ref/#autocomplete.autocompletion
29
31
  autocompletion({
30
- // TODO(burdon): Set custom keymap.
31
- // defaultKeymap: false,
32
+ defaultKeymap: false,
32
33
  // Don't start unless key press.
33
- activateOnTyping: false,
34
- // TODO(burdon): Option to create new page?
35
- // TODO(burdon): Optional decoration via addToOptions
36
- override: [
37
- (context) => {
38
- const match = context.matchBefore(/\w*/);
39
- if (!match || match.from === match.to && !context.explicit) {
40
- return null;
41
- }
42
- return {
43
- from: match.from,
44
- options: onSearch(match.text.toLowerCase())
45
- };
34
+ activateOnTyping: false
35
+ }),
36
+ // TODO(burdon): Option to create new page?
37
+ // TODO(burdon): Optional decoration via addToOptions
38
+ markdownLanguage.data.of({
39
+ autocomplete: (context) => {
40
+ const match = context.matchBefore(/\w*/);
41
+ if (!match || match.from === match.to && !context.explicit) {
42
+ return null;
46
43
  }
47
- ]
44
+ return {
45
+ from: match.from,
46
+ options: onSearch(match.text.toLowerCase())
47
+ };
48
+ }
48
49
  })
49
50
  ];
50
51
  };
@@ -342,8 +343,8 @@ var automerge3 = ({ handle, path }) => {
342
343
  };
343
344
  handle.addListener("change", this._handleChange);
344
345
  }
345
- update(update4) {
346
- if (update4.transactions.length > 0 && update4.transactions.some((tr) => !isReconcileTx(tr))) {
346
+ update(update2) {
347
+ if (update2.transactions.length > 0 && update2.transactions.some((tr) => !isReconcileTx(tr))) {
347
348
  queueMicrotask(() => {
348
349
  this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
349
350
  });
@@ -412,13 +413,13 @@ var RemoteSelectionsDecorator = class {
412
413
  void this._ctx.dispose();
413
414
  this._provider.close();
414
415
  }
415
- update(update4) {
416
- this._updateLocalSelection(update4);
417
- this._updateRemoteSelections(update4);
416
+ update(update2) {
417
+ this._updateLocalSelection(update2);
418
+ this._updateRemoteSelections(update2);
418
419
  }
419
- _updateLocalSelection(update4) {
420
- const hasFocus = update4.view.hasFocus && update4.view.dom.ownerDocument.hasFocus();
421
- const { anchor = void 0, head = void 0 } = hasFocus ? update4.state.selection.main : {};
420
+ _updateLocalSelection(update2) {
421
+ const hasFocus = update2.view.hasFocus && update2.view.dom.ownerDocument.hasFocus();
422
+ const { anchor = void 0, head = void 0 } = hasFocus ? update2.state.selection.main : {};
422
423
  if (this._lastAnchor === anchor && this._lastHead === head) {
423
424
  return;
424
425
  }
@@ -429,7 +430,7 @@ var RemoteSelectionsDecorator = class {
429
430
  head: this._cursorConverter.toCursor(head)
430
431
  } : void 0);
431
432
  }
432
- _updateRemoteSelections(update4) {
433
+ _updateRemoteSelections(update2) {
433
434
  const decorations = [];
434
435
  const awarenessStates = this._provider.getRemoteStates();
435
436
  for (const state of awarenessStates) {
@@ -438,10 +439,10 @@ var RemoteSelectionsDecorator = class {
438
439
  if (anchor == null || head == null) {
439
440
  continue;
440
441
  }
441
- const start = Math.min(Math.min(anchor, head), update4.view.state.doc.length);
442
- const end = Math.min(Math.max(anchor, head), update4.view.state.doc.length);
443
- const startLine = update4.view.state.doc.lineAt(start);
444
- const endLine = update4.view.state.doc.lineAt(end);
442
+ const start = Math.min(Math.min(anchor, head), update2.view.state.doc.length);
443
+ const end = Math.min(Math.max(anchor, head), update2.view.state.doc.length);
444
+ const startLine = update2.view.state.doc.lineAt(start);
445
+ const endLine = update2.view.state.doc.lineAt(end);
445
446
  const color = state.info.color ?? "#30bced";
446
447
  const lightColor = state.info.lightColor ?? color + "33";
447
448
  if (startLine.number === endLine.number) {
@@ -477,7 +478,7 @@ var RemoteSelectionsDecorator = class {
477
478
  })
478
479
  });
479
480
  for (let i = startLine.number + 1; i < endLine.number; i++) {
480
- const linePos = update4.view.state.doc.line(i).from;
481
+ const linePos = update2.view.state.doc.line(i).from;
481
482
  decorations.push({
482
483
  from: linePos,
483
484
  to: linePos,
@@ -667,12 +668,12 @@ var blast = (options = defaultOptions) => {
667
668
  };
668
669
  return [
669
670
  // Cursor moved.
670
- EditorView3.updateListener.of((update4) => {
671
- if (blaster?.node !== update4.view.scrollDOM) {
671
+ EditorView3.updateListener.of((update2) => {
672
+ if (blaster?.node !== update2.view.scrollDOM) {
672
673
  if (blaster) {
673
674
  blaster.destroy();
674
675
  }
675
- blaster = new Blaster(update4.view.scrollDOM, defaultsDeep({
676
+ blaster = new Blaster(update2.view.scrollDOM, defaultsDeep({
676
677
  particleGravity: 0.2,
677
678
  particleShrinkRate: 0.995,
678
679
  color: () => [
@@ -686,10 +687,10 @@ var blast = (options = defaultOptions) => {
686
687
  } else {
687
688
  blaster.resize();
688
689
  }
689
- const current = update4.state.selection.main.head;
690
+ const current = update2.state.selection.main.head;
690
691
  if (current !== last) {
691
692
  last = current;
692
- const { element, point } = getPoint(update4.view, current - 1);
693
+ const { element, point } = getPoint(update2.view, current - 1);
693
694
  if (element && point) {
694
695
  blaster.spawn({
695
696
  element,
@@ -930,7 +931,6 @@ var random = (min, max) => {
930
931
 
931
932
  // packages/ui/react-ui-editor/src/extensions/code.ts
932
933
  import { ViewPlugin as ViewPlugin3, EditorView as EditorView4, Decoration as Decoration2 } from "@codemirror/view";
933
- import get2 from "lodash.get";
934
934
  import { mx as mx2 } from "@dxos/react-ui-theme";
935
935
 
936
936
  // packages/ui/react-ui-editor/src/styles/cursors.ts
@@ -1014,20 +1014,22 @@ var inlineUrl = mx(code, "px-1");
1014
1014
  var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
1015
1015
 
1016
1016
  // packages/ui/react-ui-editor/src/styles/tokens.ts
1017
+ import get2 from "lodash.get";
1017
1018
  import { tailwindConfig } from "@dxos/react-ui-theme";
1018
1019
  var tokens = tailwindConfig({}).theme;
1020
+ var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
1019
1021
 
1020
1022
  // packages/ui/react-ui-editor/src/extensions/code.ts
1021
1023
  var CODE_REGEX = /```[\s\S]*?```/gs;
1022
1024
  var styles2 = EditorView4.baseTheme({
1023
1025
  "& .cm-codeblock": {
1024
- fontFamily: get2(tokens, "fontFamily.mono", []).join(",")
1026
+ fontFamily: getToken("fontFamily.mono", []).join(",")
1025
1027
  },
1026
1028
  '&light [aria-readonly="true"] .cm-codeblock': {
1027
- background: get2(tokens, "extend.colors.neutral.50")
1029
+ background: getToken("extend.colors.neutral.50")
1028
1030
  },
1029
1031
  '&dark [aria-readonly="true"] .cm-codeblock': {
1030
- background: get2(tokens, "extend.colors.neutral.850")
1032
+ background: getToken("extend.colors.neutral.850")
1031
1033
  },
1032
1034
  '& [aria-readonly="true"] .cm-codeblock': {
1033
1035
  display: "block",
@@ -1076,9 +1078,9 @@ var code2 = () => {
1076
1078
  constructor(view) {
1077
1079
  this.decorations = getDecorations(view);
1078
1080
  }
1079
- update(update4) {
1080
- if (update4.docChanged || update4.viewportChanged) {
1081
- this.decorations = getDecorations(update4.view);
1081
+ update(update2) {
1082
+ if (update2.docChanged || update2.viewportChanged) {
1083
+ this.decorations = getDecorations(update2.view);
1082
1084
  }
1083
1085
  }
1084
1086
  }, {
@@ -1091,7 +1093,6 @@ var code2 = () => {
1091
1093
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1092
1094
  import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
1093
1095
  import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView5, MatchDecorator, ViewPlugin as ViewPlugin4, WidgetType as WidgetType2 } from "@codemirror/view";
1094
- import get3 from "lodash.get";
1095
1096
  import sortBy from "lodash.sortby";
1096
1097
  import { debounce } from "@dxos/async";
1097
1098
  import { invariant as invariant2 } from "@dxos/invariant";
@@ -1109,10 +1110,10 @@ var styles3 = EditorView5.baseTheme({
1109
1110
  backgroundColor: "orange"
1110
1111
  },
1111
1112
  "& .cm-comment": {
1112
- backgroundColor: get3(tokens, "extend.colors.yellow.50")
1113
+ backgroundColor: getToken("extend.colors.yellow.50")
1113
1114
  },
1114
1115
  "& .cm-comment-active": {
1115
- backgroundColor: get3(tokens, "extend.colors.yellow.100")
1116
+ backgroundColor: getToken("extend.colors.yellow.100")
1116
1117
  }
1117
1118
  });
1118
1119
  var marks = {
@@ -1203,7 +1204,7 @@ var BookmarkWidget = class extends WidgetType2 {
1203
1204
  this._handleClick = _handleClick;
1204
1205
  invariant2(this._id, void 0, {
1205
1206
  F: __dxlog_file3,
1206
- L: 169,
1207
+ L: 168,
1207
1208
  S: this,
1208
1209
  A: [
1209
1210
  "this._id",
@@ -1230,7 +1231,7 @@ var comments = (options = {}) => {
1230
1231
  const cursorConverter3 = view.state.facet(CursorConverter);
1231
1232
  invariant2(options.onCreate, void 0, {
1232
1233
  F: __dxlog_file3,
1233
- L: 225,
1234
+ L: 224,
1234
1235
  S: void 0,
1235
1236
  A: [
1236
1237
  "options.onCreate",
@@ -1291,8 +1292,8 @@ var comments = (options = {}) => {
1291
1292
  constructor(view) {
1292
1293
  this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.createDeco(view);
1293
1294
  }
1294
- update(update4) {
1295
- this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.updateDeco(update4, this.bookmarks);
1295
+ update(update2) {
1296
+ this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.updateDeco(update2, this.bookmarks);
1296
1297
  }
1297
1298
  }, {
1298
1299
  decorations: (instance) => instance.bookmarks,
@@ -1361,7 +1362,7 @@ var comments = (options = {}) => {
1361
1362
  thread: range.id
1362
1363
  }, {
1363
1364
  F: __dxlog_file3,
1364
- L: 359,
1365
+ L: 358,
1365
1366
  S: void 0,
1366
1367
  C: (f, a) => f(...a)
1367
1368
  });
@@ -1429,7 +1430,7 @@ var getRangeFromCursor = (cursorConverter3, cursor) => {
1429
1430
  const parts = cursor.split(":");
1430
1431
  const from = cursorConverter3.fromCursor(parts[0]);
1431
1432
  const to = cursorConverter3.fromCursor(parts[1]);
1432
- return from && to ? {
1433
+ return from !== void 0 && to !== void 0 ? {
1433
1434
  from,
1434
1435
  to
1435
1436
  } : void 0;
@@ -1437,12 +1438,11 @@ var getRangeFromCursor = (cursorConverter3, cursor) => {
1437
1438
 
1438
1439
  // packages/ui/react-ui-editor/src/extensions/hr.ts
1439
1440
  import { Decoration as Decoration4, EditorView as EditorView6, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin5, WidgetType as WidgetType3 } from "@codemirror/view";
1440
- import get4 from "lodash.get";
1441
1441
  var styles4 = EditorView6.baseTheme({
1442
1442
  "& .cm-hr": {
1443
1443
  // TODO(burdon): ???
1444
1444
  // Note that block-level decorations should not have vertical margins,
1445
- borderBottom: `1px solid ${get4(tokens, "extend.colors.neutral.200")}`
1445
+ borderBottom: `1px solid ${getToken("extend.colors.neutral.200")}`
1446
1446
  }
1447
1447
  });
1448
1448
  var HorizontalRuleWidget = class extends WidgetType3 {
@@ -1471,8 +1471,8 @@ var hr = () => [
1471
1471
  constructor(view) {
1472
1472
  this.rules = placeholderMatcher.createDeco(view);
1473
1473
  }
1474
- update(update4) {
1475
- this.rules = placeholderMatcher.updateDeco(update4, this.rules);
1474
+ update(update2) {
1475
+ this.rules = placeholderMatcher.updateDeco(update2, this.rules);
1476
1476
  }
1477
1477
  }, {
1478
1478
  decorations: (instance) => instance.rules,
@@ -1485,17 +1485,39 @@ var hr = () => [
1485
1485
 
1486
1486
  // packages/ui/react-ui-editor/src/extensions/image.ts
1487
1487
  import { syntaxTree } from "@codemirror/language";
1488
- import { RangeSetBuilder, StateField as StateField3 } from "@codemirror/state";
1488
+ import { StateField as StateField3 } from "@codemirror/state";
1489
1489
  import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as WidgetType4 } from "@codemirror/view";
1490
1490
  var image = (options = {}) => {
1491
1491
  return StateField3.define({
1492
- create: (state) => update(state, options),
1493
- update: (_, tr) => update(tr.state, options),
1492
+ create: (state) => {
1493
+ return Decoration5.set(buildDecorations(0, state.doc.length, state));
1494
+ },
1495
+ update: (value, tr) => {
1496
+ if (!tr.docChanged && !tr.selection) {
1497
+ return value;
1498
+ }
1499
+ const cursor = tr.state.selection.main.head;
1500
+ const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
1501
+ let from = Math.min(cursor, oldCursor);
1502
+ let to = Math.max(cursor, oldCursor);
1503
+ tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
1504
+ from = Math.min(from, fromB);
1505
+ to = Math.max(to, toB);
1506
+ });
1507
+ from = tr.state.doc.lineAt(from).from;
1508
+ to = tr.state.doc.lineAt(to).to;
1509
+ return value.map(tr.changes).update({
1510
+ filterFrom: from,
1511
+ filterTo: to,
1512
+ filter: () => false,
1513
+ add: buildDecorations(from, to, tr.state)
1514
+ });
1515
+ },
1494
1516
  provide: (field) => EditorView7.decorations.from(field)
1495
1517
  });
1496
1518
  };
1497
- var update = (state, options) => {
1498
- const builder = new RangeSetBuilder();
1519
+ var buildDecorations = (from, to, state) => {
1520
+ const decorations = [];
1499
1521
  const cursor = state.selection.main.head;
1500
1522
  syntaxTree(state).iterate({
1501
1523
  enter: (node) => {
@@ -1504,22 +1526,23 @@ var update = (state, options) => {
1504
1526
  if (urlNode) {
1505
1527
  const hide = state.readOnly || cursor < node.from || cursor > node.to;
1506
1528
  const url = state.sliceDoc(urlNode.from, urlNode.to);
1507
- builder.add(hide ? node.from : node.to, node.to, Decoration5.replace({
1529
+ decorations.push(Decoration5.replace({
1508
1530
  block: true,
1509
1531
  widget: new ImageWidget(url)
1510
- }));
1532
+ }).range(hide ? node.from : node.to, node.to));
1511
1533
  }
1512
1534
  }
1513
- }
1535
+ },
1536
+ from,
1537
+ to
1514
1538
  });
1515
- return builder.finish();
1539
+ return decorations;
1516
1540
  };
1517
1541
  var ImageWidget = class extends WidgetType4 {
1518
1542
  constructor(_url) {
1519
1543
  super();
1520
1544
  this._url = _url;
1521
1545
  }
1522
- // TODO(burdon): Does this need to be unique for each position?
1523
1546
  eq(other) {
1524
1547
  return this._url === other._url;
1525
1548
  }
@@ -1527,22 +1550,29 @@ var ImageWidget = class extends WidgetType4 {
1527
1550
  const img = document.createElement("img");
1528
1551
  img.setAttribute("src", this._url);
1529
1552
  img.setAttribute("class", "cm-image");
1553
+ img.onload = () => img.classList.add("cm-loaded-image");
1530
1554
  return img;
1531
1555
  }
1532
1556
  };
1533
1557
 
1534
1558
  // packages/ui/react-ui-editor/src/extensions/link.ts
1535
1559
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
1536
- import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField4 } from "@codemirror/state";
1537
- import { Decoration as Decoration6, EditorView as EditorView8, WidgetType as WidgetType5, hoverTooltip as hoverTooltip2 } from "@codemirror/view";
1560
+ import { RangeSetBuilder } from "@codemirror/state";
1561
+ import { Decoration as Decoration6, WidgetType as WidgetType5, hoverTooltip as hoverTooltip2, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
1538
1562
  import { tooltipContent } from "@dxos/react-ui-theme";
1539
- var markdownLinkRegexp = /\[([^\]]+)]\(([^)]+)\)/;
1540
1563
  var link = (options = {}) => {
1541
1564
  const extensions = [
1542
- StateField4.define({
1543
- create: (state) => update2(state, options),
1544
- update: (_, tr) => update2(tr.state, options),
1545
- provide: (field) => EditorView8.decorations.from(field)
1565
+ ViewPlugin6.fromClass(class {
1566
+ constructor(view) {
1567
+ this.decorations = buildDecorations2(view, options);
1568
+ }
1569
+ update(update2) {
1570
+ if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
1571
+ this.decorations = buildDecorations2(update2.view, options);
1572
+ }
1573
+ }
1574
+ }, {
1575
+ decorations: (v) => v.decorations
1546
1576
  })
1547
1577
  ];
1548
1578
  if (options.onHover) {
@@ -1550,35 +1580,25 @@ var link = (options = {}) => {
1550
1580
  // https://codemirror.net/examples/tooltip
1551
1581
  // https://codemirror.net/docs/ref/#view.hoverTooltip
1552
1582
  // https://github.com/codemirror/view/blob/main/src/tooltip.ts
1553
- hoverTooltip2((view, pos) => {
1554
- const { from, text } = view.state.doc.lineAt(pos);
1555
- const p = pos - from;
1556
- let idx = 0;
1557
- let match;
1558
- do {
1559
- match = text.substring(idx).match(markdownLinkRegexp);
1560
- if (!match) {
1561
- match = void 0;
1562
- break;
1563
- }
1564
- idx = text.indexOf(match[0]);
1565
- if (p >= idx && p < idx + match[0].length) {
1566
- break;
1567
- }
1568
- idx += match[0].length;
1569
- } while (true);
1570
- if (!match) {
1583
+ hoverTooltip2((view, pos, side) => {
1584
+ const syntax = syntaxTree2(view.state).resolveInner(pos, side);
1585
+ let link2 = null;
1586
+ for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
1587
+ link2 = node.name === "Link" ? node : null;
1588
+ }
1589
+ const url = link2 && link2.getChild("URL");
1590
+ if (!url || !link2) {
1571
1591
  return null;
1572
1592
  }
1573
- const [, , url] = match ?? [];
1593
+ const urlText = view.state.sliceDoc(url.from, url.to);
1574
1594
  return {
1575
- pos: idx + from,
1576
- end: idx + from + match[0].length,
1595
+ pos: link2.from,
1596
+ end: link2.to,
1577
1597
  above: true,
1578
1598
  create: () => {
1579
1599
  const el = document.createElement("div");
1580
1600
  el.className = tooltipContent({}, "pli-2 plb-1");
1581
- options.onHover(el, url);
1601
+ options.onHover(el, urlText);
1582
1602
  return {
1583
1603
  dom: el,
1584
1604
  offset: {
@@ -1594,14 +1614,13 @@ var link = (options = {}) => {
1594
1614
  return extensions;
1595
1615
  };
1596
1616
  var LinkButton = class extends WidgetType5 {
1597
- constructor(_pos, _url, _onAttach) {
1617
+ constructor(_url, _onAttach) {
1598
1618
  super();
1599
- this._pos = _pos;
1600
1619
  this._url = _url;
1601
1620
  this._onAttach = _onAttach;
1602
1621
  }
1603
1622
  eq(other) {
1604
- return this._pos === other._pos && this._url === other._url;
1623
+ return this._url === other._url;
1605
1624
  }
1606
1625
  toDOM(view) {
1607
1626
  const el = document.createElement("span");
@@ -1638,46 +1657,51 @@ var LinkText = class extends WidgetType5 {
1638
1657
  return link2;
1639
1658
  }
1640
1659
  };
1641
- var update2 = (state, options) => {
1642
- const builder = new RangeSetBuilder2();
1660
+ var buildDecorations2 = (view, options) => {
1661
+ const builder = new RangeSetBuilder();
1662
+ const { state } = view;
1643
1663
  const cursor = state.selection.main.head;
1644
- syntaxTree2(state).iterate({
1645
- enter: (node) => {
1646
- if (node.name === "Link") {
1647
- const marks2 = node.node.getChildren("LinkMark");
1648
- const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
1649
- const urlNode = node.node.getChild("URL");
1650
- const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
1651
- if (!url) {
1664
+ for (const { from, to } of view.visibleRanges) {
1665
+ syntaxTree2(state).iterate({
1666
+ enter: (node) => {
1667
+ if (node.name === "Link") {
1668
+ const marks2 = node.node.getChildren("LinkMark");
1669
+ const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
1670
+ const urlNode = node.node.getChild("URL");
1671
+ const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
1672
+ if (!url) {
1673
+ return false;
1674
+ }
1675
+ if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
1676
+ builder.add(node.from, node.to, Decoration6.replace({
1677
+ widget: new LinkText(text, options.link ? url : void 0)
1678
+ }));
1679
+ }
1680
+ if (options.onRender) {
1681
+ builder.add(node.to, node.to, Decoration6.replace({
1682
+ widget: new LinkButton(url, options.onRender)
1683
+ }));
1684
+ }
1652
1685
  return false;
1653
1686
  }
1654
- if (state.readOnly || cursor < node.from || cursor > node.to) {
1655
- builder.add(node.from, node.to, Decoration6.replace({
1656
- widget: new LinkText(text, options.link ? url : void 0)
1657
- }));
1658
- }
1659
- if (options.onRender) {
1660
- builder.add(node.to, node.to, Decoration6.replace({
1661
- widget: new LinkButton(node.from, url, options.onRender)
1662
- }));
1663
- }
1664
- return false;
1665
- }
1666
- }
1667
- });
1687
+ },
1688
+ from,
1689
+ to
1690
+ });
1691
+ }
1668
1692
  return builder.finish();
1669
1693
  };
1670
1694
 
1671
1695
  // packages/ui/react-ui-editor/src/extensions/listener.ts
1672
- import { EditorView as EditorView9 } from "@codemirror/view";
1696
+ import { EditorView as EditorView8 } from "@codemirror/view";
1673
1697
  var listener = ({ onFocus, onChange }) => {
1674
1698
  const extensions = [];
1675
- onFocus && extensions.push(EditorView9.focusChangeEffect.of((_, focused) => {
1699
+ onFocus && extensions.push(EditorView8.focusChangeEffect.of((_, focused) => {
1676
1700
  onFocus(focused);
1677
1701
  return null;
1678
1702
  }));
1679
- onChange && extensions.push(EditorView9.updateListener.of((update4) => {
1680
- onChange(update4.state.doc.toString());
1703
+ onChange && extensions.push(EditorView8.updateListener.of((update2) => {
1704
+ onChange(update2.state.doc.toString());
1681
1705
  }));
1682
1706
  return extensions;
1683
1707
  };
@@ -1685,20 +1709,19 @@ var listener = ({ onFocus, onChange }) => {
1685
1709
  // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
1686
1710
  import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
1687
1711
  import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
1688
- import { markdownLanguage as markdownLanguage2, markdown } from "@codemirror/lang-markdown";
1712
+ import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
1689
1713
  import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
1690
1714
  import { languages } from "@codemirror/language-data";
1691
1715
  import { searchKeymap } from "@codemirror/search";
1692
1716
  import { EditorState } from "@codemirror/state";
1693
1717
  import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
1694
- import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView10, highlightActiveLine, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1718
+ import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView9, highlightActiveLine, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1695
1719
 
1696
1720
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
1697
- import { markdownLanguage } from "@codemirror/lang-markdown";
1721
+ import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
1698
1722
  import { HighlightStyle } from "@codemirror/language";
1699
1723
  import { tags, styleTags, Tag } from "@lezer/highlight";
1700
1724
  import { Table } from "@lezer/markdown";
1701
- import get5 from "lodash.get";
1702
1725
  var markdownTags = {
1703
1726
  Blockquote: Tag.define(),
1704
1727
  CodeMark: Tag.define(),
@@ -1882,9 +1905,9 @@ var markdownHighlightStyle = (readonly) => {
1882
1905
  class: "font-mono"
1883
1906
  }
1884
1907
  ], {
1885
- scope: markdownLanguage,
1908
+ scope: markdownLanguage2,
1886
1909
  all: {
1887
- fontFamily: get5(tokens, "fontFamily.body", []).join(",")
1910
+ fontFamily: getToken("fontFamily.body", []).join(",")
1888
1911
  }
1889
1912
  });
1890
1913
  };
@@ -1894,7 +1917,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
1894
1917
  return [
1895
1918
  EditorState.allowMultipleSelections.of(true),
1896
1919
  EditorState.tabSize.of(2),
1897
- EditorView10.lineWrapping,
1920
+ EditorView9.lineWrapping,
1898
1921
  customKeymap(),
1899
1922
  bracketMatching2(),
1900
1923
  closeBrackets2(),
@@ -1914,7 +1937,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
1914
1937
  // NOTE: This extends the parser; it doesn't affect rendering.
1915
1938
  // https://github.github.com/gfm
1916
1939
  // https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
1917
- base: markdownLanguage2,
1940
+ base: markdownLanguage3,
1918
1941
  // Languages for syntax highlighting fenced code blocks.
1919
1942
  codeLanguages: languages,
1920
1943
  // Parser extensions.
@@ -1965,24 +1988,19 @@ var mention = ({ onSearch }) => {
1965
1988
  });
1966
1989
  };
1967
1990
 
1968
- // packages/ui/react-ui-editor/src/extensions/mermaid.ts
1969
- var mermaid = () => {
1970
- return [];
1971
- };
1972
-
1973
1991
  // packages/ui/react-ui-editor/src/extensions/table.ts
1974
1992
  import { syntaxTree as syntaxTree3 } from "@codemirror/language";
1975
- import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField5 } from "@codemirror/state";
1976
- import { Decoration as Decoration7, EditorView as EditorView11, WidgetType as WidgetType6 } from "@codemirror/view";
1993
+ import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField4 } from "@codemirror/state";
1994
+ import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as WidgetType6 } from "@codemirror/view";
1977
1995
  var table = (options = {}) => {
1978
- return StateField5.define({
1979
- create: (state) => update3(state, options),
1980
- update: (_, tr) => update3(tr.state, options),
1981
- provide: (field) => EditorView11.decorations.from(field)
1996
+ return StateField4.define({
1997
+ create: (state) => update(state, options),
1998
+ update: (_, tr) => update(tr.state, options),
1999
+ provide: (field) => EditorView10.decorations.from(field)
1982
2000
  });
1983
2001
  };
1984
- var update3 = (state, options) => {
1985
- const builder = new RangeSetBuilder3();
2002
+ var update = (state, options) => {
2003
+ const builder = new RangeSetBuilder2();
1986
2004
  const cursor = state.selection.main.head;
1987
2005
  const tables = [];
1988
2006
  const getTable = () => tables[tables.length - 1];
@@ -2023,7 +2041,6 @@ var update3 = (state, options) => {
2023
2041
  tables.forEach((table2) => {
2024
2042
  const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
2025
2043
  hide && builder.add(table2.from, table2.to, Decoration7.replace({
2026
- block: true,
2027
2044
  widget: new TableWidget(table2)
2028
2045
  }));
2029
2046
  builder.add(table2.from, table2.to, Decoration7.mark({
@@ -2038,7 +2055,7 @@ var TableWidget = class extends WidgetType6 {
2038
2055
  this._table = _table;
2039
2056
  }
2040
2057
  eq(other) {
2041
- return this._table.from === other?._table?.from;
2058
+ return this._table.header?.join() === other._table.header?.join() && this._table.rows?.join() === other._table.rows?.join();
2042
2059
  }
2043
2060
  toDOM(view) {
2044
2061
  const table2 = document.createElement("table");
@@ -2064,26 +2081,28 @@ var TableWidget = class extends WidgetType6 {
2064
2081
  }
2065
2082
  return table2;
2066
2083
  }
2084
+ ignoreEvent(e) {
2085
+ return !/^mouse/.test(e.type);
2086
+ }
2067
2087
  };
2068
2088
 
2069
2089
  // packages/ui/react-ui-editor/src/extensions/tasklist.ts
2070
- import { EditorView as EditorView12, Decoration as Decoration8, WidgetType as WidgetType7, MatchDecorator as MatchDecorator3, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
2071
- var styles5 = EditorView12.baseTheme({
2090
+ import { EditorView as EditorView11, Decoration as Decoration8, WidgetType as WidgetType7, MatchDecorator as MatchDecorator3, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
2091
+ var styles5 = EditorView11.baseTheme({
2072
2092
  "& .cm-task-item": {
2073
2093
  paddingLeft: "4px",
2074
2094
  paddingRight: "8px"
2075
2095
  }
2076
2096
  });
2077
2097
  var CheckboxWidget = class extends WidgetType7 {
2078
- constructor(_pos, _checked, _indent, _onCheck) {
2098
+ constructor(_checked, _indent, _onCheck) {
2079
2099
  super();
2080
- this._pos = _pos;
2081
2100
  this._checked = _checked;
2082
2101
  this._indent = _indent;
2083
2102
  this._onCheck = _onCheck;
2084
2103
  }
2085
2104
  eq(other) {
2086
- return this._pos === other._pos && this._checked === other._checked && this._indent === other._indent;
2105
+ return this._checked === other._checked && this._indent === other._indent;
2087
2106
  }
2088
2107
  toDOM(view) {
2089
2108
  const wrap = document.createElement("span");
@@ -2115,7 +2134,7 @@ var tasklist = (options = {}) => {
2115
2134
  const indent = Math.floor(match[1].length / 2);
2116
2135
  const checked = match[2] === "x" || match[2] === "X";
2117
2136
  return Decoration8.replace({
2118
- widget: new CheckboxWidget(pos, checked, indent, view.state.readOnly ? void 0 : (checked2) => {
2137
+ widget: new CheckboxWidget(checked, indent, view.state.readOnly ? void 0 : (checked2) => {
2119
2138
  const idx = pos + match[0].indexOf("[") + 1;
2120
2139
  view.dispatch({
2121
2140
  changes: {
@@ -2132,16 +2151,16 @@ var tasklist = (options = {}) => {
2132
2151
  });
2133
2152
  }
2134
2153
  });
2135
- const tasks = ViewPlugin6.fromClass(class {
2154
+ const tasks = ViewPlugin7.fromClass(class {
2136
2155
  constructor(view) {
2137
2156
  this.tasks = taskMatcher.createDeco(view);
2138
2157
  }
2139
- update(update4) {
2140
- this.tasks = taskMatcher.updateDeco(update4, this.tasks);
2158
+ update(update2) {
2159
+ this.tasks = taskMatcher.updateDeco(update2, this.tasks);
2141
2160
  }
2142
2161
  }, {
2143
2162
  decorations: (value) => value.tasks,
2144
- provide: (plugin) => EditorView12.atomicRanges.of((view) => {
2163
+ provide: (plugin) => EditorView11.atomicRanges.of((view) => {
2145
2164
  return view.plugin(plugin)?.tasks || Decoration8.none;
2146
2165
  })
2147
2166
  });
@@ -2230,7 +2249,7 @@ var yjs = (content, awareness2) => [
2230
2249
  ];
2231
2250
 
2232
2251
  // packages/ui/react-ui-editor/src/themes/default.ts
2233
- import get6 from "lodash.get";
2252
+ import get3 from "lodash.get";
2234
2253
  var defaultTheme = {
2235
2254
  //
2236
2255
  // Main layout:
@@ -2259,21 +2278,21 @@ var defaultTheme = {
2259
2278
  "&.cm-focused": {
2260
2279
  outline: "none"
2261
2280
  },
2262
- "& .cm-scroller": {
2281
+ ".cm-scroller": {
2263
2282
  overflow: "visible",
2264
- fontFamily: get6(tokens, "fontFamily.mono", []).join(",")
2283
+ fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
2265
2284
  },
2266
- "& .cm-content": {
2285
+ ".cm-content": {
2267
2286
  padding: 0,
2268
2287
  // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
2269
2288
  fontSize: "16px"
2270
2289
  },
2271
2290
  "&light .cm-content": {
2272
- color: get6(tokens, "extend.colors.neutral.900", "black"),
2291
+ color: get3(tokens, "extend.colors.neutral.900", "black"),
2273
2292
  caretColor: "black"
2274
2293
  },
2275
2294
  "&dark .cm-content": {
2276
- color: get6(tokens, "extend.colors.neutral.100", "white"),
2295
+ color: get3(tokens, "extend.colors.neutral.100", "white"),
2277
2296
  caretColor: "white"
2278
2297
  },
2279
2298
  //
@@ -2285,41 +2304,41 @@ var defaultTheme = {
2285
2304
  "&dark .cm-cursor, &dark .cm-dropCursor": {
2286
2305
  borderLeft: "2px solid white"
2287
2306
  },
2288
- "& .cm-placeholder": {
2307
+ ".cm-placeholder": {
2289
2308
  fontWeight: 100
2290
2309
  },
2291
2310
  //
2292
2311
  // line
2293
2312
  //
2294
- "& .cm-line": {
2313
+ ".cm-line": {
2295
2314
  paddingInline: 0
2296
2315
  },
2297
- "& .cm-activeLine": {
2316
+ ".cm-activeLine": {
2298
2317
  background: "inherit"
2299
2318
  },
2300
2319
  //
2301
2320
  // Selection
2302
2321
  //
2303
2322
  "&light .cm-selectionBackground": {
2304
- background: get6(tokens, "extend.colors.primary.100")
2323
+ background: get3(tokens, "extend.colors.primary.100")
2305
2324
  },
2306
2325
  "&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
2307
- background: get6(tokens, "extend.colors.primary.200")
2326
+ background: get3(tokens, "extend.colors.primary.200")
2308
2327
  },
2309
2328
  "&dark .cm-selectionBackground": {
2310
- background: get6(tokens, "extend.colors.primary.700")
2329
+ background: get3(tokens, "extend.colors.primary.700")
2311
2330
  },
2312
2331
  "&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
2313
- background: get6(tokens, "extend.colors.primary.600")
2332
+ background: get3(tokens, "extend.colors.primary.600")
2314
2333
  },
2315
2334
  //
2316
2335
  // Search
2317
2336
  //
2318
2337
  "&light .cm-searchMatch": {
2319
- backgroundColor: get6(tokens, "extend.colors.yellow.100")
2338
+ backgroundColor: get3(tokens, "extend.colors.yellow.100")
2320
2339
  },
2321
2340
  "&dark .cm-searchMatch": {
2322
- backgroundColor: get6(tokens, "extend.colors.yellow.700")
2341
+ backgroundColor: get3(tokens, "extend.colors.yellow.700")
2323
2342
  },
2324
2343
  //
2325
2344
  // collaboration
@@ -2331,95 +2350,101 @@ var defaultTheme = {
2331
2350
  "&dark .cm-ySelection, &dark .cm-yLineSelection": {
2332
2351
  mixBlendMode: "screen"
2333
2352
  },
2334
- "& .cm-ySelectionInfo": {
2353
+ ".cm-ySelectionInfo": {
2335
2354
  padding: "2px 4px",
2336
2355
  marginBlockStart: "-4px"
2337
2356
  },
2338
- "& .cm-ySelection, & .cm-selectionMatch": {
2357
+ ".cm-ySelection, & .cm-selectionMatch": {
2339
2358
  paddingBlockStart: ".15em",
2340
2359
  paddingBlockEnd: ".15em"
2341
2360
  },
2342
- "& .cm-ySelectionCaret": {
2361
+ ".cm-ySelectionCaret": {
2343
2362
  display: "inline-block",
2344
2363
  insetBlockStart: ".1em",
2345
2364
  blockSize: "1.4em",
2346
2365
  verticalAlign: "top"
2347
2366
  },
2348
- "& .cm-yLineSelection": {
2367
+ ".cm-yLineSelection": {
2349
2368
  margin: 0
2350
2369
  },
2351
2370
  //
2352
2371
  // link
2353
2372
  //
2354
- "& .cm-link": {
2355
- color: get6(tokens, "extend.colors.primary.500"),
2373
+ ".cm-link": {
2374
+ color: get3(tokens, "extend.colors.primary.500"),
2356
2375
  textDecorationLine: "underline",
2357
2376
  textDecorationThickness: "1px",
2358
2377
  textUnderlineOffset: "2px",
2359
2378
  borderRadius: ".125rem",
2360
- fontFamily: get6(tokens, "fontFamily.body", []).join(",")
2379
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2361
2380
  },
2362
2381
  //
2363
2382
  // tooltip
2364
2383
  //
2365
- "& .cm-tooltip": {
2384
+ ".cm-tooltip": {
2366
2385
  border: "none"
2367
2386
  },
2368
- "& .cm-tooltip-below": {},
2387
+ ".cm-tooltip-below": {},
2369
2388
  //
2370
2389
  // autocomplete
2371
2390
  //
2372
- "& .cm-tooltip-autocomplete": {
2391
+ ".cm-tooltip-autocomplete": {
2373
2392
  marginTop: "4px",
2374
2393
  marginLeft: "-3px"
2375
2394
  },
2376
- "& .cm-tooltip-autocomplete ul li": {},
2377
- "& .cm-tooltip-autocomplete ul li[aria-selected]": {},
2378
- "& .cm-completionIcon": {
2395
+ ".cm-tooltip-autocomplete ul li": {},
2396
+ ".cm-tooltip-autocomplete ul li[aria-selected]": {},
2397
+ ".cm-completionIcon": {
2379
2398
  display: "none"
2380
2399
  },
2381
- "& .cm-completionLabel": {
2382
- fontFamily: get6(tokens, "fontFamily.body", []).join(",")
2400
+ ".cm-completionLabel": {
2401
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2383
2402
  },
2384
- "& .cm-completionMatchedText": {
2403
+ ".cm-completionMatchedText": {
2385
2404
  textDecoration: "none"
2386
2405
  },
2387
2406
  //
2388
2407
  // widgets
2389
2408
  //
2390
- "& .cm-widgetBuffer": {
2409
+ ".cm-widgetBuffer": {
2391
2410
  display: "none",
2392
2411
  height: 0
2393
2412
  },
2394
2413
  //
2395
2414
  // table
2396
2415
  //
2397
- "& .cm-table *": {
2398
- fontFamily: `${get6(tokens, "fontFamily.mono", []).join(",")} !important`,
2416
+ ".cm-table *": {
2417
+ fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
2399
2418
  textDecoration: "none !important"
2400
2419
  },
2401
- "& .cm-table-head": {
2420
+ ".cm-table-head": {
2402
2421
  padding: "2px 16px 2px 0px",
2403
- borderBottom: `1px solid ${get6(tokens, "extend.colors.neutral.500")}`,
2422
+ borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
2404
2423
  fontWeight: 100,
2405
2424
  textAlign: "left",
2406
- color: get6(tokens, "extend.colors.neutral.500")
2425
+ color: get3(tokens, "extend.colors.neutral.500")
2407
2426
  },
2408
- "& .cm-table-cell": {
2427
+ ".cm-table-cell": {
2409
2428
  padding: "2px 16px 2px 0px"
2410
2429
  },
2411
2430
  //
2412
2431
  // image
2413
2432
  //
2414
- "& .cm-image": {
2415
- margin: "0.5rem 0"
2433
+ ".cm-image": {
2434
+ display: "block",
2435
+ height: "0"
2436
+ },
2437
+ ".cm-image.cm-loaded-image": {
2438
+ height: "auto",
2439
+ borderTop: "0.5rem solid transparent",
2440
+ borderBottom: "0.5rem solid transparent"
2416
2441
  },
2417
2442
  //
2418
2443
  // font size
2419
2444
  // 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.
2420
2445
  //
2421
- ...Object.keys(get6(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
2422
- const height = get6(tokens, [
2446
+ ...Object.keys(get3(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
2447
+ const height = get3(tokens, [
2423
2448
  "extend",
2424
2449
  "fontSize",
2425
2450
  fontSize,
@@ -2453,51 +2478,51 @@ var defaultTheme = {
2453
2478
  * </div>
2454
2479
  * </div
2455
2480
  */
2456
- "& .cm-panels": {
2457
- border: `1px solid ${get6(tokens, "extend.colors.neutral.200")}`
2481
+ ".cm-panels": {
2482
+ border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`
2458
2483
  },
2459
- "& .cm-panel": {
2460
- background: get6(tokens, "extend.colors.neutral.50"),
2461
- fontFamily: get6(tokens, "fontFamily.body", []).join(",")
2484
+ ".cm-panel": {
2485
+ background: get3(tokens, "extend.colors.neutral.50"),
2486
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2462
2487
  },
2463
- "& .cm-button": {
2488
+ ".cm-button": {
2464
2489
  margin: "4px",
2465
- fontFamily: get6(tokens, "fontFamily.body", []).join(","),
2466
- background: get6(tokens, "extend.colors.neutral.100"),
2490
+ fontFamily: get3(tokens, "fontFamily.body", []).join(","),
2491
+ background: get3(tokens, "extend.colors.neutral.100"),
2467
2492
  backgroundImage: "none",
2468
2493
  border: "none",
2469
2494
  "&:hover": {
2470
- background: get6(tokens, "extend.colors.neutral.200")
2495
+ background: get3(tokens, "extend.colors.neutral.200")
2471
2496
  },
2472
2497
  "&:active": {
2473
- background: get6(tokens, "extend.colors.neutral.300"),
2498
+ background: get3(tokens, "extend.colors.neutral.300"),
2474
2499
  backgroundImage: "none"
2475
2500
  }
2476
2501
  },
2477
- "& .cm-panel input[type=checkbox]": {
2502
+ ".cm-panel input[type=checkbox]": {
2478
2503
  marginRight: "0.4rem !important"
2479
2504
  }
2480
2505
  };
2481
2506
  var textTheme = {
2482
- "& .cm-scroller": {
2483
- fontFamily: get6(tokens, "fontFamily.body", []).join(",")
2507
+ ".cm-scroller": {
2508
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2484
2509
  },
2485
- "& .cm-placeholder": {
2486
- fontFamily: get6(tokens, "fontFamily.body", []).join(",")
2510
+ ".cm-placeholder": {
2511
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2487
2512
  }
2488
2513
  };
2489
2514
  var markdownTheme = {
2490
2515
  // NOTE: Must leave base font family as is (i.e., monospace) due to fenced code blocks.
2491
- "& .cm-placeholder": {
2492
- fontFamily: get6(tokens, "fontFamily.body", []).join(",")
2516
+ ".cm-placeholder": {
2517
+ fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2493
2518
  }
2494
2519
  };
2495
2520
  var codeTheme = {
2496
- "& .cm-scroller": {
2497
- fontFamily: get6(tokens, "fontFamily.mono", []).join(",")
2521
+ ".cm-scroller": {
2522
+ fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
2498
2523
  },
2499
- "& .cm-placeholder": {
2500
- fontFamily: get6(tokens, "fontFamily.mono", []).join(",")
2524
+ ".cm-placeholder": {
2525
+ fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
2501
2526
  }
2502
2527
  };
2503
2528
 
@@ -2568,9 +2593,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2568
2593
  editorMode === "vim" && vim(),
2569
2594
  // Theme.
2570
2595
  // TODO(burdon): Make theme configurable.
2571
- EditorView13.baseTheme(defaultTheme),
2572
- EditorView13.theme(slots?.editor?.theme ?? {}),
2573
- EditorView13.darkTheme.of(themeMode === "dark"),
2596
+ EditorView12.baseTheme(defaultTheme),
2597
+ EditorView12.theme(slots?.editor?.theme ?? {}),
2598
+ EditorView12.darkTheme.of(themeMode === "dark"),
2574
2599
  // Storage and replication.
2575
2600
  model.extension,
2576
2601
  // Custom.
@@ -2580,7 +2605,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2580
2605
  view?.destroy();
2581
2606
  setEditor({
2582
2607
  state: state2,
2583
- view: new EditorView13({
2608
+ view: new EditorView12({
2584
2609
  state: state2,
2585
2610
  parent: root
2586
2611
  })
@@ -2676,7 +2701,7 @@ var defaultMarkdownSlots = {
2676
2701
  };
2677
2702
 
2678
2703
  // packages/ui/react-ui-editor/src/hooks/automerge.ts
2679
- import get7 from "lodash.get";
2704
+ import get4 from "lodash.get";
2680
2705
  import { getRawDoc } from "@dxos/echo-schema";
2681
2706
  import { isNotNullOrUndefined } from "@dxos/util";
2682
2707
 
@@ -2786,7 +2811,7 @@ var SpaceAwarenessProvider = class {
2786
2811
  };
2787
2812
 
2788
2813
  // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
2789
- import { StateField as StateField6 } from "@codemirror/state";
2814
+ import { StateField as StateField5 } from "@codemirror/state";
2790
2815
  import { useEffect as useEffect2, useState as useState2 } from "react";
2791
2816
  import { isAutomergeObject } from "@dxos/react-client/echo";
2792
2817
 
@@ -2953,7 +2978,7 @@ var YAwarenessProvider = class extends Observable {
2953
2978
  };
2954
2979
 
2955
2980
  // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
2956
- var modelState = StateField6.define({
2981
+ var modelState = StateField5.define({
2957
2982
  create: () => void 0,
2958
2983
  update: (model) => model
2959
2984
  });
@@ -2997,7 +3022,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
2997
3022
  const model = {
2998
3023
  id: obj.id,
2999
3024
  content: doc,
3000
- text: () => get7(doc.handle.docSync(), doc.path),
3025
+ text: () => get4(doc.handle.docSync(), doc.path),
3001
3026
  // TODO(burdon): https://automerge.org/automerge/api-docs/js/functions/next.getCursor.html
3002
3027
  extension: [
3003
3028
  modelState.init(() => model),
@@ -3018,6 +3043,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
3018
3043
  export {
3019
3044
  AwarenessProvider,
3020
3045
  BaseTextEditor,
3046
+ CursorConverter,
3021
3047
  Doc,
3022
3048
  EditorModes,
3023
3049
  MarkdownEditor,
@@ -3033,16 +3059,19 @@ export {
3033
3059
  awareness,
3034
3060
  basicBundle,
3035
3061
  blast,
3062
+ callbackWrapper,
3036
3063
  code2 as code,
3037
3064
  codeTheme,
3038
3065
  comments,
3039
3066
  createAutomergeModel,
3040
3067
  createYjsModel,
3068
+ cursorConverter,
3041
3069
  defaultMarkdownSlots,
3042
3070
  defaultOptions,
3043
3071
  defaultSlots,
3044
3072
  defaultTextSlots,
3045
3073
  defaultTheme,
3074
+ getToken,
3046
3075
  hr,
3047
3076
  image,
3048
3077
  link,
@@ -3053,7 +3082,6 @@ export {
3053
3082
  markdownTagsExtensions,
3054
3083
  markdownTheme,
3055
3084
  mention,
3056
- mermaid,
3057
3085
  modelState,
3058
3086
  setCommentRange,
3059
3087
  setFocus,