@dxos/react-ui-editor 0.3.11-main.d8b8a39 → 0.3.11-main.d8f9aa0

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 (39) hide show
  1. package/dist/lib/browser/index.mjs +529 -484
  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.map +1 -1
  5. package/dist/types/src/extensions/index.d.ts +0 -6
  6. package/dist/types/src/extensions/index.d.ts.map +1 -1
  7. package/dist/types/src/extensions/markdown/code.d.ts.map +1 -0
  8. package/dist/types/src/extensions/markdown/heading.d.ts +6 -0
  9. package/dist/types/src/extensions/markdown/heading.d.ts.map +1 -0
  10. package/dist/types/src/extensions/markdown/hr.d.ts.map +1 -0
  11. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
  12. package/dist/types/src/extensions/markdown/index.d.ts +7 -0
  13. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  14. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
  15. package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
  16. package/dist/types/src/extensions/markdown/tasklist.d.ts.map +1 -0
  17. package/package.json +23 -23
  18. package/src/components/TextEditor/MarkdownEditor.stories.tsx +2 -0
  19. package/src/extensions/index.ts +0 -6
  20. package/src/extensions/{code.ts → markdown/code.ts} +1 -1
  21. package/src/extensions/markdown/heading.ts +60 -0
  22. package/src/extensions/{hr.ts → markdown/hr.ts} +1 -1
  23. package/src/extensions/markdown/index.ts +7 -0
  24. package/src/extensions/{tasklist.ts → markdown/tasklist.ts} +1 -1
  25. package/dist/types/src/extensions/code.d.ts.map +0 -1
  26. package/dist/types/src/extensions/hr.d.ts.map +0 -1
  27. package/dist/types/src/extensions/image.d.ts.map +0 -1
  28. package/dist/types/src/extensions/link.d.ts.map +0 -1
  29. package/dist/types/src/extensions/table.d.ts.map +0 -1
  30. package/dist/types/src/extensions/tasklist.d.ts.map +0 -1
  31. /package/dist/types/src/extensions/{code.d.ts → markdown/code.d.ts} +0 -0
  32. /package/dist/types/src/extensions/{hr.d.ts → markdown/hr.d.ts} +0 -0
  33. /package/dist/types/src/extensions/{image.d.ts → markdown/image.d.ts} +0 -0
  34. /package/dist/types/src/extensions/{link.d.ts → markdown/link.d.ts} +0 -0
  35. /package/dist/types/src/extensions/{table.d.ts → markdown/table.d.ts} +0 -0
  36. /package/dist/types/src/extensions/{tasklist.d.ts → markdown/tasklist.d.ts} +0 -0
  37. /package/src/extensions/{image.ts → markdown/image.ts} +0 -0
  38. /package/src/extensions/{link.ts → markdown/link.ts} +0 -0
  39. /package/src/extensions/{table.ts → markdown/table.ts} +0 -0
@@ -947,9 +947,14 @@ var random = (min, max) => {
947
947
  return min + ~~(Math.random() * (max - min + 1));
948
948
  };
949
949
 
950
- // packages/ui/react-ui-editor/src/extensions/code.ts
951
- import { ViewPlugin as ViewPlugin3, EditorView as EditorView5, Decoration as Decoration2 } from "@codemirror/view";
952
- import { mx as mx2 } from "@dxos/react-ui-theme";
950
+ // packages/ui/react-ui-editor/src/extensions/comments.ts
951
+ import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
952
+ import { hoverTooltip, keymap as keymap3, Decoration as Decoration2, EditorView as EditorView5 } from "@codemirror/view";
953
+ import sortBy from "lodash.sortby";
954
+ import { useEffect } from "react";
955
+ import { debounce } from "@dxos/async";
956
+ import { invariant as invariant3 } from "@dxos/invariant";
957
+ import { nonNullable } from "@dxos/util";
953
958
 
954
959
  // packages/ui/react-ui-editor/src/styles/cursors.ts
955
960
  import * as random2 from "lib0/random";
@@ -1037,89 +1042,6 @@ import { tailwindConfig } from "@dxos/react-ui-theme";
1037
1042
  var tokens = tailwindConfig({}).theme;
1038
1043
  var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
1039
1044
 
1040
- // packages/ui/react-ui-editor/src/extensions/code.ts
1041
- var CODE_REGEX = /```[\s\S]*?```/gs;
1042
- var styles2 = EditorView5.baseTheme({
1043
- "& .cm-codeblock": {
1044
- fontFamily: getToken("fontFamily.mono", []).join(",")
1045
- },
1046
- '&light [aria-readonly="true"] .cm-codeblock': {
1047
- background: getToken("extend.colors.neutral.50")
1048
- },
1049
- '&dark [aria-readonly="true"] .cm-codeblock': {
1050
- background: getToken("extend.colors.neutral.850")
1051
- },
1052
- '& [aria-readonly="true"] .cm-codeblock': {
1053
- display: "block",
1054
- paddingInline: "4px !important"
1055
- },
1056
- '& [aria-readonly="true"] .cm-codeblock-first': {
1057
- paddingTop: "4px !important",
1058
- borderTopLeftRadius: "4px",
1059
- borderTopRightRadius: "4px"
1060
- },
1061
- '& [aria-readonly="true"] .cm-codeblock-last': {
1062
- paddingBottom: "4px !important",
1063
- borderBottomLeftRadius: "4px",
1064
- borderBottomRightRadius: "4px"
1065
- }
1066
- });
1067
- var getLineRange = (lines, from, to) => {
1068
- const start = lines.findIndex((line) => line.from >= from);
1069
- const end = lines.findIndex((line) => line.to >= to);
1070
- return [
1071
- start,
1072
- end
1073
- ];
1074
- };
1075
- var code2 = () => {
1076
- const buildDecorations5 = (view) => {
1077
- const decorations = [];
1078
- const text = view.state.doc.sliceString(0);
1079
- const matches = text.matchAll(CODE_REGEX);
1080
- const blocks = view.viewportLineBlocks;
1081
- for (const match of matches) {
1082
- const range = getLineRange(blocks, match.index, match.index + match[0].length);
1083
- for (let i = range[0]; i <= range[1]; i++) {
1084
- const block = blocks[i];
1085
- decorations.push(Decoration2.line({
1086
- class: mx2("cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
1087
- }).range(block.from));
1088
- }
1089
- }
1090
- return Decoration2.set(decorations);
1091
- };
1092
- return [
1093
- ViewPlugin3.fromClass(class {
1094
- constructor(view) {
1095
- this.hasFocus = false;
1096
- this.decorations = buildDecorations5(view);
1097
- }
1098
- update(update2) {
1099
- if (
1100
- // TODO(burdon): Generalize for other extensions.
1101
- this.hasFocus !== update2.view.hasFocus || update2.startState.readOnly !== update2.view.state.readOnly || update2.docChanged || update2.viewportChanged
1102
- ) {
1103
- this.hasFocus = update2.view.hasFocus;
1104
- this.decorations = buildDecorations5(update2.view);
1105
- }
1106
- }
1107
- }, {
1108
- decorations: (value) => value.decorations
1109
- }),
1110
- styles2
1111
- ];
1112
- };
1113
-
1114
- // packages/ui/react-ui-editor/src/extensions/comments.ts
1115
- import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
1116
- import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView6 } from "@codemirror/view";
1117
- import sortBy from "lodash.sortby";
1118
- import { useEffect } from "react";
1119
- import { debounce } from "@dxos/async";
1120
- import { invariant as invariant3 } from "@dxos/invariant";
1121
- import { nonNullable } from "@dxos/util";
1122
-
1123
1045
  // packages/ui/react-ui-editor/src/util.ts
1124
1046
  import { log } from "@dxos/log";
1125
1047
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
@@ -1157,7 +1079,7 @@ var logChanges = (trs) => {
1157
1079
 
1158
1080
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1159
1081
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
1160
- var styles3 = EditorView6.baseTheme({
1082
+ var styles2 = EditorView5.baseTheme({
1161
1083
  "& .cm-comment": {
1162
1084
  backgroundColor: getToken("extend.colors.yellow.50")
1163
1085
  },
@@ -1166,10 +1088,10 @@ var styles3 = EditorView6.baseTheme({
1166
1088
  }
1167
1089
  });
1168
1090
  var marks = {
1169
- highlight: Decoration3.mark({
1091
+ highlight: Decoration2.mark({
1170
1092
  class: "cm-comment"
1171
1093
  }),
1172
- highlightActive: Decoration3.mark({
1094
+ highlightActive: Decoration2.mark({
1173
1095
  class: "cm-comment-current"
1174
1096
  })
1175
1097
  };
@@ -1186,7 +1108,7 @@ var setFocus = (view, id, center = true) => {
1186
1108
  },
1187
1109
  effects: [
1188
1110
  //
1189
- EditorView6.scrollIntoView(range.from, center ? {
1111
+ EditorView5.scrollIntoView(range.from, center ? {
1190
1112
  y: "center"
1191
1113
  } : void 0),
1192
1114
  setSelection.of({
@@ -1235,7 +1157,7 @@ var commentsState = StateField2.define({
1235
1157
  return value;
1236
1158
  }
1237
1159
  });
1238
- var highlightDecorations = EditorView6.decorations.compute([
1160
+ var highlightDecorations = EditorView5.decorations.compute([
1239
1161
  commentsState
1240
1162
  ], (state) => {
1241
1163
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -1251,7 +1173,7 @@ var highlightDecorations = EditorView6.decorations.compute([
1251
1173
  return marks.highlight.range(range.from, range.to);
1252
1174
  }
1253
1175
  }).filter(nonNullable);
1254
- return Decoration3.set(decorations);
1176
+ return Decoration2.set(decorations);
1255
1177
  });
1256
1178
  var trackPastedComments = (onUpdate) => {
1257
1179
  let tracked = null;
@@ -1273,12 +1195,12 @@ var trackPastedComments = (onUpdate) => {
1273
1195
  }
1274
1196
  };
1275
1197
  return [
1276
- EditorView6.domEventHandlers({
1198
+ EditorView5.domEventHandlers({
1277
1199
  cut: handleTrack,
1278
1200
  copy: handleTrack
1279
1201
  }),
1280
1202
  // Handle paste.
1281
- EditorView6.updateListener.of(({ view, state, transactions }) => {
1203
+ EditorView5.updateListener.of(({ view, state, transactions }) => {
1282
1204
  if (tracked) {
1283
1205
  const paste = transactions.find((tr) => tr.isUserEvent("input.paste"));
1284
1206
  if (paste) {
@@ -1355,7 +1277,7 @@ var comments = (options = {}) => {
1355
1277
  return [
1356
1278
  commentsState,
1357
1279
  highlightDecorations,
1358
- styles3,
1280
+ styles2,
1359
1281
  //
1360
1282
  // Keymap.
1361
1283
  //
@@ -1398,7 +1320,7 @@ var comments = (options = {}) => {
1398
1320
  //
1399
1321
  // Track deleted ranges and update ranges for decorations.
1400
1322
  //
1401
- EditorView6.updateListener.of(({ view, state, changes }) => {
1323
+ EditorView5.updateListener.of(({ view, state, changes }) => {
1402
1324
  let mod = false;
1403
1325
  const { comments: comments2, ...value } = state.field(commentsState);
1404
1326
  changes.iterChanges((from, to, from2, to2) => {
@@ -1428,7 +1350,7 @@ var comments = (options = {}) => {
1428
1350
  //
1429
1351
  // Track selection/proximity.
1430
1352
  //
1431
- EditorView6.updateListener.of(({ view, state }) => {
1353
+ EditorView5.updateListener.of(({ view, state }) => {
1432
1354
  let min = Infinity;
1433
1355
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
1434
1356
  const { head } = state.selection.main;
@@ -1476,329 +1398,65 @@ var useComments = (view, comments2 = []) => {
1476
1398
  ]);
1477
1399
  };
1478
1400
 
1479
- // packages/ui/react-ui-editor/src/extensions/hr.ts
1480
- import { syntaxTree } from "@codemirror/language";
1481
- import { RangeSetBuilder } from "@codemirror/state";
1482
- import { Decoration as Decoration4, EditorView as EditorView7, ViewPlugin as ViewPlugin4, WidgetType as WidgetType2 } from "@codemirror/view";
1483
- var styles4 = EditorView7.baseTheme({
1484
- "& .cm-hr": {
1485
- // Note that block-level decorations should not have vertical margins,
1486
- borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
1487
- }
1488
- });
1489
- var HorizontalRuleWidget = class extends WidgetType2 {
1490
- toDOM() {
1491
- const el = document.createElement("div");
1492
- el.className = "cm-hr";
1493
- return el;
1494
- }
1495
- };
1496
- var decoration = Decoration4.replace({
1497
- widget: new HorizontalRuleWidget()
1498
- });
1499
- var buildDecorations = (view) => {
1500
- const builder = new RangeSetBuilder();
1501
- const { state } = view;
1502
- const cursor = state.selection.main.head;
1503
- for (const { from, to } of view.visibleRanges) {
1504
- syntaxTree(state).iterate({
1505
- enter: (node) => {
1506
- if (node.name === "HorizontalRule") {
1507
- if (cursor <= node.from || cursor >= node.to) {
1508
- builder.add(node.from, node.to, decoration);
1509
- }
1510
- }
1511
- },
1512
- from,
1513
- to
1514
- });
1515
- }
1516
- return builder.finish();
1517
- };
1518
- var hr = () => {
1519
- return [
1520
- styles4,
1521
- ViewPlugin4.fromClass(class {
1522
- constructor(view) {
1523
- this.decorations = buildDecorations(view);
1524
- }
1525
- update(update2) {
1526
- this.decorations = buildDecorations(update2.view);
1527
- }
1528
- }, {
1529
- decorations: (v) => v.decorations
1530
- })
1531
- ];
1401
+ // packages/ui/react-ui-editor/src/extensions/listener.ts
1402
+ import { EditorView as EditorView6 } from "@codemirror/view";
1403
+ var listener = ({ onFocus, onChange }) => {
1404
+ const extensions = [];
1405
+ onFocus && extensions.push(EditorView6.focusChangeEffect.of((_, focused) => {
1406
+ onFocus(focused);
1407
+ return null;
1408
+ }));
1409
+ onChange && extensions.push(EditorView6.updateListener.of((update2) => {
1410
+ onChange(update2.state.doc.toString());
1411
+ }));
1412
+ return extensions;
1532
1413
  };
1533
1414
 
1534
- // packages/ui/react-ui-editor/src/extensions/image.ts
1535
- import { syntaxTree as syntaxTree2 } from "@codemirror/language";
1536
- import { StateField as StateField3 } from "@codemirror/state";
1537
- import { Decoration as Decoration5, EditorView as EditorView8, WidgetType as WidgetType3 } from "@codemirror/view";
1538
- var image = (options = {}) => {
1539
- return StateField3.define({
1540
- create: (state) => {
1541
- return Decoration5.set(buildDecorations2(0, state.doc.length, state));
1542
- },
1543
- update: (value, tr) => {
1544
- if (!tr.docChanged && !tr.selection) {
1545
- return value;
1546
- }
1547
- const cursor = tr.state.selection.main.head;
1548
- const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
1549
- let from = Math.min(cursor, oldCursor);
1550
- let to = Math.max(cursor, oldCursor);
1551
- tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
1552
- from = Math.min(from, fromB);
1553
- to = Math.max(to, toB);
1554
- });
1555
- from = tr.state.doc.lineAt(from).from;
1556
- to = tr.state.doc.lineAt(to).to;
1557
- return value.map(tr.changes).update({
1558
- filterFrom: from,
1559
- filterTo: to,
1560
- filter: () => false,
1561
- add: buildDecorations2(from, to, tr.state)
1562
- });
1563
- },
1564
- provide: (field) => EditorView8.decorations.from(field)
1565
- });
1566
- };
1567
- var buildDecorations2 = (from, to, state) => {
1568
- const decorations = [];
1569
- const cursor = state.selection.main.head;
1570
- syntaxTree2(state).iterate({
1571
- enter: (node) => {
1572
- if (node.name === "Image") {
1573
- const urlNode = node.node.getChild("URL");
1574
- if (urlNode) {
1575
- const hide = state.readOnly || cursor < node.from || cursor > node.to;
1576
- const url = state.sliceDoc(urlNode.from, urlNode.to);
1577
- decorations.push(Decoration5.replace({
1578
- block: true,
1579
- widget: new ImageWidget(url)
1580
- }).range(hide ? node.from : node.to, node.to));
1581
- }
1582
- }
1583
- },
1584
- from,
1585
- to
1586
- });
1587
- return decorations;
1415
+ // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
1416
+ import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
1417
+ import { history as history2, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
1418
+ import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
1419
+ import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
1420
+ import { languages } from "@codemirror/language-data";
1421
+ import { searchKeymap } from "@codemirror/search";
1422
+ import { EditorState } from "@codemirror/state";
1423
+ import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
1424
+ import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView7, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1425
+
1426
+ // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
1427
+ import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
1428
+ import { HighlightStyle } from "@codemirror/language";
1429
+ import { tags, styleTags, Tag } from "@lezer/highlight";
1430
+ import { Table } from "@lezer/markdown";
1431
+ var markdownTags = {
1432
+ Blockquote: Tag.define(),
1433
+ CodeMark: Tag.define(),
1434
+ CodeText: Tag.define(),
1435
+ EmphasisMark: Tag.define(),
1436
+ HeaderMark: Tag.define(),
1437
+ InlineCode: Tag.define(),
1438
+ LinkLabel: Tag.define(),
1439
+ LinkReference: Tag.define(),
1440
+ ListMark: Tag.define(),
1441
+ QuoteMark: Tag.define(),
1442
+ URL: Tag.define(),
1443
+ // Custom.
1444
+ TableCell: Tag.define()
1588
1445
  };
1589
- var ImageWidget = class extends WidgetType3 {
1590
- constructor(_url) {
1591
- super();
1592
- this._url = _url;
1593
- }
1594
- eq(other) {
1595
- return this._url === other._url;
1446
+ Table.defineNodes?.forEach((node) => {
1447
+ switch (node?.name) {
1448
+ case "TableCell": {
1449
+ node.style = markdownTags.TableCell;
1450
+ break;
1451
+ }
1596
1452
  }
1597
- toDOM(view) {
1598
- const img = document.createElement("img");
1599
- img.setAttribute("src", this._url);
1600
- img.setAttribute("class", "cm-image");
1601
- img.onload = () => img.classList.add("cm-loaded-image");
1602
- return img;
1603
- }
1604
- };
1605
-
1606
- // packages/ui/react-ui-editor/src/extensions/link.ts
1607
- import { syntaxTree as syntaxTree3 } from "@codemirror/language";
1608
- import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
1609
- import { hoverTooltip as hoverTooltip2, Decoration as Decoration6, ViewPlugin as ViewPlugin5, WidgetType as WidgetType4 } from "@codemirror/view";
1610
- import { tooltipContent } from "@dxos/react-ui-theme";
1611
- var link = (options = {}) => {
1612
- const extensions = [
1613
- ViewPlugin5.fromClass(class {
1614
- constructor(view) {
1615
- this.decorations = buildDecorations3(view, options);
1616
- }
1617
- update(update2) {
1618
- if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
1619
- this.decorations = buildDecorations3(update2.view, options);
1620
- }
1621
- }
1622
- }, {
1623
- decorations: (v) => v.decorations
1624
- })
1625
- ];
1626
- if (options.onHover) {
1627
- extensions.push(
1628
- // https://codemirror.net/examples/tooltip
1629
- // https://codemirror.net/docs/ref/#view.hoverTooltip
1630
- // https://github.com/codemirror/view/blob/main/src/tooltip.ts
1631
- hoverTooltip2((view, pos, side) => {
1632
- const syntax = syntaxTree3(view.state).resolveInner(pos, side);
1633
- let link2 = null;
1634
- for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
1635
- link2 = node.name === "Link" ? node : null;
1636
- }
1637
- const url = link2 && link2.getChild("URL");
1638
- if (!url || !link2) {
1639
- return null;
1640
- }
1641
- const urlText = view.state.sliceDoc(url.from, url.to);
1642
- return {
1643
- pos: link2.from,
1644
- end: link2.to,
1645
- above: true,
1646
- create: () => {
1647
- const el = document.createElement("div");
1648
- el.className = tooltipContent({}, "pli-2 plb-1");
1649
- options.onHover(el, urlText);
1650
- return {
1651
- dom: el,
1652
- offset: {
1653
- x: 0,
1654
- y: 4
1655
- }
1656
- };
1657
- }
1658
- };
1659
- })
1660
- );
1661
- }
1662
- return extensions;
1663
- };
1664
- var LinkButton = class extends WidgetType4 {
1665
- constructor(_url, _onAttach) {
1666
- super();
1667
- this._url = _url;
1668
- this._onAttach = _onAttach;
1669
- }
1670
- eq(other) {
1671
- return this._url === other._url;
1672
- }
1673
- toDOM(view) {
1674
- const el = document.createElement("span");
1675
- this._onAttach(el, this._url);
1676
- return el;
1677
- }
1678
- };
1679
- var LinkText = class extends WidgetType4 {
1680
- constructor(_text, _url) {
1681
- super();
1682
- this._text = _text;
1683
- this._url = _url;
1684
- }
1685
- eq(other) {
1686
- return this._url === other._url;
1687
- }
1688
- toDOM(view) {
1689
- const link2 = document.createElement("a");
1690
- link2.setAttribute("class", "cm-link");
1691
- link2.textContent = this._text;
1692
- if (this._url) {
1693
- link2.setAttribute("rel", "noreferrer");
1694
- link2.setAttribute("target", "_blank");
1695
- link2.href = this._url;
1696
- } else {
1697
- link2.onclick = () => {
1698
- view.dispatch({
1699
- selection: {
1700
- anchor: view.posAtDOM(link2)
1701
- }
1702
- });
1703
- };
1704
- }
1705
- return link2;
1706
- }
1707
- };
1708
- var buildDecorations3 = (view, options) => {
1709
- const builder = new RangeSetBuilder2();
1710
- const { state } = view;
1711
- const cursor = state.selection.main.head;
1712
- for (const { from, to } of view.visibleRanges) {
1713
- syntaxTree3(state).iterate({
1714
- enter: (node) => {
1715
- if (node.name === "Link") {
1716
- const marks2 = node.node.getChildren("LinkMark");
1717
- const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
1718
- const urlNode = node.node.getChild("URL");
1719
- const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
1720
- if (!url) {
1721
- return false;
1722
- }
1723
- if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
1724
- builder.add(node.from, node.to, Decoration6.replace({
1725
- widget: new LinkText(text, options.link ? url : void 0)
1726
- }));
1727
- }
1728
- if (options.onRender) {
1729
- builder.add(node.to, node.to, Decoration6.replace({
1730
- widget: new LinkButton(url, options.onRender)
1731
- }));
1732
- }
1733
- return false;
1734
- }
1735
- },
1736
- from,
1737
- to
1738
- });
1739
- }
1740
- return builder.finish();
1741
- };
1742
-
1743
- // packages/ui/react-ui-editor/src/extensions/listener.ts
1744
- import { EditorView as EditorView9 } from "@codemirror/view";
1745
- var listener = ({ onFocus, onChange }) => {
1746
- const extensions = [];
1747
- onFocus && extensions.push(EditorView9.focusChangeEffect.of((_, focused) => {
1748
- onFocus(focused);
1749
- return null;
1750
- }));
1751
- onChange && extensions.push(EditorView9.updateListener.of((update2) => {
1752
- onChange(update2.state.doc.toString());
1753
- }));
1754
- return extensions;
1755
- };
1756
-
1757
- // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
1758
- import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
1759
- import { history as history2, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
1760
- import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
1761
- import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
1762
- import { languages } from "@codemirror/language-data";
1763
- import { searchKeymap } from "@codemirror/search";
1764
- import { EditorState } from "@codemirror/state";
1765
- import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
1766
- import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView10, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1767
-
1768
- // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
1769
- import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
1770
- import { HighlightStyle } from "@codemirror/language";
1771
- import { tags, styleTags, Tag } from "@lezer/highlight";
1772
- import { Table } from "@lezer/markdown";
1773
- var markdownTags = {
1774
- Blockquote: Tag.define(),
1775
- CodeMark: Tag.define(),
1776
- CodeText: Tag.define(),
1777
- EmphasisMark: Tag.define(),
1778
- HeaderMark: Tag.define(),
1779
- InlineCode: Tag.define(),
1780
- LinkLabel: Tag.define(),
1781
- LinkReference: Tag.define(),
1782
- ListMark: Tag.define(),
1783
- QuoteMark: Tag.define(),
1784
- URL: Tag.define(),
1785
- // Custom.
1786
- TableCell: Tag.define()
1787
- };
1788
- Table.defineNodes?.forEach((node) => {
1789
- switch (node?.name) {
1790
- case "TableCell": {
1791
- node.style = markdownTags.TableCell;
1792
- break;
1793
- }
1794
- }
1795
- });
1796
- var markdownTagsExtensions = [
1797
- Table,
1798
- {
1799
- props: [
1800
- styleTags(markdownTags)
1801
- ]
1453
+ });
1454
+ var markdownTagsExtensions = [
1455
+ Table,
1456
+ {
1457
+ props: [
1458
+ styleTags(markdownTags)
1459
+ ]
1802
1460
  }
1803
1461
  ];
1804
1462
  var markdownHighlightStyle = (readonly) => {
@@ -1958,7 +1616,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
1958
1616
  return [
1959
1617
  EditorState.allowMultipleSelections.of(true),
1960
1618
  EditorState.tabSize.of(2),
1961
- EditorView10.lineWrapping,
1619
+ EditorView7.lineWrapping,
1962
1620
  // https://github.com/codemirror/basic-setup
1963
1621
  bracketMatching2(),
1964
1622
  closeBrackets2(),
@@ -2006,61 +1664,413 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
2006
1664
  ];
2007
1665
  };
2008
1666
 
2009
- // packages/ui/react-ui-editor/src/extensions/mention.ts
2010
- import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
2011
- var mention = ({ onSearch }) => {
2012
- return autocompletion2({
2013
- // TODO(burdon): Not working.
2014
- activateOnTyping: true,
2015
- // activateOnTypingDelay: 100,
2016
- // selectOnOpen: true,
2017
- closeOnBlur: false,
2018
- // defaultKeymap: false,
2019
- icons: false,
2020
- override: [
2021
- (context) => {
2022
- console.log(context);
2023
- const match = context.matchBefore(/@(\w+)?/);
2024
- if (!match || match.from === match.to && !context.explicit) {
2025
- return null;
2026
- }
2027
- return {
2028
- from: match.from,
2029
- options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
2030
- label: `@${value}`
2031
- }))
2032
- };
2033
- }
2034
- ]
2035
- });
2036
- };
2037
-
2038
- // packages/ui/react-ui-editor/src/extensions/outliner.ts
2039
- var outliner = (options = {}) => {
2040
- return [];
2041
- };
2042
-
2043
- // packages/ui/react-ui-editor/src/extensions/table.ts
2044
- import { syntaxTree as syntaxTree4 } from "@codemirror/language";
2045
- import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField4 } from "@codemirror/state";
2046
- import { Decoration as Decoration7, EditorView as EditorView11, WidgetType as WidgetType5 } from "@codemirror/view";
2047
- var table = (options = {}) => {
2048
- return StateField4.define({
2049
- create: (state) => update(state, options),
2050
- update: (_, tr) => update(tr.state, options),
2051
- provide: (field) => EditorView11.decorations.from(field)
2052
- });
1667
+ // packages/ui/react-ui-editor/src/extensions/markdown/code.ts
1668
+ import { ViewPlugin as ViewPlugin3, EditorView as EditorView8, Decoration as Decoration3 } from "@codemirror/view";
1669
+ import { mx as mx2 } from "@dxos/react-ui-theme";
1670
+ var CODE_REGEX = /```[\s\S]*?```/gs;
1671
+ var styles3 = EditorView8.baseTheme({
1672
+ "& .cm-codeblock": {
1673
+ fontFamily: getToken("fontFamily.mono", []).join(",")
1674
+ },
1675
+ '&light [aria-readonly="true"] .cm-codeblock': {
1676
+ background: getToken("extend.colors.neutral.50")
1677
+ },
1678
+ '&dark [aria-readonly="true"] .cm-codeblock': {
1679
+ background: getToken("extend.colors.neutral.850")
1680
+ },
1681
+ '& [aria-readonly="true"] .cm-codeblock': {
1682
+ display: "block",
1683
+ paddingInline: "4px !important"
1684
+ },
1685
+ '& [aria-readonly="true"] .cm-codeblock-first': {
1686
+ paddingTop: "4px !important",
1687
+ borderTopLeftRadius: "4px",
1688
+ borderTopRightRadius: "4px"
1689
+ },
1690
+ '& [aria-readonly="true"] .cm-codeblock-last': {
1691
+ paddingBottom: "4px !important",
1692
+ borderBottomLeftRadius: "4px",
1693
+ borderBottomRightRadius: "4px"
1694
+ }
1695
+ });
1696
+ var getLineRange = (lines, from, to) => {
1697
+ const start = lines.findIndex((line) => line.from >= from);
1698
+ const end = lines.findIndex((line) => line.to >= to);
1699
+ return [
1700
+ start,
1701
+ end
1702
+ ];
2053
1703
  };
2054
- var update = (state, options) => {
2055
- const builder = new RangeSetBuilder3();
2056
- const cursor = state.selection.main.head;
2057
- const tables = [];
2058
- const getTable = () => tables[tables.length - 1];
2059
- const getRow = () => {
2060
- const table2 = getTable();
1704
+ var code2 = () => {
1705
+ const buildDecorations6 = (view) => {
1706
+ const decorations = [];
1707
+ const text = view.state.doc.sliceString(0);
1708
+ const matches = text.matchAll(CODE_REGEX);
1709
+ const blocks = view.viewportLineBlocks;
1710
+ for (const match of matches) {
1711
+ const range = getLineRange(blocks, match.index, match.index + match[0].length);
1712
+ for (let i = range[0]; i <= range[1]; i++) {
1713
+ const block = blocks[i];
1714
+ decorations.push(Decoration3.line({
1715
+ class: mx2("cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
1716
+ }).range(block.from));
1717
+ }
1718
+ }
1719
+ return Decoration3.set(decorations);
1720
+ };
1721
+ return [
1722
+ ViewPlugin3.fromClass(class {
1723
+ constructor(view) {
1724
+ this.hasFocus = false;
1725
+ this.decorations = buildDecorations6(view);
1726
+ }
1727
+ update(update2) {
1728
+ if (
1729
+ // TODO(burdon): Generalize for other extensions.
1730
+ this.hasFocus !== update2.view.hasFocus || update2.startState.readOnly !== update2.view.state.readOnly || update2.docChanged || update2.viewportChanged
1731
+ ) {
1732
+ this.hasFocus = update2.view.hasFocus;
1733
+ this.decorations = buildDecorations6(update2.view);
1734
+ }
1735
+ }
1736
+ }, {
1737
+ decorations: (value) => value.decorations
1738
+ }),
1739
+ styles3
1740
+ ];
1741
+ };
1742
+
1743
+ // packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
1744
+ import { syntaxTree } from "@codemirror/language";
1745
+ import { RangeSetBuilder } from "@codemirror/state";
1746
+ import { Decoration as Decoration4, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1747
+ var buildDecorations = (view) => {
1748
+ const builder = new RangeSetBuilder();
1749
+ const { state } = view;
1750
+ const cursor = state.selection.main.head;
1751
+ for (const { from, to } of view.visibleRanges) {
1752
+ syntaxTree(state).iterate({
1753
+ enter: (node) => {
1754
+ switch (node.name) {
1755
+ case "ATXHeading1":
1756
+ case "ATXHeading2":
1757
+ case "ATXHeading3":
1758
+ case "ATXHeading4":
1759
+ case "ATXHeading5":
1760
+ case "ATXHeading6": {
1761
+ const mark2 = node.node.getChild("HeaderMark");
1762
+ if (mark2 && (cursor < node.from || cursor > node.to)) {
1763
+ builder.add(mark2.from, mark2.to + 1, Decoration4.replace({}));
1764
+ }
1765
+ }
1766
+ }
1767
+ },
1768
+ from,
1769
+ to
1770
+ });
1771
+ }
1772
+ return builder.finish();
1773
+ };
1774
+ var heading2 = () => {
1775
+ return [
1776
+ ViewPlugin4.fromClass(class {
1777
+ constructor(view) {
1778
+ this.decorations = buildDecorations(view);
1779
+ }
1780
+ update(update2) {
1781
+ this.decorations = buildDecorations(update2.view);
1782
+ }
1783
+ }, {
1784
+ decorations: (v) => v.decorations
1785
+ })
1786
+ ];
1787
+ };
1788
+
1789
+ // packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
1790
+ import { syntaxTree as syntaxTree2 } from "@codemirror/language";
1791
+ import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
1792
+ import { Decoration as Decoration5, EditorView as EditorView9, ViewPlugin as ViewPlugin5, WidgetType as WidgetType2 } from "@codemirror/view";
1793
+ var styles4 = EditorView9.baseTheme({
1794
+ "& .cm-hr": {
1795
+ // Note that block-level decorations should not have vertical margins,
1796
+ borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
1797
+ }
1798
+ });
1799
+ var HorizontalRuleWidget = class extends WidgetType2 {
1800
+ toDOM() {
1801
+ const el = document.createElement("div");
1802
+ el.className = "cm-hr";
1803
+ return el;
1804
+ }
1805
+ };
1806
+ var decoration = Decoration5.replace({
1807
+ widget: new HorizontalRuleWidget()
1808
+ });
1809
+ var buildDecorations2 = (view) => {
1810
+ const builder = new RangeSetBuilder2();
1811
+ const { state } = view;
1812
+ const cursor = state.selection.main.head;
1813
+ for (const { from, to } of view.visibleRanges) {
1814
+ syntaxTree2(state).iterate({
1815
+ enter: (node) => {
1816
+ if (node.name === "HorizontalRule") {
1817
+ if (cursor <= node.from || cursor >= node.to) {
1818
+ builder.add(node.from, node.to, decoration);
1819
+ }
1820
+ }
1821
+ },
1822
+ from,
1823
+ to
1824
+ });
1825
+ }
1826
+ return builder.finish();
1827
+ };
1828
+ var hr = () => {
1829
+ return [
1830
+ styles4,
1831
+ ViewPlugin5.fromClass(class {
1832
+ constructor(view) {
1833
+ this.decorations = buildDecorations2(view);
1834
+ }
1835
+ update(update2) {
1836
+ this.decorations = buildDecorations2(update2.view);
1837
+ }
1838
+ }, {
1839
+ decorations: (v) => v.decorations
1840
+ })
1841
+ ];
1842
+ };
1843
+
1844
+ // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
1845
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
1846
+ import { StateField as StateField3 } from "@codemirror/state";
1847
+ import { Decoration as Decoration6, EditorView as EditorView10, WidgetType as WidgetType3 } from "@codemirror/view";
1848
+ var image = (options = {}) => {
1849
+ return StateField3.define({
1850
+ create: (state) => {
1851
+ return Decoration6.set(buildDecorations3(0, state.doc.length, state));
1852
+ },
1853
+ update: (value, tr) => {
1854
+ if (!tr.docChanged && !tr.selection) {
1855
+ return value;
1856
+ }
1857
+ const cursor = tr.state.selection.main.head;
1858
+ const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
1859
+ let from = Math.min(cursor, oldCursor);
1860
+ let to = Math.max(cursor, oldCursor);
1861
+ tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
1862
+ from = Math.min(from, fromB);
1863
+ to = Math.max(to, toB);
1864
+ });
1865
+ from = tr.state.doc.lineAt(from).from;
1866
+ to = tr.state.doc.lineAt(to).to;
1867
+ return value.map(tr.changes).update({
1868
+ filterFrom: from,
1869
+ filterTo: to,
1870
+ filter: () => false,
1871
+ add: buildDecorations3(from, to, tr.state)
1872
+ });
1873
+ },
1874
+ provide: (field) => EditorView10.decorations.from(field)
1875
+ });
1876
+ };
1877
+ var buildDecorations3 = (from, to, state) => {
1878
+ const decorations = [];
1879
+ const cursor = state.selection.main.head;
1880
+ syntaxTree3(state).iterate({
1881
+ enter: (node) => {
1882
+ if (node.name === "Image") {
1883
+ const urlNode = node.node.getChild("URL");
1884
+ if (urlNode) {
1885
+ const hide = state.readOnly || cursor < node.from || cursor > node.to;
1886
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
1887
+ decorations.push(Decoration6.replace({
1888
+ block: true,
1889
+ widget: new ImageWidget(url)
1890
+ }).range(hide ? node.from : node.to, node.to));
1891
+ }
1892
+ }
1893
+ },
1894
+ from,
1895
+ to
1896
+ });
1897
+ return decorations;
1898
+ };
1899
+ var ImageWidget = class extends WidgetType3 {
1900
+ constructor(_url) {
1901
+ super();
1902
+ this._url = _url;
1903
+ }
1904
+ eq(other) {
1905
+ return this._url === other._url;
1906
+ }
1907
+ toDOM(view) {
1908
+ const img = document.createElement("img");
1909
+ img.setAttribute("src", this._url);
1910
+ img.setAttribute("class", "cm-image");
1911
+ img.onload = () => img.classList.add("cm-loaded-image");
1912
+ return img;
1913
+ }
1914
+ };
1915
+
1916
+ // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
1917
+ import { syntaxTree as syntaxTree4 } from "@codemirror/language";
1918
+ import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
1919
+ import { hoverTooltip as hoverTooltip2, Decoration as Decoration7, ViewPlugin as ViewPlugin6, WidgetType as WidgetType4 } from "@codemirror/view";
1920
+ import { tooltipContent } from "@dxos/react-ui-theme";
1921
+ var link = (options = {}) => {
1922
+ const extensions = [
1923
+ ViewPlugin6.fromClass(class {
1924
+ constructor(view) {
1925
+ this.decorations = buildDecorations4(view, options);
1926
+ }
1927
+ update(update2) {
1928
+ if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
1929
+ this.decorations = buildDecorations4(update2.view, options);
1930
+ }
1931
+ }
1932
+ }, {
1933
+ decorations: (v) => v.decorations
1934
+ })
1935
+ ];
1936
+ if (options.onHover) {
1937
+ extensions.push(
1938
+ // https://codemirror.net/examples/tooltip
1939
+ // https://codemirror.net/docs/ref/#view.hoverTooltip
1940
+ // https://github.com/codemirror/view/blob/main/src/tooltip.ts
1941
+ hoverTooltip2((view, pos, side) => {
1942
+ const syntax = syntaxTree4(view.state).resolveInner(pos, side);
1943
+ let link2 = null;
1944
+ for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
1945
+ link2 = node.name === "Link" ? node : null;
1946
+ }
1947
+ const url = link2 && link2.getChild("URL");
1948
+ if (!url || !link2) {
1949
+ return null;
1950
+ }
1951
+ const urlText = view.state.sliceDoc(url.from, url.to);
1952
+ return {
1953
+ pos: link2.from,
1954
+ end: link2.to,
1955
+ above: true,
1956
+ create: () => {
1957
+ const el = document.createElement("div");
1958
+ el.className = tooltipContent({}, "pli-2 plb-1");
1959
+ options.onHover(el, urlText);
1960
+ return {
1961
+ dom: el,
1962
+ offset: {
1963
+ x: 0,
1964
+ y: 4
1965
+ }
1966
+ };
1967
+ }
1968
+ };
1969
+ })
1970
+ );
1971
+ }
1972
+ return extensions;
1973
+ };
1974
+ var LinkButton = class extends WidgetType4 {
1975
+ constructor(_url, _onAttach) {
1976
+ super();
1977
+ this._url = _url;
1978
+ this._onAttach = _onAttach;
1979
+ }
1980
+ eq(other) {
1981
+ return this._url === other._url;
1982
+ }
1983
+ toDOM(view) {
1984
+ const el = document.createElement("span");
1985
+ this._onAttach(el, this._url);
1986
+ return el;
1987
+ }
1988
+ };
1989
+ var LinkText = class extends WidgetType4 {
1990
+ constructor(_text, _url) {
1991
+ super();
1992
+ this._text = _text;
1993
+ this._url = _url;
1994
+ }
1995
+ eq(other) {
1996
+ return this._url === other._url;
1997
+ }
1998
+ toDOM(view) {
1999
+ const link2 = document.createElement("a");
2000
+ link2.setAttribute("class", "cm-link");
2001
+ link2.textContent = this._text;
2002
+ if (this._url) {
2003
+ link2.setAttribute("rel", "noreferrer");
2004
+ link2.setAttribute("target", "_blank");
2005
+ link2.href = this._url;
2006
+ } else {
2007
+ link2.onclick = () => {
2008
+ view.dispatch({
2009
+ selection: {
2010
+ anchor: view.posAtDOM(link2)
2011
+ }
2012
+ });
2013
+ };
2014
+ }
2015
+ return link2;
2016
+ }
2017
+ };
2018
+ var buildDecorations4 = (view, options) => {
2019
+ const builder = new RangeSetBuilder3();
2020
+ const { state } = view;
2021
+ const cursor = state.selection.main.head;
2022
+ for (const { from, to } of view.visibleRanges) {
2023
+ syntaxTree4(state).iterate({
2024
+ enter: (node) => {
2025
+ if (node.name === "Link") {
2026
+ const marks2 = node.node.getChildren("LinkMark");
2027
+ const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
2028
+ const urlNode = node.node.getChild("URL");
2029
+ const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
2030
+ if (!url) {
2031
+ return false;
2032
+ }
2033
+ if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
2034
+ builder.add(node.from, node.to, Decoration7.replace({
2035
+ widget: new LinkText(text, options.link ? url : void 0)
2036
+ }));
2037
+ }
2038
+ if (options.onRender) {
2039
+ builder.add(node.to, node.to, Decoration7.replace({
2040
+ widget: new LinkButton(url, options.onRender)
2041
+ }));
2042
+ }
2043
+ return false;
2044
+ }
2045
+ },
2046
+ from,
2047
+ to
2048
+ });
2049
+ }
2050
+ return builder.finish();
2051
+ };
2052
+
2053
+ // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
2054
+ import { syntaxTree as syntaxTree5 } from "@codemirror/language";
2055
+ import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField4 } from "@codemirror/state";
2056
+ import { Decoration as Decoration8, EditorView as EditorView11, WidgetType as WidgetType5 } from "@codemirror/view";
2057
+ var table = (options = {}) => {
2058
+ return StateField4.define({
2059
+ create: (state) => update(state, options),
2060
+ update: (_, tr) => update(tr.state, options),
2061
+ provide: (field) => EditorView11.decorations.from(field)
2062
+ });
2063
+ };
2064
+ var update = (state, options) => {
2065
+ const builder = new RangeSetBuilder4();
2066
+ const cursor = state.selection.main.head;
2067
+ const tables = [];
2068
+ const getTable = () => tables[tables.length - 1];
2069
+ const getRow = () => {
2070
+ const table2 = getTable();
2061
2071
  return table2.rows?.[table2.rows.length - 1];
2062
2072
  };
2063
- syntaxTree4(state).iterate({
2073
+ syntaxTree5(state).iterate({
2064
2074
  enter: (node) => {
2065
2075
  switch (node.name) {
2066
2076
  case "Table": {
@@ -2092,10 +2102,10 @@ var update = (state, options) => {
2092
2102
  });
2093
2103
  tables.forEach((table2) => {
2094
2104
  const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
2095
- hide && builder.add(table2.from, table2.to, Decoration7.replace({
2105
+ hide && builder.add(table2.from, table2.to, Decoration8.replace({
2096
2106
  widget: new TableWidget(table2)
2097
2107
  }));
2098
- builder.add(table2.from, table2.to, Decoration7.mark({
2108
+ builder.add(table2.from, table2.to, Decoration8.mark({
2099
2109
  class: "cm-table"
2100
2110
  }));
2101
2111
  });
@@ -2138,10 +2148,10 @@ var TableWidget = class extends WidgetType5 {
2138
2148
  }
2139
2149
  };
2140
2150
 
2141
- // packages/ui/react-ui-editor/src/extensions/tasklist.ts
2142
- import { syntaxTree as syntaxTree5 } from "@codemirror/language";
2143
- import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
2144
- import { EditorView as EditorView12, Decoration as Decoration8, WidgetType as WidgetType6, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
2151
+ // packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
2152
+ import { syntaxTree as syntaxTree6 } from "@codemirror/language";
2153
+ import { RangeSetBuilder as RangeSetBuilder5 } from "@codemirror/state";
2154
+ import { EditorView as EditorView12, Decoration as Decoration9, WidgetType as WidgetType6, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
2145
2155
  var styles5 = EditorView12.baseTheme({
2146
2156
  "& .cm-task": {
2147
2157
  color: getToken("extend.colors.blue.500")
@@ -2188,23 +2198,23 @@ var CheckboxWidget = class extends WidgetType6 {
2188
2198
  return false;
2189
2199
  }
2190
2200
  };
2191
- var checkedDecoration = Decoration8.replace({
2201
+ var checkedDecoration = Decoration9.replace({
2192
2202
  widget: new CheckboxWidget(true)
2193
2203
  });
2194
- var uncheckedDecoration = Decoration8.replace({
2204
+ var uncheckedDecoration = Decoration9.replace({
2195
2205
  widget: new CheckboxWidget(false)
2196
2206
  });
2197
- var buildDecorations4 = (view) => {
2198
- const builder = new RangeSetBuilder4();
2207
+ var buildDecorations5 = (view) => {
2208
+ const builder = new RangeSetBuilder5();
2199
2209
  const { state } = view;
2200
2210
  const cursor = state.selection.main.head;
2201
2211
  for (const { from, to } of view.visibleRanges) {
2202
- syntaxTree5(state).iterate({
2212
+ syntaxTree6(state).iterate({
2203
2213
  enter: (node) => {
2204
2214
  if (node.name === "TaskMarker") {
2205
2215
  if (cursor < node.from || cursor > node.to) {
2206
2216
  const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
2207
- builder.add(node.from - 2, node.from - 1, Decoration8.mark({
2217
+ builder.add(node.from - 2, node.from - 1, Decoration9.mark({
2208
2218
  class: "cm-task"
2209
2219
  }));
2210
2220
  builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
@@ -2219,13 +2229,13 @@ var buildDecorations4 = (view) => {
2219
2229
  };
2220
2230
  var tasklist = (options = {}) => {
2221
2231
  return [
2222
- ViewPlugin6.fromClass(class {
2232
+ ViewPlugin7.fromClass(class {
2223
2233
  constructor(view) {
2224
- this.decorations = buildDecorations4(view);
2234
+ this.decorations = buildDecorations5(view);
2225
2235
  }
2226
2236
  update(update2) {
2227
2237
  if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
2228
- this.decorations = buildDecorations4(update2.view);
2238
+ this.decorations = buildDecorations5(update2.view);
2229
2239
  }
2230
2240
  }
2231
2241
  }, {
@@ -2235,6 +2245,40 @@ var tasklist = (options = {}) => {
2235
2245
  ];
2236
2246
  };
2237
2247
 
2248
+ // packages/ui/react-ui-editor/src/extensions/mention.ts
2249
+ import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
2250
+ var mention = ({ onSearch }) => {
2251
+ return autocompletion2({
2252
+ // TODO(burdon): Not working.
2253
+ activateOnTyping: true,
2254
+ // activateOnTypingDelay: 100,
2255
+ // selectOnOpen: true,
2256
+ closeOnBlur: false,
2257
+ // defaultKeymap: false,
2258
+ icons: false,
2259
+ override: [
2260
+ (context) => {
2261
+ console.log(context);
2262
+ const match = context.matchBefore(/@(\w+)?/);
2263
+ if (!match || match.from === match.to && !context.explicit) {
2264
+ return null;
2265
+ }
2266
+ return {
2267
+ from: match.from,
2268
+ options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
2269
+ label: `@${value}`
2270
+ }))
2271
+ };
2272
+ }
2273
+ ]
2274
+ });
2275
+ };
2276
+
2277
+ // packages/ui/react-ui-editor/src/extensions/outliner.ts
2278
+ var outliner = (options = {}) => {
2279
+ return [];
2280
+ };
2281
+
2238
2282
  // packages/ui/react-ui-editor/src/extensions/typewriter.ts
2239
2283
  import { keymap as keymap5 } from "@codemirror/view";
2240
2284
  var defaultItems = [
@@ -2913,6 +2957,7 @@ export {
2913
2957
  defaultTextSlots,
2914
2958
  defaultTheme,
2915
2959
  getToken,
2960
+ heading2 as heading,
2916
2961
  hr,
2917
2962
  image,
2918
2963
  link,