@dxos/react-ui-editor 0.3.9-main.35264cb → 0.3.9-main.35e0812

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 (35) hide show
  1. package/dist/lib/browser/index.mjs +88 -183
  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/Editor/Editor.d.ts +1 -0
  5. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
  6. package/dist/types/src/components/Markdown/Markdown.d.ts +1 -2
  7. package/dist/types/src/components/Markdown/Markdown.d.ts.map +1 -1
  8. package/dist/types/src/components/Markdown/Markdown.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/Markdown/markdownTheme.d.ts +1 -8
  10. package/dist/types/src/components/Markdown/markdownTheme.d.ts.map +1 -1
  11. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  12. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +15 -0
  13. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  14. package/dist/types/src/components/TextEditor/extensions/{hyperlinkWidget.d.ts → hyperlink.d.ts} +3 -3
  15. package/dist/types/src/components/TextEditor/extensions/hyperlink.d.ts.map +1 -0
  16. package/dist/types/src/components/TextEditor/extensions/hyperlinkTooltip.d.ts.map +1 -1
  17. package/dist/types/src/components/TextEditor/extensions/index.d.ts +1 -2
  18. package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
  19. package/dist/types/src/components/TextEditor/theme.d.ts +0 -1
  20. package/dist/types/src/components/TextEditor/theme.d.ts.map +1 -1
  21. package/package.json +17 -17
  22. package/src/components/Editor/Editor.tsx +1 -4
  23. package/src/components/Markdown/Markdown.stories.tsx +1 -12
  24. package/src/components/Markdown/Markdown.tsx +22 -47
  25. package/src/components/Markdown/markdownTheme.ts +1 -12
  26. package/src/components/TextEditor/TextEditor.stories.tsx +64 -39
  27. package/src/components/TextEditor/TextEditor.tsx +0 -1
  28. package/src/components/TextEditor/extensions/{hyperlinkWidget.tsx → hyperlink.tsx} +10 -21
  29. package/src/components/TextEditor/extensions/hyperlinkTooltip.tsx +0 -1
  30. package/src/components/TextEditor/extensions/index.ts +1 -2
  31. package/src/components/TextEditor/theme.ts +4 -6
  32. package/dist/types/src/components/TextEditor/extensions/hyperlinkDecoration.d.ts +0 -11
  33. package/dist/types/src/components/TextEditor/extensions/hyperlinkDecoration.d.ts.map +0 -1
  34. package/dist/types/src/components/TextEditor/extensions/hyperlinkWidget.d.ts.map +0 -1
  35. package/src/components/TextEditor/extensions/hyperlinkDecoration.ts +0 -99
@@ -397,13 +397,6 @@ var markdownTheme = {
397
397
  "& .cm-yLineSelection": {
398
398
  margin: "0"
399
399
  },
400
- ".cm-link": {
401
- color: "rgb(20 89 208)",
402
- textDecorationLine: "underline",
403
- textDecorationThickness: "1px",
404
- textUnderlineOffset: "2px",
405
- borderRadius: ".125rem"
406
- },
407
400
  ...Object.keys(get(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
408
401
  const height = get(tokens, [
409
402
  "extend",
@@ -424,7 +417,7 @@ var markdownTheme = {
424
417
  return acc;
425
418
  }, {})
426
419
  };
427
- var markdownHighlightStyle = HighlightStyle.define([
420
+ var markdownDarkHighlighting = HighlightStyle.define([
428
421
  {
429
422
  tag: [
430
423
  tags.keyword,
@@ -601,56 +594,49 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ model, slots = {}, editorMode
601
594
  const state2 = EditorState.create({
602
595
  doc: content?.toString(),
603
596
  extensions: [
604
- // Based on https://github.com/codemirror/dev/issues/44#issuecomment-789093799
597
+ // Based on https://github.com/codemirror/dev/issues/44#issuecomment-789093799.
605
598
  listenChangesExtension,
606
- // TODO(burdon): Create custom bundle to make this class more reusable and retire simpler TextEditor component.
599
+ ...editorMode === "vim" ? [
600
+ vim()
601
+ ] : [],
607
602
  // All of https://github.com/codemirror/basic-setup minus line numbers and fold gutter.
608
- // https://codemirror.net/docs/ref/#codemirror.basicSetup
609
- autocompletion(),
610
- bracketMatching(),
611
- closeBrackets(),
612
- crosshairCursor(),
613
- dropCursor(),
614
- drawSelection(),
615
- highlightActiveLine(),
616
603
  highlightActiveLineGutter(),
617
- highlightSelectionMatches(),
618
604
  highlightSpecialChars(),
619
605
  history(),
606
+ drawSelection(),
607
+ dropCursor(),
608
+ EditorState.allowMultipleSelections.of(true),
620
609
  indentOnInput(),
621
- placeholder(slots.editor?.placeholder ?? ""),
622
- rectangularSelection(),
623
610
  syntaxHighlighting(defaultHighlightStyle, {
624
611
  fallback: true
625
612
  }),
626
- EditorState.allowMultipleSelections.of(true),
627
- EditorView.lineWrapping,
613
+ bracketMatching(),
614
+ closeBrackets(),
615
+ autocompletion(),
616
+ rectangularSelection(),
617
+ crosshairCursor(),
618
+ highlightActiveLine(),
619
+ highlightSelectionMatches(),
620
+ placeholder(slots.editor?.placeholder ?? ""),
628
621
  keymap.of([
629
622
  ...closeBracketsKeymap,
630
- ...completionKeymap,
631
623
  ...defaultKeymap,
632
- ...foldKeymap,
624
+ ...searchKeymap,
633
625
  ...historyKeymap,
626
+ ...foldKeymap,
627
+ ...completionKeymap,
634
628
  ...lintKeymap,
635
- ...searchKeymap,
636
629
  indentWithTab
637
630
  ]),
638
- // Main extension.
639
- // https://github.com/codemirror/lang-markdown
631
+ EditorView.lineWrapping,
632
+ // Themes.
640
633
  markdown({
641
634
  base: markdownLanguage2,
642
635
  codeLanguages: languages,
643
636
  extensions: [
644
- // TODO(burdon): This seems to upgrade the parser.
645
- // GitHub flavored markdown bundle: Table, TaskList, Strikethrough, and Autolink.
646
- // https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
647
- // https://github.github.com/gfm
648
- // GFM,
649
- // Custom styling.
650
637
  markdownTagsExtension
651
638
  ]
652
639
  }),
653
- // Theme.
654
640
  EditorView.theme({
655
641
  ...markdownTheme,
656
642
  ...slots.editor?.markdownTheme
@@ -661,14 +647,8 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ model, slots = {}, editorMode
661
647
  syntaxHighlighting(defaultHighlightStyle)
662
648
  ],
663
649
  // TODO(thure): All but one rule here apply to both themes; rename or refactor.
664
- syntaxHighlighting(markdownHighlightStyle),
665
- // Settings.
666
- ...editorMode === "vim" ? [
667
- vim()
668
- ] : [],
669
- // TODO(burdon): Move to extensions.
650
+ syntaxHighlighting(markdownDarkHighlighting),
670
651
  // Replication and awareness (incl. remote selection).
671
- // https://codemirror.net/docs/ref/#collab
672
652
  ...content instanceof YText ? [
673
653
  yCollab(content, provider?.awareness)
674
654
  ] : [],
@@ -870,9 +850,6 @@ var RichTextEditor = /* @__PURE__ */ forwardRef2((props, ref) => {
870
850
  // packages/ui/react-ui-editor/src/components/Editor/Editor.tsx
871
851
  var Editor = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef3(({ slots, ...params }, forwardedRef) => {
872
852
  const model = useTextModel(params);
873
- if (!model) {
874
- return null;
875
- }
876
853
  if (model?.content instanceof YXmlFragment) {
877
854
  return /* @__PURE__ */ React3.createElement(RichTextEditor, {
878
855
  ref: forwardedRef,
@@ -910,17 +887,16 @@ var defaultStyles = {
910
887
  "&.cm-focused": {
911
888
  outline: "none"
912
889
  },
913
- ".cm-scroller": {
890
+ ".cm-placeholder": {
891
+ fontFamily: get2(tokens2, "fontFamily.body", []).join(",")
892
+ },
893
+ "& .cm-scroller": {
914
894
  fontFamily: get2(tokens2, "fontFamily.body", []).join(","),
915
895
  overflow: "visible"
916
896
  },
917
897
  ".cm-tooltip": {
918
898
  backgroundColor: "transparent",
919
899
  border: "none"
920
- },
921
- ".cm-link": {
922
- color: get2(tokens2, "extend.colors.primary.500"),
923
- textDecoration: "underline"
924
900
  }
925
901
  };
926
902
 
@@ -960,7 +936,6 @@ var TextEditor = /* @__PURE__ */ forwardRef4(({ model, extensions = [], theme =
960
936
  syntaxHighlighting2(defaultHighlightStyle2)
961
937
  ],
962
938
  // Replication.
963
- // TODO(burdon): Move to default extensions.
964
939
  ...content instanceof YText2 ? [
965
940
  yCollab2(content, void 0)
966
941
  ] : [],
@@ -1008,117 +983,11 @@ var TextEditor = /* @__PURE__ */ forwardRef4(({ model, extensions = [], theme =
1008
983
  });
1009
984
  });
1010
985
 
1011
- // packages/ui/react-ui-editor/src/components/TextEditor/extensions/hyperlinkDecoration.ts
1012
- import { syntaxTree } from "@codemirror/language";
1013
- import { RangeSetBuilder, StateField as StateField2 } from "@codemirror/state";
1014
- import { Decoration, EditorView as EditorView3, WidgetType } from "@codemirror/view";
1015
- var Link = class extends WidgetType {
1016
- constructor(_anchor, _text, _url) {
1017
- super();
1018
- this._anchor = _anchor;
1019
- this._text = _text;
1020
- this._url = _url;
1021
- }
1022
- eq(other) {
1023
- return this._text === other.text && this._url === other.url;
1024
- }
1025
- toDOM(view) {
1026
- const link = document.createElement("a");
1027
- link.setAttribute("class", "cm-link");
1028
- link.textContent = this._text;
1029
- if (this._url) {
1030
- link.setAttribute("target", "_blank");
1031
- link.href = this._url;
1032
- } else {
1033
- link.onclick = () => {
1034
- view.dispatch({
1035
- selection: {
1036
- anchor: this._anchor
1037
- }
1038
- });
1039
- };
1040
- }
1041
- return link;
1042
- }
1043
- };
1044
- var hyperlinkDecoration = ({ link } = {}) => {
1045
- return StateField2.define({
1046
- create: (state) => update(state, link),
1047
- update: (_, tr) => update(tr.state, link),
1048
- provide: (field) => EditorView3.decorations.from(field)
1049
- });
1050
- };
1051
- var update = (state, link) => {
1052
- const builder = new RangeSetBuilder();
1053
- const cursor2 = state.selection.main.head;
1054
- syntaxTree(state).iterate({
1055
- enter: (node) => {
1056
- if (cursor2 < node.from || cursor2 > node.to) {
1057
- if (node.name === "Link") {
1058
- const marks = node.node.getChildren("LinkMark");
1059
- const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
1060
- const urlNode = node.node.getChild("URL");
1061
- const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
1062
- builder.add(node.from, node.to, Decoration.replace({
1063
- widget: new Link(node.from, text, link ? url : void 0)
1064
- }));
1065
- return false;
1066
- }
1067
- }
1068
- return true;
1069
- }
1070
- });
1071
- return builder.finish();
1072
- };
1073
-
1074
- // packages/ui/react-ui-editor/src/components/TextEditor/extensions/hyperlinkTooltip.tsx
1075
- import { hoverTooltip } from "@codemirror/view";
1076
- import { tooltipContent } from "@dxos/react-ui-theme";
1077
- var markdownLinkRegexp = /\[([^\]]+)]\(([^)]+)\)/;
1078
- var createHyperlinkTooltip = (onHover, regexp = markdownLinkRegexp) => hoverTooltip((view, pos) => {
1079
- const { from, text } = view.state.doc.lineAt(pos);
1080
- const p = pos - from;
1081
- let idx = 0;
1082
- let match;
1083
- do {
1084
- match = text.substring(idx).match(regexp);
1085
- if (!match) {
1086
- match = void 0;
1087
- break;
1088
- }
1089
- idx = text.indexOf(match[0]);
1090
- if (p >= idx && p < idx + match[0].length) {
1091
- break;
1092
- }
1093
- idx += match[0].length;
1094
- } while (true);
1095
- if (!match) {
1096
- return null;
1097
- }
1098
- const [, , url] = match ?? [];
1099
- return {
1100
- pos: idx + from,
1101
- end: idx + from + match[0].length,
1102
- above: true,
1103
- create: () => {
1104
- const el = document.createElement("a");
1105
- el.innerText = "_";
1106
- el.className = tooltipContent({}, "mb-2 p-1");
1107
- el.setAttribute("target", "_blank");
1108
- el.setAttribute("href", url);
1109
- onHover(el, url);
1110
- return {
1111
- dom: el
1112
- };
1113
- }
1114
- };
1115
- });
1116
-
1117
- // packages/ui/react-ui-editor/src/components/TextEditor/extensions/hyperlinkWidget.tsx
1118
- import { Decoration as Decoration2, EditorView as EditorView4, MatchDecorator, ViewPlugin } from "@codemirror/view";
1119
- var markdownLinkRegexp2 = /\[([^\]]+)]\(([^)]+)\)(!?)/gi;
986
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/hyperlink.tsx
987
+ import { Decoration, EditorView as EditorView3, MatchDecorator, ViewPlugin } from "@codemirror/view";
988
+ var markdownLinkRegexp = /\[([^\]]+)]\(([^)]+)\)(!?)/gi;
1120
989
  var linkDecorator = () => new MatchDecorator({
1121
- regexp: markdownLinkRegexp2,
990
+ regexp: markdownLinkRegexp,
1122
991
  decorate: (add, from, to, match, view) => {
1123
992
  const [_, label, url] = match;
1124
993
  const p0 = {
@@ -1137,24 +1006,18 @@ var linkDecorator = () => new MatchDecorator({
1137
1006
  start: p1.end + 1,
1138
1007
  end: p1.end + 1 + url.length + 2
1139
1008
  };
1140
- add(p0.start, p0.end, Decoration2.mark({
1141
- class: "cm-hyperlink-bracket",
1142
- _attributes: {
1143
- style: "display: none"
1144
- }
1009
+ add(p0.start, p0.end, Decoration.mark({
1010
+ class: "cm-hyperlink-bracket"
1145
1011
  }));
1146
- add(p1.start, p1.end, Decoration2.mark({
1012
+ add(p1.start, p1.end, Decoration.mark({
1147
1013
  class: "cm-hyperlink-label"
1148
1014
  }));
1149
- add(p2.start, p2.end, Decoration2.mark({
1150
- class: "cm-hyperlink-bracket",
1151
- _attributes: {
1152
- style: "display: none"
1153
- }
1015
+ add(p2.start, p2.end, Decoration.mark({
1016
+ class: "cm-hyperlink-bracket"
1154
1017
  }));
1155
- add(p3.start, p3.end, Decoration2.mark({
1018
+ add(p3.start, p3.end, Decoration.mark({
1156
1019
  class: "cm-hyperlink-url",
1157
- _attributes: {
1020
+ __attributes: {
1158
1021
  style: "display: none"
1159
1022
  }
1160
1023
  }));
@@ -1166,9 +1029,9 @@ function hyperLinkExtension() {
1166
1029
  this.decorator = linkDecorator();
1167
1030
  this.decorations = this.decorator.createDeco(view);
1168
1031
  }
1169
- update(update2) {
1170
- if (update2.docChanged || update2.viewportChanged) {
1171
- this.decorations = this.decorator.updateDeco(update2, this.decorations);
1032
+ update(update) {
1033
+ if (update.docChanged || update.viewportChanged) {
1034
+ this.decorations = this.decorator.updateDeco(update, this.decorations);
1172
1035
  }
1173
1036
  }
1174
1037
  }, {
@@ -1189,7 +1052,7 @@ function hyperLinkExtension() {
1189
1052
  }
1190
1053
  });
1191
1054
  }
1192
- var hyperlinkStyle = EditorView4.baseTheme({
1055
+ var hyperLinkStyle = EditorView3.baseTheme({
1193
1056
  ".cm-hyperlink-label": {
1194
1057
  cursor: "pointer",
1195
1058
  textDecoration: "underline"
@@ -1202,11 +1065,54 @@ var hyperlinkStyle = EditorView4.baseTheme({
1202
1065
  fontFamily: "monospace"
1203
1066
  }
1204
1067
  });
1205
- var hyperlinkWidget = [
1068
+ var hyperlink = [
1206
1069
  hyperLinkExtension(),
1207
- hyperlinkStyle
1070
+ hyperLinkStyle
1208
1071
  ];
1209
1072
 
1073
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/hyperlinkTooltip.tsx
1074
+ import { hoverTooltip } from "@codemirror/view";
1075
+ import { tooltipContent } from "@dxos/react-ui-theme";
1076
+ var markdownLinkRegexp2 = /\[([^\]]+)]\(([^)]+)\)/;
1077
+ var createHyperlinkTooltip = (onHover, regexp = markdownLinkRegexp2) => hoverTooltip((view, pos) => {
1078
+ const { from, text } = view.state.doc.lineAt(pos);
1079
+ const p = pos - from;
1080
+ let idx = 0;
1081
+ let match;
1082
+ do {
1083
+ match = text.substring(idx).match(regexp);
1084
+ if (!match) {
1085
+ match = void 0;
1086
+ break;
1087
+ }
1088
+ idx = text.indexOf(match[0]);
1089
+ if (p >= idx && p < idx + match[0].length) {
1090
+ break;
1091
+ }
1092
+ idx += match[0].length;
1093
+ } while (true);
1094
+ if (!match) {
1095
+ return null;
1096
+ }
1097
+ const [, , url] = match ?? [];
1098
+ return {
1099
+ pos: idx + from,
1100
+ end: idx + from + match[0].length,
1101
+ above: true,
1102
+ create: () => {
1103
+ const el = document.createElement("a");
1104
+ el.innerText = "_";
1105
+ el.className = tooltipContent({}, "mb-2 p-1");
1106
+ el.setAttribute("target", "_blank");
1107
+ el.setAttribute("href", url);
1108
+ onHover(el, url);
1109
+ return {
1110
+ dom: el
1111
+ };
1112
+ }
1113
+ };
1114
+ });
1115
+
1210
1116
  // packages/ui/react-ui-editor/src/index.ts
1211
1117
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
1212
1118
  import { Doc, YText as YText3, YXmlFragment as YXmlFragment2 } from "@dxos/text-model";
@@ -1223,9 +1129,8 @@ export {
1223
1129
  createHyperlinkTooltip,
1224
1130
  defaultStyles,
1225
1131
  hyperLinkExtension,
1226
- hyperlinkDecoration,
1227
- hyperlinkStyle,
1228
- hyperlinkWidget,
1132
+ hyperLinkStyle,
1133
+ hyperlink,
1229
1134
  tags2 as tags,
1230
1135
  useTextModel
1231
1136
  };