@squiz/formatted-text-editor 1.57.1-alpha.3 → 1.58.1-alpha.0
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/lib/Editor/Editor.d.ts +3 -1
- package/lib/Editor/Editor.js +2 -2
- package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.d.ts +3 -1
- package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.js +11 -2
- package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.d.ts +1 -1
- package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.js +1 -1
- package/package.json +5 -5
- package/src/Editor/Editor.tsx +13 -1
- package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.spec.ts +12 -1
- package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.ts +13 -4
- package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.ts +1 -1
package/lib/Editor/Editor.d.ts
CHANGED
@@ -8,6 +8,8 @@ type EditorProps = {
|
|
8
8
|
border?: boolean;
|
9
9
|
children?: ReactNode;
|
10
10
|
isFocused?: boolean;
|
11
|
+
label?: string;
|
12
|
+
attributes?: Record<string, string>;
|
11
13
|
};
|
12
|
-
declare const Editor: ({ content, className, border, editable, onChange, children, isFocused }: EditorProps) => JSX.Element;
|
14
|
+
declare const Editor: ({ content, className, border, editable, onChange, children, isFocused, attributes, }: EditorProps) => JSX.Element;
|
13
15
|
export default Editor;
|
package/lib/Editor/Editor.js
CHANGED
@@ -47,7 +47,7 @@ const WrappedEditor = () => {
|
|
47
47
|
(0, react_2.useEditorEvent)('paste', preventImagePaste);
|
48
48
|
return react_1.default.createElement(react_2.EditorComponent, null);
|
49
49
|
};
|
50
|
-
const Editor = ({ content, className, border = true, editable = true, onChange, children, isFocused }) => {
|
50
|
+
const Editor = ({ content, className, border = true, editable = true, onChange, children, isFocused, attributes, }) => {
|
51
51
|
const { manager, state, setState } = (0, react_2.useRemirror)({
|
52
52
|
extensions: (0, Extensions_1.createExtensions)((0, react_1.useContext)(EditorContext_1.EditorContext), (0, react_1.useContext)(resource_browser_1.ResourceBrowserContext)),
|
53
53
|
content,
|
@@ -66,7 +66,7 @@ const Editor = ({ content, className, border = true, editable = true, onChange,
|
|
66
66
|
}
|
67
67
|
}, []);
|
68
68
|
return (react_1.default.createElement("div", { ref: wrapperRef, onBlur: handleBlur, onFocusCapture: handleFocus, className: (0, clsx_1.default)('squiz-fte-scope', 'squiz-fte-scope__editor', !editable && 'squiz-fte-scope__editor--is-disabled', border && 'squiz-fte-scope__editor--bordered', className) },
|
69
|
-
react_1.default.createElement(react_2.Remirror, { manager: manager, state: state, editable: editable, onChange: handleChange, placeholder: "Write something", label: "Text editor" },
|
69
|
+
react_1.default.createElement(react_2.Remirror, { manager: manager, state: state, editable: editable, onChange: handleChange, placeholder: "Write something", label: "Text editor", attributes: attributes },
|
70
70
|
editable && react_1.default.createElement(EditorToolbar_1.Toolbar, { isVisible: isVisible }),
|
71
71
|
children && react_1.default.createElement("div", { className: "squiz-fte-scope__editor__children" }, children),
|
72
72
|
react_1.default.createElement(WrappedEditor, null),
|
@@ -1,9 +1,11 @@
|
|
1
1
|
import { ProsemirrorNode } from 'remirror';
|
2
2
|
import { FORMATTED_TEXT_MODELS as FormattedTextModels } from '@squiz/dx-json-schema-lib';
|
3
|
+
type FormattedText = FormattedTextModels.v1.FormattedText;
|
3
4
|
export declare const resolveNodeTag: (node: ProsemirrorNode) => string;
|
4
5
|
/**
|
5
6
|
* Converts Remirror node JSON structure to Squiz component JSON structure.
|
6
7
|
* @param {ProsemirrorNode} node Remirror node to convert to component.
|
7
8
|
* @returns {FormattedText} The converted Squiz component JSON.
|
8
9
|
*/
|
9
|
-
export declare const remirrorNodeToSquizNode: (node: ProsemirrorNode) =>
|
10
|
+
export declare const remirrorNodeToSquizNode: (node: ProsemirrorNode) => FormattedText | undefined;
|
11
|
+
export {};
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.remirrorNodeToSquizNode = exports.resolveNodeTag = void 0;
|
4
|
+
const remirror_1 = require("remirror");
|
4
5
|
const undefinedIfEmpty_1 = require("../../undefinedIfEmpty");
|
5
6
|
const Extensions_1 = require("../../../Extensions/Extensions");
|
6
7
|
const resolveNodeTag = (node) => {
|
@@ -62,7 +63,9 @@ const transformAttributes = (attributes) => {
|
|
62
63
|
};
|
63
64
|
const transformFragment = (fragment) => {
|
64
65
|
const transformed = [];
|
65
|
-
fragment.forEach((child) =>
|
66
|
+
fragment.forEach((child) => {
|
67
|
+
transformed.push(transformNode(child));
|
68
|
+
});
|
66
69
|
return transformed;
|
67
70
|
};
|
68
71
|
const transformNode = (node) => {
|
@@ -178,6 +181,12 @@ const remirrorNodeToSquizNode = (node) => {
|
|
178
181
|
if (node?.type?.name !== 'doc') {
|
179
182
|
throw new Error('Unable to convert from Remirror to Node data structure, unexpected node provided.');
|
180
183
|
}
|
181
|
-
|
184
|
+
// Squiz FormattedText should be set to undefined
|
185
|
+
// To allow validation on required values
|
186
|
+
if ((0, remirror_1.isDocNodeEmpty)(node) || node.childCount === 0) {
|
187
|
+
return undefined;
|
188
|
+
}
|
189
|
+
const transformedFragment = transformFragment(node.content);
|
190
|
+
return transformedFragment;
|
182
191
|
};
|
183
192
|
exports.remirrorNodeToSquizNode = remirrorNodeToSquizNode;
|
@@ -6,4 +6,4 @@ import { FORMATTED_TEXT_MODELS as FormattedTextModels } from '@squiz/dx-json-sch
|
|
6
6
|
* @export
|
7
7
|
* @returns {RemirrorJSON} The converted Remirror JSON.
|
8
8
|
*/
|
9
|
-
export declare const squizNodeToRemirrorNode: (nodes
|
9
|
+
export declare const squizNodeToRemirrorNode: (nodes?: FormattedTextModels.v1.FormattedText) => RemirrorJSON;
|
@@ -143,7 +143,7 @@ const formatNode = (node) => {
|
|
143
143
|
* @export
|
144
144
|
* @returns {RemirrorJSON} The converted Remirror JSON.
|
145
145
|
*/
|
146
|
-
const squizNodeToRemirrorNode = (nodes) => {
|
146
|
+
const squizNodeToRemirrorNode = (nodes = []) => {
|
147
147
|
let children = [];
|
148
148
|
nodes.forEach((node) => {
|
149
149
|
try {
|
package/package.json
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
{
|
2
2
|
"name": "@squiz/formatted-text-editor",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.58.1-alpha.0",
|
4
4
|
"main": "lib/index.js",
|
5
5
|
"types": "lib/index.d.ts",
|
6
6
|
"scripts": {
|
7
7
|
"build": "vite build",
|
8
|
-
"clean": "rimraf ./lib",
|
8
|
+
"clean": "rimraf ./lib tsconfig.tsbuildinfo",
|
9
9
|
"compile": "npm run clean && npm run compile:styles && npm run compile:code",
|
10
10
|
"compile:code": "tsc",
|
11
11
|
"compile:styles": "node build.js",
|
@@ -19,8 +19,8 @@
|
|
19
19
|
"@headlessui/react": "1.7.11",
|
20
20
|
"@mui/icons-material": "5.11.16",
|
21
21
|
"@remirror/react": "2.0.25",
|
22
|
-
"@squiz/dx-json-schema-lib": "1.
|
23
|
-
"@squiz/resource-browser": "1.
|
22
|
+
"@squiz/dx-json-schema-lib": "1.58.1-alpha.0",
|
23
|
+
"@squiz/resource-browser": "1.58.1-alpha.0",
|
24
24
|
"clsx": "1.2.1",
|
25
25
|
"react-hook-form": "7.43.2",
|
26
26
|
"react-image-size": "2.0.0",
|
@@ -74,5 +74,5 @@
|
|
74
74
|
"volta": {
|
75
75
|
"node": "18.15.0"
|
76
76
|
},
|
77
|
-
"gitHead": "
|
77
|
+
"gitHead": "e1147337893bb889e9c5d3a5e6fd0b8ab893e407"
|
78
78
|
}
|
package/src/Editor/Editor.tsx
CHANGED
@@ -17,6 +17,8 @@ type EditorProps = {
|
|
17
17
|
border?: boolean;
|
18
18
|
children?: ReactNode;
|
19
19
|
isFocused?: boolean;
|
20
|
+
label?: string;
|
21
|
+
attributes?: Record<string, string>;
|
20
22
|
};
|
21
23
|
|
22
24
|
const WrappedEditor = () => {
|
@@ -35,7 +37,16 @@ const WrappedEditor = () => {
|
|
35
37
|
return <EditorComponent />;
|
36
38
|
};
|
37
39
|
|
38
|
-
const Editor = ({
|
40
|
+
const Editor = ({
|
41
|
+
content,
|
42
|
+
className,
|
43
|
+
border = true,
|
44
|
+
editable = true,
|
45
|
+
onChange,
|
46
|
+
children,
|
47
|
+
isFocused,
|
48
|
+
attributes,
|
49
|
+
}: EditorProps) => {
|
39
50
|
const { manager, state, setState } = useRemirror({
|
40
51
|
extensions: createExtensions(useContext(EditorContext), useContext(ResourceBrowserContext)),
|
41
52
|
content,
|
@@ -77,6 +88,7 @@ const Editor = ({ content, className, border = true, editable = true, onChange,
|
|
77
88
|
onChange={handleChange}
|
78
89
|
placeholder="Write something"
|
79
90
|
label="Text editor"
|
91
|
+
attributes={attributes}
|
80
92
|
>
|
81
93
|
{editable && <Toolbar isVisible={isVisible} />}
|
82
94
|
{children && <div className="squiz-fte-scope__editor__children">{children}</div>}
|
@@ -457,7 +457,7 @@ describe('remirrorNodeToSquizNode', () => {
|
|
457
457
|
const { editor } = await renderWithEditor(null, { content });
|
458
458
|
|
459
459
|
const result = remirrorNodeToSquizNode(editor.doc);
|
460
|
-
expect(result).
|
460
|
+
expect(result).toBeUndefined();
|
461
461
|
});
|
462
462
|
|
463
463
|
it.each(sharedNodeExamples)(
|
@@ -491,6 +491,17 @@ describe('remirrorNodeToSquizNode', () => {
|
|
491
491
|
|
492
492
|
expect(() => remirrorNodeToSquizNode(editor.doc)).toThrow('Unsupported mark "sup" was applied to node.');
|
493
493
|
});
|
494
|
+
|
495
|
+
it('should ignore empty root node', async () => {
|
496
|
+
const { editor } = await renderWithEditor(null, {
|
497
|
+
content: {
|
498
|
+
type: 'doc',
|
499
|
+
content: [{ type: 'paragraph', content: [] }],
|
500
|
+
},
|
501
|
+
});
|
502
|
+
|
503
|
+
expect(remirrorNodeToSquizNode(editor.doc)).toBeUndefined();
|
504
|
+
});
|
494
505
|
});
|
495
506
|
|
496
507
|
describe('resolveNodeTag', () => {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ProsemirrorNode, Fragment as ProsemirrorFragment, Mark } from 'remirror';
|
1
|
+
import { ProsemirrorNode, Fragment as ProsemirrorFragment, Mark, isDocNodeEmpty } from 'remirror';
|
2
2
|
import { Attrs } from 'prosemirror-model';
|
3
3
|
import { FORMATTED_TEXT_MODELS as FormattedTextModels } from '@squiz/dx-json-schema-lib';
|
4
4
|
import { undefinedIfEmpty } from '../../undefinedIfEmpty';
|
@@ -90,7 +90,9 @@ const transformAttributes = (attributes: Attrs): Record<string, string> => {
|
|
90
90
|
const transformFragment = (fragment: Fragment): FormattedText => {
|
91
91
|
const transformed: FormattedText = [];
|
92
92
|
|
93
|
-
fragment.forEach((child) =>
|
93
|
+
fragment.forEach((child) => {
|
94
|
+
transformed.push(transformNode(child));
|
95
|
+
});
|
94
96
|
|
95
97
|
return transformed;
|
96
98
|
};
|
@@ -216,10 +218,17 @@ const transformMark = (mark: Mark, node: FormattedNode): FormattedNode => {
|
|
216
218
|
* @param {ProsemirrorNode} node Remirror node to convert to component.
|
217
219
|
* @returns {FormattedText} The converted Squiz component JSON.
|
218
220
|
*/
|
219
|
-
export const remirrorNodeToSquizNode = (node: ProsemirrorNode): FormattedText => {
|
221
|
+
export const remirrorNodeToSquizNode = (node: ProsemirrorNode): FormattedText | undefined => {
|
220
222
|
if (node?.type?.name !== 'doc') {
|
221
223
|
throw new Error('Unable to convert from Remirror to Node data structure, unexpected node provided.');
|
222
224
|
}
|
223
225
|
|
224
|
-
|
226
|
+
// Squiz FormattedText should be set to undefined
|
227
|
+
// To allow validation on required values
|
228
|
+
if (isDocNodeEmpty(node) || node.childCount === 0) {
|
229
|
+
return undefined;
|
230
|
+
}
|
231
|
+
|
232
|
+
const transformedFragment = transformFragment(node.content);
|
233
|
+
return transformedFragment;
|
225
234
|
};
|
@@ -160,7 +160,7 @@ const formatNode = (node: FormattedNodes): RemirrorJSON[] => {
|
|
160
160
|
* @export
|
161
161
|
* @returns {RemirrorJSON} The converted Remirror JSON.
|
162
162
|
*/
|
163
|
-
export const squizNodeToRemirrorNode = (nodes: FormattedText): RemirrorJSON => {
|
163
|
+
export const squizNodeToRemirrorNode = (nodes: FormattedText = []): RemirrorJSON => {
|
164
164
|
let children: RemirrorJSON[] = [];
|
165
165
|
|
166
166
|
nodes.forEach((node) => {
|