@dxos/react-ui-editor 0.3.11-main.3f845e1 → 0.3.11-main.9bacd9f
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 +92 -87
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +0 -3
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +2 -2
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/index.d.ts +0 -1
- package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/link.d.ts +1 -0
- package/dist/types/src/components/TextEditor/extensions/link.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts +5 -4
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts.map +1 -1
- package/package.json +21 -21
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +10 -12
- package/src/components/TextEditor/TextEditor.tsx +4 -4
- package/src/components/TextEditor/extensions/comments.ts +2 -1
- package/src/components/TextEditor/extensions/index.ts +0 -1
- package/src/components/TextEditor/extensions/link.ts +66 -10
- package/src/components/TextEditor/extensions/listener.ts +25 -13
- package/dist/types/src/components/TextEditor/extensions/tooltip.d.ts +0 -12
- package/dist/types/src/components/TextEditor/extensions/tooltip.d.ts.map +0 -1
- package/src/components/TextEditor/extensions/tooltip.ts +0 -61
|
@@ -12,7 +12,11 @@ import {
|
|
|
12
12
|
StateField,
|
|
13
13
|
type Transaction,
|
|
14
14
|
} from '@codemirror/state';
|
|
15
|
-
import { Decoration, EditorView, WidgetType } from '@codemirror/view';
|
|
15
|
+
import { Decoration, EditorView, WidgetType, hoverTooltip } from '@codemirror/view';
|
|
16
|
+
|
|
17
|
+
import { tooltipContent } from '@dxos/react-ui-theme';
|
|
18
|
+
|
|
19
|
+
const markdownLinkRegexp = /\[([^\]]+)]\(([^)]+)\)/;
|
|
16
20
|
|
|
17
21
|
// Adapted from:
|
|
18
22
|
// https://codemirror.net/try/?c=aW1wb3J0IHsgYmFzaWNTZXR1cCwgRWRpdG9yVmlldyB9IGZyb20gImNvZGVtaXJyb3IiCmltcG9ydCB7IG1hcmtkb3duIH0gZnJvbSAiQGNvZGVtaXJyb3IvbGFuZy1tYXJrZG93biIKaW1wb3J0IHsgc3ludGF4VHJlZSB9IGZyb20gIkBjb2RlbWlycm9yL2xhbmd1YWdlIjsKaW1wb3J0IHsgRWRpdG9yU3RhdGUsIFJhbmdlU2V0QnVpbGRlciwgU3RhdGVGaWVsZCB9IGZyb20gIkBjb2RlbWlycm9yL3N0YXRlIjsKaW1wb3J0IHsgRGVjb3JhdGlvbiwgV2lkZ2V0VHlwZSB9IGZyb20gIkBjb2RlbWlycm9yL3ZpZXciOwoKY2xhc3MgTGluayBleHRlbmRzIFdpZGdldFR5cGUgewogIGNvbnN0cnVjdG9yKHRleHQsIHVybCkgewogICAgc3VwZXIoKQogICAgdGhpcy50ZXh0ID0gdGV4dAogICAgdGhpcy51cmwgPSB1cmwKICB9CiAgZXEob3RoZXIpIHsgcmV0dXJuIHRoaXMudGV4dCA9PSBvdGhlci50ZXh0ICYmIHRoaXMudXJsID09IG90aGVyLnVybCB9CiAgdG9ET00oKSB7CiAgICBsZXQgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKQogICAgbGluay50ZXh0Q29udGVudCA9IHRoaXMudGV4dAogICAgbGluay5ocmVmID0gdGhpcy51cmwKICAgIHJldHVybiBsaW5rOwogIH0KfQoKbGV0IGRlY29yYXRpb25zRmllbGQgPSBTdGF0ZUZpZWxkLmRlZmluZSh7CiAgY3JlYXRlKCkgewogICAgcmV0dXJuIERlY29yYXRpb24ubm9uZTsKICB9LAogIHVwZGF0ZShfLCB0cikgewogICAgY29uc3QgYnVpbGRlciA9IG5ldyBSYW5nZVNldEJ1aWxkZXIoKTsKICAgIGxldCBjdXJzb3IgPSB0ci5zdGF0ZS5zZWxlY3Rpb24ubWFpbi5oZWFkOwogICAgc3ludGF4VHJlZSh0ci5zdGF0ZSkuaXRlcmF0ZSh7CiAgICAgIGVudGVyOiAobm9kZSkgPT4gewogICAgICAgIGlmICgoY3Vyc29yIDwgbm9kZS5mcm9tIHx8IGN1cnNvciA+IG5vZGUudG8pICYmIG5vZGUubmFtZSA9PSAiTGluayIpIHsKICAgICAgICAgIGxldCBtYXJrcyA9IG5vZGUubm9kZS5nZXRDaGlsZHJlbigiTGlua01hcmsiKTsKICAgICAgICAgIGxldCB0ZXh0ID0gbWFya3MubGVuZ3RoID49IDIgPyB0ci5zdGF0ZS5zbGljZURvYyhtYXJrc1swXS50bywgbWFya3NbMV0uZnJvbSkgOiAiIgoKICAgICAgICAgIGxldCB1cmxOb2RlID0gbm9kZS5ub2RlLmdldENoaWxkKCJVUkwiKTsKICAgICAgICAgIGxldCB1cmwgPSB1cmxOb2RlID8gdHIuc3RhdGUuc2xpY2VEb2ModXJsTm9kZS5mcm9tLCB1cmxOb2RlLnRvKSA6ICIiCiAgICAgICAgICBidWlsZGVyLmFkZChub2RlLmZyb20sIG5vZGUudG8sIERlY29yYXRpb24ucmVwbGFjZSh7CiAgICAgICAgICAgIHdpZGdldDogbmV3IExpbmsodGV4dCwgdXJsKSwKICAgICAgICAgIH0pLAogICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfSwKICAgIH0pOwogICAgcmV0dXJuIGJ1aWxkZXIuZmluaXNoKCk7CiAgfSwKICBwcm92aWRlOiAoZikgPT4gRWRpdG9yVmlldy5kZWNvcmF0aW9ucy5mcm9tKGYpLAp9KTsKCmxldCB2aWV3ID0gbmV3IEVkaXRvclZpZXcoewogIGRvYzogIiMgSGVsbG8gV29ybGRcblxuW1Rlc3RdKGh0dHBzOi8vZXhhbXBsZS5jb20pXG5cblxuIiwKICBleHRlbnNpb25zOiBbZGVjb3JhdGlvbnNGaWVsZCwgbWFya2Rvd24oKV0sCiAgcGFyZW50OiBkb2N1bWVudC5ib2R5LAp9KTsKCnZpZXcuZm9jdXMoKTs=
|
|
@@ -20,6 +24,7 @@ import { Decoration, EditorView, WidgetType } from '@codemirror/view';
|
|
|
20
24
|
|
|
21
25
|
export type LinkOptions = {
|
|
22
26
|
link?: boolean;
|
|
27
|
+
onHover?: (el: Element, url: string) => void;
|
|
23
28
|
onRender?: (el: Element, url: string) => void;
|
|
24
29
|
};
|
|
25
30
|
|
|
@@ -28,11 +33,62 @@ export type LinkOptions = {
|
|
|
28
33
|
* https://codemirror.net/docs/ref/#state.StateField
|
|
29
34
|
*/
|
|
30
35
|
export const link = (options: LinkOptions = {}): Extension => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const extensions: Extension[] = [
|
|
37
|
+
StateField.define<RangeSet<any>>({
|
|
38
|
+
create: (state) => update(state, options),
|
|
39
|
+
update: (_: RangeSet<any>, tr: Transaction) => update(tr.state, options),
|
|
40
|
+
provide: (field) => EditorView.decorations.from(field),
|
|
41
|
+
}),
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
if (options.onHover) {
|
|
45
|
+
extensions.push(
|
|
46
|
+
// https://codemirror.net/examples/tooltip
|
|
47
|
+
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
48
|
+
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
49
|
+
hoverTooltip((view, pos) => {
|
|
50
|
+
const { from, text } = view.state.doc.lineAt(pos);
|
|
51
|
+
const p = pos - from;
|
|
52
|
+
|
|
53
|
+
let idx = 0;
|
|
54
|
+
let match;
|
|
55
|
+
do {
|
|
56
|
+
match = text.substring(idx).match(markdownLinkRegexp);
|
|
57
|
+
if (!match) {
|
|
58
|
+
match = undefined;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
idx = text.indexOf(match[0]);
|
|
63
|
+
if (p >= idx && p < idx + match[0].length) {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
idx += match[0].length;
|
|
68
|
+
} while (true);
|
|
69
|
+
|
|
70
|
+
if (!match) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const [, , url] = match ?? [];
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
pos: idx + from,
|
|
78
|
+
end: idx + from + match[0].length,
|
|
79
|
+
above: true,
|
|
80
|
+
create: () => {
|
|
81
|
+
const el = document.createElement('div');
|
|
82
|
+
el.className = tooltipContent({}, 'pli-2 plb-1');
|
|
83
|
+
options.onHover!(el, url);
|
|
84
|
+
return { dom: el, offset: { x: 0, y: 4 } };
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}),
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return extensions;
|
|
36
92
|
};
|
|
37
93
|
|
|
38
94
|
class LinkButton extends WidgetType {
|
|
@@ -56,12 +112,12 @@ class LinkButton extends WidgetType {
|
|
|
56
112
|
}
|
|
57
113
|
|
|
58
114
|
class LinkText extends WidgetType {
|
|
59
|
-
constructor(private readonly
|
|
115
|
+
constructor(private readonly _text: string, private readonly _url?: string) {
|
|
60
116
|
super();
|
|
61
117
|
}
|
|
62
118
|
|
|
63
119
|
override eq(other: LinkText) {
|
|
64
|
-
return this.
|
|
120
|
+
return this._url === other._url;
|
|
65
121
|
}
|
|
66
122
|
|
|
67
123
|
toDOM(view: EditorView) {
|
|
@@ -76,7 +132,7 @@ class LinkText extends WidgetType {
|
|
|
76
132
|
link.onclick = () => {
|
|
77
133
|
view.dispatch({
|
|
78
134
|
selection: {
|
|
79
|
-
anchor:
|
|
135
|
+
anchor: view.posAtDOM(link),
|
|
80
136
|
},
|
|
81
137
|
});
|
|
82
138
|
};
|
|
@@ -112,7 +168,7 @@ const update = (state: EditorState, options: LinkOptions) => {
|
|
|
112
168
|
node.from,
|
|
113
169
|
node.to,
|
|
114
170
|
Decoration.replace({
|
|
115
|
-
widget: new LinkText(
|
|
171
|
+
widget: new LinkText(text, options.link ? url : undefined),
|
|
116
172
|
}),
|
|
117
173
|
);
|
|
118
174
|
}
|
|
@@ -2,22 +2,34 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { type Extension } from '@codemirror/state';
|
|
6
|
+
import { EditorView } from '@codemirror/view';
|
|
6
7
|
|
|
7
|
-
export type ListenerOptions = {
|
|
8
|
+
export type ListenerOptions = {
|
|
9
|
+
onFocus?: (focused: boolean) => void;
|
|
10
|
+
onChange?: (text: string) => void;
|
|
11
|
+
};
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
|
-
*
|
|
14
|
+
* Event listener.
|
|
11
15
|
*/
|
|
12
|
-
export const listener = ({ onChange }: ListenerOptions) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
export const listener = ({ onFocus, onChange }: ListenerOptions): Extension => {
|
|
17
|
+
const extensions: Extension[] = [];
|
|
18
|
+
|
|
19
|
+
onFocus &&
|
|
20
|
+
extensions.push(
|
|
21
|
+
EditorView.focusChangeEffect.of((_, focused) => {
|
|
22
|
+
onFocus(focused);
|
|
23
|
+
return null;
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
onChange &&
|
|
28
|
+
extensions.push(
|
|
29
|
+
EditorView.updateListener.of((update) => {
|
|
30
|
+
onChange(update.state.doc.toString());
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
19
33
|
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
});
|
|
34
|
+
return extensions;
|
|
23
35
|
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type Extension } from '@codemirror/state';
|
|
2
|
-
export type TooltipOptions = {
|
|
3
|
-
onHover: (el: Element, url: string) => void;
|
|
4
|
-
regexp?: RegExp;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* https://codemirror.net/examples/tooltip
|
|
8
|
-
* https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
9
|
-
* https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
10
|
-
*/
|
|
11
|
-
export declare const tooltip: ({ onHover, regexp }: TooltipOptions) => Extension;
|
|
12
|
-
//# sourceMappingURL=tooltip.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../../../../src/components/TextEditor/extensions/tooltip.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAOnD,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,OAAO,wBAA8C,cAAc,KAAG,SAuC/E,CAAC"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2023 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { type Extension } from '@codemirror/state';
|
|
6
|
-
import { hoverTooltip } from '@codemirror/view';
|
|
7
|
-
|
|
8
|
-
import { tooltipContent } from '@dxos/react-ui-theme';
|
|
9
|
-
|
|
10
|
-
const markdownLinkRegexp = /\[([^\]]+)]\(([^)]+)\)/;
|
|
11
|
-
|
|
12
|
-
export type TooltipOptions = {
|
|
13
|
-
onHover: (el: Element, url: string) => void;
|
|
14
|
-
regexp?: RegExp;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* https://codemirror.net/examples/tooltip
|
|
19
|
-
* https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
20
|
-
* https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
21
|
-
*/
|
|
22
|
-
export const tooltip = ({ onHover, regexp = markdownLinkRegexp }: TooltipOptions): Extension =>
|
|
23
|
-
hoverTooltip((view, pos) => {
|
|
24
|
-
const { from, text } = view.state.doc.lineAt(pos);
|
|
25
|
-
const p = pos - from;
|
|
26
|
-
|
|
27
|
-
let idx = 0;
|
|
28
|
-
let match;
|
|
29
|
-
do {
|
|
30
|
-
match = text.substring(idx).match(regexp);
|
|
31
|
-
if (!match) {
|
|
32
|
-
match = undefined;
|
|
33
|
-
break;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
idx = text.indexOf(match[0]);
|
|
37
|
-
if (p >= idx && p < idx + match[0].length) {
|
|
38
|
-
break;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
idx += match[0].length;
|
|
42
|
-
} while (true);
|
|
43
|
-
|
|
44
|
-
if (!match) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const [, , url] = match ?? [];
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
pos: idx + from,
|
|
52
|
-
end: idx + from + match[0].length,
|
|
53
|
-
above: true,
|
|
54
|
-
create: () => {
|
|
55
|
-
const el = document.createElement('div');
|
|
56
|
-
el.className = tooltipContent({}, 'pli-2 plb-1');
|
|
57
|
-
onHover(el, url);
|
|
58
|
-
return { dom: el, offset: { x: 0, y: 4 } };
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
});
|