hero-editor 1.9.2 → 1.9.3
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/package.json +1 -1
- package/src/constants.js +4 -0
- package/src/helpers/__tests__/helpers.test.js +21 -0
- package/src/helpers/getUrlFromNode.js +6 -0
- package/src/helpers/index.js +1 -0
- package/src/lib.js +1 -1
- package/src/plugins/__tests__/__snapshots__/link.test.js.snap +1 -1
- package/src/plugins/link.js +60 -24
package/package.json
CHANGED
package/src/constants.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
composeRenderLeaf,
|
|
8
8
|
makeRenderLeaf,
|
|
9
9
|
getUrl,
|
|
10
|
+
getUrlFromNode,
|
|
10
11
|
isEmptyContent,
|
|
11
12
|
} from '../index';
|
|
12
13
|
|
|
@@ -47,6 +48,26 @@ describe('getUrl', () => {
|
|
|
47
48
|
});
|
|
48
49
|
});
|
|
49
50
|
|
|
51
|
+
describe('getUrlFromNode', () => {
|
|
52
|
+
it.each`
|
|
53
|
+
node | expected
|
|
54
|
+
${{ type: 'link', data: { url: 'https://google.com' }, children: [{ text: 'link' }] }} | ${'https://google.com'}
|
|
55
|
+
${{ type: 'link', data: { url: 'https://google.com' }, children: [{ text: 'https:/' }, { text: 'google.com', bold: true }] }} | ${'https://google.com'}
|
|
56
|
+
`('gets URL from link node', ({ node, expected }) => {
|
|
57
|
+
expect(getUrlFromNode(node)).toEqual(expected);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it.each`
|
|
61
|
+
node | expected
|
|
62
|
+
${{ type: 'paragraph', children: [{ text: 'text' }] }} | ${null}
|
|
63
|
+
${null} | ${null}
|
|
64
|
+
${undefined} | ${null}
|
|
65
|
+
${{}} | ${null}
|
|
66
|
+
`('returns null when link node is not provided', ({ node, expected }) => {
|
|
67
|
+
expect(getUrlFromNode(node)).toEqual(expected);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
50
71
|
describe('compose', () => {
|
|
51
72
|
it('composes functions', () => {
|
|
52
73
|
expect(
|
package/src/helpers/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export { default as apply } from './apply';
|
|
|
9
9
|
export { default as createPlugin } from './createPlugin';
|
|
10
10
|
export { default as withId } from './withId';
|
|
11
11
|
export { default as getUrl } from './getUrl';
|
|
12
|
+
export { default as getUrlFromNode } from './getUrlFromNode';
|
|
12
13
|
export { default as isEmptyContent } from './isEmptyContent';
|
|
13
14
|
|
|
14
15
|
export { default as useForceUpdate } from './useForceUpdate';
|
package/src/lib.js
CHANGED
|
@@ -151,6 +151,6 @@ export { default as Icon } from './components/Icon';
|
|
|
151
151
|
export { default as plainSerializer } from './serializers/plain';
|
|
152
152
|
export { default as makeReactTransformer } from './transformers/react';
|
|
153
153
|
export { defaultReactTransformer } from './transformers/react';
|
|
154
|
-
export { isEmptyContent, getUrl, isUrl } from './helpers';
|
|
154
|
+
export { isEmptyContent, getUrl, isUrl, getUrlFromNode } from './helpers';
|
|
155
155
|
export { EMPTY_VALUE } from './constants';
|
|
156
156
|
export default HeroEditor;
|
package/src/plugins/link.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useCallback, useEffect } from 'react';
|
|
2
2
|
import { useSlate } from 'slate-react';
|
|
3
3
|
import isUrl from 'is-url';
|
|
4
4
|
import { Transforms, Editor, Range } from 'slate';
|
|
@@ -9,29 +9,25 @@ import {
|
|
|
9
9
|
postMessage,
|
|
10
10
|
isBlockActive,
|
|
11
11
|
isLink,
|
|
12
|
+
getUrlFromNode,
|
|
12
13
|
} from '../helpers';
|
|
13
|
-
import { LINK } from '../constants';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
element.children.reduce((url, node) => url + node.text, '');
|
|
14
|
+
import { LINK, ADD_LINK } from '../constants';
|
|
15
|
+
import Toolbar from '../components/Toolbar';
|
|
16
|
+
import Icon from '../components/Icon';
|
|
17
17
|
|
|
18
18
|
const getUrlFromNodes = (editor) => {
|
|
19
19
|
const [...linkNodes] = Editor.nodes(editor, { match: isLink });
|
|
20
20
|
|
|
21
21
|
if (linkNodes.length === 1) {
|
|
22
|
-
const [
|
|
23
|
-
return
|
|
22
|
+
const [node] = linkNodes[0];
|
|
23
|
+
return getUrlFromNode(node);
|
|
24
24
|
}
|
|
25
|
+
|
|
25
26
|
return '';
|
|
26
27
|
};
|
|
27
28
|
|
|
28
|
-
const getSelectedData = (editor) => ({
|
|
29
|
-
text: Editor.string(editor, editor.selection),
|
|
30
|
-
url: getUrlFromNodes(editor),
|
|
31
|
-
});
|
|
32
|
-
|
|
33
29
|
const LinkElement = ({ attributes, children, element }) => (
|
|
34
|
-
<a {...attributes} href={
|
|
30
|
+
<a {...attributes} href={getUrlFromNode(element)}>
|
|
35
31
|
{children}
|
|
36
32
|
</a>
|
|
37
33
|
);
|
|
@@ -80,7 +76,7 @@ const enhanceEditor = (editor) => {
|
|
|
80
76
|
const text = data.getData('text/plain');
|
|
81
77
|
|
|
82
78
|
if (text && isUrl(text)) {
|
|
83
|
-
postMessage(LINK, { url: text }, editor);
|
|
79
|
+
postMessage(LINK, { text, url: text }, editor);
|
|
84
80
|
} else {
|
|
85
81
|
insertData(data);
|
|
86
82
|
}
|
|
@@ -89,30 +85,70 @@ const enhanceEditor = (editor) => {
|
|
|
89
85
|
return editor;
|
|
90
86
|
};
|
|
91
87
|
|
|
92
|
-
const
|
|
88
|
+
const AddLinkModal = ({ renderAddLinkCustom }) => {
|
|
89
|
+
const [showAddLinkCustom, setShowAddLinkCustom] = useState(false);
|
|
93
90
|
const editor = useSlate();
|
|
94
91
|
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
const { selection } = editor || {};
|
|
93
|
+
|
|
94
|
+
const handleAddLink = useCallback((data) => {
|
|
95
|
+
postMessage(LINK, data, editor);
|
|
96
|
+
}, []);
|
|
97
|
+
|
|
98
|
+
const getSelectedData = (editor) => ({
|
|
99
|
+
text: selection ? Editor.string(editor, selection) : '',
|
|
100
|
+
url: getUrlFromNodes(editor),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const removeAddLinkListener = addMessageListener(ADD_LINK, () => {
|
|
105
|
+
setShowAddLinkCustom(true);
|
|
106
|
+
})(editor);
|
|
107
|
+
|
|
108
|
+
return () => removeAddLinkListener();
|
|
109
|
+
});
|
|
98
110
|
|
|
99
111
|
return (
|
|
100
112
|
<>
|
|
101
|
-
{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
113
|
+
{showAddLinkCustom &&
|
|
114
|
+
renderAddLinkCustom?.({
|
|
115
|
+
handleAddLink,
|
|
116
|
+
getSelectedData: () => getSelectedData(editor),
|
|
117
|
+
hideAddLinkCustom: () => setShowAddLinkCustom(false),
|
|
118
|
+
})}
|
|
105
119
|
</>
|
|
106
120
|
);
|
|
107
121
|
};
|
|
108
122
|
|
|
109
|
-
|
|
123
|
+
const ToolbarButton = ({ showToolbarButton }) => {
|
|
124
|
+
const editor = useSlate();
|
|
125
|
+
|
|
126
|
+
const handleMouseDown = useCallback(() => {
|
|
127
|
+
postMessage(ADD_LINK, {}, editor);
|
|
128
|
+
}, []);
|
|
129
|
+
|
|
130
|
+
if (!showToolbarButton) return null;
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<>
|
|
134
|
+
<Toolbar.Button active={false} onMouseDown={handleMouseDown}>
|
|
135
|
+
<Icon>link</Icon>
|
|
136
|
+
</Toolbar.Button>
|
|
137
|
+
<Toolbar.Separator />
|
|
138
|
+
</>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export default ({ renderAddLinkCustom, showToolbarButton } = {}) =>
|
|
110
143
|
createPlugin({
|
|
111
144
|
name: LINK,
|
|
112
145
|
renderElement,
|
|
113
146
|
handleMessage,
|
|
147
|
+
renderCustom: () => (
|
|
148
|
+
<AddLinkModal renderAddLinkCustom={renderAddLinkCustom} />
|
|
149
|
+
),
|
|
114
150
|
ToolbarButton: () => (
|
|
115
|
-
<ToolbarButton
|
|
151
|
+
<ToolbarButton showToolbarButton={showToolbarButton} />
|
|
116
152
|
),
|
|
117
153
|
enhanceEditor,
|
|
118
154
|
});
|