@dxos/react-ui-editor 0.4.5-main.e7f0200 → 0.4.5-main.ea4f804

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 (58) hide show
  1. package/dist/lib/browser/index.mjs +464 -572
  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 +7 -5
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +2 -0
  7. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  8. package/dist/types/src/components/TextEditor/automerge.stories.d.ts +2 -0
  9. package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +1 -1
  10. package/dist/types/src/components/TextEditor/hooks.stories.d.ts +2 -0
  11. package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -1
  12. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  13. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +2 -0
  14. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  15. package/dist/types/src/extensions/cursor-line-margin.d.ts +8 -0
  16. package/dist/types/src/extensions/cursor-line-margin.d.ts.map +1 -0
  17. package/dist/types/src/extensions/index.d.ts +1 -0
  18. package/dist/types/src/extensions/index.d.ts.map +1 -1
  19. package/dist/types/src/extensions/markdown/decorate.d.ts +5 -0
  20. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -0
  21. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  22. package/dist/types/src/extensions/markdown/index.d.ts +1 -4
  23. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  24. package/dist/types/src/extensions/markdown/link.d.ts +1 -11
  25. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  26. package/dist/types/src/index.d.ts +2 -0
  27. package/dist/types/src/index.d.ts.map +1 -1
  28. package/dist/types/src/styles/layout.d.ts +2 -2
  29. package/dist/types/src/styles/layout.d.ts.map +1 -1
  30. package/dist/types/src/translations.d.ts +2 -0
  31. package/dist/types/src/translations.d.ts.map +1 -1
  32. package/package.json +28 -25
  33. package/src/components/TextEditor/MarkdownEditor.stories.tsx +29 -37
  34. package/src/components/TextEditor/hooks.stories.tsx +5 -17
  35. package/src/components/Toolbar/Toolbar.stories.tsx +4 -7
  36. package/src/components/Toolbar/Toolbar.tsx +79 -47
  37. package/src/extensions/cursor-line-margin.ts +92 -0
  38. package/src/extensions/index.ts +1 -0
  39. package/src/extensions/markdown/decorate.ts +301 -0
  40. package/src/extensions/markdown/formatting.test.ts +17 -0
  41. package/src/extensions/markdown/formatting.ts +67 -76
  42. package/src/extensions/markdown/index.ts +1 -4
  43. package/src/extensions/markdown/link.ts +23 -185
  44. package/src/index.ts +2 -0
  45. package/src/styles/layout.ts +3 -2
  46. package/src/translations.ts +5 -3
  47. package/dist/types/src/extensions/markdown/code.d.ts +0 -2
  48. package/dist/types/src/extensions/markdown/code.d.ts.map +0 -1
  49. package/dist/types/src/extensions/markdown/heading.d.ts +0 -6
  50. package/dist/types/src/extensions/markdown/heading.d.ts.map +0 -1
  51. package/dist/types/src/extensions/markdown/hr.d.ts +0 -2
  52. package/dist/types/src/extensions/markdown/hr.d.ts.map +0 -1
  53. package/dist/types/src/extensions/markdown/tasklist.d.ts +0 -3
  54. package/dist/types/src/extensions/markdown/tasklist.d.ts.map +0 -1
  55. package/src/extensions/markdown/code.ts +0 -162
  56. package/src/extensions/markdown/heading.ts +0 -59
  57. package/src/extensions/markdown/hr.ts +0 -71
  58. package/src/extensions/markdown/tasklist.ts +0 -110
@@ -1,3 +1,27 @@
1
+ // packages/ui/react-ui-editor/src/translations.ts
2
+ var translationKey = "react-ui-editor";
3
+ var translations_default = [
4
+ {
5
+ "en-US": {
6
+ [translationKey]: {
7
+ "strong label": "Bold",
8
+ "emphasis label": "Italics",
9
+ "strikethrough label": "Strikethrough",
10
+ "code label": "Code",
11
+ "link label": "Link",
12
+ "list-bullet label": "Bullet list",
13
+ "list-ordered label": "Numbered list",
14
+ "list-task label": "Task list",
15
+ "blockquote label": "Block quote",
16
+ "codeblock label": "Code block",
17
+ "comment label": "Create comment",
18
+ "heading label": "Heading level",
19
+ "table label": "Create table"
20
+ }
21
+ }
22
+ }
23
+ ];
24
+
1
25
  // packages/ui/react-ui-editor/src/index.ts
2
26
  import { keymap as keymap8 } from "@codemirror/view";
3
27
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
@@ -8,7 +32,7 @@ import { tags as tags2 } from "@lezer/highlight";
8
32
 
9
33
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
10
34
  import { EditorState as EditorState2 } from "@codemirror/state";
11
- import { EditorView as EditorView15 } from "@codemirror/view";
35
+ import { EditorView as EditorView14 } from "@codemirror/view";
12
36
  import { useFocusableGroup } from "@fluentui/react-tabster";
13
37
  import defaultsDeep2 from "lodash.defaultsdeep";
14
38
  import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2, useMemo as useMemo2 } from "react";
@@ -102,8 +126,8 @@ var annotations = (options = {}) => {
102
126
  annotationsState
103
127
  ], (state) => {
104
128
  const annotations2 = state.field(annotationsState);
105
- const decorations = annotations2.map((annotation) => {
106
- const range = Cursor.getRangeFromCursor(state, annotation.cursor);
129
+ const decorations = annotations2.map((annotation2) => {
130
+ const range = Cursor.getRangeFromCursor(state, annotation2.cursor);
107
131
  return range && annotationMark.range(range.from, range.to);
108
132
  }).filter(isNotFalsy);
109
133
  return Decoration.set(decorations);
@@ -765,10 +789,10 @@ var blast = (options = defaultOptions) => {
765
789
  const getPoint = (view, pos) => {
766
790
  const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};
767
791
  const element = document.elementFromPoint(x, y);
768
- const { offsetLeft: left = 0, offsetTop: top2 = 0 } = view.scrollDOM.parentElement ?? {};
792
+ const { offsetLeft: left = 0, offsetTop: top = 0 } = view.scrollDOM.parentElement ?? {};
769
793
  const point = {
770
794
  x: x - left,
771
- y: y - top2
795
+ y: y - top
772
796
  };
773
797
  return {
774
798
  element,
@@ -1116,8 +1140,8 @@ var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue)
1116
1140
 
1117
1141
  // packages/ui/react-ui-editor/src/styles/layout.ts
1118
1142
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
1119
- var editorFillLayoutRoot = "min-bs-full grid";
1120
- var editorFillLayoutEditor = "min-bs-full";
1143
+ var editorFillLayoutRoot = "bs-full overflow-hidden grid";
1144
+ var editorFillLayoutEditor = "bs-full overflow-hidden [&>.cm-scroller]:bs-full [&>.cm-scroller]:overflow-y-auto";
1121
1145
  var editorHalfViewportOverscrollContent = "after:block after:min-bs-[50dvh] after:pointer-events-none";
1122
1146
 
1123
1147
  // packages/ui/react-ui-editor/src/util.ts
@@ -1553,15 +1577,66 @@ var useComments = (view, id, comments2 = []) => {
1553
1577
  ]);
1554
1578
  };
1555
1579
 
1556
- // packages/ui/react-ui-editor/src/extensions/listener.ts
1580
+ // packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
1581
+ import { Facet as Facet4, Transaction } from "@codemirror/state";
1557
1582
  import { EditorView as EditorView7 } from "@codemirror/view";
1583
+ var cursorLineMarginFacet = Facet4.define({
1584
+ combine: (input) => input[0] ?? 3
1585
+ });
1586
+ var annotation = "cursorLineMargin";
1587
+ var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
1588
+ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
1589
+ if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
1590
+ return;
1591
+ }
1592
+ const s = state;
1593
+ const { main } = s.selection;
1594
+ const cursorLineMargin2 = s.facet(cursorLineMarginFacet);
1595
+ const rect = view.dom.getBoundingClientRect();
1596
+ const viewportTop = rect.top - view.documentTop;
1597
+ const viewportBottom = rect.bottom - view.documentTop;
1598
+ const mainLine = lineAtPos(s, main.head);
1599
+ const _visTopLine = lineAtPos(s, view.lineBlockAtHeight(viewportTop).from);
1600
+ const botLineBlk = view.lineBlockAtHeight(viewportBottom);
1601
+ const visBotLineDoc = lineAtPos(s, Math.min(botLineBlk.to, s.doc.length));
1602
+ const visBotLine = botLineBlk.bottom >= viewportBottom ? visBotLineDoc : visBotLineDoc + Math.floor((viewportBottom - botLineBlk.bottom) / view.defaultLineHeight);
1603
+ const needsScrollTop = false;
1604
+ const needsScrollBot = mainLine >= visBotLine - cursorLineMargin2;
1605
+ if (needsScrollTop && needsScrollBot) {
1606
+ console.warn("is cursorScrollMargin too large for the editor size?");
1607
+ return;
1608
+ }
1609
+ if (!needsScrollTop && !needsScrollBot) {
1610
+ return;
1611
+ }
1612
+ if (selectionSet) {
1613
+ const { head } = startState.selection.main;
1614
+ const oldMainLine = lineAtPos(startState, head);
1615
+ if (needsScrollTop && oldMainLine < mainLine) {
1616
+ return;
1617
+ }
1618
+ if (needsScrollBot && oldMainLine > mainLine) {
1619
+ return;
1620
+ }
1621
+ }
1622
+ view.dispatch({
1623
+ annotations: Transaction.userEvent.of(annotation),
1624
+ effects: EditorView7.scrollIntoView(s.selection.main.head, {
1625
+ y: needsScrollTop ? "start" : "end",
1626
+ yMargin: view.defaultLineHeight * cursorLineMargin2
1627
+ })
1628
+ });
1629
+ });
1630
+
1631
+ // packages/ui/react-ui-editor/src/extensions/listener.ts
1632
+ import { EditorView as EditorView8 } from "@codemirror/view";
1558
1633
  var listener = ({ onFocus, onChange }) => {
1559
1634
  const extensions = [];
1560
- onFocus && extensions.push(EditorView7.focusChangeEffect.of((_, focused) => {
1635
+ onFocus && extensions.push(EditorView8.focusChangeEffect.of((_, focused) => {
1561
1636
  onFocus(focused);
1562
1637
  return null;
1563
1638
  }));
1564
- onChange && extensions.push(EditorView7.updateListener.of((update2) => {
1639
+ onChange && extensions.push(EditorView8.updateListener.of((update2) => {
1565
1640
  onChange(update2.state.doc.toString());
1566
1641
  }));
1567
1642
  return extensions;
@@ -1576,7 +1651,7 @@ import { languages } from "@codemirror/language-data";
1576
1651
  import { searchKeymap } from "@codemirror/search";
1577
1652
  import { EditorState } from "@codemirror/state";
1578
1653
  import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
1579
- import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView8, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1654
+ import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView9, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1580
1655
  import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
1581
1656
 
1582
1657
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
@@ -1770,7 +1845,7 @@ var markdownHighlightStyle = (readonly) => {
1770
1845
  // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
1771
1846
  var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
1772
1847
  return [
1773
- lineWrapping && EditorView8.lineWrapping,
1848
+ lineWrapping && EditorView9.lineWrapping,
1774
1849
  EditorState.allowMultipleSelections.of(true),
1775
1850
  EditorState.tabSize.of(2),
1776
1851
  // https://github.com/codemirror/basic-setup
@@ -1820,12 +1895,207 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
1820
1895
  ].filter(isNotFalsy3);
1821
1896
  };
1822
1897
 
1823
- // packages/ui/react-ui-editor/src/extensions/markdown/code.ts
1898
+ // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
1824
1899
  import { syntaxTree } from "@codemirror/language";
1825
1900
  import { RangeSetBuilder } from "@codemirror/state";
1826
- import { ViewPlugin as ViewPlugin3, EditorView as EditorView9, Decoration as Decoration4, WidgetType as WidgetType2 } from "@codemirror/view";
1901
+ import { EditorView as EditorView10, Decoration as Decoration4, WidgetType as WidgetType2, ViewPlugin as ViewPlugin3 } from "@codemirror/view";
1827
1902
  import { mx as mx2 } from "@dxos/react-ui-theme";
1828
- var styles4 = EditorView9.baseTheme({
1903
+ var FencedCodeBoundary = class extends WidgetType2 {
1904
+ constructor(_className) {
1905
+ super();
1906
+ this._className = _className;
1907
+ }
1908
+ toDOM() {
1909
+ const el = document.createElement("span");
1910
+ el.innerHTML = "&nbsp;";
1911
+ el.className = mx2("cm-code cm-codeblock", this._className);
1912
+ return el;
1913
+ }
1914
+ };
1915
+ var HorizontalRuleWidget = class extends WidgetType2 {
1916
+ toDOM() {
1917
+ const el = document.createElement("span");
1918
+ el.className = "cm-hr";
1919
+ return el;
1920
+ }
1921
+ };
1922
+ var LinkButton = class extends WidgetType2 {
1923
+ constructor(url, render) {
1924
+ super();
1925
+ this.url = url;
1926
+ this.render = render;
1927
+ }
1928
+ eq(other) {
1929
+ return this.url === other.url;
1930
+ }
1931
+ toDOM(view) {
1932
+ const el = document.createElement("span");
1933
+ this.render(el, this.url);
1934
+ return el;
1935
+ }
1936
+ };
1937
+ var CheckboxWidget = class extends WidgetType2 {
1938
+ constructor(_checked) {
1939
+ super();
1940
+ this._checked = _checked;
1941
+ }
1942
+ eq(other) {
1943
+ return this._checked === other._checked;
1944
+ }
1945
+ toDOM(view) {
1946
+ const input = document.createElement("input");
1947
+ input.className = "cm-task-checkbox";
1948
+ input.type = "checkbox";
1949
+ input.checked = this._checked;
1950
+ if (view.state.readOnly) {
1951
+ input.setAttribute("disabled", "true");
1952
+ } else {
1953
+ input.onmousedown = (event) => {
1954
+ const pos = view.posAtDOM(input);
1955
+ const text = view.state.sliceDoc(pos, pos + 3);
1956
+ if (text === (this._checked ? "[x]" : "[ ]")) {
1957
+ view.dispatch({
1958
+ changes: {
1959
+ from: pos + 1,
1960
+ to: pos + 2,
1961
+ insert: this._checked ? " " : "x"
1962
+ }
1963
+ });
1964
+ event.preventDefault();
1965
+ }
1966
+ };
1967
+ }
1968
+ return input;
1969
+ }
1970
+ ignoreEvent() {
1971
+ return false;
1972
+ }
1973
+ };
1974
+ var hide = Decoration4.replace({});
1975
+ var fencedCodeTop = Decoration4.replace({
1976
+ widget: new FencedCodeBoundary("cm-codeblock-end cm-codeblock-first")
1977
+ });
1978
+ var fencedCodeBottom = Decoration4.replace({
1979
+ widget: new FencedCodeBoundary("cm-codeblock-end cm-codeblock-last")
1980
+ });
1981
+ var horizontalRule = Decoration4.replace({
1982
+ widget: new HorizontalRuleWidget()
1983
+ });
1984
+ var checkedTask = Decoration4.replace({
1985
+ widget: new CheckboxWidget(true)
1986
+ });
1987
+ var uncheckedTask = Decoration4.replace({
1988
+ widget: new CheckboxWidget(false)
1989
+ });
1990
+ var editingRange = (state, range) => {
1991
+ const { readOnly, selection: { main: { head } } } = state;
1992
+ return !readOnly && head >= range.from && head <= range.to;
1993
+ };
1994
+ var MarksByParent = /* @__PURE__ */ new Set([
1995
+ "CodeMark",
1996
+ "EmphasisMark",
1997
+ "StrikethroughMark",
1998
+ "SubscriptMark",
1999
+ "SuperscriptMark"
2000
+ ]);
2001
+ var buildDecorations = (view, options) => {
2002
+ const builder = new RangeSetBuilder();
2003
+ const { state } = view;
2004
+ for (const { from, to } of view.visibleRanges) {
2005
+ syntaxTree(state).iterate({
2006
+ from,
2007
+ to,
2008
+ enter: (node) => {
2009
+ if (node.name === "FencedCode") {
2010
+ const editing = editingRange(state, node);
2011
+ for (const block of view.viewportLineBlocks) {
2012
+ if (block.to < node.from) {
2013
+ continue;
2014
+ }
2015
+ if (block.from > node.to) {
2016
+ break;
2017
+ }
2018
+ const first = block.from <= node.from;
2019
+ const last = block.to >= node.to;
2020
+ if (!editing && (first || last)) {
2021
+ builder.add(block.from, block.to, first ? fencedCodeTop : fencedCodeBottom);
2022
+ } else {
2023
+ builder.add(block.from, block.from, Decoration4.line({
2024
+ class: mx2("cm-code cm-codeblock-line", first && "cm-codeblock-first", last && "cm-codeblock-last")
2025
+ }));
2026
+ }
2027
+ }
2028
+ return false;
2029
+ } else if (node.name === "Link") {
2030
+ const marks = node.node.getChildren("LinkMark");
2031
+ const urlNode = node.node.getChild("URL");
2032
+ const editing = editingRange(state, node);
2033
+ if (urlNode && marks.length >= 2) {
2034
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
2035
+ if (!editing) {
2036
+ builder.add(node.from, marks[0].to, hide);
2037
+ }
2038
+ builder.add(marks[0].to, marks[1].from, Decoration4.mark({
2039
+ tagName: "a",
2040
+ attributes: {
2041
+ class: "cm-link",
2042
+ href: url,
2043
+ rel: "noreferrer",
2044
+ target: "_blank"
2045
+ }
2046
+ }));
2047
+ if (!editing) {
2048
+ builder.add(marks[1].from, node.to, options.renderLinkButton ? Decoration4.replace({
2049
+ widget: new LinkButton(url, options.renderLinkButton)
2050
+ }) : hide);
2051
+ }
2052
+ }
2053
+ } else if (node.name === "HeaderMark") {
2054
+ const parent = node.node.parent;
2055
+ if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from))) {
2056
+ const next = state.doc.sliceString(node.to, node.to + 1);
2057
+ builder.add(node.from, node.to + (next === " " ? 1 : 0), hide);
2058
+ }
2059
+ } else if (node.name === "HorizontalRule") {
2060
+ if (!editingRange(state, node)) {
2061
+ builder.add(node.from, node.to, horizontalRule);
2062
+ }
2063
+ } else if (node.name === "TaskMarker") {
2064
+ if (!editingRange(state, node)) {
2065
+ const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
2066
+ builder.add(node.from - 2, node.from - 1, Decoration4.mark({
2067
+ class: "cm-task"
2068
+ }));
2069
+ builder.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
2070
+ }
2071
+ } else if (MarksByParent.has(node.name)) {
2072
+ if (!editingRange(state, node.node.parent)) {
2073
+ builder.add(node.from, node.to, hide);
2074
+ }
2075
+ }
2076
+ }
2077
+ });
2078
+ }
2079
+ return builder.finish();
2080
+ };
2081
+ var decorateMarkdown = (options = {}) => {
2082
+ return [
2083
+ ViewPlugin3.fromClass(class {
2084
+ constructor(view) {
2085
+ this.decorations = buildDecorations(view, options);
2086
+ }
2087
+ update(update2) {
2088
+ if (update2.docChanged || update2.selectionSet || update2.viewportChanged) {
2089
+ this.decorations = buildDecorations(update2.view, options);
2090
+ }
2091
+ }
2092
+ }, {
2093
+ decorations: (value) => value.decorations
2094
+ }),
2095
+ formattingStyles
2096
+ ];
2097
+ };
2098
+ var formattingStyles = EditorView10.baseTheme({
1829
2099
  "& .cm-code": {
1830
2100
  fontFamily: getToken("fontFamily.mono", []).join(",")
1831
2101
  },
@@ -1873,82 +2143,28 @@ var styles4 = EditorView9.baseTheme({
1873
2143
  "&::after": {
1874
2144
  background: getToken("extend.semanticColors.input.dark")
1875
2145
  }
2146
+ },
2147
+ "& .cm-hr": {
2148
+ display: "inline-block",
2149
+ width: "100%",
2150
+ height: "0",
2151
+ verticalAlign: "middle",
2152
+ borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
2153
+ },
2154
+ "& .cm-task": {
2155
+ color: getToken("extend.colors.blue.500")
2156
+ },
2157
+ "& .cm-task-checkbox": {
2158
+ marginLeft: "4px",
2159
+ marginRight: "4px"
1876
2160
  }
1877
2161
  });
1878
- var getLineRange = (lines, from, to) => {
1879
- const start = lines.findIndex((line) => line.from >= from);
1880
- const end = lines.findIndex((line) => line.to >= to);
1881
- return [
1882
- start,
1883
- end
1884
- ];
1885
- };
1886
- var LineWidget = class extends WidgetType2 {
1887
- constructor(_className) {
1888
- super();
1889
- this._className = _className;
1890
- }
1891
- toDOM() {
1892
- const el = document.createElement("span");
1893
- el.innerHTML = "&nbsp;";
1894
- el.className = mx2("cm-code cm-codeblock", this._className);
1895
- return el;
1896
- }
1897
- };
1898
- var top = new LineWidget("cm-codeblock-end cm-codeblock-first");
1899
- var bottom = new LineWidget("cm-codeblock-end cm-codeblock-last");
1900
- var buildDecorations = (view) => {
1901
- const builder = new RangeSetBuilder();
1902
- const { state } = view;
1903
- const blocks = view.viewportLineBlocks;
1904
- const cursor = state.selection.main.head;
1905
- for (const { from, to } of view.visibleRanges) {
1906
- syntaxTree(state).iterate({
1907
- enter: (node) => {
1908
- if (node.name === "FencedCode") {
1909
- const editing = !view.state.readOnly && cursor >= node.from && cursor <= node.to;
1910
- const range = getLineRange(blocks, node.from, node.to);
1911
- for (let i = range[0]; i <= range[1]; i++) {
1912
- const block = blocks[i];
1913
- if (!editing && (i === range[0] || i === range[1])) {
1914
- builder.add(block.from, block.to, Decoration4.replace({
1915
- widget: i === range[0] ? top : bottom
1916
- }));
1917
- } else {
1918
- builder.add(block.from, block.from, Decoration4.line({
1919
- class: mx2("cm-code cm-codeblock-line", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
1920
- }));
1921
- }
1922
- }
1923
- }
1924
- },
1925
- from,
1926
- to
1927
- });
1928
- }
1929
- return builder.finish();
1930
- };
1931
- var code2 = () => {
1932
- return [
1933
- ViewPlugin3.fromClass(class {
1934
- constructor(view) {
1935
- this.decorations = buildDecorations(view);
1936
- }
1937
- update(update2) {
1938
- this.decorations = buildDecorations(update2.view);
1939
- }
1940
- }, {
1941
- decorations: (value) => value.decorations
1942
- }),
1943
- styles4
1944
- ];
1945
- };
1946
2162
 
1947
2163
  // packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
1948
2164
  import { snippet } from "@codemirror/autocomplete";
1949
2165
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
1950
- import { RangeSetBuilder as RangeSetBuilder2, EditorSelection } from "@codemirror/state";
1951
- import { Decoration as Decoration5, EditorView as EditorView10, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
2166
+ import { EditorSelection } from "@codemirror/state";
2167
+ import { EditorView as EditorView11, keymap as keymap5 } from "@codemirror/view";
1952
2168
  import { useState, useMemo } from "react";
1953
2169
  var compareFormatting = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
1954
2170
  var Inline;
@@ -1969,6 +2185,7 @@ var setHeading = (level) => ({ state, dispatch }) => {
1969
2185
  const changes = [];
1970
2186
  let prevBlock = -1;
1971
2187
  for (const range of ranges) {
2188
+ let sawBlock = false;
1972
2189
  syntaxTree2(state).iterate({
1973
2190
  from: range.from,
1974
2191
  to: range.to,
@@ -1976,6 +2193,7 @@ var setHeading = (level) => ({ state, dispatch }) => {
1976
2193
  if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
1977
2194
  return;
1978
2195
  }
2196
+ sawBlock = true;
1979
2197
  prevBlock = node.from;
1980
2198
  const blockType = Textblocks[node.name];
1981
2199
  const isHeading = /heading(\d)/.exec(blockType);
@@ -2020,12 +2238,22 @@ var setHeading = (level) => ({ state, dispatch }) => {
2020
2238
  }
2021
2239
  }
2022
2240
  });
2241
+ let line;
2242
+ if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state.doc.lineAt(range.from)).text)) {
2243
+ changes.push({
2244
+ from: line.from,
2245
+ to: line.to,
2246
+ insert: "#".repeat(level) + " "
2247
+ });
2248
+ }
2023
2249
  }
2024
2250
  if (!changes.length) {
2025
2251
  return false;
2026
2252
  }
2253
+ const changeSet = state.changes(changes);
2027
2254
  dispatch(state.update({
2028
- changes,
2255
+ changes: changeSet,
2256
+ selection: state.selection.map(changeSet, 1),
2029
2257
  userEvent: "format.setHeading",
2030
2258
  scrollIntoView: true
2031
2259
  }));
@@ -2097,10 +2325,16 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
2097
2325
  const closeStart = node.to - size;
2098
2326
  if (markType === type) {
2099
2327
  if (openEnd <= from && closeStart >= from) {
2100
- startCovered = openEnd === from ? "adjacent" : true;
2328
+ startCovered = !enable && openEnd === skipMarkers(from, node.node, -1, openEnd) ? {
2329
+ from: node.from,
2330
+ to: openEnd
2331
+ } : true;
2101
2332
  }
2102
2333
  if (openEnd <= to && closeStart >= to) {
2103
- endCovered = closeStart === to ? "adjacent" : true;
2334
+ endCovered = !enable && closeStart === skipMarkers(to, node.node, 1, closeStart) ? {
2335
+ from: closeStart,
2336
+ to: node.to
2337
+ } : true;
2104
2338
  }
2105
2339
  }
2106
2340
  if (markType === type || type === 3 && enable) {
@@ -2149,22 +2383,16 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
2149
2383
  });
2150
2384
  }
2151
2385
  } else {
2152
- if (startCovered === "adjacent") {
2153
- changes2.push({
2154
- from: from - marker.length,
2155
- to: from
2156
- });
2386
+ if (typeof startCovered === "object") {
2387
+ changes2.push(startCovered);
2157
2388
  } else if (startCovered) {
2158
2389
  changes2.push({
2159
2390
  from: skipSpaces(rangeStart, state.doc, -1, blockStart),
2160
2391
  insert: marker
2161
2392
  });
2162
2393
  }
2163
- if (endCovered === "adjacent") {
2164
- changes2.push({
2165
- from: to,
2166
- to: to + marker.length
2167
- });
2394
+ if (typeof endCovered === "object") {
2395
+ changes2.push(endCovered);
2168
2396
  } else if (endCovered) {
2169
2397
  changes2.push({
2170
2398
  from: skipSpaces(rangeEnd, state.doc, 1, blockEnd),
@@ -2175,6 +2403,15 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
2175
2403
  }
2176
2404
  }
2177
2405
  });
2406
+ if (blockStart < 0 && range.empty && enable && !/\S/.test(state.doc.lineAt(range.from).text)) {
2407
+ return {
2408
+ changes: {
2409
+ from: range.head,
2410
+ insert: marker + marker
2411
+ },
2412
+ range: EditorSelection.cursor(range.head + marker.length)
2413
+ };
2414
+ }
2178
2415
  const changeSet = state.changes(changes2.concat(changesAtEnd));
2179
2416
  return {
2180
2417
  changes: changeSet,
@@ -2220,6 +2457,19 @@ var skipSpaces = (pos, doc, dir, limit) => {
2220
2457
  }
2221
2458
  return pos;
2222
2459
  };
2460
+ var skipMarkers = (pos, tree, dir, limit) => {
2461
+ for (; ; ) {
2462
+ const next = tree.resolve(pos, dir);
2463
+ if (!IgnoreInline.has(next.name)) {
2464
+ return pos;
2465
+ }
2466
+ const moveTo = dir < 0 ? next.from : next.to;
2467
+ if (limit != null && (dir < 0 ? moveTo < limit : moveTo > limit)) {
2468
+ return pos;
2469
+ }
2470
+ pos = moveTo;
2471
+ }
2472
+ };
2223
2473
  var snippets = {
2224
2474
  codeblock: snippet([
2225
2475
  //
@@ -2498,8 +2748,10 @@ var addList = (type) => ({ state, dispatch }) => {
2498
2748
  renumberListItems(next.firstChild, last.counter + 1, changes, state.doc);
2499
2749
  }
2500
2750
  }
2751
+ const changeSet = state.changes(changes);
2501
2752
  dispatch(state.update({
2502
- changes,
2753
+ changes: changeSet,
2754
+ selection: state.selection.map(changeSet, 1),
2503
2755
  userEvent: "format.list.add",
2504
2756
  scrollIntoView: true
2505
2757
  }));
@@ -2593,6 +2845,7 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2593
2845
  const lines = [];
2594
2846
  let lastBlock = -1;
2595
2847
  for (const { from, to } of state.selection.ranges) {
2848
+ const sawBlock = false;
2596
2849
  syntaxTree2(state).iterate({
2597
2850
  from,
2598
2851
  to,
@@ -2602,9 +2855,9 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2602
2855
  return false;
2603
2856
  }
2604
2857
  lastBlock = node.from;
2605
- let line = state.doc.lineAt(node.from);
2606
- if (line.number > 1) {
2607
- const prevLine = state.doc.line(line.number - 1);
2858
+ let line2 = state.doc.lineAt(node.from);
2859
+ if (line2.number > 1) {
2860
+ const prevLine = state.doc.line(line2.number - 1);
2608
2861
  if (/^[>\s]*$/.test(prevLine.text)) {
2609
2862
  if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
2610
2863
  lines.push(prevLine);
@@ -2612,14 +2865,14 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2612
2865
  }
2613
2866
  }
2614
2867
  for (; ; ) {
2615
- lines.push(line);
2616
- if (line.to >= node.to) {
2868
+ lines.push(line2);
2869
+ if (line2.to >= node.to) {
2617
2870
  break;
2618
2871
  }
2619
- line = state.doc.line(line.number + 1);
2872
+ line2 = state.doc.line(line2.number + 1);
2620
2873
  }
2621
- if (!enable && line.number < state.doc.lines) {
2622
- const nextLine = state.doc.line(line.number + 1);
2874
+ if (!enable && line2.number < state.doc.lines) {
2875
+ const nextLine = state.doc.line(line2.number + 1);
2623
2876
  if (/^[>\s]*$/.test(nextLine.text)) {
2624
2877
  lines.push(nextLine);
2625
2878
  }
@@ -2628,6 +2881,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2628
2881
  }
2629
2882
  }
2630
2883
  });
2884
+ let line;
2885
+ if (!sawBlock && enable && from === to && !/\S/.test((line = state.doc.lineAt(from)).text)) {
2886
+ lines.push(line);
2887
+ }
2631
2888
  }
2632
2889
  const changes = [];
2633
2890
  for (const line of lines) {
@@ -2649,8 +2906,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2649
2906
  if (!changes.length) {
2650
2907
  return false;
2651
2908
  }
2909
+ const changeSet = state.changes(changes);
2652
2910
  dispatch(state.update({
2653
- changes,
2911
+ changes: changeSet,
2912
+ selection: state.selection.map(changeSet, 1),
2654
2913
  userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
2655
2914
  scrollIntoView: true
2656
2915
  }));
@@ -2782,56 +3041,7 @@ var formatting = (options = {}) => {
2782
3041
  key: "meta-b",
2783
3042
  run: toggleStrong
2784
3043
  }
2785
- ]),
2786
- styling()
2787
- ];
2788
- };
2789
- var styling = () => {
2790
- const buildDecorations7 = (view) => {
2791
- const builder = new RangeSetBuilder2();
2792
- const { state } = view;
2793
- const cursor = state.selection.main.head;
2794
- const replace = (node, marks) => {
2795
- if (cursor <= node.from || cursor >= node.to) {
2796
- for (const mark2 of marks) {
2797
- builder.add(mark2.from, mark2.to, Decoration5.replace({}));
2798
- }
2799
- }
2800
- };
2801
- for (const { from, to } of view.visibleRanges) {
2802
- syntaxTree2(state).iterate({
2803
- enter: (node) => {
2804
- switch (node.name) {
2805
- case "Emphasis":
2806
- case "StrongEmphasis": {
2807
- const marks = node.node.getChildren("EmphasisMark");
2808
- replace(node, marks);
2809
- break;
2810
- }
2811
- case "Strikethrough": {
2812
- const marks = node.node.getChildren("StrikethroughMark");
2813
- replace(node, marks);
2814
- break;
2815
- }
2816
- }
2817
- },
2818
- from,
2819
- to
2820
- });
2821
- }
2822
- return builder.finish();
2823
- };
2824
- return [
2825
- ViewPlugin4.fromClass(class {
2826
- constructor(view) {
2827
- this.decorations = buildDecorations7(view);
2828
- }
2829
- update(update2) {
2830
- this.decorations = buildDecorations7(update2.view);
2831
- }
2832
- }, {
2833
- decorations: (value) => value.decorations
2834
- })
3044
+ ])
2835
3045
  ];
2836
3046
  };
2837
3047
  var InlineMarker = {
@@ -2881,7 +3091,7 @@ var getFormatting = (state) => {
2881
3091
  null,
2882
3092
  null
2883
3093
  ];
2884
- let link2 = false;
3094
+ let link = false;
2885
3095
  let blockQuote = null;
2886
3096
  let listStyle = null;
2887
3097
  const stack = [];
@@ -2943,7 +3153,7 @@ var getFormatting = (state) => {
2943
3153
  if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
2944
3154
  stack.push(name);
2945
3155
  } else if (name === "Link") {
2946
- link2 = true;
3156
+ link = true;
2947
3157
  } else if (Object.hasOwn(Textblocks, name) && (range.empty || node.to > range.from || node.from < range.to)) {
2948
3158
  if (name === "Task" && stack[stack.length - 1] === "BulletList") {
2949
3159
  stack[stack.length - 1] = "TaskList";
@@ -3018,13 +3228,13 @@ var getFormatting = (state) => {
3018
3228
  emphasis: inline[1] ?? false,
3019
3229
  strong: inline[0] ?? false,
3020
3230
  strikethrough: inline[2] ?? false,
3021
- link: link2,
3231
+ link,
3022
3232
  listStyle: listStyle || null
3023
3233
  };
3024
3234
  };
3025
3235
  var useFormattingState = () => {
3026
3236
  const [state, setState] = useState(null);
3027
- const observer = useMemo(() => EditorView10.updateListener.of((update2) => {
3237
+ const observer = useMemo(() => EditorView11.updateListener.of((update2) => {
3028
3238
  if (update2.docChanged || update2.selectionSet) {
3029
3239
  const newState = getFormatting(update2.state);
3030
3240
  if (!state || !compareFormatting(state, newState)) {
@@ -3038,117 +3248,14 @@ var useFormattingState = () => {
3038
3248
  ];
3039
3249
  };
3040
3250
 
3041
- // packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
3042
- import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3043
- import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
3044
- import { Decoration as Decoration6, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
3045
- var buildDecorations2 = (view) => {
3046
- const builder = new RangeSetBuilder3();
3047
- const { state } = view;
3048
- const cursor = state.selection.main.head;
3049
- for (const { from, to } of view.visibleRanges) {
3050
- syntaxTree3(state).iterate({
3051
- enter: (node) => {
3052
- switch (node.name) {
3053
- case "ATXHeading1":
3054
- case "ATXHeading2":
3055
- case "ATXHeading3":
3056
- case "ATXHeading4":
3057
- case "ATXHeading5":
3058
- case "ATXHeading6": {
3059
- const mark2 = node.node.getChild("HeaderMark");
3060
- if (mark2) {
3061
- if (!view.hasFocus || view.state.readOnly || cursor < node.from || cursor > node.to) {
3062
- builder.add(mark2.from, mark2.to + 1, Decoration6.replace({}));
3063
- }
3064
- }
3065
- }
3066
- }
3067
- },
3068
- from,
3069
- to
3070
- });
3071
- }
3072
- return builder.finish();
3073
- };
3074
- var heading2 = () => {
3075
- return [
3076
- ViewPlugin5.fromClass(class {
3077
- constructor(view) {
3078
- this.decorations = buildDecorations2(view);
3079
- }
3080
- update(update2) {
3081
- this.decorations = buildDecorations2(update2.view);
3082
- }
3083
- }, {
3084
- decorations: (value) => value.decorations
3085
- })
3086
- ];
3087
- };
3088
-
3089
- // packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
3090
- import { syntaxTree as syntaxTree4 } from "@codemirror/language";
3091
- import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
3092
- import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
3093
- var styles5 = EditorView11.baseTheme({
3094
- "& .cm-hr": {
3095
- // Note that block-level decorations should not have vertical margins,
3096
- borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
3097
- }
3098
- });
3099
- var HorizontalRuleWidget = class extends WidgetType3 {
3100
- toDOM() {
3101
- const el = document.createElement("div");
3102
- el.className = "cm-hr";
3103
- return el;
3104
- }
3105
- };
3106
- var decoration = Decoration7.replace({
3107
- widget: new HorizontalRuleWidget()
3108
- });
3109
- var buildDecorations3 = (view) => {
3110
- const builder = new RangeSetBuilder4();
3111
- const { state } = view;
3112
- const cursor = state.selection.main.head;
3113
- for (const { from, to } of view.visibleRanges) {
3114
- syntaxTree4(state).iterate({
3115
- enter: (node) => {
3116
- if (node.name === "HorizontalRule") {
3117
- if (cursor <= node.from || cursor >= node.to) {
3118
- builder.add(node.from, node.to, decoration);
3119
- }
3120
- }
3121
- },
3122
- from,
3123
- to
3124
- });
3125
- }
3126
- return builder.finish();
3127
- };
3128
- var hr = () => {
3129
- return [
3130
- ViewPlugin6.fromClass(class {
3131
- constructor(view) {
3132
- this.decorations = buildDecorations3(view);
3133
- }
3134
- update(update2) {
3135
- this.decorations = buildDecorations3(update2.view);
3136
- }
3137
- }, {
3138
- decorations: (value) => value.decorations
3139
- }),
3140
- styles5
3141
- ];
3142
- };
3143
-
3144
3251
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3145
- import { syntaxTree as syntaxTree5 } from "@codemirror/language";
3252
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3146
3253
  import { StateField as StateField4 } from "@codemirror/state";
3147
- import { Decoration as Decoration8, EditorView as EditorView12, WidgetType as WidgetType4 } from "@codemirror/view";
3254
+ import { Decoration as Decoration5, EditorView as EditorView12, WidgetType as WidgetType3 } from "@codemirror/view";
3148
3255
  var image = (options = {}) => {
3149
3256
  return StateField4.define({
3150
3257
  create: (state) => {
3151
- return Decoration8.set(buildDecorations4(0, state.doc.length, state));
3258
+ return Decoration5.set(buildDecorations2(0, state.doc.length, state));
3152
3259
  },
3153
3260
  update: (value, tr) => {
3154
3261
  if (!tr.docChanged && !tr.selection) {
@@ -3168,26 +3275,26 @@ var image = (options = {}) => {
3168
3275
  filterFrom: from,
3169
3276
  filterTo: to,
3170
3277
  filter: () => false,
3171
- add: buildDecorations4(from, to, tr.state)
3278
+ add: buildDecorations2(from, to, tr.state)
3172
3279
  });
3173
3280
  },
3174
3281
  provide: (field) => EditorView12.decorations.from(field)
3175
3282
  });
3176
3283
  };
3177
- var buildDecorations4 = (from, to, state) => {
3284
+ var buildDecorations2 = (from, to, state) => {
3178
3285
  const decorations = [];
3179
3286
  const cursor = state.selection.main.head;
3180
- syntaxTree5(state).iterate({
3287
+ syntaxTree3(state).iterate({
3181
3288
  enter: (node) => {
3182
3289
  if (node.name === "Image") {
3183
3290
  const urlNode = node.node.getChild("URL");
3184
3291
  if (urlNode) {
3185
- const hide = state.readOnly || cursor < node.from || cursor > node.to;
3292
+ const hide2 = state.readOnly || cursor < node.from || cursor > node.to;
3186
3293
  const url = state.sliceDoc(urlNode.from, urlNode.to);
3187
- decorations.push(Decoration8.replace({
3294
+ decorations.push(Decoration5.replace({
3188
3295
  block: true,
3189
3296
  widget: new ImageWidget(url)
3190
- }).range(hide ? node.from : node.to, node.to));
3297
+ }).range(hide2 ? node.from : node.to, node.to));
3191
3298
  }
3192
3299
  }
3193
3300
  },
@@ -3196,7 +3303,7 @@ var buildDecorations4 = (from, to, state) => {
3196
3303
  });
3197
3304
  return decorations;
3198
3305
  };
3199
- var ImageWidget = class extends WidgetType4 {
3306
+ var ImageWidget = class extends WidgetType3 {
3200
3307
  constructor(_url) {
3201
3308
  super();
3202
3309
  this._url = _url;
@@ -3214,146 +3321,43 @@ var ImageWidget = class extends WidgetType4 {
3214
3321
  };
3215
3322
 
3216
3323
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
3217
- import { syntaxTree as syntaxTree6 } from "@codemirror/language";
3218
- import { RangeSetBuilder as RangeSetBuilder5 } from "@codemirror/state";
3219
- import { hoverTooltip as hoverTooltip2, Decoration as Decoration9, ViewPlugin as ViewPlugin7, WidgetType as WidgetType5 } from "@codemirror/view";
3324
+ import { syntaxTree as syntaxTree4 } from "@codemirror/language";
3325
+ import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
3220
3326
  import { tooltipContent } from "@dxos/react-ui-theme";
3221
- var link = (options = {}) => {
3222
- const extensions = [
3223
- ViewPlugin7.fromClass(class {
3224
- constructor(view) {
3225
- this.decorations = buildDecorations5(view, options);
3226
- }
3227
- update(update2) {
3228
- if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
3229
- this.decorations = buildDecorations5(update2.view, options);
3230
- }
3231
- }
3232
- }, {
3233
- decorations: (value) => value.decorations
3234
- })
3235
- ];
3236
- if (options.onHover) {
3237
- extensions.push(
3238
- // https://codemirror.net/examples/tooltip
3239
- // https://codemirror.net/docs/ref/#view.hoverTooltip
3240
- // https://github.com/codemirror/view/blob/main/src/tooltip.ts
3241
- hoverTooltip2((view, pos, side) => {
3242
- const syntax = syntaxTree6(view.state).resolveInner(pos, side);
3243
- let link2 = null;
3244
- for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
3245
- link2 = node.name === "Link" ? node : null;
3246
- }
3247
- const url = link2 && link2.getChild("URL");
3248
- if (!url || !link2) {
3249
- return null;
3250
- }
3251
- const urlText = view.state.sliceDoc(url.from, url.to);
3252
- return {
3253
- pos: link2.from,
3254
- end: link2.to,
3255
- above: true,
3256
- create: () => {
3257
- const el = document.createElement("div");
3258
- el.className = tooltipContent({}, "pli-2 plb-1");
3259
- options.onHover(el, urlText);
3260
- return {
3261
- dom: el,
3262
- offset: {
3263
- x: 0,
3264
- y: 4
3265
- }
3266
- };
3267
- }
3268
- };
3269
- })
3270
- );
3271
- }
3272
- return extensions;
3273
- };
3274
- var LinkButton = class extends WidgetType5 {
3275
- constructor(_url, _onAttach) {
3276
- super();
3277
- this._url = _url;
3278
- this._onAttach = _onAttach;
3279
- }
3280
- eq(other) {
3281
- return this._url === other._url;
3282
- }
3283
- toDOM(view) {
3284
- const el = document.createElement("span");
3285
- this._onAttach(el, this._url);
3286
- return el;
3287
- }
3288
- };
3289
- var LinkText = class extends WidgetType5 {
3290
- constructor(_text, _url) {
3291
- super();
3292
- this._text = _text;
3293
- this._url = _url;
3294
- }
3295
- eq(other) {
3296
- return this._url === other._url;
3327
+ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
3328
+ const syntax = syntaxTree4(view.state).resolveInner(pos, side);
3329
+ let link = null;
3330
+ for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
3331
+ link = node.name === "Link" ? node : null;
3332
+ }
3333
+ const url = link && link.getChild("URL");
3334
+ if (!url || !link) {
3335
+ return null;
3297
3336
  }
3298
- toDOM(view) {
3299
- const link2 = document.createElement("a");
3300
- link2.setAttribute("class", "cm-link");
3301
- link2.textContent = this._text;
3302
- if (this._url) {
3303
- link2.setAttribute("rel", "noreferrer");
3304
- link2.setAttribute("target", "_blank");
3305
- link2.href = this._url;
3306
- } else {
3307
- link2.onclick = () => {
3308
- view.dispatch({
3309
- selection: {
3310
- anchor: view.posAtDOM(link2)
3311
- }
3312
- });
3337
+ const urlText = view.state.sliceDoc(url.from, url.to);
3338
+ return {
3339
+ pos: link.from,
3340
+ end: link.to,
3341
+ above: true,
3342
+ create: () => {
3343
+ const el = document.createElement("div");
3344
+ el.className = tooltipContent({}, "pli-2 plb-1");
3345
+ render(el, urlText);
3346
+ return {
3347
+ dom: el,
3348
+ offset: {
3349
+ x: 0,
3350
+ y: 4
3351
+ }
3313
3352
  };
3314
3353
  }
3315
- return link2;
3316
- }
3317
- };
3318
- var buildDecorations5 = (view, options) => {
3319
- const builder = new RangeSetBuilder5();
3320
- const { state } = view;
3321
- const cursor = state.selection.main.head;
3322
- for (const { from, to } of view.visibleRanges) {
3323
- syntaxTree6(state).iterate({
3324
- enter: (node) => {
3325
- if (node.name === "Link") {
3326
- const marks = node.node.getChildren("LinkMark");
3327
- const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
3328
- const urlNode = node.node.getChild("URL");
3329
- const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
3330
- if (!url) {
3331
- return false;
3332
- }
3333
- if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
3334
- builder.add(node.from, node.to, Decoration9.replace({
3335
- widget: new LinkText(text, options.link ? url : void 0)
3336
- }));
3337
- }
3338
- if (options.onRender) {
3339
- builder.add(node.to, node.to, Decoration9.replace({
3340
- widget: new LinkButton(url, options.onRender)
3341
- }));
3342
- }
3343
- return false;
3344
- }
3345
- },
3346
- from,
3347
- to
3348
- });
3349
- }
3350
- return builder.finish();
3351
- };
3354
+ };
3355
+ });
3352
3356
 
3353
3357
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
3354
- import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3355
- import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField5 } from "@codemirror/state";
3356
- import { Decoration as Decoration10, EditorView as EditorView13, WidgetType as WidgetType6 } from "@codemirror/view";
3358
+ import { syntaxTree as syntaxTree5 } from "@codemirror/language";
3359
+ import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField5 } from "@codemirror/state";
3360
+ import { Decoration as Decoration6, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
3357
3361
  var table = (options = {}) => {
3358
3362
  return StateField5.define({
3359
3363
  create: (state) => update(state, options),
@@ -3362,7 +3366,7 @@ var table = (options = {}) => {
3362
3366
  });
3363
3367
  };
3364
3368
  var update = (state, options) => {
3365
- const builder = new RangeSetBuilder6();
3369
+ const builder = new RangeSetBuilder2();
3366
3370
  const cursor = state.selection.main.head;
3367
3371
  const tables = [];
3368
3372
  const getTable = () => tables[tables.length - 1];
@@ -3370,7 +3374,7 @@ var update = (state, options) => {
3370
3374
  const table2 = getTable();
3371
3375
  return table2.rows?.[table2.rows.length - 1];
3372
3376
  };
3373
- syntaxTree7(state).iterate({
3377
+ syntaxTree5(state).iterate({
3374
3378
  enter: (node) => {
3375
3379
  switch (node.name) {
3376
3380
  case "Table": {
@@ -3401,17 +3405,17 @@ var update = (state, options) => {
3401
3405
  }
3402
3406
  });
3403
3407
  tables.forEach((table2) => {
3404
- const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
3405
- hide && builder.add(table2.from, table2.to, Decoration10.replace({
3408
+ const hide2 = state.readOnly || cursor < table2.from || cursor > table2.to;
3409
+ hide2 && builder.add(table2.from, table2.to, Decoration6.replace({
3406
3410
  widget: new TableWidget(table2)
3407
3411
  }));
3408
- builder.add(table2.from, table2.to, Decoration10.mark({
3412
+ builder.add(table2.from, table2.to, Decoration6.mark({
3409
3413
  class: "cm-table"
3410
3414
  }));
3411
3415
  });
3412
3416
  return builder.finish();
3413
3417
  };
3414
- var TableWidget = class extends WidgetType6 {
3418
+ var TableWidget = class extends WidgetType4 {
3415
3419
  constructor(_table) {
3416
3420
  super();
3417
3421
  this._table = _table;
@@ -3448,103 +3452,6 @@ var TableWidget = class extends WidgetType6 {
3448
3452
  }
3449
3453
  };
3450
3454
 
3451
- // packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
3452
- import { syntaxTree as syntaxTree8 } from "@codemirror/language";
3453
- import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
3454
- import { EditorView as EditorView14, Decoration as Decoration11, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
3455
- var styles6 = EditorView14.baseTheme({
3456
- "& .cm-task": {
3457
- color: getToken("extend.colors.blue.500")
3458
- },
3459
- "& .cm-task-checkbox": {
3460
- marginLeft: "4px",
3461
- marginRight: "4px"
3462
- }
3463
- });
3464
- var CheckboxWidget = class extends WidgetType7 {
3465
- constructor(_checked) {
3466
- super();
3467
- this._checked = _checked;
3468
- }
3469
- eq(other) {
3470
- return this._checked === other._checked;
3471
- }
3472
- toDOM(view) {
3473
- const input = document.createElement("input");
3474
- input.className = "cm-task-checkbox";
3475
- input.type = "checkbox";
3476
- input.checked = this._checked;
3477
- if (view.state.readOnly) {
3478
- input.setAttribute("disabled", "true");
3479
- } else {
3480
- input.onmousedown = (event) => {
3481
- const pos = view.posAtDOM(input);
3482
- const text = view.state.sliceDoc(pos, pos + 3);
3483
- if (text === (this._checked ? "[x]" : "[ ]")) {
3484
- view.dispatch({
3485
- changes: {
3486
- from: pos + 1,
3487
- to: pos + 2,
3488
- insert: this._checked ? " " : "x"
3489
- }
3490
- });
3491
- event.preventDefault();
3492
- }
3493
- };
3494
- }
3495
- return input;
3496
- }
3497
- ignoreEvent() {
3498
- return false;
3499
- }
3500
- };
3501
- var checkedDecoration = Decoration11.replace({
3502
- widget: new CheckboxWidget(true)
3503
- });
3504
- var uncheckedDecoration = Decoration11.replace({
3505
- widget: new CheckboxWidget(false)
3506
- });
3507
- var buildDecorations6 = (view) => {
3508
- const builder = new RangeSetBuilder7();
3509
- const { state } = view;
3510
- const cursor = state.selection.main.head;
3511
- for (const { from, to } of view.visibleRanges) {
3512
- syntaxTree8(state).iterate({
3513
- enter: (node) => {
3514
- if (node.name === "TaskMarker") {
3515
- if (cursor < node.from || cursor > node.to) {
3516
- const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
3517
- builder.add(node.from - 2, node.from - 1, Decoration11.mark({
3518
- class: "cm-task"
3519
- }));
3520
- builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
3521
- }
3522
- }
3523
- },
3524
- from,
3525
- to
3526
- });
3527
- }
3528
- return builder.finish();
3529
- };
3530
- var tasklist = (options = {}) => {
3531
- return [
3532
- ViewPlugin8.fromClass(class {
3533
- constructor(view) {
3534
- this.decorations = buildDecorations6(view);
3535
- }
3536
- update(update2) {
3537
- if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
3538
- this.decorations = buildDecorations6(update2.view);
3539
- }
3540
- }
3541
- }, {
3542
- decorations: (value) => value.decorations
3543
- }),
3544
- styles6
3545
- ];
3546
- };
3547
-
3548
3455
  // packages/ui/react-ui-editor/src/extensions/mention.ts
3549
3456
  import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
3550
3457
  var mention = ({ onSearch }) => {
@@ -3575,10 +3482,10 @@ var mention = ({ onSearch }) => {
3575
3482
  };
3576
3483
 
3577
3484
  // packages/ui/react-ui-editor/src/extensions/modes.ts
3578
- import { Facet as Facet4 } from "@codemirror/state";
3485
+ import { Facet as Facet5 } from "@codemirror/state";
3579
3486
  import { keymap as keymap6 } from "@codemirror/view";
3580
3487
  import { vim } from "@replit/codemirror-vim";
3581
- var editorMode = Facet4.define({
3488
+ var editorMode = Facet5.define({
3582
3489
  combine: (modes) => modes[0] ?? {}
3583
3490
  });
3584
3491
  var EditorModes = {
@@ -3942,7 +3849,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3942
3849
  selection,
3943
3850
  extensions: [
3944
3851
  // TODO(burdon): Doesn't catch errors in keymap functions.
3945
- EditorView15.exceptionSink.of((err) => {
3852
+ EditorView14.exceptionSink.of((err) => {
3946
3853
  log3.catch(err, void 0, {
3947
3854
  F: __dxlog_file4,
3948
3855
  L: 113,
@@ -3952,17 +3859,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3952
3859
  }),
3953
3860
  // Theme.
3954
3861
  // TODO(burdon): Make configurable.
3955
- EditorView15.baseTheme(defaultTheme),
3956
- EditorView15.theme(theme ?? {}),
3957
- EditorView15.darkTheme.of(themeMode === "dark"),
3958
- EditorView15.editorAttributes.of({
3862
+ EditorView14.baseTheme(defaultTheme),
3863
+ EditorView14.theme(theme ?? {}),
3864
+ EditorView14.darkTheme.of(themeMode === "dark"),
3865
+ EditorView14.editorAttributes.of({
3959
3866
  class: slots.editor?.className ?? ""
3960
3867
  }),
3961
- EditorView15.contentAttributes.of({
3868
+ EditorView14.contentAttributes.of({
3962
3869
  class: slots.content?.className ?? ""
3963
3870
  }),
3964
3871
  // Focus.
3965
- EditorView15.updateListener.of((update2) => {
3872
+ EditorView14.updateListener.of((update2) => {
3966
3873
  update2.transactions.forEach((transaction) => {
3967
3874
  if (transaction.isUserEvent("focus.container")) {
3968
3875
  rootRef.current?.focus();
@@ -3970,7 +3877,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3970
3877
  });
3971
3878
  }),
3972
3879
  // State.
3973
- EditorView15.editable.of(!readonly),
3880
+ EditorView14.editable.of(!readonly),
3974
3881
  EditorState2.readOnly.of(!!readonly),
3975
3882
  // Storage and replication.
3976
3883
  // NOTE: This must come before user extensions.
@@ -3979,7 +3886,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3979
3886
  ...extensions
3980
3887
  ].filter(isNotFalsy4)
3981
3888
  });
3982
- const newView = new EditorView15({
3889
+ const newView = new EditorView14({
3983
3890
  state,
3984
3891
  parent: rootRef.current,
3985
3892
  scrollTo,
@@ -4096,32 +4003,12 @@ var defaultMarkdownSlots = {
4096
4003
  import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes } from "@phosphor-icons/react";
4097
4004
  import { createContext } from "@radix-ui/react-context";
4098
4005
  import React2 from "react";
4099
- import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, useTranslation } from "@dxos/react-ui";
4006
+ import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
4100
4007
  import { getSize } from "@dxos/react-ui-theme";
4101
-
4102
- // packages/ui/react-ui-editor/src/translations.ts
4103
- var translationKey = "react-ui-editor";
4104
- var translations_default = [
4105
- {
4106
- "en-US": {
4107
- [translationKey]: {
4108
- "strong label": "Strong",
4109
- "emphasis label": "Emphasis",
4110
- "strikethrough label": "Strike-through",
4111
- "code label": "Code",
4112
- "list-bullet label": "Bullet list",
4113
- "list-ordered label": "Numbered list",
4114
- "list-task label": "Task list",
4115
- "blockquote label": "Block quote",
4116
- "codeblock label": "Code block",
4117
- "comment label": "Create comment",
4118
- "heading label": "Heading level"
4119
- }
4120
- }
4121
- }
4122
- ];
4123
-
4124
- // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
4008
+ var tooltipProps = {
4009
+ side: "top",
4010
+ classNames: "z-10"
4011
+ };
4125
4012
  var HeadingIcons = {
4126
4013
  "0": Paragraph,
4127
4014
  "1": TextHOne,
@@ -4150,7 +4037,9 @@ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
4150
4037
  var buttonStyles = "min-bs-0 p-2";
4151
4038
  var iconStyles = getSize(5);
4152
4039
  var ToolbarButton = ({ Icon, children, ...props }) => {
4153
- return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
4040
+ return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4041
+ asChild: true
4042
+ }, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
4154
4043
  variant: "ghost",
4155
4044
  ...props,
4156
4045
  classNames: buttonStyles
@@ -4158,7 +4047,7 @@ var ToolbarButton = ({ Icon, children, ...props }) => {
4158
4047
  className: iconStyles
4159
4048
  }), /* @__PURE__ */ React2.createElement("span", {
4160
4049
  className: "sr-only"
4161
- }, children));
4050
+ }, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4162
4051
  };
4163
4052
  var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
4164
4053
  role: "separator",
@@ -4171,13 +4060,15 @@ var MarkdownHeading = () => {
4171
4060
  const header = blockType && /heading(\d)/.exec(blockType);
4172
4061
  const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
4173
4062
  const HeadingIcon = HeadingIcons[value ?? "0"];
4174
- return /* @__PURE__ */ React2.createElement(Select.Root, {
4063
+ return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Select.Root, {
4175
4064
  disabled: value === null,
4176
4065
  value: value ?? "0",
4177
4066
  onValueChange: (value2) => onAction?.({
4178
4067
  type: "heading",
4179
4068
  data: parseInt(value2)
4180
4069
  })
4070
+ }, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4071
+ asChild: true
4181
4072
  }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4182
4073
  asChild: true
4183
4074
  }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
@@ -4187,7 +4078,7 @@ var MarkdownHeading = () => {
4187
4078
  className: "sr-only"
4188
4079
  }, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
4189
4080
  className: iconStyles
4190
- }))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
4081
+ })))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
4191
4082
  value: "0"
4192
4083
  }, /* @__PURE__ */ React2.createElement(Paragraph, {
4193
4084
  className: iconStyles
@@ -4213,7 +4104,7 @@ var MarkdownHeading = () => {
4213
4104
  className: iconStyles
4214
4105
  }), level === 6 && /* @__PURE__ */ React2.createElement(TextHSix, {
4215
4106
  className: iconStyles
4216
- })))), /* @__PURE__ */ React2.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React2.createElement(Select.Arrow, null))));
4107
+ })))), /* @__PURE__ */ React2.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React2.createElement(Select.Arrow, null)))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4217
4108
  };
4218
4109
  var markdownStyles = [
4219
4110
  {
@@ -4301,8 +4192,7 @@ var markdownBlocks = [
4301
4192
  {
4302
4193
  type: "codeblock",
4303
4194
  Icon: CodeBlock,
4304
- getState: (state) => state.blockType === "codeblock",
4305
- disabled: (state) => !state.blankLine
4195
+ getState: (state) => state.blockType === "codeblock"
4306
4196
  },
4307
4197
  {
4308
4198
  type: "table",
@@ -4333,7 +4223,9 @@ var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragmen
4333
4223
  var MarkdownExtended = () => {
4334
4224
  const { onAction } = useToolbarContext("MarkdownStyles");
4335
4225
  const { t } = useTranslation(translationKey);
4336
- return /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4226
+ return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4227
+ asChild: true
4228
+ }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4337
4229
  variant: "ghost",
4338
4230
  "data-testid": "editor.toolbar.comment",
4339
4231
  onClick: () => onAction?.({
@@ -4344,7 +4236,7 @@ var MarkdownExtended = () => {
4344
4236
  className: iconStyles
4345
4237
  }), /* @__PURE__ */ React2.createElement("span", {
4346
4238
  className: "sr-only"
4347
- }, t("comment label")));
4239
+ }, t("comment label")))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("comment label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4348
4240
  };
4349
4241
  var Toolbar = {
4350
4242
  Root: ToolbarRoot,
@@ -4535,7 +4427,7 @@ var useEditorView = (id) => {
4535
4427
 
4536
4428
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
4537
4429
  import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
4538
- import { EditorView as EditorView16 } from "@codemirror/view";
4430
+ import { EditorView as EditorView15 } from "@codemirror/view";
4539
4431
  import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
4540
4432
  import { log as log5 } from "@dxos/log";
4541
4433
  import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
@@ -4552,7 +4444,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4552
4444
  selection,
4553
4445
  extensions: [
4554
4446
  // TODO(burdon): Doesn't catch errors in keymap functions.
4555
- EditorView16.exceptionSink.of((err) => {
4447
+ EditorView15.exceptionSink.of((err) => {
4556
4448
  log5.catch(err, void 0, {
4557
4449
  F: __dxlog_file6,
4558
4450
  L: 60,
@@ -4561,12 +4453,12 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4561
4453
  });
4562
4454
  }),
4563
4455
  extensions,
4564
- EditorView16.updateListener.of(() => {
4456
+ EditorView15.updateListener.of(() => {
4565
4457
  onUpdate.current?.();
4566
4458
  })
4567
4459
  ].filter(isNotFalsy5)
4568
4460
  });
4569
- view2 = new EditorView16({
4461
+ view2 = new EditorView15({
4570
4462
  parent: parentRef.current,
4571
4463
  scrollTo,
4572
4464
  state,
@@ -4624,19 +4516,19 @@ var createDataExtensions = ({ readonly = false } = {}) => {
4624
4516
  return [
4625
4517
  //
4626
4518
  EditorState3.readOnly.of(readonly),
4627
- EditorView16.editable.of(!readonly)
4519
+ EditorView15.editable.of(!readonly)
4628
4520
  ];
4629
4521
  };
4630
4522
  var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
4631
4523
  return [
4632
4524
  //
4633
- EditorView16.baseTheme(defaultTheme),
4634
- theme && EditorView16.theme(theme),
4635
- EditorView16.darkTheme.of(themeMode === "dark"),
4636
- EditorView16.editorAttributes.of({
4525
+ EditorView15.baseTheme(defaultTheme),
4526
+ theme && EditorView15.theme(theme),
4527
+ EditorView15.darkTheme.of(themeMode === "dark"),
4528
+ EditorView15.editorAttributes.of({
4637
4529
  class: slots?.editor?.className ?? ""
4638
4530
  }),
4639
- EditorView16.contentAttributes.of({
4531
+ EditorView15.contentAttributes.of({
4640
4532
  class: slots?.content?.className ?? ""
4641
4533
  })
4642
4534
  ].filter(isNotFalsy5);
@@ -4736,7 +4628,6 @@ export {
4736
4628
  awarenessProvider,
4737
4629
  blast,
4738
4630
  callbackWrapper,
4739
- code2 as code,
4740
4631
  codeTheme,
4741
4632
  comments,
4742
4633
  compareFormatting,
@@ -4745,6 +4636,9 @@ export {
4745
4636
  createDataExtensions,
4746
4637
  createMarkdownExtensions,
4747
4638
  createThemeExtensions,
4639
+ cursorLineMargin,
4640
+ cursorLineMarginFacet,
4641
+ decorateMarkdown,
4748
4642
  defaultMarkdownSlots,
4749
4643
  defaultOptions,
4750
4644
  defaultSlots,
@@ -4759,12 +4653,10 @@ export {
4759
4653
  formatting,
4760
4654
  getFormatting,
4761
4655
  getToken,
4762
- heading2 as heading,
4763
- hr,
4764
4656
  image,
4765
4657
  insertTable,
4766
4658
  keymap8 as keymap,
4767
- link,
4659
+ linkTooltip,
4768
4660
  listener,
4769
4661
  logChanges,
4770
4662
  markdownHighlightStyle,
@@ -4786,7 +4678,6 @@ export {
4786
4678
  setStyle,
4787
4679
  table,
4788
4680
  tags2 as tags,
4789
- tasklist,
4790
4681
  textTheme,
4791
4682
  toggleBlockquote,
4792
4683
  toggleCodeblock,
@@ -4796,6 +4687,7 @@ export {
4796
4687
  toggleStrikethrough,
4797
4688
  toggleStrong,
4798
4689
  toggleStyle,
4690
+ translations_default as translations,
4799
4691
  typewriter,
4800
4692
  useActionHandler,
4801
4693
  useComments,