@squiz/formatted-text-editor 1.56.1-alpha.3 → 1.56.1-alpha.30
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/demo/App.tsx +13 -2
- package/demo/index.scss +0 -6
- package/lib/Editor/Editor.d.ts +3 -1
- package/lib/Editor/Editor.js +7 -8
- package/lib/EditorToolbar/Toolbar.js +18 -17
- package/lib/index.css +53 -51
- package/package.json +5 -6
- package/postcss.config.js +1 -1
- package/src/Editor/Editor.tsx +27 -21
- package/src/Editor/_editor.scss +17 -8
- package/src/EditorToolbar/Toolbar.tsx +25 -23
- package/src/EditorToolbar/_toolbar.scss +19 -17
- package/tailwind.config.cjs +1 -1
package/demo/App.tsx
CHANGED
@@ -8,7 +8,7 @@ import TextFieldsOutlinedIcon from '@mui/icons-material/TextFieldsOutlined';
|
|
8
8
|
import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined';
|
9
9
|
import { VerticalDivider } from '@remirror/react-components';
|
10
10
|
const ComponentHandlers = () => (
|
11
|
-
<div style={{ display: 'flex', justifyContent: 'flex-end',
|
11
|
+
<div style={{ display: 'flex', justifyContent: 'flex-end', maxHeight: '2rem' }}>
|
12
12
|
<Button icon={<TextFieldsOutlinedIcon />} onClick={(x) => x} />
|
13
13
|
<VerticalDivider />
|
14
14
|
<Button icon={<DeleteOutlineOutlinedIcon />} onClick={(x) => x} />
|
@@ -16,12 +16,13 @@ const ComponentHandlers = () => (
|
|
16
16
|
);
|
17
17
|
|
18
18
|
function App() {
|
19
|
-
const [showChildren] = useState(false);
|
19
|
+
const [showChildren, setShowChildren] = useState(false);
|
20
20
|
const [doc, setDoc] = useState('');
|
21
21
|
const [squizDoc, setSquizDoc] = useState('');
|
22
22
|
const [reconvertedDoc, setReconvertedDoc] = useState('');
|
23
23
|
const [error, setError] = useState<unknown>(null);
|
24
24
|
const [editable, setEditable] = useState(true);
|
25
|
+
const [border, setBorder] = useState(true);
|
25
26
|
|
26
27
|
const handleEditorChange: RemirrorEventListener<Extension> = (parameter) => {
|
27
28
|
try {
|
@@ -44,6 +45,15 @@ function App() {
|
|
44
45
|
<div className="form-group">
|
45
46
|
<label htmlFor="editable">Editable</label>
|
46
47
|
<input id="editable" type="checkbox" onChange={() => setEditable(!editable)} checked={editable} />
|
48
|
+
<label htmlFor="border">Border</label>
|
49
|
+
<input id="border" type="checkbox" onChange={() => setBorder(!border)} checked={border} />
|
50
|
+
<label htmlFor="showChildren">Show children</label>
|
51
|
+
<input
|
52
|
+
id="showChildren"
|
53
|
+
type="checkbox"
|
54
|
+
onChange={() => setShowChildren(!showChildren)}
|
55
|
+
checked={showChildren}
|
56
|
+
/>
|
47
57
|
</div>
|
48
58
|
</div>
|
49
59
|
<h1>Editor</h1>
|
@@ -51,6 +61,7 @@ function App() {
|
|
51
61
|
<AppContext>
|
52
62
|
<Editor
|
53
63
|
editable={editable}
|
64
|
+
border={border}
|
54
65
|
content={`<p>Hello <a href="https://www.google.com"><strong>Mr Bean</strong></a>, nice to <a href="https://www.google.com">meet you</a>.<img src="https://media2.giphy.com/media/3o6ozsIxg5legYvggo/giphy.gif" height="150" width="200"/></p>`}
|
55
66
|
onChange={handleEditorChange}
|
56
67
|
>
|
package/demo/index.scss
CHANGED
package/lib/Editor/Editor.d.ts
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
import { ReactNode } from 'react';
|
2
2
|
import { RemirrorContentType, RemirrorEventListener, Extension } from '@remirror/core';
|
3
3
|
type EditorProps = {
|
4
|
+
className?: string;
|
4
5
|
content?: RemirrorContentType;
|
5
6
|
onChange?: RemirrorEventListener<Extension>;
|
6
7
|
editable?: boolean;
|
8
|
+
border?: boolean;
|
7
9
|
children?: ReactNode;
|
8
10
|
isFocused?: boolean;
|
9
11
|
};
|
10
|
-
declare const Editor: ({ content, editable, onChange, children, isFocused }: EditorProps) => JSX.Element;
|
12
|
+
declare const Editor: ({ content, className, border, editable, onChange, children, isFocused }: EditorProps) => JSX.Element;
|
11
13
|
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, editable = true, onChange, children, isFocused }) => {
|
50
|
+
const Editor = ({ content, className, border = true, editable = true, onChange, children, isFocused }) => {
|
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,
|
@@ -65,12 +65,11 @@ const Editor = ({ content, editable = true, onChange, children, isFocused }) =>
|
|
65
65
|
manager.view.dom.focus();
|
66
66
|
}
|
67
67
|
}, []);
|
68
|
-
return (react_1.default.createElement("div", { className:
|
69
|
-
react_1.default.createElement(
|
70
|
-
react_1.default.createElement(
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
editable && react_1.default.createElement(EditorToolbar_1.FloatingToolbar, null)))));
|
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" },
|
70
|
+
editable && react_1.default.createElement(EditorToolbar_1.Toolbar, { isVisible: isVisible }),
|
71
|
+
children && react_1.default.createElement("div", { className: "squiz-fte-scope__editor__children" }, children),
|
72
|
+
react_1.default.createElement(WrappedEditor, null),
|
73
|
+
editable && react_1.default.createElement(EditorToolbar_1.FloatingToolbar, null))));
|
75
74
|
};
|
76
75
|
exports.default = Editor;
|
@@ -23,22 +23,23 @@ const HorizontalLineButton_1 = __importDefault(require("./Tools/HorizontalLine/H
|
|
23
23
|
const hooks_1 = require("../hooks");
|
24
24
|
const Toolbar = ({ isVisible }) => {
|
25
25
|
const extensionNames = (0, hooks_1.useExtensionNames)();
|
26
|
-
return (react_1.default.createElement(react_components_1.Toolbar, { className: (0, clsx_1.default)('
|
27
|
-
|
28
|
-
react_1.default.createElement(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
react_1.default.createElement(
|
40
|
-
|
41
|
-
|
42
|
-
|
26
|
+
return (react_1.default.createElement(react_components_1.Toolbar, { className: (0, clsx_1.default)('editor-toolbar header-toolbar', isVisible && 'show-toolbar'), role: "toolbar", tabIndex: 0 },
|
27
|
+
react_1.default.createElement("div", { className: "editor-toolbar__tools" },
|
28
|
+
extensionNames.history && (react_1.default.createElement(react_1.default.Fragment, null,
|
29
|
+
react_1.default.createElement(UndoButton_1.default, null),
|
30
|
+
react_1.default.createElement(RedoButton_1.default, null),
|
31
|
+
react_1.default.createElement(react_components_1.VerticalDivider, null))),
|
32
|
+
extensionNames.heading && extensionNames.paragraph && extensionNames.preformatted && react_1.default.createElement(TextTypeDropdown_1.default, null),
|
33
|
+
extensionNames.bold && react_1.default.createElement(BoldButton_1.default, null),
|
34
|
+
extensionNames.italic && react_1.default.createElement(ItalicButton_1.default, null),
|
35
|
+
extensionNames.underline && react_1.default.createElement(UnderlineButton_1.default, null),
|
36
|
+
extensionNames.nodeFormatting && react_1.default.createElement(TextAlignButtons_1.default, null),
|
37
|
+
extensionNames.listItem && react_1.default.createElement(ListButtons_1.default, null),
|
38
|
+
extensionNames.horizontalRule && react_1.default.createElement(HorizontalLineButton_1.default, null),
|
39
|
+
extensionNames.link && (react_1.default.createElement(react_1.default.Fragment, null,
|
40
|
+
react_1.default.createElement(LinkButton_1.default, null),
|
41
|
+
react_1.default.createElement(RemoveLinkButton_1.default, null))),
|
42
|
+
extensionNames.image && react_1.default.createElement(ImageButton_1.default, null),
|
43
|
+
extensionNames.clearFormatting && react_1.default.createElement(ClearFormattingButton_1.default, null))));
|
43
44
|
};
|
44
45
|
exports.Toolbar = Toolbar;
|
package/lib/index.css
CHANGED
@@ -509,12 +509,15 @@
|
|
509
509
|
white-space: nowrap !important;
|
510
510
|
}
|
511
511
|
.squiz-fte-scope .rounded {
|
512
|
-
border-radius:
|
512
|
+
border-radius: 8px !important;
|
513
513
|
}
|
514
514
|
.squiz-fte-scope .rounded-t-sm {
|
515
515
|
border-top-left-radius: 0.125rem !important;
|
516
516
|
border-top-right-radius: 0.125rem !important;
|
517
517
|
}
|
518
|
+
.squiz-fte-scope .border {
|
519
|
+
border-width: 1px !important;
|
520
|
+
}
|
518
521
|
.squiz-fte-scope .border-0 {
|
519
522
|
border-width: 0px !important;
|
520
523
|
}
|
@@ -741,7 +744,7 @@
|
|
741
744
|
padding: 6px 12px;
|
742
745
|
position: relative;
|
743
746
|
width: 100%;
|
744
|
-
border-radius:
|
747
|
+
border-radius: 8px;
|
745
748
|
border-width: 2px;
|
746
749
|
--tw-border-opacity: 1;
|
747
750
|
border-color: rgb(224 224 224 / var(--tw-border-opacity));
|
@@ -788,27 +791,23 @@
|
|
788
791
|
line-height: 1.23;
|
789
792
|
padding-top: 0.25rem;
|
790
793
|
}
|
791
|
-
.squiz-fte-scope
|
794
|
+
.squiz-fte-scope.squiz-fte-scope__editor {
|
792
795
|
font-family: "Open Sans" !important;
|
793
|
-
border-radius:
|
794
|
-
border-width: 2px;
|
795
|
-
border-style: solid;
|
796
|
+
border-radius: 8px;
|
796
797
|
--tw-border-opacity: 1;
|
797
798
|
border-color: rgb(224 224 224 / var(--tw-border-opacity));
|
798
799
|
--tw-bg-opacity: 1;
|
799
800
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
800
801
|
}
|
801
|
-
.squiz-fte-scope
|
802
|
+
.squiz-fte-scope.squiz-fte-scope__editor:has(.squiz-fte-scope.squiz-fte-scope__editor__children) {
|
803
|
+
min-height: 2rem;
|
804
|
+
width: 100%;
|
805
|
+
}
|
806
|
+
.squiz-fte-scope.squiz-fte-scope__editor:has(.squiz-fte-scope.squiz-fte-scope__editor__children) .remirror-editor {
|
802
807
|
padding-top: 0px;
|
803
|
-
--tw-text-opacity: 1;
|
804
|
-
color: rgb(61 61 61 / var(--tw-text-opacity));
|
805
808
|
}
|
806
|
-
.squiz-fte-scope
|
807
|
-
|
808
|
-
border-bottom-left-radius: 4px;
|
809
|
-
--tw-bg-opacity: 1;
|
810
|
-
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
811
|
-
padding: 0.75rem;
|
809
|
+
.squiz-fte-scope.squiz-fte-scope__editor .remirror-editor {
|
810
|
+
padding: 2rem;
|
812
811
|
--tw-shadow: 0 0 #0000;
|
813
812
|
--tw-shadow-colored: 0 0 #0000;
|
814
813
|
box-shadow:
|
@@ -818,22 +817,27 @@
|
|
818
817
|
overflow: auto;
|
819
818
|
min-height: 15vh;
|
820
819
|
}
|
821
|
-
.squiz-fte-scope
|
822
|
-
.squiz-fte-scope
|
820
|
+
.squiz-fte-scope.squiz-fte-scope__editor .remirror-editor:active,
|
821
|
+
.squiz-fte-scope.squiz-fte-scope__editor .remirror-editor:focus {
|
823
822
|
outline-width: 0px;
|
824
823
|
}
|
825
|
-
.squiz-fte-scope
|
824
|
+
.squiz-fte-scope.squiz-fte-scope__editor .remirror-editor p {
|
826
825
|
display: block;
|
827
826
|
}
|
828
|
-
.squiz-fte-scope
|
827
|
+
.squiz-fte-scope.squiz-fte-scope__editor--bordered {
|
828
|
+
border-width: 2px;
|
829
|
+
border-style: solid;
|
830
|
+
}
|
831
|
+
.squiz-fte-scope.squiz-fte-scope__editor--is-disabled {
|
829
832
|
cursor: not-allowed;
|
833
|
+
border-width: 0px;
|
830
834
|
--tw-bg-opacity: 1;
|
831
|
-
background-color: rgb(
|
835
|
+
background-color: rgb(247 247 247 / var(--tw-bg-opacity));
|
832
836
|
}
|
833
|
-
.squiz-fte-scope
|
837
|
+
.squiz-fte-scope.squiz-fte-scope__editor--is-disabled .remirror-is-empty:first-of-type::before {
|
834
838
|
display: none;
|
835
839
|
}
|
836
|
-
.squiz-fte-scope
|
840
|
+
.squiz-fte-scope.squiz-fte-scope__editor .remirror-is-empty:first-of-type::before {
|
837
841
|
position: absolute;
|
838
842
|
pointer-events: none;
|
839
843
|
height: 0;
|
@@ -842,16 +846,16 @@
|
|
842
846
|
--tw-text-opacity: 1;
|
843
847
|
color: rgb(148 148 148 / var(--tw-text-opacity));
|
844
848
|
}
|
845
|
-
.squiz-fte-scope
|
849
|
+
.squiz-fte-scope.squiz-fte-scope__editor .ProseMirror-selectednode {
|
846
850
|
border-width: 2px;
|
847
851
|
border-style: solid;
|
848
852
|
--tw-border-opacity: 1;
|
849
853
|
border-color: rgb(7 116 210 / var(--tw-border-opacity));
|
850
854
|
}
|
851
|
-
.squiz-fte-scope
|
855
|
+
.squiz-fte-scope.squiz-fte-scope__editor img {
|
852
856
|
display: inline;
|
853
857
|
}
|
854
|
-
.squiz-fte-scope
|
858
|
+
.squiz-fte-scope.squiz-fte-scope__editor:has(.show-toolbar) {
|
855
859
|
border-width: 0px;
|
856
860
|
--tw-shadow: 0 0 0 1px rgba(0,0,0,0.04), 0 1px 12px 4px rgba(0,0,0,0.12);
|
857
861
|
--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color), 0 1px 12px 4px var(--tw-shadow-color);
|
@@ -862,25 +866,25 @@
|
|
862
866
|
}
|
863
867
|
.squiz-fte-scope .editor-toolbar,
|
864
868
|
.squiz-fte-scope__floating-popover {
|
865
|
-
border-top-left-radius:
|
866
|
-
border-top-right-radius:
|
869
|
+
border-top-left-radius: 8px;
|
870
|
+
border-top-right-radius: 8px;
|
871
|
+
background-color: transparent;
|
872
|
+
}
|
873
|
+
.squiz-fte-scope .editor-toolbar__tools {
|
874
|
+
display: flex;
|
875
|
+
width: 100%;
|
876
|
+
flex-wrap: wrap;
|
877
|
+
justify-items: center;
|
867
878
|
border-bottom-width: 2px;
|
868
879
|
border-style: solid;
|
869
880
|
--tw-border-opacity: 1;
|
870
881
|
border-color: rgb(237 237 237 / var(--tw-border-opacity));
|
871
|
-
--tw-bg-opacity: 1;
|
872
|
-
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
873
882
|
padding: 0.25rem;
|
874
|
-
display: flex;
|
875
|
-
justify-items: center;
|
876
|
-
flex-wrap: wrap;
|
877
883
|
}
|
878
|
-
.squiz-fte-scope .editor-
|
879
|
-
.squiz-fte-scope__floating-popover > *:not(:first-child, .MuiDivider-root) {
|
884
|
+
.squiz-fte-scope .editor-toolbar__tools > *:not(:first-child, .MuiDivider-root) {
|
880
885
|
margin: 0 0 0 2px;
|
881
886
|
}
|
882
|
-
.squiz-fte-scope .editor-
|
883
|
-
.squiz-fte-scope__floating-popover .MuiDivider-root {
|
887
|
+
.squiz-fte-scope .editor-toolbar__tools .MuiDivider-root {
|
884
888
|
margin-top: 0px;
|
885
889
|
margin-bottom: 0px;
|
886
890
|
margin-left: 0.25rem;
|
@@ -889,17 +893,17 @@
|
|
889
893
|
margin-right: 2px;
|
890
894
|
height: auto;
|
891
895
|
}
|
892
|
-
.squiz-fte-scope .editor-
|
893
|
-
.squiz-fte-scope__floating-popover .squiz-fte-btn {
|
896
|
+
.squiz-fte-scope .editor-toolbar__tools .squiz-fte-btn {
|
894
897
|
padding: 0.25rem;
|
895
898
|
font-weight: 700;
|
896
899
|
}
|
897
|
-
.squiz-fte-scope .editor-
|
898
|
-
.squiz-fte-scope__floating-popover .squiz-fte-btn ~ .squiz-fte-btn {
|
900
|
+
.squiz-fte-scope .editor-toolbar__tools .squiz-fte-btn ~ .squiz-fte-btn {
|
899
901
|
margin-left: 2px;
|
900
902
|
}
|
901
903
|
.squiz-fte-scope .header-toolbar {
|
902
|
-
transition:
|
904
|
+
transition-duration: 0.3s;
|
905
|
+
transition-property: max-height, opacity;
|
906
|
+
transition-timing-function: ease-out;
|
903
907
|
opacity: 0;
|
904
908
|
max-height: 0;
|
905
909
|
}
|
@@ -928,7 +932,7 @@
|
|
928
932
|
margin-bottom: 0px;
|
929
933
|
}
|
930
934
|
.squiz-fte-scope button.squiz-fte-btn {
|
931
|
-
border-radius:
|
935
|
+
border-radius: 8px;
|
932
936
|
--tw-bg-opacity: 1;
|
933
937
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
934
938
|
font-weight: 700;
|
@@ -974,7 +978,7 @@
|
|
974
978
|
.squiz-fte-scope .toolbar-dropdown__button {
|
975
979
|
display: flex;
|
976
980
|
align-items: center;
|
977
|
-
border-radius:
|
981
|
+
border-radius: 8px;
|
978
982
|
font-family:
|
979
983
|
Open Sans,
|
980
984
|
Arial,
|
@@ -1001,7 +1005,7 @@
|
|
1001
1005
|
height: 1.5rem;
|
1002
1006
|
}
|
1003
1007
|
.squiz-fte-scope .toolbar-dropdown__menu {
|
1004
|
-
border-radius:
|
1008
|
+
border-radius: 8px;
|
1005
1009
|
border-width: 1px;
|
1006
1010
|
--tw-border-opacity: 1;
|
1007
1011
|
border-color: rgb(224 224 224 / var(--tw-border-opacity));
|
@@ -1148,24 +1152,22 @@
|
|
1148
1152
|
display: flex;
|
1149
1153
|
align-items: center;
|
1150
1154
|
justify-content: flex-end;
|
1151
|
-
border-bottom-right-radius:
|
1152
|
-
border-bottom-left-radius:
|
1155
|
+
border-bottom-right-radius: 8px;
|
1156
|
+
border-bottom-left-radius: 8px;
|
1153
1157
|
}
|
1154
1158
|
.squiz-fte-scope .squiz-fte-modal-footer__button {
|
1155
1159
|
font-size: 0.875rem;
|
1156
1160
|
font-weight: 700;
|
1157
1161
|
}
|
1158
|
-
.squiz-fte-scope .editor-
|
1159
|
-
.squiz-fte-scope__floating-popover .squiz-fte-modal-footer__button {
|
1162
|
+
.squiz-fte-scope .editor-toolbar__tools .squiz-fte-modal-footer__button {
|
1160
1163
|
padding: 0.25rem;
|
1161
1164
|
font-weight: 700;
|
1162
1165
|
}
|
1163
|
-
.squiz-fte-scope .editor-
|
1164
|
-
.squiz-fte-scope__floating-popover .squiz-fte-modal-footer__button ~ .squiz-fte-btn {
|
1166
|
+
.squiz-fte-scope .editor-toolbar__tools .squiz-fte-modal-footer__button ~ .squiz-fte-btn {
|
1165
1167
|
margin-left: 2px;
|
1166
1168
|
}
|
1167
1169
|
.squiz-fte-scope button.squiz-fte-modal-footer__button {
|
1168
|
-
border-radius:
|
1170
|
+
border-radius: 8px;
|
1169
1171
|
--tw-bg-opacity: 1;
|
1170
1172
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
1171
1173
|
font-weight: 700;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@squiz/formatted-text-editor",
|
3
|
-
"version": "1.56.1-alpha.
|
3
|
+
"version": "1.56.1-alpha.30",
|
4
4
|
"main": "lib/index.js",
|
5
5
|
"types": "lib/index.d.ts",
|
6
6
|
"scripts": {
|
@@ -10,7 +10,6 @@
|
|
10
10
|
"compile:code": "tsc",
|
11
11
|
"compile:styles": "node build.js",
|
12
12
|
"dev": "vite",
|
13
|
-
"preview": "vite preview",
|
14
13
|
"test": "jest",
|
15
14
|
"test:coverage": "jest --coverage",
|
16
15
|
"test:e2e": "vite build && vite preview --port 8080 & cypress open",
|
@@ -20,8 +19,8 @@
|
|
20
19
|
"@headlessui/react": "1.7.11",
|
21
20
|
"@mui/icons-material": "5.11.16",
|
22
21
|
"@remirror/react": "2.0.25",
|
23
|
-
"@squiz/dx-json-schema-lib": "1.56.1-alpha.
|
24
|
-
"@squiz/resource-browser": "1.56.1-alpha.
|
22
|
+
"@squiz/dx-json-schema-lib": "1.56.1-alpha.30",
|
23
|
+
"@squiz/resource-browser": "1.56.1-alpha.30",
|
25
24
|
"clsx": "1.2.1",
|
26
25
|
"react-hook-form": "7.43.2",
|
27
26
|
"react-image-size": "2.0.0",
|
@@ -55,7 +54,7 @@
|
|
55
54
|
"tailwindcss": "3.2.6",
|
56
55
|
"ts-jest": "29.0.5",
|
57
56
|
"typescript": "4.9.3",
|
58
|
-
"vite": "4.
|
57
|
+
"vite": "^4.5.0"
|
59
58
|
},
|
60
59
|
"peerDependencies": {
|
61
60
|
"@types/react": "^16.14.0 || ^17 || ^18",
|
@@ -75,5 +74,5 @@
|
|
75
74
|
"volta": {
|
76
75
|
"node": "18.15.0"
|
77
76
|
},
|
78
|
-
"gitHead": "
|
77
|
+
"gitHead": "a7c213b73e9131ac1739a6212820ea54e7839042"
|
79
78
|
}
|
package/postcss.config.js
CHANGED
@@ -5,7 +5,7 @@ module.exports = {
|
|
5
5
|
require('postcss-nested'),
|
6
6
|
require('postcss-prefix-selector')({
|
7
7
|
prefix: '.squiz-fte-scope',
|
8
|
-
exclude: [/\.squiz-fte-scope__floating-popover/],
|
8
|
+
exclude: [/\.squiz-fte-scope__floating-popover/, /\.squiz-fte-scope__editor/],
|
9
9
|
includeFiles: ['./src/index.scss'],
|
10
10
|
}),
|
11
11
|
],
|
package/src/Editor/Editor.tsx
CHANGED
@@ -10,9 +10,11 @@ import useFocus from '../hooks/useFocus';
|
|
10
10
|
import { ResourceBrowserContext } from '@squiz/resource-browser';
|
11
11
|
|
12
12
|
type EditorProps = {
|
13
|
+
className?: string;
|
13
14
|
content?: RemirrorContentType;
|
14
15
|
onChange?: RemirrorEventListener<Extension>;
|
15
16
|
editable?: boolean;
|
17
|
+
border?: boolean;
|
16
18
|
children?: ReactNode;
|
17
19
|
isFocused?: boolean;
|
18
20
|
};
|
@@ -33,7 +35,7 @@ const WrappedEditor = () => {
|
|
33
35
|
return <EditorComponent />;
|
34
36
|
};
|
35
37
|
|
36
|
-
const Editor = ({ content, editable = true, onChange, children, isFocused }: EditorProps) => {
|
38
|
+
const Editor = ({ content, className, border = true, editable = true, onChange, children, isFocused }: EditorProps) => {
|
37
39
|
const { manager, state, setState } = useRemirror({
|
38
40
|
extensions: createExtensions(useContext(EditorContext), useContext(ResourceBrowserContext)),
|
39
41
|
content,
|
@@ -56,27 +58,31 @@ const Editor = ({ content, editable = true, onChange, children, isFocused }: Edi
|
|
56
58
|
}, []);
|
57
59
|
|
58
60
|
return (
|
59
|
-
<div
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
<div
|
62
|
+
ref={wrapperRef}
|
63
|
+
onBlur={handleBlur}
|
64
|
+
onFocusCapture={handleFocus}
|
65
|
+
className={clsx(
|
66
|
+
'squiz-fte-scope',
|
67
|
+
'squiz-fte-scope__editor',
|
68
|
+
!editable && 'squiz-fte-scope__editor--is-disabled',
|
69
|
+
border && 'squiz-fte-scope__editor--bordered',
|
70
|
+
className,
|
71
|
+
)}
|
72
|
+
>
|
73
|
+
<Remirror
|
74
|
+
manager={manager}
|
75
|
+
state={state}
|
76
|
+
editable={editable}
|
77
|
+
onChange={handleChange}
|
78
|
+
placeholder="Write something"
|
79
|
+
label="Text editor"
|
65
80
|
>
|
66
|
-
<
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
placeholder="Write something"
|
72
|
-
label="Text editor"
|
73
|
-
>
|
74
|
-
{editable && <Toolbar isVisible={isVisible} />}
|
75
|
-
{children}
|
76
|
-
<WrappedEditor />
|
77
|
-
{editable && <FloatingToolbar />}
|
78
|
-
</Remirror>
|
79
|
-
</div>
|
81
|
+
{editable && <Toolbar isVisible={isVisible} />}
|
82
|
+
{children && <div className="squiz-fte-scope__editor__children">{children}</div>}
|
83
|
+
<WrappedEditor />
|
84
|
+
{editable && <FloatingToolbar />}
|
85
|
+
</Remirror>
|
80
86
|
</div>
|
81
87
|
);
|
82
88
|
};
|
package/src/Editor/_editor.scss
CHANGED
@@ -1,13 +1,19 @@
|
|
1
|
-
.
|
1
|
+
/* 2 class selectors so specificity is higher vs eg. ".squiz-ce-scope *" which would take priority over this. */
|
2
|
+
.squiz-fte-scope.squiz-fte-scope__editor {
|
2
3
|
font-family: 'Open Sans' !important;
|
3
|
-
@apply bg-white rounded border-gray-300
|
4
|
+
@apply bg-white rounded border-gray-300;
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
&:has(&__children) {
|
7
|
+
/* The children replace the space taken up by top padding of the editor when present. */
|
8
|
+
@apply w-full min-h-[2rem];
|
9
|
+
|
10
|
+
.remirror-editor {
|
11
|
+
@apply pt-0;
|
12
|
+
}
|
7
13
|
}
|
8
14
|
|
9
15
|
.remirror-editor {
|
10
|
-
@apply
|
16
|
+
@apply shadow-none p-8;
|
11
17
|
overflow: auto;
|
12
18
|
min-height: 15vh;
|
13
19
|
|
@@ -22,10 +28,13 @@
|
|
22
28
|
}
|
23
29
|
}
|
24
30
|
|
31
|
+
&--bordered {
|
32
|
+
@apply border-2 border-solid;
|
33
|
+
}
|
34
|
+
|
25
35
|
&--is-disabled {
|
26
|
-
|
27
|
-
|
28
|
-
}
|
36
|
+
@apply bg-gray-50 border-0 cursor-not-allowed;
|
37
|
+
|
29
38
|
.remirror-is-empty:first-of-type::before {
|
30
39
|
display: none;
|
31
40
|
}
|
@@ -24,32 +24,34 @@ export const Toolbar = ({ isVisible }: ToolbarProps) => {
|
|
24
24
|
|
25
25
|
return (
|
26
26
|
<RemirrorToolbar
|
27
|
-
className={clsx('
|
27
|
+
className={clsx('editor-toolbar header-toolbar', isVisible && 'show-toolbar')}
|
28
28
|
role="toolbar"
|
29
29
|
tabIndex={0}
|
30
30
|
>
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
31
|
+
<div className="editor-toolbar__tools">
|
32
|
+
{extensionNames.history && (
|
33
|
+
<>
|
34
|
+
<UndoButton />
|
35
|
+
<RedoButton />
|
36
|
+
<VerticalDivider />
|
37
|
+
</>
|
38
|
+
)}
|
39
|
+
{extensionNames.heading && extensionNames.paragraph && extensionNames.preformatted && <TextTypeDropdown />}
|
40
|
+
{extensionNames.bold && <BoldButton />}
|
41
|
+
{extensionNames.italic && <ItalicButton />}
|
42
|
+
{extensionNames.underline && <UnderlineButton />}
|
43
|
+
{extensionNames.nodeFormatting && <TextAlignButtons />}
|
44
|
+
{extensionNames.listItem && <ListButtons />}
|
45
|
+
{extensionNames.horizontalRule && <HorizontalLineButton />}
|
46
|
+
{extensionNames.link && (
|
47
|
+
<>
|
48
|
+
<LinkButton />
|
49
|
+
<RemoveLinkButton />
|
50
|
+
</>
|
51
|
+
)}
|
52
|
+
{extensionNames.image && <ImageButton />}
|
53
|
+
{extensionNames.clearFormatting && <ClearFormattingButton />}
|
54
|
+
</div>
|
53
55
|
</RemirrorToolbar>
|
54
56
|
);
|
55
57
|
};
|
@@ -1,30 +1,32 @@
|
|
1
1
|
.editor-toolbar {
|
2
|
-
@apply bg-
|
2
|
+
@apply bg-transparent rounded-t;
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
flex-wrap: wrap;
|
4
|
+
&__tools {
|
5
|
+
@apply border-gray-200 border-b-2 border-solid p-1 w-full flex flex-wrap justify-items-center;
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
> *:not(:first-child, .MuiDivider-root) {
|
8
|
+
margin: 0 0 0 2px;
|
9
|
+
}
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
.MuiDivider-root {
|
12
|
+
@apply my-0 mx-1 border;
|
13
|
+
margin-right: 2px;
|
14
|
+
height: auto;
|
15
|
+
}
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
.squiz-fte-btn {
|
18
|
+
@apply p-1 font-bold;
|
19
|
+
~ .squiz-fte-btn {
|
20
|
+
margin-left: 2px;
|
21
|
+
}
|
22
22
|
}
|
23
23
|
}
|
24
24
|
}
|
25
25
|
|
26
26
|
.header-toolbar {
|
27
|
-
transition:
|
27
|
+
transition-duration: 0.3s;
|
28
|
+
transition-property: max-height, opacity;
|
29
|
+
transition-timing-function: ease-out;
|
28
30
|
opacity: 0;
|
29
31
|
max-height: 0;
|
30
32
|
|