@contentful/field-editor-rich-text 3.8.1 → 3.8.2
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/cjs/RichTextEditor.js +21 -23
- package/dist/cjs/internal/misc.js +14 -0
- package/dist/cjs/test-utils/createEditor.js +3 -3
- package/dist/esm/RichTextEditor.js +21 -23
- package/dist/esm/internal/misc.js +11 -0
- package/dist/esm/test-utils/createEditor.js +3 -3
- package/dist/types/internal/misc.d.ts +22 -0
- package/dist/types/test-utils/createEditor.d.ts +6 -6
- package/package.json +3 -3
|
@@ -27,6 +27,7 @@ const _noop = _interop_require_default(require("lodash/noop"));
|
|
|
27
27
|
const _ContentfulEditorProvider = require("./ContentfulEditorProvider");
|
|
28
28
|
const _callbacks = require("./helpers/callbacks");
|
|
29
29
|
const _toSlateValue = require("./helpers/toSlateValue");
|
|
30
|
+
const _misc = require("./internal/misc");
|
|
30
31
|
const _plugins = require("./plugins");
|
|
31
32
|
const _RichTextEditorstyles = require("./RichTextEditor.styles");
|
|
32
33
|
const _SdkProvider = require("./SdkProvider");
|
|
@@ -78,32 +79,33 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
78
79
|
return newObj;
|
|
79
80
|
}
|
|
80
81
|
const ConnectedRichTextEditor = (props)=>{
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
const { sdk , onAction , restrictedMarks } = props;
|
|
83
|
+
const id = (0, _ContentfulEditorProvider.getContentfulEditorId)(sdk);
|
|
84
|
+
const plugins = _react.useMemo(()=>(0, _plugins.getPlugins)(sdk, onAction ?? _noop.default, restrictedMarks), [
|
|
85
|
+
sdk,
|
|
86
|
+
onAction,
|
|
87
|
+
restrictedMarks
|
|
86
88
|
]);
|
|
87
89
|
const handleChange = props.onChange;
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
+
const initialValue = _react.useMemo(()=>{
|
|
91
|
+
return (0, _misc.normalizeInitialValue)({
|
|
92
|
+
plugins,
|
|
93
|
+
disableCorePlugins: _plugins.disableCorePlugins
|
|
94
|
+
}, (0, _toSlateValue.toSlateValue)(props.value));
|
|
95
|
+
}, [
|
|
96
|
+
props.value,
|
|
97
|
+
plugins
|
|
98
|
+
]);
|
|
90
99
|
const onChange = _react.useMemo(()=>(0, _callbacks.createOnChangeCallback)((document)=>{
|
|
91
|
-
|
|
92
|
-
handleChange(document);
|
|
93
|
-
}
|
|
100
|
+
handleChange?.(document);
|
|
94
101
|
}), [
|
|
95
102
|
handleChange
|
|
96
103
|
]);
|
|
97
|
-
const firstInteractionHandler = _react.useCallback(()=>{
|
|
98
|
-
isFirstRender.current = false;
|
|
99
|
-
}, [
|
|
100
|
-
isFirstRender
|
|
101
|
-
]);
|
|
102
104
|
const classNames = (0, _emotion.cx)(_RichTextEditorstyles.styles.editor, props.minHeight !== undefined ? (0, _emotion.css)({
|
|
103
105
|
minHeight: props.minHeight
|
|
104
106
|
}) : undefined, props.isDisabled ? _RichTextEditorstyles.styles.disabled : _RichTextEditorstyles.styles.enabled, props.isToolbarHidden && _RichTextEditorstyles.styles.hiddenToolbar);
|
|
105
107
|
return _react.createElement(_SdkProvider.SdkProvider, {
|
|
106
|
-
sdk:
|
|
108
|
+
sdk: sdk
|
|
107
109
|
}, _react.createElement(_ContentfulEditorProvider.ContentfulEditorIdProvider, {
|
|
108
110
|
value: id
|
|
109
111
|
}, _react.createElement("div", {
|
|
@@ -111,8 +113,7 @@ const ConnectedRichTextEditor = (props)=>{
|
|
|
111
113
|
"data-test-id": "rich-text-editor"
|
|
112
114
|
}, _react.createElement(_platecore.PlateProvider, {
|
|
113
115
|
id: id,
|
|
114
|
-
initialValue:
|
|
115
|
-
normalizeInitialValue: true,
|
|
116
|
+
initialValue: initialValue,
|
|
116
117
|
plugins: plugins,
|
|
117
118
|
disableCorePlugins: _plugins.disableCorePlugins,
|
|
118
119
|
onChange: onChange
|
|
@@ -121,15 +122,12 @@ const ConnectedRichTextEditor = (props)=>{
|
|
|
121
122
|
}, _react.createElement(_Toolbar.default, {
|
|
122
123
|
isDisabled: props.isDisabled
|
|
123
124
|
})), _react.createElement(_SyncEditorValue.SyncEditorValue, {
|
|
124
|
-
incomingValue:
|
|
125
|
+
incomingValue: initialValue
|
|
125
126
|
}), _react.createElement(_platecore.Plate, {
|
|
126
127
|
id: id,
|
|
127
128
|
editableProps: {
|
|
128
129
|
className: classNames,
|
|
129
|
-
readOnly: props.isDisabled
|
|
130
|
-
onKeyDown: firstInteractionHandler,
|
|
131
|
-
onChange: firstInteractionHandler,
|
|
132
|
-
onClick: firstInteractionHandler
|
|
130
|
+
readOnly: props.isDisabled
|
|
133
131
|
}
|
|
134
132
|
})))));
|
|
135
133
|
};
|
|
@@ -12,6 +12,9 @@ _export(exports, {
|
|
|
12
12
|
createPlateEditor: function() {
|
|
13
13
|
return createPlateEditor;
|
|
14
14
|
},
|
|
15
|
+
normalizeInitialValue: function() {
|
|
16
|
+
return normalizeInitialValue;
|
|
17
|
+
},
|
|
15
18
|
withoutNormalizing: function() {
|
|
16
19
|
return withoutNormalizing;
|
|
17
20
|
},
|
|
@@ -32,6 +35,7 @@ _export(exports, {
|
|
|
32
35
|
}
|
|
33
36
|
});
|
|
34
37
|
const _platecore = _interop_require_wildcard(require("@udecode/plate-core"));
|
|
38
|
+
const _transforms = require("./transforms");
|
|
35
39
|
function _getRequireWildcardCache(nodeInterop) {
|
|
36
40
|
if (typeof WeakMap !== "function") return null;
|
|
37
41
|
var cacheBabelInterop = new WeakMap();
|
|
@@ -74,6 +78,16 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
74
78
|
const createPlateEditor = (options = {})=>{
|
|
75
79
|
return _platecore.createPlateEditor(options);
|
|
76
80
|
};
|
|
81
|
+
const normalizeInitialValue = (options, initialValue)=>{
|
|
82
|
+
const editor = createPlateEditor(options);
|
|
83
|
+
if (initialValue) {
|
|
84
|
+
editor.children = initialValue;
|
|
85
|
+
}
|
|
86
|
+
(0, _transforms.normalize)(editor, {
|
|
87
|
+
force: true
|
|
88
|
+
});
|
|
89
|
+
return editor.children;
|
|
90
|
+
};
|
|
77
91
|
const withoutNormalizing = (editor, fn)=>{
|
|
78
92
|
return _platecore.withoutNormalizing(editor, fn);
|
|
79
93
|
};
|
|
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "createTestEditor", {
|
|
|
8
8
|
return createTestEditor;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const _platecore = require("@udecode/plate-core");
|
|
12
11
|
const _internal = require("../internal");
|
|
13
12
|
const _plugins = require("../plugins");
|
|
14
13
|
const _randomId = require("./randomId");
|
|
@@ -19,10 +18,11 @@ const createTestEditor = (options)=>{
|
|
|
19
18
|
validation: []
|
|
20
19
|
}
|
|
21
20
|
};
|
|
22
|
-
const editor = (0,
|
|
21
|
+
const editor = (0, _internal.createPlateEditor)({
|
|
23
22
|
id: (0, _randomId.randomId)('editor'),
|
|
24
23
|
editor: options.input,
|
|
25
|
-
plugins: options.plugins || (0, _plugins.getPlugins)(sdk, trackingHandler)
|
|
24
|
+
plugins: options.plugins || (0, _plugins.getPlugins)(sdk, trackingHandler),
|
|
25
|
+
normalizeInitialValue: false
|
|
26
26
|
});
|
|
27
27
|
return {
|
|
28
28
|
editor,
|
|
@@ -9,6 +9,7 @@ import noop from 'lodash/noop';
|
|
|
9
9
|
import { ContentfulEditorIdProvider, getContentfulEditorId } from './ContentfulEditorProvider';
|
|
10
10
|
import { createOnChangeCallback } from './helpers/callbacks';
|
|
11
11
|
import { toSlateValue } from './helpers/toSlateValue';
|
|
12
|
+
import { normalizeInitialValue } from './internal/misc';
|
|
12
13
|
import { getPlugins, disableCorePlugins } from './plugins';
|
|
13
14
|
import { styles } from './RichTextEditor.styles';
|
|
14
15
|
import { SdkProvider } from './SdkProvider';
|
|
@@ -16,32 +17,33 @@ import { SyncEditorValue } from './SyncEditorValue';
|
|
|
16
17
|
import Toolbar from './Toolbar';
|
|
17
18
|
import StickyToolbarWrapper from './Toolbar/components/StickyToolbarWrapper';
|
|
18
19
|
export const ConnectedRichTextEditor = (props)=>{
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const { sdk , onAction , restrictedMarks } = props;
|
|
21
|
+
const id = getContentfulEditorId(sdk);
|
|
22
|
+
const plugins = React.useMemo(()=>getPlugins(sdk, onAction ?? noop, restrictedMarks), [
|
|
23
|
+
sdk,
|
|
24
|
+
onAction,
|
|
25
|
+
restrictedMarks
|
|
24
26
|
]);
|
|
25
27
|
const handleChange = props.onChange;
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
+
const initialValue = React.useMemo(()=>{
|
|
29
|
+
return normalizeInitialValue({
|
|
30
|
+
plugins,
|
|
31
|
+
disableCorePlugins
|
|
32
|
+
}, toSlateValue(props.value));
|
|
33
|
+
}, [
|
|
34
|
+
props.value,
|
|
35
|
+
plugins
|
|
36
|
+
]);
|
|
28
37
|
const onChange = React.useMemo(()=>createOnChangeCallback((document)=>{
|
|
29
|
-
|
|
30
|
-
handleChange(document);
|
|
31
|
-
}
|
|
38
|
+
handleChange?.(document);
|
|
32
39
|
}), [
|
|
33
40
|
handleChange
|
|
34
41
|
]);
|
|
35
|
-
const firstInteractionHandler = React.useCallback(()=>{
|
|
36
|
-
isFirstRender.current = false;
|
|
37
|
-
}, [
|
|
38
|
-
isFirstRender
|
|
39
|
-
]);
|
|
40
42
|
const classNames = cx(styles.editor, props.minHeight !== undefined ? css({
|
|
41
43
|
minHeight: props.minHeight
|
|
42
44
|
}) : undefined, props.isDisabled ? styles.disabled : styles.enabled, props.isToolbarHidden && styles.hiddenToolbar);
|
|
43
45
|
return React.createElement(SdkProvider, {
|
|
44
|
-
sdk:
|
|
46
|
+
sdk: sdk
|
|
45
47
|
}, React.createElement(ContentfulEditorIdProvider, {
|
|
46
48
|
value: id
|
|
47
49
|
}, React.createElement("div", {
|
|
@@ -49,8 +51,7 @@ export const ConnectedRichTextEditor = (props)=>{
|
|
|
49
51
|
"data-test-id": "rich-text-editor"
|
|
50
52
|
}, React.createElement(PlateProvider, {
|
|
51
53
|
id: id,
|
|
52
|
-
initialValue:
|
|
53
|
-
normalizeInitialValue: true,
|
|
54
|
+
initialValue: initialValue,
|
|
54
55
|
plugins: plugins,
|
|
55
56
|
disableCorePlugins: disableCorePlugins,
|
|
56
57
|
onChange: onChange
|
|
@@ -59,15 +60,12 @@ export const ConnectedRichTextEditor = (props)=>{
|
|
|
59
60
|
}, React.createElement(Toolbar, {
|
|
60
61
|
isDisabled: props.isDisabled
|
|
61
62
|
})), React.createElement(SyncEditorValue, {
|
|
62
|
-
incomingValue:
|
|
63
|
+
incomingValue: initialValue
|
|
63
64
|
}), React.createElement(Plate, {
|
|
64
65
|
id: id,
|
|
65
66
|
editableProps: {
|
|
66
67
|
className: classNames,
|
|
67
|
-
readOnly: props.isDisabled
|
|
68
|
-
onKeyDown: firstInteractionHandler,
|
|
69
|
-
onChange: firstInteractionHandler,
|
|
70
|
-
onClick: firstInteractionHandler
|
|
68
|
+
readOnly: props.isDisabled
|
|
71
69
|
}
|
|
72
70
|
})))));
|
|
73
71
|
};
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import * as p from '@udecode/plate-core';
|
|
2
|
+
import { normalize } from './transforms';
|
|
2
3
|
export const createPlateEditor = (options = {})=>{
|
|
3
4
|
return p.createPlateEditor(options);
|
|
4
5
|
};
|
|
6
|
+
export const normalizeInitialValue = (options, initialValue)=>{
|
|
7
|
+
const editor = createPlateEditor(options);
|
|
8
|
+
if (initialValue) {
|
|
9
|
+
editor.children = initialValue;
|
|
10
|
+
}
|
|
11
|
+
normalize(editor, {
|
|
12
|
+
force: true
|
|
13
|
+
});
|
|
14
|
+
return editor.children;
|
|
15
|
+
};
|
|
5
16
|
export const withoutNormalizing = (editor, fn)=>{
|
|
6
17
|
return p.withoutNormalizing(editor, fn);
|
|
7
18
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { createPlateEditor } from '
|
|
2
|
-
import { normalize } from '../internal';
|
|
1
|
+
import { normalize, createPlateEditor } from '../internal';
|
|
3
2
|
import { getPlugins } from '../plugins';
|
|
4
3
|
import { randomId } from './randomId';
|
|
5
4
|
export const createTestEditor = (options)=>{
|
|
@@ -12,7 +11,8 @@ export const createTestEditor = (options)=>{
|
|
|
12
11
|
const editor = createPlateEditor({
|
|
13
12
|
id: randomId('editor'),
|
|
14
13
|
editor: options.input,
|
|
15
|
-
plugins: options.plugins || getPlugins(sdk, trackingHandler)
|
|
14
|
+
plugins: options.plugins || getPlugins(sdk, trackingHandler),
|
|
15
|
+
normalizeInitialValue: false
|
|
16
16
|
});
|
|
17
17
|
return {
|
|
18
18
|
editor,
|
|
@@ -26,6 +26,28 @@ export declare const createPlateEditor: (options?: CreatePlateEditorOptions) =>
|
|
|
26
26
|
childrenFactory: () => Value;
|
|
27
27
|
currentKeyboardEvent: import("react").KeyboardEvent<Element> | null;
|
|
28
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* The only reason for this helper to exist is to run the initial normalization
|
|
31
|
+
* before mounting the Plate editor component which in turn avoids the false
|
|
32
|
+
* trigger of `onChange`.
|
|
33
|
+
*
|
|
34
|
+
* Background:
|
|
35
|
+
*
|
|
36
|
+
* Due to legacy behavior, it's possible to have "valid" RT document (based on
|
|
37
|
+
* the schema from rich-text-types) that doesn't make sense. For example, links
|
|
38
|
+
* with no text nodes?[1]. Solving that requires an initial normalization pass
|
|
39
|
+
* which modifies the slate tree by definition -> triggering onChange.
|
|
40
|
+
*
|
|
41
|
+
* The initial onChange trigger is undesirable as the user may not have touched
|
|
42
|
+
* the RT content yet or the editor is rendered as readonly.
|
|
43
|
+
*
|
|
44
|
+
* Ideally, we should not initialize the editor twice but that's the only
|
|
45
|
+
* way that I could get this to work. Improvements are welcome.
|
|
46
|
+
*
|
|
47
|
+
* [1]: See cypress/e2e/rich-text/.../invalidDocumentNormalizable.js for more
|
|
48
|
+
* examples.
|
|
49
|
+
*/
|
|
50
|
+
export declare const normalizeInitialValue: (options: CreatePlateEditorOptions, initialValue?: Value) => Value;
|
|
29
51
|
export declare const withoutNormalizing: (editor: PlateEditor, fn: () => boolean | void) => boolean;
|
|
30
52
|
export declare const focusEditor: (editor: PlateEditor, target?: Location) => void;
|
|
31
53
|
export declare const blurEditor: (editor: PlateEditor) => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { FieldExtensionSDK } from '@contentful/app-sdk';
|
|
3
|
-
import {
|
|
3
|
+
import { PlatePlugin } from '../internal/types';
|
|
4
4
|
import { RichTextTrackingActionHandler } from '../plugins/Tracking';
|
|
5
5
|
export declare const createTestEditor: (options: {
|
|
6
6
|
input?: any;
|
|
@@ -8,8 +8,8 @@ export declare const createTestEditor: (options: {
|
|
|
8
8
|
trackingHandler?: RichTextTrackingActionHandler;
|
|
9
9
|
plugins?: PlatePlugin[];
|
|
10
10
|
}) => {
|
|
11
|
-
editor: PlateEditor & Omit<import("slate").BaseEditor, "children" | "operations" | "marks" | "isInline" | "isVoid" | "normalizeNode" | "apply" | "getFragment" | "insertFragment" | "insertNode"> & {
|
|
12
|
-
children: Value;
|
|
11
|
+
editor: import("../internal").PlateEditor & Omit<import("slate").BaseEditor, "children" | "operations" | "marks" | "isInline" | "isVoid" | "normalizeNode" | "apply" | "getFragment" | "insertFragment" | "insertNode"> & {
|
|
12
|
+
children: import("../internal").Value;
|
|
13
13
|
operations: import("@udecode/plate-core").TOperation<import("@udecode/plate-core").TDescendant>[];
|
|
14
14
|
marks: Record<string, any> | null;
|
|
15
15
|
isInline: <N extends import("@udecode/plate-core").TElement>(element: N) => boolean;
|
|
@@ -22,11 +22,11 @@ export declare const createTestEditor: (options: {
|
|
|
22
22
|
} & import("@udecode/plate-core").UnknownObject & Pick<import("slate-history").HistoryEditor, "history" | "undo" | "redo"> & Pick<import("slate-react").ReactEditor, "insertData" | "insertFragmentData" | "setFragmentData" | "insertTextData" | "hasRange"> & {
|
|
23
23
|
key: any;
|
|
24
24
|
id: string;
|
|
25
|
-
plugins: import("@udecode/plate-core").WithPlatePlugin<{}, Value, import("@udecode/plate-core").PlateEditor<Value>>[];
|
|
26
|
-
pluginsByKey: Record<string, import("@udecode/plate-core").WithPlatePlugin<{}, Value, import("@udecode/plate-core").PlateEditor<Value>>>;
|
|
25
|
+
plugins: import("@udecode/plate-core").WithPlatePlugin<{}, import("../internal").Value, import("@udecode/plate-core").PlateEditor<import("../internal").Value>>[];
|
|
26
|
+
pluginsByKey: Record<string, import("@udecode/plate-core").WithPlatePlugin<{}, import("../internal").Value, import("@udecode/plate-core").PlateEditor<import("../internal").Value>>>;
|
|
27
27
|
prevSelection: import("slate").BaseRange | null;
|
|
28
28
|
blockFactory: (node?: Partial<import("@udecode/plate-core").TElement> | undefined, path?: import("slate").Path | undefined) => import("@udecode/plate-core").TElement;
|
|
29
|
-
childrenFactory: () => Value;
|
|
29
|
+
childrenFactory: () => import("../internal").Value;
|
|
30
30
|
currentKeyboardEvent: import("react").KeyboardEvent<Element> | null;
|
|
31
31
|
};
|
|
32
32
|
normalize: () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-rich-text",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.2",
|
|
4
4
|
"source": "./src/index.tsx",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@contentful/f36-icons": "^4.1.1",
|
|
45
45
|
"@contentful/f36-tokens": "^4.0.0",
|
|
46
46
|
"@contentful/f36-utils": "^4.19.0",
|
|
47
|
-
"@contentful/field-editor-reference": "^5.
|
|
47
|
+
"@contentful/field-editor-reference": "^5.13.0",
|
|
48
48
|
"@contentful/field-editor-shared": "^1.3.0",
|
|
49
49
|
"@contentful/rich-text-plain-text-renderer": "^16.0.4",
|
|
50
50
|
"@contentful/rich-text-types": "16.1.0",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"prism-react-renderer": "2.0.5",
|
|
82
82
|
"react": ">=16.14.0"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "2a23fcf8d6a1ee441274f5020ad94e847fd93ad4"
|
|
85
85
|
}
|