@dxos/react-ui-editor 0.3.9-main.f8fc6b9 → 0.3.9-next.35264cb
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.
- package/dist/lib/browser/index.mjs +284 -48
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/Editor/Editor.d.ts +0 -1
- package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
- package/dist/types/src/components/Editor/Editor.stories.d.ts +3 -2
- package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Markdown/Markdown.d.ts +4 -2
- package/dist/types/src/components/Markdown/Markdown.d.ts.map +1 -1
- package/dist/types/src/components/Markdown/Markdown.stories.d.ts +2 -1
- package/dist/types/src/components/Markdown/Markdown.stories.d.ts.map +1 -1
- package/dist/types/src/components/Markdown/markdownTheme.d.ts +10 -17
- package/dist/types/src/components/Markdown/markdownTheme.d.ts.map +1 -1
- package/dist/types/src/components/RichText/RichText.stories.d.ts +2 -1
- package/dist/types/src/components/RichText/RichText.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -0
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/hyperlinkDecoration.d.ts +11 -0
- package/dist/types/src/components/TextEditor/extensions/hyperlinkDecoration.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/hyperlinkTooltip.d.ts +8 -0
- package/dist/types/src/components/TextEditor/extensions/hyperlinkTooltip.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/hyperlinkWidget.d.ts +10 -0
- package/dist/types/src/components/TextEditor/extensions/hyperlinkWidget.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts +4 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/index.d.ts +1 -0
- package/dist/types/src/components/TextEditor/index.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/theme.d.ts +1 -0
- package/dist/types/src/components/TextEditor/theme.d.ts.map +1 -1
- package/package.json +19 -16
- package/src/components/Editor/Editor.stories.tsx +2 -0
- package/src/components/Editor/Editor.tsx +4 -1
- package/src/components/Markdown/Markdown.stories.tsx +14 -1
- package/src/components/Markdown/Markdown.tsx +53 -24
- package/src/components/Markdown/markdownTheme.ts +32 -17
- package/src/components/RichText/RichText.stories.tsx +2 -0
- package/src/components/TextEditor/TextEditor.stories.tsx +47 -6
- package/src/components/TextEditor/TextEditor.tsx +1 -0
- package/src/components/TextEditor/extensions/hyperlinkDecoration.ts +99 -0
- package/src/components/TextEditor/extensions/hyperlinkTooltip.tsx +61 -0
- package/src/components/TextEditor/extensions/hyperlinkWidget.tsx +119 -0
- package/src/components/TextEditor/extensions/index.ts +7 -0
- package/src/components/TextEditor/index.ts +2 -0
- package/src/components/TextEditor/theme.ts +10 -4
|
@@ -261,10 +261,7 @@ import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
|
261
261
|
var tokens = tailwindConfig({}).theme;
|
|
262
262
|
|
|
263
263
|
// packages/ui/react-ui-editor/src/components/Markdown/markdownTheme.ts
|
|
264
|
-
var ivory = "#abb2bf";
|
|
265
264
|
var malibu = "#61afef";
|
|
266
|
-
var highlightBackground = "#2c313a";
|
|
267
|
-
var tooltipBackground = "#353a42";
|
|
268
265
|
var cursor = "#ffffff";
|
|
269
266
|
var monospace = get(tokens, "fontFamily.mono", [
|
|
270
267
|
"monospace"
|
|
@@ -307,24 +304,28 @@ var markdownTheme = {
|
|
|
307
304
|
// border: 'none',
|
|
308
305
|
// color: '#ddd'
|
|
309
306
|
// },
|
|
310
|
-
".
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
},
|
|
314
|
-
".dark & .cm-tooltip .cm-tooltip-arrow:before": {
|
|
315
|
-
borderTopColor: "transparent",
|
|
316
|
-
borderBottomColor: "transparent"
|
|
317
|
-
},
|
|
318
|
-
".dark & .cm-tooltip .cm-tooltip-arrow:after": {
|
|
319
|
-
borderTopColor: tooltipBackground,
|
|
320
|
-
borderBottomColor: tooltipBackground
|
|
321
|
-
},
|
|
322
|
-
".dark & .cm-tooltip-autocomplete": {
|
|
323
|
-
"& > ul > li[aria-selected]": {
|
|
324
|
-
backgroundColor: highlightBackground,
|
|
325
|
-
color: ivory
|
|
326
|
-
}
|
|
307
|
+
".cm-tooltip": {
|
|
308
|
+
backgroundColor: "transparent",
|
|
309
|
+
border: "none"
|
|
327
310
|
},
|
|
311
|
+
// '.dark & .cm-tooltip': {
|
|
312
|
+
// border: 'none',
|
|
313
|
+
// backgroundColor: tooltipBackground,
|
|
314
|
+
// },
|
|
315
|
+
// '.dark & .cm-tooltip .cm-tooltip-arrow:before': {
|
|
316
|
+
// borderTopColor: 'transparent',
|
|
317
|
+
// borderBottomColor: 'transparent',
|
|
318
|
+
// },
|
|
319
|
+
// '.dark & .cm-tooltip .cm-tooltip-arrow:after': {
|
|
320
|
+
// borderTopColor: tooltipBackground,
|
|
321
|
+
// borderBottomColor: tooltipBackground,
|
|
322
|
+
// },
|
|
323
|
+
// '.dark & .cm-tooltip-autocomplete': {
|
|
324
|
+
// '& > ul > li[aria-selected]': {
|
|
325
|
+
// backgroundColor: highlightBackground,
|
|
326
|
+
// color: ivory,
|
|
327
|
+
// },
|
|
328
|
+
// },
|
|
328
329
|
"&.cm-focused": {
|
|
329
330
|
outline: "none"
|
|
330
331
|
},
|
|
@@ -396,6 +397,13 @@ var markdownTheme = {
|
|
|
396
397
|
"& .cm-yLineSelection": {
|
|
397
398
|
margin: "0"
|
|
398
399
|
},
|
|
400
|
+
".cm-link": {
|
|
401
|
+
color: "rgb(20 89 208)",
|
|
402
|
+
textDecorationLine: "underline",
|
|
403
|
+
textDecorationThickness: "1px",
|
|
404
|
+
textUnderlineOffset: "2px",
|
|
405
|
+
borderRadius: ".125rem"
|
|
406
|
+
},
|
|
399
407
|
...Object.keys(get(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
|
|
400
408
|
const height = get(tokens, [
|
|
401
409
|
"extend",
|
|
@@ -416,7 +424,7 @@ var markdownTheme = {
|
|
|
416
424
|
return acc;
|
|
417
425
|
}, {})
|
|
418
426
|
};
|
|
419
|
-
var
|
|
427
|
+
var markdownHighlightStyle = HighlightStyle.define([
|
|
420
428
|
{
|
|
421
429
|
tag: [
|
|
422
430
|
tags.keyword,
|
|
@@ -541,7 +549,7 @@ var EditorModes = [
|
|
|
541
549
|
"default",
|
|
542
550
|
"vim"
|
|
543
551
|
];
|
|
544
|
-
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ model, slots = {}, editorMode, onChange }, forwardedRef) => {
|
|
552
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ model, slots = {}, editorMode, extensions = [], onChange }, forwardedRef) => {
|
|
545
553
|
const { id, content, provider, peer } = model ?? {};
|
|
546
554
|
const { themeMode } = useThemeContext();
|
|
547
555
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
@@ -593,49 +601,56 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ model, slots = {}, editorMode
|
|
|
593
601
|
const state2 = EditorState.create({
|
|
594
602
|
doc: content?.toString(),
|
|
595
603
|
extensions: [
|
|
596
|
-
// Based on https://github.com/codemirror/dev/issues/44#issuecomment-789093799
|
|
604
|
+
// Based on https://github.com/codemirror/dev/issues/44#issuecomment-789093799
|
|
597
605
|
listenChangesExtension,
|
|
598
|
-
|
|
599
|
-
vim()
|
|
600
|
-
] : [],
|
|
606
|
+
// TODO(burdon): Create custom bundle to make this class more reusable and retire simpler TextEditor component.
|
|
601
607
|
// 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(),
|
|
602
616
|
highlightActiveLineGutter(),
|
|
617
|
+
highlightSelectionMatches(),
|
|
603
618
|
highlightSpecialChars(),
|
|
604
619
|
history(),
|
|
605
|
-
drawSelection(),
|
|
606
|
-
dropCursor(),
|
|
607
|
-
EditorState.allowMultipleSelections.of(true),
|
|
608
620
|
indentOnInput(),
|
|
621
|
+
placeholder(slots.editor?.placeholder ?? ""),
|
|
622
|
+
rectangularSelection(),
|
|
609
623
|
syntaxHighlighting(defaultHighlightStyle, {
|
|
610
624
|
fallback: true
|
|
611
625
|
}),
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
autocompletion(),
|
|
615
|
-
rectangularSelection(),
|
|
616
|
-
crosshairCursor(),
|
|
617
|
-
highlightActiveLine(),
|
|
618
|
-
highlightSelectionMatches(),
|
|
619
|
-
placeholder(slots.editor?.placeholder ?? ""),
|
|
626
|
+
EditorState.allowMultipleSelections.of(true),
|
|
627
|
+
EditorView.lineWrapping,
|
|
620
628
|
keymap.of([
|
|
621
629
|
...closeBracketsKeymap,
|
|
630
|
+
...completionKeymap,
|
|
622
631
|
...defaultKeymap,
|
|
623
|
-
...searchKeymap,
|
|
624
|
-
...historyKeymap,
|
|
625
632
|
...foldKeymap,
|
|
626
|
-
...
|
|
633
|
+
...historyKeymap,
|
|
627
634
|
...lintKeymap,
|
|
635
|
+
...searchKeymap,
|
|
628
636
|
indentWithTab
|
|
629
637
|
]),
|
|
630
|
-
|
|
631
|
-
//
|
|
638
|
+
// Main extension.
|
|
639
|
+
// https://github.com/codemirror/lang-markdown
|
|
632
640
|
markdown({
|
|
633
641
|
base: markdownLanguage2,
|
|
634
642
|
codeLanguages: languages,
|
|
635
643
|
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.
|
|
636
650
|
markdownTagsExtension
|
|
637
651
|
]
|
|
638
652
|
}),
|
|
653
|
+
// Theme.
|
|
639
654
|
EditorView.theme({
|
|
640
655
|
...markdownTheme,
|
|
641
656
|
...slots.editor?.markdownTheme
|
|
@@ -646,11 +661,19 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ model, slots = {}, editorMode
|
|
|
646
661
|
syntaxHighlighting(defaultHighlightStyle)
|
|
647
662
|
],
|
|
648
663
|
// TODO(thure): All but one rule here apply to both themes; rename or refactor.
|
|
649
|
-
syntaxHighlighting(
|
|
664
|
+
syntaxHighlighting(markdownHighlightStyle),
|
|
665
|
+
// Settings.
|
|
666
|
+
...editorMode === "vim" ? [
|
|
667
|
+
vim()
|
|
668
|
+
] : [],
|
|
669
|
+
// TODO(burdon): Move to extensions.
|
|
650
670
|
// Replication and awareness (incl. remote selection).
|
|
671
|
+
// https://codemirror.net/docs/ref/#collab
|
|
651
672
|
...content instanceof YText ? [
|
|
652
673
|
yCollab(content, provider?.awareness)
|
|
653
|
-
] : []
|
|
674
|
+
] : [],
|
|
675
|
+
// Custom.
|
|
676
|
+
...extensions
|
|
654
677
|
]
|
|
655
678
|
});
|
|
656
679
|
setState(state2);
|
|
@@ -847,6 +870,9 @@ var RichTextEditor = /* @__PURE__ */ forwardRef2((props, ref) => {
|
|
|
847
870
|
// packages/ui/react-ui-editor/src/components/Editor/Editor.tsx
|
|
848
871
|
var Editor = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef3(({ slots, ...params }, forwardedRef) => {
|
|
849
872
|
const model = useTextModel(params);
|
|
873
|
+
if (!model) {
|
|
874
|
+
return null;
|
|
875
|
+
}
|
|
850
876
|
if (model?.content instanceof YXmlFragment) {
|
|
851
877
|
return /* @__PURE__ */ React3.createElement(RichTextEditor, {
|
|
852
878
|
ref: forwardedRef,
|
|
@@ -884,12 +910,17 @@ var defaultStyles = {
|
|
|
884
910
|
"&.cm-focused": {
|
|
885
911
|
outline: "none"
|
|
886
912
|
},
|
|
887
|
-
".cm-
|
|
888
|
-
fontFamily: get2(tokens2, "fontFamily.body", []).join(",")
|
|
889
|
-
},
|
|
890
|
-
"& .cm-scroller": {
|
|
913
|
+
".cm-scroller": {
|
|
891
914
|
fontFamily: get2(tokens2, "fontFamily.body", []).join(","),
|
|
892
915
|
overflow: "visible"
|
|
916
|
+
},
|
|
917
|
+
".cm-tooltip": {
|
|
918
|
+
backgroundColor: "transparent",
|
|
919
|
+
border: "none"
|
|
920
|
+
},
|
|
921
|
+
".cm-link": {
|
|
922
|
+
color: get2(tokens2, "extend.colors.primary.500"),
|
|
923
|
+
textDecoration: "underline"
|
|
893
924
|
}
|
|
894
925
|
};
|
|
895
926
|
|
|
@@ -929,6 +960,7 @@ var TextEditor = /* @__PURE__ */ forwardRef4(({ model, extensions = [], theme =
|
|
|
929
960
|
syntaxHighlighting2(defaultHighlightStyle2)
|
|
930
961
|
],
|
|
931
962
|
// Replication.
|
|
963
|
+
// TODO(burdon): Move to default extensions.
|
|
932
964
|
...content instanceof YText2 ? [
|
|
933
965
|
yCollab2(content, void 0)
|
|
934
966
|
] : [],
|
|
@@ -976,6 +1008,205 @@ var TextEditor = /* @__PURE__ */ forwardRef4(({ model, extensions = [], theme =
|
|
|
976
1008
|
});
|
|
977
1009
|
});
|
|
978
1010
|
|
|
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;
|
|
1120
|
+
var linkDecorator = () => new MatchDecorator({
|
|
1121
|
+
regexp: markdownLinkRegexp2,
|
|
1122
|
+
decorate: (add, from, to, match, view) => {
|
|
1123
|
+
const [_, label, url] = match;
|
|
1124
|
+
const p0 = {
|
|
1125
|
+
start: from,
|
|
1126
|
+
end: from + 1
|
|
1127
|
+
};
|
|
1128
|
+
const p1 = {
|
|
1129
|
+
start: from + 1,
|
|
1130
|
+
end: from + 1 + label.length
|
|
1131
|
+
};
|
|
1132
|
+
const p2 = {
|
|
1133
|
+
start: p1.end,
|
|
1134
|
+
end: p1.end + 1
|
|
1135
|
+
};
|
|
1136
|
+
const p3 = {
|
|
1137
|
+
start: p1.end + 1,
|
|
1138
|
+
end: p1.end + 1 + url.length + 2
|
|
1139
|
+
};
|
|
1140
|
+
add(p0.start, p0.end, Decoration2.mark({
|
|
1141
|
+
class: "cm-hyperlink-bracket",
|
|
1142
|
+
_attributes: {
|
|
1143
|
+
style: "display: none"
|
|
1144
|
+
}
|
|
1145
|
+
}));
|
|
1146
|
+
add(p1.start, p1.end, Decoration2.mark({
|
|
1147
|
+
class: "cm-hyperlink-label"
|
|
1148
|
+
}));
|
|
1149
|
+
add(p2.start, p2.end, Decoration2.mark({
|
|
1150
|
+
class: "cm-hyperlink-bracket",
|
|
1151
|
+
_attributes: {
|
|
1152
|
+
style: "display: none"
|
|
1153
|
+
}
|
|
1154
|
+
}));
|
|
1155
|
+
add(p3.start, p3.end, Decoration2.mark({
|
|
1156
|
+
class: "cm-hyperlink-url",
|
|
1157
|
+
_attributes: {
|
|
1158
|
+
style: "display: none"
|
|
1159
|
+
}
|
|
1160
|
+
}));
|
|
1161
|
+
}
|
|
1162
|
+
});
|
|
1163
|
+
function hyperLinkExtension() {
|
|
1164
|
+
return ViewPlugin.fromClass(class HyperLinkView {
|
|
1165
|
+
constructor(view) {
|
|
1166
|
+
this.decorator = linkDecorator();
|
|
1167
|
+
this.decorations = this.decorator.createDeco(view);
|
|
1168
|
+
}
|
|
1169
|
+
update(update2) {
|
|
1170
|
+
if (update2.docChanged || update2.viewportChanged) {
|
|
1171
|
+
this.decorations = this.decorator.updateDeco(update2, this.decorations);
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}, {
|
|
1175
|
+
decorations: (view) => view.decorations,
|
|
1176
|
+
eventHandlers: {
|
|
1177
|
+
// TODO(burdon): CLick to expand link.
|
|
1178
|
+
// https://discuss.codemirror.net/t/decorator-iteration-on-click-event/4226/2
|
|
1179
|
+
mousedown: function(event, view) {
|
|
1180
|
+
const pos = view.posAtDOM(event.target);
|
|
1181
|
+
if (pos !== 0) {
|
|
1182
|
+
console.log(this);
|
|
1183
|
+
}
|
|
1184
|
+
},
|
|
1185
|
+
// TODO(burdon): Hide when cursor moves away.
|
|
1186
|
+
keydown: (event, view) => {
|
|
1187
|
+
view.update([]);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
var hyperlinkStyle = EditorView4.baseTheme({
|
|
1193
|
+
".cm-hyperlink-label": {
|
|
1194
|
+
cursor: "pointer",
|
|
1195
|
+
textDecoration: "underline"
|
|
1196
|
+
},
|
|
1197
|
+
".cm-hyperlink-bracket": {
|
|
1198
|
+
opacity: 0.2
|
|
1199
|
+
},
|
|
1200
|
+
".cm-hyperlink-url": {
|
|
1201
|
+
opacity: 0.5,
|
|
1202
|
+
fontFamily: "monospace"
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
var hyperlinkWidget = [
|
|
1206
|
+
hyperLinkExtension(),
|
|
1207
|
+
hyperlinkStyle
|
|
1208
|
+
];
|
|
1209
|
+
|
|
979
1210
|
// packages/ui/react-ui-editor/src/index.ts
|
|
980
1211
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
981
1212
|
import { Doc, YText as YText3, YXmlFragment as YXmlFragment2 } from "@dxos/text-model";
|
|
@@ -989,7 +1220,12 @@ export {
|
|
|
989
1220
|
TextKind,
|
|
990
1221
|
YText3 as YText,
|
|
991
1222
|
YXmlFragment2 as YXmlFragment,
|
|
1223
|
+
createHyperlinkTooltip,
|
|
992
1224
|
defaultStyles,
|
|
1225
|
+
hyperLinkExtension,
|
|
1226
|
+
hyperlinkDecoration,
|
|
1227
|
+
hyperlinkStyle,
|
|
1228
|
+
hyperlinkWidget,
|
|
993
1229
|
tags2 as tags,
|
|
994
1230
|
useTextModel
|
|
995
1231
|
};
|