-
Notifications
You must be signed in to change notification settings - Fork 5
/
Slate.js
66 lines (56 loc) · 1.54 KB
/
Slate.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import React from "react";
import { Editor } from "slate-react";
import Plain from "slate-plain-serializer";
import InstantReplace from "slate-instant-replace";
import isUrl from "is-url";
// Transformation function
const AddURL = (editor, lastWord) => {
if (isUrl(lastWord)) {
editor.moveFocusBackward(lastWord.length); // select last word
editor.unwrapInline("link"); // remove existing urls
const href = lastWord.startsWith("http") ? lastWord : `https://${lastWord}`;
editor.wrapInline({ type: "link", data: { href } }); // set URL inline
editor.moveFocusForward(lastWord.length); // deselect it
}
};
// Initialise the plugin
const plugins = [InstantReplace(AddURL)];
const initialValue = Plain.deserialize("Habak");
class Slate extends React.Component {
// Set the initial value when the app is first constructed.
state = {
value: initialValue,
};
// On change, update the app's React state with the new editor value.
onChange = ({ value }) => {
this.setState({ value });
};
// Render the editor.
render() {
return (
<Editor
value={this.state.value}
onChange={this.onChange}
plugins={plugins}
renderNode={Node}
/>
);
}
}
// Render slate node
const Node = ({ attributes, children, node }) => {
switch (node.type) {
case "link": {
const { data } = node;
const href = data.get("href");
return (
<a href={href} {...attributes}>
{children}
</a>
);
}
default:
return null;
}
};
export default Slate;