@dxos/react-ui-editor 0.4.5-main.181e1ed → 0.4.5-main.2a3f55f

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 (48) hide show
  1. package/dist/lib/browser/index.mjs +334 -537
  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/markdown/decorate.d.ts +5 -0
  16. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -0
  17. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  18. package/dist/types/src/extensions/markdown/index.d.ts +1 -4
  19. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  20. package/dist/types/src/extensions/markdown/link.d.ts +1 -11
  21. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  22. package/dist/types/src/index.d.ts +2 -0
  23. package/dist/types/src/index.d.ts.map +1 -1
  24. package/dist/types/src/translations.d.ts +2 -0
  25. package/dist/types/src/translations.d.ts.map +1 -1
  26. package/package.json +24 -24
  27. package/src/components/TextEditor/MarkdownEditor.stories.tsx +29 -37
  28. package/src/components/TextEditor/hooks.stories.tsx +2 -10
  29. package/src/components/Toolbar/Toolbar.stories.tsx +2 -6
  30. package/src/components/Toolbar/Toolbar.tsx +79 -46
  31. package/src/extensions/markdown/decorate.ts +301 -0
  32. package/src/extensions/markdown/formatting.ts +1 -64
  33. package/src/extensions/markdown/index.ts +1 -4
  34. package/src/extensions/markdown/link.ts +23 -185
  35. package/src/index.ts +2 -0
  36. package/src/translations.ts +5 -3
  37. package/dist/types/src/extensions/markdown/code.d.ts +0 -2
  38. package/dist/types/src/extensions/markdown/code.d.ts.map +0 -1
  39. package/dist/types/src/extensions/markdown/heading.d.ts +0 -6
  40. package/dist/types/src/extensions/markdown/heading.d.ts.map +0 -1
  41. package/dist/types/src/extensions/markdown/hr.d.ts +0 -2
  42. package/dist/types/src/extensions/markdown/hr.d.ts.map +0 -1
  43. package/dist/types/src/extensions/markdown/tasklist.d.ts +0 -3
  44. package/dist/types/src/extensions/markdown/tasklist.d.ts.map +0 -1
  45. package/src/extensions/markdown/code.ts +0 -162
  46. package/src/extensions/markdown/heading.ts +0 -59
  47. package/src/extensions/markdown/hr.ts +0 -71
  48. 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 EditorView16 } 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";
@@ -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,
@@ -1871,12 +1895,207 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
1871
1895
  ].filter(isNotFalsy3);
1872
1896
  };
1873
1897
 
1874
- // packages/ui/react-ui-editor/src/extensions/markdown/code.ts
1898
+ // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
1875
1899
  import { syntaxTree } from "@codemirror/language";
1876
1900
  import { RangeSetBuilder } from "@codemirror/state";
1877
- import { ViewPlugin as ViewPlugin3, EditorView as EditorView10, 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";
1878
1902
  import { mx as mx2 } from "@dxos/react-ui-theme";
1879
- var styles4 = EditorView10.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 = " ";
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({
1880
2099
  "& .cm-code": {
1881
2100
  fontFamily: getToken("fontFamily.mono", []).join(",")
1882
2101
  },
@@ -1924,82 +2143,28 @@ var styles4 = EditorView10.baseTheme({
1924
2143
  "&::after": {
1925
2144
  background: getToken("extend.semanticColors.input.dark")
1926
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"
1927
2160
  }
1928
2161
  });
1929
- var getLineRange = (lines, from, to) => {
1930
- const start = lines.findIndex((line) => line.from >= from);
1931
- const end = lines.findIndex((line) => line.to >= to);
1932
- return [
1933
- start,
1934
- end
1935
- ];
1936
- };
1937
- var LineWidget = class extends WidgetType2 {
1938
- constructor(_className) {
1939
- super();
1940
- this._className = _className;
1941
- }
1942
- toDOM() {
1943
- const el = document.createElement("span");
1944
- el.innerHTML = "&nbsp;";
1945
- el.className = mx2("cm-code cm-codeblock", this._className);
1946
- return el;
1947
- }
1948
- };
1949
- var top = new LineWidget("cm-codeblock-end cm-codeblock-first");
1950
- var bottom = new LineWidget("cm-codeblock-end cm-codeblock-last");
1951
- var buildDecorations = (view) => {
1952
- const builder = new RangeSetBuilder();
1953
- const { state } = view;
1954
- const blocks = view.viewportLineBlocks;
1955
- const cursor = state.selection.main.head;
1956
- for (const { from, to } of view.visibleRanges) {
1957
- syntaxTree(state).iterate({
1958
- enter: (node) => {
1959
- if (node.name === "FencedCode") {
1960
- const editing = !view.state.readOnly && cursor >= node.from && cursor <= node.to;
1961
- const range = getLineRange(blocks, node.from, node.to);
1962
- for (let i = range[0]; i <= range[1]; i++) {
1963
- const block = blocks[i];
1964
- if (!editing && (i === range[0] || i === range[1])) {
1965
- builder.add(block.from, block.to, Decoration4.replace({
1966
- widget: i === range[0] ? top : bottom
1967
- }));
1968
- } else {
1969
- builder.add(block.from, block.from, Decoration4.line({
1970
- class: mx2("cm-code cm-codeblock-line", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
1971
- }));
1972
- }
1973
- }
1974
- }
1975
- },
1976
- from,
1977
- to
1978
- });
1979
- }
1980
- return builder.finish();
1981
- };
1982
- var code2 = () => {
1983
- return [
1984
- ViewPlugin3.fromClass(class {
1985
- constructor(view) {
1986
- this.decorations = buildDecorations(view);
1987
- }
1988
- update(update2) {
1989
- this.decorations = buildDecorations(update2.view);
1990
- }
1991
- }, {
1992
- decorations: (value) => value.decorations
1993
- }),
1994
- styles4
1995
- ];
1996
- };
1997
2162
 
1998
2163
  // packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
1999
2164
  import { snippet } from "@codemirror/autocomplete";
2000
2165
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2001
- import { RangeSetBuilder as RangeSetBuilder2, EditorSelection } from "@codemirror/state";
2002
- import { Decoration as Decoration5, EditorView as EditorView11, 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";
2003
2168
  import { useState, useMemo } from "react";
2004
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;
2005
2170
  var Inline;
@@ -2876,56 +3041,7 @@ var formatting = (options = {}) => {
2876
3041
  key: "meta-b",
2877
3042
  run: toggleStrong
2878
3043
  }
2879
- ]),
2880
- styling()
2881
- ];
2882
- };
2883
- var styling = () => {
2884
- const buildDecorations7 = (view) => {
2885
- const builder = new RangeSetBuilder2();
2886
- const { state } = view;
2887
- const cursor = state.selection.main.head;
2888
- const replace = (node, marks) => {
2889
- if (cursor <= node.from || cursor >= node.to) {
2890
- for (const mark2 of marks) {
2891
- builder.add(mark2.from, mark2.to, Decoration5.replace({}));
2892
- }
2893
- }
2894
- };
2895
- for (const { from, to } of view.visibleRanges) {
2896
- syntaxTree2(state).iterate({
2897
- enter: (node) => {
2898
- switch (node.name) {
2899
- case "Emphasis":
2900
- case "StrongEmphasis": {
2901
- const marks = node.node.getChildren("EmphasisMark");
2902
- replace(node, marks);
2903
- break;
2904
- }
2905
- case "Strikethrough": {
2906
- const marks = node.node.getChildren("StrikethroughMark");
2907
- replace(node, marks);
2908
- break;
2909
- }
2910
- }
2911
- },
2912
- from,
2913
- to
2914
- });
2915
- }
2916
- return builder.finish();
2917
- };
2918
- return [
2919
- ViewPlugin4.fromClass(class {
2920
- constructor(view) {
2921
- this.decorations = buildDecorations7(view);
2922
- }
2923
- update(update2) {
2924
- this.decorations = buildDecorations7(update2.view);
2925
- }
2926
- }, {
2927
- decorations: (value) => value.decorations
2928
- })
3044
+ ])
2929
3045
  ];
2930
3046
  };
2931
3047
  var InlineMarker = {
@@ -2975,7 +3091,7 @@ var getFormatting = (state) => {
2975
3091
  null,
2976
3092
  null
2977
3093
  ];
2978
- let link2 = false;
3094
+ let link = false;
2979
3095
  let blockQuote = null;
2980
3096
  let listStyle = null;
2981
3097
  const stack = [];
@@ -3037,7 +3153,7 @@ var getFormatting = (state) => {
3037
3153
  if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
3038
3154
  stack.push(name);
3039
3155
  } else if (name === "Link") {
3040
- link2 = true;
3156
+ link = true;
3041
3157
  } else if (Object.hasOwn(Textblocks, name) && (range.empty || node.to > range.from || node.from < range.to)) {
3042
3158
  if (name === "Task" && stack[stack.length - 1] === "BulletList") {
3043
3159
  stack[stack.length - 1] = "TaskList";
@@ -3112,7 +3228,7 @@ var getFormatting = (state) => {
3112
3228
  emphasis: inline[1] ?? false,
3113
3229
  strong: inline[0] ?? false,
3114
3230
  strikethrough: inline[2] ?? false,
3115
- link: link2,
3231
+ link,
3116
3232
  listStyle: listStyle || null
3117
3233
  };
3118
3234
  };
@@ -3132,117 +3248,14 @@ var useFormattingState = () => {
3132
3248
  ];
3133
3249
  };
3134
3250
 
3135
- // packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
3136
- import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3137
- import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
3138
- import { Decoration as Decoration6, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
3139
- var buildDecorations2 = (view) => {
3140
- const builder = new RangeSetBuilder3();
3141
- const { state } = view;
3142
- const cursor = state.selection.main.head;
3143
- for (const { from, to } of view.visibleRanges) {
3144
- syntaxTree3(state).iterate({
3145
- enter: (node) => {
3146
- switch (node.name) {
3147
- case "ATXHeading1":
3148
- case "ATXHeading2":
3149
- case "ATXHeading3":
3150
- case "ATXHeading4":
3151
- case "ATXHeading5":
3152
- case "ATXHeading6": {
3153
- const mark2 = node.node.getChild("HeaderMark");
3154
- if (mark2) {
3155
- if (!view.hasFocus || view.state.readOnly || cursor < node.from || cursor > node.to) {
3156
- builder.add(mark2.from, mark2.to + 1, Decoration6.replace({}));
3157
- }
3158
- }
3159
- }
3160
- }
3161
- },
3162
- from,
3163
- to
3164
- });
3165
- }
3166
- return builder.finish();
3167
- };
3168
- var heading2 = () => {
3169
- return [
3170
- ViewPlugin5.fromClass(class {
3171
- constructor(view) {
3172
- this.decorations = buildDecorations2(view);
3173
- }
3174
- update(update2) {
3175
- this.decorations = buildDecorations2(update2.view);
3176
- }
3177
- }, {
3178
- decorations: (value) => value.decorations
3179
- })
3180
- ];
3181
- };
3182
-
3183
- // packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
3184
- import { syntaxTree as syntaxTree4 } from "@codemirror/language";
3185
- import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
3186
- import { Decoration as Decoration7, EditorView as EditorView12, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
3187
- var styles5 = EditorView12.baseTheme({
3188
- "& .cm-hr": {
3189
- // Note that block-level decorations should not have vertical margins,
3190
- borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
3191
- }
3192
- });
3193
- var HorizontalRuleWidget = class extends WidgetType3 {
3194
- toDOM() {
3195
- const el = document.createElement("div");
3196
- el.className = "cm-hr";
3197
- return el;
3198
- }
3199
- };
3200
- var decoration = Decoration7.replace({
3201
- widget: new HorizontalRuleWidget()
3202
- });
3203
- var buildDecorations3 = (view) => {
3204
- const builder = new RangeSetBuilder4();
3205
- const { state } = view;
3206
- const cursor = state.selection.main.head;
3207
- for (const { from, to } of view.visibleRanges) {
3208
- syntaxTree4(state).iterate({
3209
- enter: (node) => {
3210
- if (node.name === "HorizontalRule") {
3211
- if (cursor <= node.from || cursor >= node.to) {
3212
- builder.add(node.from, node.to, decoration);
3213
- }
3214
- }
3215
- },
3216
- from,
3217
- to
3218
- });
3219
- }
3220
- return builder.finish();
3221
- };
3222
- var hr = () => {
3223
- return [
3224
- ViewPlugin6.fromClass(class {
3225
- constructor(view) {
3226
- this.decorations = buildDecorations3(view);
3227
- }
3228
- update(update2) {
3229
- this.decorations = buildDecorations3(update2.view);
3230
- }
3231
- }, {
3232
- decorations: (value) => value.decorations
3233
- }),
3234
- styles5
3235
- ];
3236
- };
3237
-
3238
3251
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3239
- import { syntaxTree as syntaxTree5 } from "@codemirror/language";
3252
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3240
3253
  import { StateField as StateField4 } from "@codemirror/state";
3241
- import { Decoration as Decoration8, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
3254
+ import { Decoration as Decoration5, EditorView as EditorView12, WidgetType as WidgetType3 } from "@codemirror/view";
3242
3255
  var image = (options = {}) => {
3243
3256
  return StateField4.define({
3244
3257
  create: (state) => {
3245
- return Decoration8.set(buildDecorations4(0, state.doc.length, state));
3258
+ return Decoration5.set(buildDecorations2(0, state.doc.length, state));
3246
3259
  },
3247
3260
  update: (value, tr) => {
3248
3261
  if (!tr.docChanged && !tr.selection) {
@@ -3262,26 +3275,26 @@ var image = (options = {}) => {
3262
3275
  filterFrom: from,
3263
3276
  filterTo: to,
3264
3277
  filter: () => false,
3265
- add: buildDecorations4(from, to, tr.state)
3278
+ add: buildDecorations2(from, to, tr.state)
3266
3279
  });
3267
3280
  },
3268
- provide: (field) => EditorView13.decorations.from(field)
3281
+ provide: (field) => EditorView12.decorations.from(field)
3269
3282
  });
3270
3283
  };
3271
- var buildDecorations4 = (from, to, state) => {
3284
+ var buildDecorations2 = (from, to, state) => {
3272
3285
  const decorations = [];
3273
3286
  const cursor = state.selection.main.head;
3274
- syntaxTree5(state).iterate({
3287
+ syntaxTree3(state).iterate({
3275
3288
  enter: (node) => {
3276
3289
  if (node.name === "Image") {
3277
3290
  const urlNode = node.node.getChild("URL");
3278
3291
  if (urlNode) {
3279
- const hide = state.readOnly || cursor < node.from || cursor > node.to;
3292
+ const hide2 = state.readOnly || cursor < node.from || cursor > node.to;
3280
3293
  const url = state.sliceDoc(urlNode.from, urlNode.to);
3281
- decorations.push(Decoration8.replace({
3294
+ decorations.push(Decoration5.replace({
3282
3295
  block: true,
3283
3296
  widget: new ImageWidget(url)
3284
- }).range(hide ? node.from : node.to, node.to));
3297
+ }).range(hide2 ? node.from : node.to, node.to));
3285
3298
  }
3286
3299
  }
3287
3300
  },
@@ -3290,7 +3303,7 @@ var buildDecorations4 = (from, to, state) => {
3290
3303
  });
3291
3304
  return decorations;
3292
3305
  };
3293
- var ImageWidget = class extends WidgetType4 {
3306
+ var ImageWidget = class extends WidgetType3 {
3294
3307
  constructor(_url) {
3295
3308
  super();
3296
3309
  this._url = _url;
@@ -3308,155 +3321,52 @@ var ImageWidget = class extends WidgetType4 {
3308
3321
  };
3309
3322
 
3310
3323
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
3311
- import { syntaxTree as syntaxTree6 } from "@codemirror/language";
3312
- import { RangeSetBuilder as RangeSetBuilder5 } from "@codemirror/state";
3313
- 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";
3314
3326
  import { tooltipContent } from "@dxos/react-ui-theme";
3315
- var link = (options = {}) => {
3316
- const extensions = [
3317
- ViewPlugin7.fromClass(class {
3318
- constructor(view) {
3319
- this.decorations = buildDecorations5(view, options);
3320
- }
3321
- update(update2) {
3322
- if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
3323
- this.decorations = buildDecorations5(update2.view, options);
3324
- }
3325
- }
3326
- }, {
3327
- decorations: (value) => value.decorations
3328
- })
3329
- ];
3330
- if (options.onHover) {
3331
- extensions.push(
3332
- // https://codemirror.net/examples/tooltip
3333
- // https://codemirror.net/docs/ref/#view.hoverTooltip
3334
- // https://github.com/codemirror/view/blob/main/src/tooltip.ts
3335
- hoverTooltip2((view, pos, side) => {
3336
- const syntax = syntaxTree6(view.state).resolveInner(pos, side);
3337
- let link2 = null;
3338
- for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
3339
- link2 = node.name === "Link" ? node : null;
3340
- }
3341
- const url = link2 && link2.getChild("URL");
3342
- if (!url || !link2) {
3343
- return null;
3344
- }
3345
- const urlText = view.state.sliceDoc(url.from, url.to);
3346
- return {
3347
- pos: link2.from,
3348
- end: link2.to,
3349
- above: true,
3350
- create: () => {
3351
- const el = document.createElement("div");
3352
- el.className = tooltipContent({}, "pli-2 plb-1");
3353
- options.onHover(el, urlText);
3354
- return {
3355
- dom: el,
3356
- offset: {
3357
- x: 0,
3358
- y: 4
3359
- }
3360
- };
3361
- }
3362
- };
3363
- })
3364
- );
3365
- }
3366
- return extensions;
3367
- };
3368
- var LinkButton = class extends WidgetType5 {
3369
- constructor(_url, _onAttach) {
3370
- super();
3371
- this._url = _url;
3372
- this._onAttach = _onAttach;
3373
- }
3374
- eq(other) {
3375
- return this._url === other._url;
3376
- }
3377
- toDOM(view) {
3378
- const el = document.createElement("span");
3379
- this._onAttach(el, this._url);
3380
- return el;
3381
- }
3382
- };
3383
- var LinkText = class extends WidgetType5 {
3384
- constructor(_text, _url) {
3385
- super();
3386
- this._text = _text;
3387
- this._url = _url;
3388
- }
3389
- eq(other) {
3390
- 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;
3391
3336
  }
3392
- toDOM(view) {
3393
- const link2 = document.createElement("a");
3394
- link2.setAttribute("class", "cm-link");
3395
- link2.textContent = this._text;
3396
- if (this._url) {
3397
- link2.setAttribute("rel", "noreferrer");
3398
- link2.setAttribute("target", "_blank");
3399
- link2.href = this._url;
3400
- } else {
3401
- link2.onclick = () => {
3402
- view.dispatch({
3403
- selection: {
3404
- anchor: view.posAtDOM(link2)
3405
- }
3406
- });
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
+ }
3407
3352
  };
3408
3353
  }
3409
- return link2;
3410
- }
3411
- };
3412
- var buildDecorations5 = (view, options) => {
3413
- const builder = new RangeSetBuilder5();
3414
- const { state } = view;
3415
- const cursor = state.selection.main.head;
3416
- for (const { from, to } of view.visibleRanges) {
3417
- syntaxTree6(state).iterate({
3418
- enter: (node) => {
3419
- if (node.name === "Link") {
3420
- const marks = node.node.getChildren("LinkMark");
3421
- const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
3422
- const urlNode = node.node.getChild("URL");
3423
- const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
3424
- if (!url) {
3425
- return false;
3426
- }
3427
- if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
3428
- builder.add(node.from, node.to, Decoration9.replace({
3429
- widget: new LinkText(text, options.link ? url : void 0)
3430
- }));
3431
- }
3432
- if (options.onRender) {
3433
- builder.add(node.to, node.to, Decoration9.replace({
3434
- widget: new LinkButton(url, options.onRender)
3435
- }));
3436
- }
3437
- return false;
3438
- }
3439
- },
3440
- from,
3441
- to
3442
- });
3443
- }
3444
- return builder.finish();
3445
- };
3354
+ };
3355
+ });
3446
3356
 
3447
3357
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
3448
- import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3449
- import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField5 } from "@codemirror/state";
3450
- import { Decoration as Decoration10, EditorView as EditorView14, 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";
3451
3361
  var table = (options = {}) => {
3452
3362
  return StateField5.define({
3453
3363
  create: (state) => update(state, options),
3454
3364
  update: (_, tr) => update(tr.state, options),
3455
- provide: (field) => EditorView14.decorations.from(field)
3365
+ provide: (field) => EditorView13.decorations.from(field)
3456
3366
  });
3457
3367
  };
3458
3368
  var update = (state, options) => {
3459
- const builder = new RangeSetBuilder6();
3369
+ const builder = new RangeSetBuilder2();
3460
3370
  const cursor = state.selection.main.head;
3461
3371
  const tables = [];
3462
3372
  const getTable = () => tables[tables.length - 1];
@@ -3464,7 +3374,7 @@ var update = (state, options) => {
3464
3374
  const table2 = getTable();
3465
3375
  return table2.rows?.[table2.rows.length - 1];
3466
3376
  };
3467
- syntaxTree7(state).iterate({
3377
+ syntaxTree5(state).iterate({
3468
3378
  enter: (node) => {
3469
3379
  switch (node.name) {
3470
3380
  case "Table": {
@@ -3495,17 +3405,17 @@ var update = (state, options) => {
3495
3405
  }
3496
3406
  });
3497
3407
  tables.forEach((table2) => {
3498
- const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
3499
- 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({
3500
3410
  widget: new TableWidget(table2)
3501
3411
  }));
3502
- builder.add(table2.from, table2.to, Decoration10.mark({
3412
+ builder.add(table2.from, table2.to, Decoration6.mark({
3503
3413
  class: "cm-table"
3504
3414
  }));
3505
3415
  });
3506
3416
  return builder.finish();
3507
3417
  };
3508
- var TableWidget = class extends WidgetType6 {
3418
+ var TableWidget = class extends WidgetType4 {
3509
3419
  constructor(_table) {
3510
3420
  super();
3511
3421
  this._table = _table;
@@ -3542,103 +3452,6 @@ var TableWidget = class extends WidgetType6 {
3542
3452
  }
3543
3453
  };
3544
3454
 
3545
- // packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
3546
- import { syntaxTree as syntaxTree8 } from "@codemirror/language";
3547
- import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
3548
- import { EditorView as EditorView15, Decoration as Decoration11, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
3549
- var styles6 = EditorView15.baseTheme({
3550
- "& .cm-task": {
3551
- color: getToken("extend.colors.blue.500")
3552
- },
3553
- "& .cm-task-checkbox": {
3554
- marginLeft: "4px",
3555
- marginRight: "4px"
3556
- }
3557
- });
3558
- var CheckboxWidget = class extends WidgetType7 {
3559
- constructor(_checked) {
3560
- super();
3561
- this._checked = _checked;
3562
- }
3563
- eq(other) {
3564
- return this._checked === other._checked;
3565
- }
3566
- toDOM(view) {
3567
- const input = document.createElement("input");
3568
- input.className = "cm-task-checkbox";
3569
- input.type = "checkbox";
3570
- input.checked = this._checked;
3571
- if (view.state.readOnly) {
3572
- input.setAttribute("disabled", "true");
3573
- } else {
3574
- input.onmousedown = (event) => {
3575
- const pos = view.posAtDOM(input);
3576
- const text = view.state.sliceDoc(pos, pos + 3);
3577
- if (text === (this._checked ? "[x]" : "[ ]")) {
3578
- view.dispatch({
3579
- changes: {
3580
- from: pos + 1,
3581
- to: pos + 2,
3582
- insert: this._checked ? " " : "x"
3583
- }
3584
- });
3585
- event.preventDefault();
3586
- }
3587
- };
3588
- }
3589
- return input;
3590
- }
3591
- ignoreEvent() {
3592
- return false;
3593
- }
3594
- };
3595
- var checkedDecoration = Decoration11.replace({
3596
- widget: new CheckboxWidget(true)
3597
- });
3598
- var uncheckedDecoration = Decoration11.replace({
3599
- widget: new CheckboxWidget(false)
3600
- });
3601
- var buildDecorations6 = (view) => {
3602
- const builder = new RangeSetBuilder7();
3603
- const { state } = view;
3604
- const cursor = state.selection.main.head;
3605
- for (const { from, to } of view.visibleRanges) {
3606
- syntaxTree8(state).iterate({
3607
- enter: (node) => {
3608
- if (node.name === "TaskMarker") {
3609
- if (cursor < node.from || cursor > node.to) {
3610
- const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
3611
- builder.add(node.from - 2, node.from - 1, Decoration11.mark({
3612
- class: "cm-task"
3613
- }));
3614
- builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
3615
- }
3616
- }
3617
- },
3618
- from,
3619
- to
3620
- });
3621
- }
3622
- return builder.finish();
3623
- };
3624
- var tasklist = (options = {}) => {
3625
- return [
3626
- ViewPlugin8.fromClass(class {
3627
- constructor(view) {
3628
- this.decorations = buildDecorations6(view);
3629
- }
3630
- update(update2) {
3631
- if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
3632
- this.decorations = buildDecorations6(update2.view);
3633
- }
3634
- }
3635
- }, {
3636
- decorations: (value) => value.decorations
3637
- }),
3638
- styles6
3639
- ];
3640
- };
3641
-
3642
3455
  // packages/ui/react-ui-editor/src/extensions/mention.ts
3643
3456
  import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
3644
3457
  var mention = ({ onSearch }) => {
@@ -4036,7 +3849,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
4036
3849
  selection,
4037
3850
  extensions: [
4038
3851
  // TODO(burdon): Doesn't catch errors in keymap functions.
4039
- EditorView16.exceptionSink.of((err) => {
3852
+ EditorView14.exceptionSink.of((err) => {
4040
3853
  log3.catch(err, void 0, {
4041
3854
  F: __dxlog_file4,
4042
3855
  L: 113,
@@ -4046,17 +3859,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
4046
3859
  }),
4047
3860
  // Theme.
4048
3861
  // TODO(burdon): Make configurable.
4049
- EditorView16.baseTheme(defaultTheme),
4050
- EditorView16.theme(theme ?? {}),
4051
- EditorView16.darkTheme.of(themeMode === "dark"),
4052
- EditorView16.editorAttributes.of({
3862
+ EditorView14.baseTheme(defaultTheme),
3863
+ EditorView14.theme(theme ?? {}),
3864
+ EditorView14.darkTheme.of(themeMode === "dark"),
3865
+ EditorView14.editorAttributes.of({
4053
3866
  class: slots.editor?.className ?? ""
4054
3867
  }),
4055
- EditorView16.contentAttributes.of({
3868
+ EditorView14.contentAttributes.of({
4056
3869
  class: slots.content?.className ?? ""
4057
3870
  }),
4058
3871
  // Focus.
4059
- EditorView16.updateListener.of((update2) => {
3872
+ EditorView14.updateListener.of((update2) => {
4060
3873
  update2.transactions.forEach((transaction) => {
4061
3874
  if (transaction.isUserEvent("focus.container")) {
4062
3875
  rootRef.current?.focus();
@@ -4064,7 +3877,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
4064
3877
  });
4065
3878
  }),
4066
3879
  // State.
4067
- EditorView16.editable.of(!readonly),
3880
+ EditorView14.editable.of(!readonly),
4068
3881
  EditorState2.readOnly.of(!!readonly),
4069
3882
  // Storage and replication.
4070
3883
  // NOTE: This must come before user extensions.
@@ -4073,7 +3886,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
4073
3886
  ...extensions
4074
3887
  ].filter(isNotFalsy4)
4075
3888
  });
4076
- const newView = new EditorView16({
3889
+ const newView = new EditorView14({
4077
3890
  state,
4078
3891
  parent: rootRef.current,
4079
3892
  scrollTo,
@@ -4190,32 +4003,12 @@ var defaultMarkdownSlots = {
4190
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";
4191
4004
  import { createContext } from "@radix-ui/react-context";
4192
4005
  import React2 from "react";
4193
- 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";
4194
4007
  import { getSize } from "@dxos/react-ui-theme";
4195
-
4196
- // packages/ui/react-ui-editor/src/translations.ts
4197
- var translationKey = "react-ui-editor";
4198
- var translations_default = [
4199
- {
4200
- "en-US": {
4201
- [translationKey]: {
4202
- "strong label": "Strong",
4203
- "emphasis label": "Emphasis",
4204
- "strikethrough label": "Strike-through",
4205
- "code label": "Code",
4206
- "list-bullet label": "Bullet list",
4207
- "list-ordered label": "Numbered list",
4208
- "list-task label": "Task list",
4209
- "blockquote label": "Block quote",
4210
- "codeblock label": "Code block",
4211
- "comment label": "Create comment",
4212
- "heading label": "Heading level"
4213
- }
4214
- }
4215
- }
4216
- ];
4217
-
4218
- // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
4008
+ var tooltipProps = {
4009
+ side: "top",
4010
+ classNames: "z-10"
4011
+ };
4219
4012
  var HeadingIcons = {
4220
4013
  "0": Paragraph,
4221
4014
  "1": TextHOne,
@@ -4244,7 +4037,9 @@ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
4244
4037
  var buttonStyles = "min-bs-0 p-2";
4245
4038
  var iconStyles = getSize(5);
4246
4039
  var ToolbarButton = ({ Icon, children, ...props }) => {
4247
- 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, {
4248
4043
  variant: "ghost",
4249
4044
  ...props,
4250
4045
  classNames: buttonStyles
@@ -4252,7 +4047,7 @@ var ToolbarButton = ({ Icon, children, ...props }) => {
4252
4047
  className: iconStyles
4253
4048
  }), /* @__PURE__ */ React2.createElement("span", {
4254
4049
  className: "sr-only"
4255
- }, children));
4050
+ }, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4256
4051
  };
4257
4052
  var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
4258
4053
  role: "separator",
@@ -4265,13 +4060,15 @@ var MarkdownHeading = () => {
4265
4060
  const header = blockType && /heading(\d)/.exec(blockType);
4266
4061
  const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
4267
4062
  const HeadingIcon = HeadingIcons[value ?? "0"];
4268
- return /* @__PURE__ */ React2.createElement(Select.Root, {
4063
+ return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Select.Root, {
4269
4064
  disabled: value === null,
4270
4065
  value: value ?? "0",
4271
4066
  onValueChange: (value2) => onAction?.({
4272
4067
  type: "heading",
4273
4068
  data: parseInt(value2)
4274
4069
  })
4070
+ }, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4071
+ asChild: true
4275
4072
  }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4276
4073
  asChild: true
4277
4074
  }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
@@ -4281,7 +4078,7 @@ var MarkdownHeading = () => {
4281
4078
  className: "sr-only"
4282
4079
  }, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
4283
4080
  className: iconStyles
4284
- }))), /* @__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, {
4285
4082
  value: "0"
4286
4083
  }, /* @__PURE__ */ React2.createElement(Paragraph, {
4287
4084
  className: iconStyles
@@ -4307,7 +4104,7 @@ var MarkdownHeading = () => {
4307
4104
  className: iconStyles
4308
4105
  }), level === 6 && /* @__PURE__ */ React2.createElement(TextHSix, {
4309
4106
  className: iconStyles
4310
- })))), /* @__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))));
4311
4108
  };
4312
4109
  var markdownStyles = [
4313
4110
  {
@@ -4426,7 +4223,9 @@ var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragmen
4426
4223
  var MarkdownExtended = () => {
4427
4224
  const { onAction } = useToolbarContext("MarkdownStyles");
4428
4225
  const { t } = useTranslation(translationKey);
4429
- 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, {
4430
4229
  variant: "ghost",
4431
4230
  "data-testid": "editor.toolbar.comment",
4432
4231
  onClick: () => onAction?.({
@@ -4437,7 +4236,7 @@ var MarkdownExtended = () => {
4437
4236
  className: iconStyles
4438
4237
  }), /* @__PURE__ */ React2.createElement("span", {
4439
4238
  className: "sr-only"
4440
- }, 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))));
4441
4240
  };
4442
4241
  var Toolbar = {
4443
4242
  Root: ToolbarRoot,
@@ -4628,7 +4427,7 @@ var useEditorView = (id) => {
4628
4427
 
4629
4428
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
4630
4429
  import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
4631
- import { EditorView as EditorView17 } from "@codemirror/view";
4430
+ import { EditorView as EditorView15 } from "@codemirror/view";
4632
4431
  import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
4633
4432
  import { log as log5 } from "@dxos/log";
4634
4433
  import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
@@ -4645,7 +4444,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4645
4444
  selection,
4646
4445
  extensions: [
4647
4446
  // TODO(burdon): Doesn't catch errors in keymap functions.
4648
- EditorView17.exceptionSink.of((err) => {
4447
+ EditorView15.exceptionSink.of((err) => {
4649
4448
  log5.catch(err, void 0, {
4650
4449
  F: __dxlog_file6,
4651
4450
  L: 60,
@@ -4654,12 +4453,12 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4654
4453
  });
4655
4454
  }),
4656
4455
  extensions,
4657
- EditorView17.updateListener.of(() => {
4456
+ EditorView15.updateListener.of(() => {
4658
4457
  onUpdate.current?.();
4659
4458
  })
4660
4459
  ].filter(isNotFalsy5)
4661
4460
  });
4662
- view2 = new EditorView17({
4461
+ view2 = new EditorView15({
4663
4462
  parent: parentRef.current,
4664
4463
  scrollTo,
4665
4464
  state,
@@ -4717,19 +4516,19 @@ var createDataExtensions = ({ readonly = false } = {}) => {
4717
4516
  return [
4718
4517
  //
4719
4518
  EditorState3.readOnly.of(readonly),
4720
- EditorView17.editable.of(!readonly)
4519
+ EditorView15.editable.of(!readonly)
4721
4520
  ];
4722
4521
  };
4723
4522
  var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
4724
4523
  return [
4725
4524
  //
4726
- EditorView17.baseTheme(defaultTheme),
4727
- theme && EditorView17.theme(theme),
4728
- EditorView17.darkTheme.of(themeMode === "dark"),
4729
- EditorView17.editorAttributes.of({
4525
+ EditorView15.baseTheme(defaultTheme),
4526
+ theme && EditorView15.theme(theme),
4527
+ EditorView15.darkTheme.of(themeMode === "dark"),
4528
+ EditorView15.editorAttributes.of({
4730
4529
  class: slots?.editor?.className ?? ""
4731
4530
  }),
4732
- EditorView17.contentAttributes.of({
4531
+ EditorView15.contentAttributes.of({
4733
4532
  class: slots?.content?.className ?? ""
4734
4533
  })
4735
4534
  ].filter(isNotFalsy5);
@@ -4829,7 +4628,6 @@ export {
4829
4628
  awarenessProvider,
4830
4629
  blast,
4831
4630
  callbackWrapper,
4832
- code2 as code,
4833
4631
  codeTheme,
4834
4632
  comments,
4835
4633
  compareFormatting,
@@ -4840,6 +4638,7 @@ export {
4840
4638
  createThemeExtensions,
4841
4639
  cursorLineMargin,
4842
4640
  cursorLineMarginFacet,
4641
+ decorateMarkdown,
4843
4642
  defaultMarkdownSlots,
4844
4643
  defaultOptions,
4845
4644
  defaultSlots,
@@ -4854,12 +4653,10 @@ export {
4854
4653
  formatting,
4855
4654
  getFormatting,
4856
4655
  getToken,
4857
- heading2 as heading,
4858
- hr,
4859
4656
  image,
4860
4657
  insertTable,
4861
4658
  keymap8 as keymap,
4862
- link,
4659
+ linkTooltip,
4863
4660
  listener,
4864
4661
  logChanges,
4865
4662
  markdownHighlightStyle,
@@ -4881,7 +4678,6 @@ export {
4881
4678
  setStyle,
4882
4679
  table,
4883
4680
  tags2 as tags,
4884
- tasklist,
4885
4681
  textTheme,
4886
4682
  toggleBlockquote,
4887
4683
  toggleCodeblock,
@@ -4891,6 +4687,7 @@ export {
4891
4687
  toggleStrikethrough,
4892
4688
  toggleStrong,
4893
4689
  toggleStyle,
4690
+ translations_default as translations,
4894
4691
  typewriter,
4895
4692
  useActionHandler,
4896
4693
  useComments,