@squiz/formatted-text-editor 1.21.1-alpha.13 → 1.21.1-alpha.16
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.js +5 -4
- package/lib/index.css +9 -2
- package/package.json +4 -3
- package/src/Editor/Editor.spec.tsx +24 -0
- package/src/Editor/Editor.tsx +5 -4
- package/src/Editor/_editor.scss +11 -4
- package/src/EditorToolbar/FloatingToolbar.spec.tsx +2 -3
- package/tests/renderWithEditor.tsx +5 -1
package/lib/Editor/Editor.js
CHANGED
@@ -7,7 +7,8 @@ const react_1 = __importDefault(require("react"));
|
|
7
7
|
const react_2 = require("@remirror/react");
|
8
8
|
const EditorToolbar_1 = require("../EditorToolbar");
|
9
9
|
const Extensions_1 = require("../Extensions/Extensions");
|
10
|
-
const
|
10
|
+
const clsx_1 = __importDefault(require("clsx"));
|
11
|
+
const Editor = ({ content, editable = true, onChange }) => {
|
11
12
|
const { manager, state, setState } = (0, react_2.useRemirror)({
|
12
13
|
extensions: Extensions_1.Extensions,
|
13
14
|
content,
|
@@ -19,10 +20,10 @@ const Editor = ({ content, editable, onChange }) => {
|
|
19
20
|
onChange?.(parameter);
|
20
21
|
};
|
21
22
|
return (react_1.default.createElement("div", { className: "squiz-fte-scope" },
|
22
|
-
react_1.default.createElement("div", { className:
|
23
|
+
react_1.default.createElement("div", { className: (0, clsx_1.default)('remirror-theme formatted-text-editor', !editable && 'formatted-text-editor--is-disabled') },
|
23
24
|
react_1.default.createElement(react_2.Remirror, { manager: manager, state: state, editable: editable, onChange: handleChange, placeholder: "Write something", label: "Text editor" },
|
24
|
-
react_1.default.createElement(EditorToolbar_1.Toolbar, null),
|
25
|
+
editable && react_1.default.createElement(EditorToolbar_1.Toolbar, null),
|
25
26
|
react_1.default.createElement(react_2.EditorComponent, null),
|
26
|
-
react_1.default.createElement(EditorToolbar_1.FloatingToolbar, null)))));
|
27
|
+
editable && react_1.default.createElement(EditorToolbar_1.FloatingToolbar, null)))));
|
27
28
|
};
|
28
29
|
exports.default = Editor;
|
package/lib/index.css
CHANGED
@@ -667,8 +667,6 @@
|
|
667
667
|
}
|
668
668
|
.squiz-fte-scope .formatted-text-editor {
|
669
669
|
font-family: "Open Sans" !important;
|
670
|
-
}
|
671
|
-
.squiz-fte-scope .formatted-text-editor.editor-wrapper {
|
672
670
|
border-radius: 4px;
|
673
671
|
border-width: 2px;
|
674
672
|
border-style: solid;
|
@@ -695,6 +693,7 @@
|
|
695
693
|
var(--tw-ring-shadow, 0 0 #0000),
|
696
694
|
var(--tw-shadow);
|
697
695
|
overflow: auto;
|
696
|
+
min-height: 15vh;
|
698
697
|
}
|
699
698
|
.squiz-fte-scope .formatted-text-editor .remirror-editor:active,
|
700
699
|
.squiz-fte-scope .formatted-text-editor .remirror-editor:focus {
|
@@ -703,6 +702,14 @@
|
|
703
702
|
.squiz-fte-scope .formatted-text-editor .remirror-editor p {
|
704
703
|
display: block;
|
705
704
|
}
|
705
|
+
.squiz-fte-scope .formatted-text-editor--is-disabled .remirror-editor {
|
706
|
+
cursor: not-allowed;
|
707
|
+
--tw-bg-opacity: 1;
|
708
|
+
background-color: rgb(224 224 224 / var(--tw-bg-opacity));
|
709
|
+
}
|
710
|
+
.squiz-fte-scope .formatted-text-editor--is-disabled .remirror-is-empty:first-of-type::before {
|
711
|
+
display: none;
|
712
|
+
}
|
706
713
|
.squiz-fte-scope .formatted-text-editor .remirror-is-empty:first-of-type::before {
|
707
714
|
position: absolute;
|
708
715
|
pointer-events: none;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@squiz/formatted-text-editor",
|
3
|
-
"version": "1.21.1-alpha.
|
3
|
+
"version": "1.21.1-alpha.16",
|
4
4
|
"main": "lib/index.js",
|
5
5
|
"types": "lib/index.d.ts",
|
6
6
|
"scripts": {
|
@@ -30,6 +30,7 @@
|
|
30
30
|
"@testing-library/jest-dom": "5.16.5",
|
31
31
|
"@testing-library/react": "14.0.0",
|
32
32
|
"@testing-library/user-event": "14.4.3",
|
33
|
+
"@types/node": "18.15.2",
|
33
34
|
"@types/react": "18.0.26",
|
34
35
|
"@types/react-dom": "18.0.9",
|
35
36
|
"@vitejs/plugin-react": "3.0.0",
|
@@ -68,7 +69,7 @@
|
|
68
69
|
}
|
69
70
|
},
|
70
71
|
"volta": {
|
71
|
-
"node": "
|
72
|
+
"node": "18.15.0"
|
72
73
|
},
|
73
|
-
"gitHead": "
|
74
|
+
"gitHead": "1d008f8debcfd1acaad50d73fa83b51c46253bf4"
|
74
75
|
}
|
@@ -4,6 +4,7 @@ import { act, fireEvent, render, screen } from '@testing-library/react';
|
|
4
4
|
import { MockEditor } from './Editor.mock';
|
5
5
|
import Editor from './Editor';
|
6
6
|
import '@testing-library/jest-dom';
|
7
|
+
import { renderWithEditor } from '../../tests/renderWithEditor';
|
7
8
|
|
8
9
|
const setContent: any = jest.fn();
|
9
10
|
|
@@ -251,4 +252,27 @@ describe('Formatted text editor', () => {
|
|
251
252
|
|
252
253
|
expect(editorNode.textContent).toBe('');
|
253
254
|
});
|
255
|
+
|
256
|
+
it('Should not display the toolbar if is not editable', () => {
|
257
|
+
render(<Editor editable={false} />);
|
258
|
+
expect(screen.queryByRole('button', { name: 'Bold (cmd+B)' })).not.toBeInTheDocument();
|
259
|
+
expect(screen.queryByRole('button', { name: 'Italic (cmd+I)' })).not.toBeInTheDocument();
|
260
|
+
expect(screen.queryByRole('button', { name: 'Underline (cmd+U)' })).not.toBeInTheDocument();
|
261
|
+
});
|
262
|
+
|
263
|
+
it('Should not display the floating toolbar if is not editable', async () => {
|
264
|
+
const from = 3 as number;
|
265
|
+
const to = 17 as number;
|
266
|
+
const { editor } = await renderWithEditor(null, {
|
267
|
+
content: 'My awesome <a href="https://example.org">example</a> content.',
|
268
|
+
editable: false,
|
269
|
+
});
|
270
|
+
|
271
|
+
await act(() => editor.selectText({ from, to }));
|
272
|
+
|
273
|
+
const buttons = screen.queryAllByRole('button');
|
274
|
+
const buttonLabels = buttons.map((button) => button.getAttribute('title'));
|
275
|
+
|
276
|
+
expect(buttonLabels).toEqual([]);
|
277
|
+
});
|
254
278
|
});
|
package/src/Editor/Editor.tsx
CHANGED
@@ -3,6 +3,7 @@ import { EditorComponent, Remirror, useRemirror } from '@remirror/react';
|
|
3
3
|
import { RemirrorContentType, RemirrorEventListener, Extension } from '@remirror/core';
|
4
4
|
import { Toolbar, FloatingToolbar } from '../EditorToolbar';
|
5
5
|
import { Extensions } from '../Extensions/Extensions';
|
6
|
+
import clsx from 'clsx';
|
6
7
|
|
7
8
|
type EditorProps = {
|
8
9
|
content?: RemirrorContentType;
|
@@ -10,7 +11,7 @@ type EditorProps = {
|
|
10
11
|
editable?: boolean;
|
11
12
|
};
|
12
13
|
|
13
|
-
const Editor = ({ content, editable, onChange }: EditorProps) => {
|
14
|
+
const Editor = ({ content, editable = true, onChange }: EditorProps) => {
|
14
15
|
const { manager, state, setState } = useRemirror({
|
15
16
|
extensions: Extensions,
|
16
17
|
content,
|
@@ -25,7 +26,7 @@ const Editor = ({ content, editable, onChange }: EditorProps) => {
|
|
25
26
|
|
26
27
|
return (
|
27
28
|
<div className="squiz-fte-scope">
|
28
|
-
<div className=
|
29
|
+
<div className={clsx('remirror-theme formatted-text-editor', !editable && 'formatted-text-editor--is-disabled')}>
|
29
30
|
<Remirror
|
30
31
|
manager={manager}
|
31
32
|
state={state}
|
@@ -34,9 +35,9 @@ const Editor = ({ content, editable, onChange }: EditorProps) => {
|
|
34
35
|
placeholder="Write something"
|
35
36
|
label="Text editor"
|
36
37
|
>
|
37
|
-
<Toolbar />
|
38
|
+
{editable && <Toolbar />}
|
38
39
|
<EditorComponent />
|
39
|
-
<FloatingToolbar />
|
40
|
+
{editable && <FloatingToolbar />}
|
40
41
|
</Remirror>
|
41
42
|
</div>
|
42
43
|
</div>
|
package/src/Editor/_editor.scss
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
.formatted-text-editor {
|
2
2
|
font-family: 'Open Sans' !important;
|
3
|
-
|
4
|
-
&.editor-wrapper {
|
5
|
-
@apply bg-white rounded border-gray-300 border-2 border-solid;
|
6
|
-
}
|
3
|
+
@apply bg-white rounded border-gray-300 border-2 border-solid;
|
7
4
|
|
8
5
|
.remirror-editor-wrapper {
|
9
6
|
@apply text-gray-800 pt-0;
|
@@ -12,6 +9,7 @@
|
|
12
9
|
.remirror-editor {
|
13
10
|
@apply bg-white shadow-none rounded-b p-3;
|
14
11
|
overflow: auto;
|
12
|
+
min-height: 15vh;
|
15
13
|
|
16
14
|
&:active,
|
17
15
|
&:focus {
|
@@ -24,6 +22,15 @@
|
|
24
22
|
}
|
25
23
|
}
|
26
24
|
|
25
|
+
&--is-disabled {
|
26
|
+
.remirror-editor {
|
27
|
+
@apply bg-gray-300 cursor-not-allowed;
|
28
|
+
}
|
29
|
+
.remirror-is-empty:first-of-type::before {
|
30
|
+
display: none;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
27
34
|
.remirror-is-empty:first-of-type::before {
|
28
35
|
position: absolute;
|
29
36
|
pointer-events: none;
|
@@ -1,7 +1,5 @@
|
|
1
|
-
import React from 'react';
|
2
1
|
import { act, screen } from '@testing-library/react';
|
3
2
|
import { renderWithEditor } from '../../tests';
|
4
|
-
import { FloatingToolbar } from './FloatingToolbar';
|
5
3
|
|
6
4
|
describe('FloatingToolbar', () => {
|
7
5
|
it.each([
|
@@ -15,8 +13,9 @@ describe('FloatingToolbar', () => {
|
|
15
13
|
])(
|
16
14
|
'Renders formatting buttons when text is selected - %s',
|
17
15
|
async (description: string, from: number, to: number, expectedButtons: string[]) => {
|
18
|
-
const { editor } = await renderWithEditor(
|
16
|
+
const { editor } = await renderWithEditor(null, {
|
19
17
|
content: 'My awesome <a href="https://example.org">example</a> content.',
|
18
|
+
editable: true,
|
20
19
|
});
|
21
20
|
|
22
21
|
await act(() => editor.selectText({ from, to }));
|
@@ -6,9 +6,11 @@ import { BuiltinPreset } from 'remirror';
|
|
6
6
|
import { EditorComponent, Remirror, useRemirror } from '@remirror/react';
|
7
7
|
import { Extensions } from '../src/Extensions/Extensions';
|
8
8
|
import { RemirrorTestChain } from 'jest-remirror';
|
9
|
+
import { FloatingToolbar } from '../src/EditorToolbar/FloatingToolbar';
|
9
10
|
|
10
11
|
export type EditorRenderOptions = RenderOptions & {
|
11
12
|
content?: RemirrorContentType;
|
13
|
+
editable?: boolean;
|
12
14
|
extensions?: Extension[];
|
13
15
|
};
|
14
16
|
|
@@ -27,7 +29,7 @@ type EditorRenderResult = {
|
|
27
29
|
};
|
28
30
|
};
|
29
31
|
|
30
|
-
const TestEditor = ({ children, extensions, content, onReady }: TestEditorProps) => {
|
32
|
+
const TestEditor = ({ children, extensions, content, onReady, editable }: TestEditorProps) => {
|
31
33
|
const { manager, state, setState } = useRemirror({
|
32
34
|
extensions: () => extensions || Extensions(),
|
33
35
|
content: content,
|
@@ -43,12 +45,14 @@ const TestEditor = ({ children, extensions, content, onReady }: TestEditorProps)
|
|
43
45
|
<Remirror
|
44
46
|
manager={manager}
|
45
47
|
state={state}
|
48
|
+
editable={editable}
|
46
49
|
onChange={(params) => {
|
47
50
|
setState(params.state);
|
48
51
|
}}
|
49
52
|
>
|
50
53
|
{children}
|
51
54
|
<EditorComponent />
|
55
|
+
{editable && <FloatingToolbar />}
|
52
56
|
</Remirror>
|
53
57
|
);
|
54
58
|
};
|