@pie-lib/editable-html-tip-tap 1.0.1 → 1.0.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.
Files changed (129) hide show
  1. package/lib/components/CharacterPicker.js +221 -0
  2. package/lib/components/EditableHtml.js +323 -0
  3. package/lib/components/MenuBar.js +693 -0
  4. package/lib/components/TiptapContainer.js +90 -0
  5. package/lib/components/buttons/done-button.js +53 -0
  6. package/lib/components/characters/characterUtils.js +112 -0
  7. package/lib/components/characters/custom-popper.js +73 -0
  8. package/lib/components/common/done-button.js +53 -0
  9. package/lib/components/icons/CssIcon.js +37 -0
  10. package/lib/components/icons/RespArea.js +95 -0
  11. package/lib/components/icons/TableIcons.js +69 -0
  12. package/lib/components/icons/TextAlign.js +194 -0
  13. package/lib/components/icons/index.js +194 -0
  14. package/lib/components/image/ImageToolbar.js +16 -0
  15. package/lib/components/image/InsertImageHandler.js +16 -0
  16. package/lib/components/media/MediaDialog.js +16 -0
  17. package/lib/components/media/MediaToolbar.js +16 -0
  18. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +94 -0
  19. package/lib/components/respArea/DragInTheBlank/choice.js +289 -0
  20. package/lib/components/respArea/DragInTheBlank.js +94 -0
  21. package/lib/components/respArea/ExplicitConstructedResponse.js +120 -0
  22. package/lib/components/respArea/InlineDropdown.js +126 -0
  23. package/lib/components/respArea/ToolbarIcon.js +105 -0
  24. package/lib/components/respArea/choice.js +2 -0
  25. package/lib/extensions/component.js +5 -5
  26. package/lib/extensions/custom-toolbar-wrapper.js +2 -4
  27. package/lib/extensions/extended-table.js +30 -0
  28. package/lib/extensions/index.js +52 -0
  29. package/lib/extensions/media.js +5 -5
  30. package/lib/extensions/responseArea.js +7 -7
  31. package/lib/index.js +16 -1454
  32. package/lib/plugins/index.js +10 -82
  33. package/lib/styles/editorContainerStyles.js +200 -0
  34. package/lib/utils/size.js +34 -0
  35. package/package.json +1 -1
  36. package/src/components/CharacterPicker.jsx +185 -0
  37. package/src/components/EditableHtml.jsx +306 -0
  38. package/src/components/MenuBar.jsx +630 -0
  39. package/src/components/TiptapContainer.jsx +96 -0
  40. package/src/components/characters/characterUtils.js +127 -0
  41. package/src/components/image/ImageToolbar.jsx +1 -0
  42. package/src/components/image/InsertImageHandler.js +1 -0
  43. package/src/components/media/MediaDialog.js +1 -0
  44. package/src/components/media/MediaToolbar.jsx +1 -0
  45. package/src/{plugins/respArea/drag-in-the-blank → components/respArea/DragInTheBlank}/choice.jsx +1 -1
  46. package/src/{plugins/respArea/inline-dropdown/index.jsx → components/respArea/InlineDropdown.jsx} +1 -1
  47. package/src/components/respArea/ToolbarIcon.jsx +68 -0
  48. package/src/extensions/component.jsx +2 -2
  49. package/src/extensions/custom-toolbar-wrapper.jsx +6 -7
  50. package/src/extensions/extended-table.js +27 -0
  51. package/src/extensions/index.js +76 -0
  52. package/src/extensions/media.js +10 -4
  53. package/src/extensions/responseArea.js +7 -7
  54. package/src/index.jsx +3 -1409
  55. package/src/styles/editorContainerStyles.js +203 -0
  56. package/src/utils/size.js +32 -0
  57. package/src/__tests__/editor.test.jsx +0 -363
  58. package/src/__tests__/serialization.test.js +0 -291
  59. package/src/block-tags.js +0 -17
  60. package/src/editor.jsx +0 -1197
  61. package/src/extensions/characters.js +0 -46
  62. package/src/old-index.jsx +0 -162
  63. package/src/parse-html.js +0 -8
  64. package/src/plugins/README.md +0 -27
  65. package/src/plugins/characters/index.jsx +0 -284
  66. package/src/plugins/characters/utils.js +0 -447
  67. package/src/plugins/css/index.jsx +0 -340
  68. package/src/plugins/customPlugin/index.jsx +0 -85
  69. package/src/plugins/html/icons/index.jsx +0 -19
  70. package/src/plugins/html/index.jsx +0 -72
  71. package/src/plugins/image/__tests__/__snapshots__/component.test.jsx.snap +0 -51
  72. package/src/plugins/image/__tests__/__snapshots__/image-toolbar-logic.test.jsx.snap +0 -27
  73. package/src/plugins/image/__tests__/__snapshots__/image-toolbar.test.jsx.snap +0 -44
  74. package/src/plugins/image/__tests__/component.test.jsx +0 -41
  75. package/src/plugins/image/__tests__/image-toolbar-logic.test.jsx +0 -42
  76. package/src/plugins/image/__tests__/image-toolbar.test.jsx +0 -11
  77. package/src/plugins/image/__tests__/index.test.js +0 -95
  78. package/src/plugins/image/__tests__/insert-image-handler.test.js +0 -113
  79. package/src/plugins/image/__tests__/mock-change.js +0 -15
  80. package/src/plugins/image/alt-dialog.jsx +0 -82
  81. package/src/plugins/image/component.jsx +0 -343
  82. package/src/plugins/image/image-toolbar.jsx +0 -100
  83. package/src/plugins/image/index.jsx +0 -227
  84. package/src/plugins/image/insert-image-handler.js +0 -79
  85. package/src/plugins/index.jsx +0 -377
  86. package/src/plugins/list/__tests__/index.test.js +0 -54
  87. package/src/plugins/list/index.jsx +0 -305
  88. package/src/plugins/math/__tests__/__snapshots__/index.test.jsx.snap +0 -48
  89. package/src/plugins/math/__tests__/index.test.jsx +0 -245
  90. package/src/plugins/math/index.jsx +0 -379
  91. package/src/plugins/media/__tests__/index.test.js +0 -75
  92. package/src/plugins/media/index.jsx +0 -325
  93. package/src/plugins/media/media-dialog.js +0 -624
  94. package/src/plugins/media/media-toolbar.jsx +0 -56
  95. package/src/plugins/media/media-wrapper.jsx +0 -43
  96. package/src/plugins/rendering/index.js +0 -31
  97. package/src/plugins/respArea/index.jsx +0 -299
  98. package/src/plugins/respArea/math-templated/index.jsx +0 -104
  99. package/src/plugins/respArea/utils.jsx +0 -90
  100. package/src/plugins/table/CustomTablePlugin.js +0 -113
  101. package/src/plugins/table/__tests__/__snapshots__/table-toolbar.test.jsx.snap +0 -44
  102. package/src/plugins/table/__tests__/index.test.jsx +0 -401
  103. package/src/plugins/table/__tests__/table-toolbar.test.jsx +0 -42
  104. package/src/plugins/table/index.jsx +0 -427
  105. package/src/plugins/table/table-toolbar.jsx +0 -136
  106. package/src/plugins/textAlign/index.jsx +0 -23
  107. package/src/plugins/toolbar/__tests__/__snapshots__/default-toolbar.test.jsx.snap +0 -923
  108. package/src/plugins/toolbar/__tests__/__snapshots__/editor-and-toolbar.test.jsx.snap +0 -20
  109. package/src/plugins/toolbar/__tests__/__snapshots__/toolbar-buttons.test.jsx.snap +0 -36
  110. package/src/plugins/toolbar/__tests__/__snapshots__/toolbar.test.jsx.snap +0 -46
  111. package/src/plugins/toolbar/__tests__/default-toolbar.test.jsx +0 -94
  112. package/src/plugins/toolbar/__tests__/editor-and-toolbar.test.jsx +0 -37
  113. package/src/plugins/toolbar/__tests__/toolbar-buttons.test.jsx +0 -51
  114. package/src/plugins/toolbar/__tests__/toolbar.test.jsx +0 -106
  115. package/src/plugins/toolbar/default-toolbar.jsx +0 -206
  116. package/src/plugins/toolbar/editor-and-toolbar.jsx +0 -257
  117. package/src/plugins/toolbar/index.jsx +0 -23
  118. package/src/plugins/toolbar/toolbar-buttons.jsx +0 -138
  119. package/src/plugins/toolbar/toolbar.jsx +0 -338
  120. package/src/plugins/utils.js +0 -31
  121. package/src/serialization.jsx +0 -621
  122. /package/src/{plugins → components}/characters/custom-popper.js +0 -0
  123. /package/src/{plugins/toolbar → components/common}/done-button.jsx +0 -0
  124. /package/src/{plugins/css/icons/index.jsx → components/icons/CssIcon.jsx} +0 -0
  125. /package/src/{plugins/respArea/icons/index.jsx → components/icons/RespArea.jsx} +0 -0
  126. /package/src/{plugins/table/icons/index.jsx → components/icons/TableIcons.jsx} +0 -0
  127. /package/src/{plugins/textAlign/icons/index.jsx → components/icons/TextAlign.jsx} +0 -0
  128. /package/src/{plugins/respArea/drag-in-the-blank/index.jsx → components/respArea/DragInTheBlank/DragInTheBlank.jsx} +0 -0
  129. /package/src/{plugins/respArea/explicit-constructed-response/index.jsx → components/respArea/ExplicitConstructedResponse.jsx} +0 -0
@@ -0,0 +1,185 @@
1
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import PropTypes from 'prop-types';
4
+ import get from 'lodash/get';
5
+
6
+ import { PureToolbar } from '@pie-lib/math-toolbar';
7
+
8
+ import CustomPopper from './characters/custom-popper';
9
+ import { spanishConfig, specialConfig } from './characters/characterUtils';
10
+
11
+ const CharacterIcon = ({ letter }) => (
12
+ <div
13
+ style={{
14
+ fontSize: '24px',
15
+ lineHeight: '24px',
16
+ }}
17
+ >
18
+ {letter}
19
+ </div>
20
+ );
21
+
22
+ CharacterIcon.propTypes = {
23
+ letter: PropTypes.string,
24
+ };
25
+
26
+ export function CharacterPicker({ editor, opts, onClose }) {
27
+ if (!opts?.characters?.length) {
28
+ return null;
29
+ }
30
+
31
+ const containerRef = useRef(null);
32
+ const [position, setPosition] = useState({ top: 0, left: 0 });
33
+ const [popover, setPopover] = useState(null);
34
+
35
+ const configToUse = useMemo(() => {
36
+ if (!opts) return spanishConfig;
37
+
38
+ switch (true) {
39
+ case opts.language === 'spanish':
40
+ return spanishConfig;
41
+ case opts.language === 'special':
42
+ return specialConfig;
43
+ default:
44
+ return opts;
45
+ }
46
+ }, [opts]);
47
+
48
+ const layoutForCharacters = useMemo(
49
+ () =>
50
+ configToUse.characters.reduce(
51
+ (obj, arr) => {
52
+ if (arr.length >= obj.columns) {
53
+ obj.columns = arr.length;
54
+ }
55
+
56
+ return obj;
57
+ },
58
+ { rows: configToUse.characters.length, columns: 0 },
59
+ ),
60
+ [configToUse],
61
+ );
62
+
63
+ const closePopOver = () => setPopover(null);
64
+
65
+ useEffect(
66
+ () => () => {
67
+ closePopOver();
68
+ },
69
+ [],
70
+ );
71
+
72
+ useEffect(() => {
73
+ if (!editor) return;
74
+
75
+ // Calculate position relative to selection
76
+ const bodyRect = document.body.getBoundingClientRect();
77
+ const { from } = editor.state.selection;
78
+ const start = editor.view.coordsAtPos(from);
79
+ setPosition({
80
+ top: start.top + Math.abs(bodyRect.top) + 40, // shift above
81
+ left: start.left,
82
+ });
83
+
84
+ const handleClickOutside = (e) => {
85
+ if (containerRef.current && !containerRef.current.contains(e.target) && !editor.view.dom.contains(e.target)) {
86
+ onClose();
87
+ }
88
+ };
89
+
90
+ document.addEventListener('mousedown', handleClickOutside);
91
+ return () => document.removeEventListener('mousedown', handleClickOutside);
92
+ }, [editor, onClose]);
93
+
94
+ const renderPopOver = (event, el) => setPopover({ anchorEl: event.currentTarget, el });
95
+
96
+ const handleChange = (val) => {
97
+ if (typeof val === 'string') {
98
+ editor
99
+ .chain()
100
+ .focus()
101
+ .insertContent(val)
102
+ .run();
103
+ }
104
+ };
105
+
106
+ return (
107
+ <>
108
+ {ReactDOM.createPortal(
109
+ <div
110
+ ref={containerRef}
111
+ className="insert-character-dialog"
112
+ style={{
113
+ position: 'absolute',
114
+ top: `${position.top}px`,
115
+ left: `${position.left}px`,
116
+ maxWidth: '500px',
117
+ }}
118
+ >
119
+ <div>
120
+ <PureToolbar
121
+ keyPadCharacterRef={opts.keyPadCharacterRef}
122
+ setKeypadInteraction={opts.setKeypadInteraction}
123
+ autoFocus
124
+ noDecimal
125
+ hideInput
126
+ noLatexHandling
127
+ hideDoneButtonBackground
128
+ layoutForKeyPad={layoutForCharacters}
129
+ additionalKeys={configToUse.characters.reduce((arr, n) => {
130
+ arr = [
131
+ ...arr,
132
+ ...n.map((k) => ({
133
+ name: get(k, 'name') || k,
134
+ write: get(k, 'write') || k,
135
+ label: get(k, 'label') || k,
136
+ category: 'character',
137
+ extraClass: 'character',
138
+ extraProps: {
139
+ ...(k.extraProps || {}),
140
+ style: {
141
+ ...(k.extraProps || {}).style,
142
+ border: '1px solid #000',
143
+ },
144
+ },
145
+ ...(configToUse.hasPreview
146
+ ? {
147
+ actions: {
148
+ onMouseEnter: (ev) => renderPopOver(ev, k),
149
+ onMouseLeave: closePopOver,
150
+ },
151
+ }
152
+ : {}),
153
+ })),
154
+ ];
155
+
156
+ return arr;
157
+ }, [])}
158
+ keypadMode="language"
159
+ onChange={handleChange}
160
+ onDone={onClose}
161
+ />
162
+ </div>
163
+ </div>,
164
+ document.body,
165
+ )}
166
+ {popover &&
167
+ ReactDOM.createPortal(
168
+ <CustomPopper onClose={closePopOver} anchorEl={popover.anchorEl}>
169
+ <div>{popover.el.label}</div>
170
+ <div style={{ fontSize: 20, lineHeight: '20px' }}>{popover.el.description}</div>
171
+ <div style={{ fontSize: 20, lineHeight: '20px' }}>{popover.el.unicode}</div>
172
+ </CustomPopper>,
173
+ document.body,
174
+ )}
175
+ </>
176
+ );
177
+ }
178
+
179
+ CharacterPicker.propTypes = {
180
+ editor: PropTypes.object,
181
+ opts: PropTypes.object,
182
+ onClose: PropTypes.func.isRequired,
183
+ };
184
+
185
+ export { CharacterIcon };
@@ -0,0 +1,306 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { EditorContent, useEditor, useEditorState } from '@tiptap/react';
3
+ import StarterKit from '@tiptap/starter-kit';
4
+ import { TextStyleKit } from '@tiptap/extension-text-style';
5
+ import SuperScript from '@tiptap/extension-superscript';
6
+ import SubScript from '@tiptap/extension-subscript';
7
+ import TextAlign from '@tiptap/extension-text-align';
8
+ import Image from '@tiptap/extension-image';
9
+ import { withStyles } from '@material-ui/core/styles';
10
+
11
+ import ExtendedTable from '../extensions/extended-table';
12
+ import { TableRow } from '@tiptap/extension-table-row';
13
+ import { TableCell } from '@tiptap/extension-table-cell';
14
+ import { TableHeader } from '@tiptap/extension-table-header';
15
+ import {
16
+ ExplicitConstructedResponseNode,
17
+ DragInTheBlankNode,
18
+ InlineDropdownNode,
19
+ ResponseAreaExtension,
20
+ } from '../extensions/responseArea';
21
+ import { MathNode } from '../extensions/math';
22
+ import { ImageUploadNode } from '../extensions/image';
23
+ import { Media } from '../extensions/media';
24
+ import { CSSMark } from '../extensions/css';
25
+
26
+ import EditorContainer from './TiptapContainer';
27
+ import { valueToSize } from '../utils/size';
28
+ import { buildExtensions } from '../extensions';
29
+
30
+ const defaultToolbarOpts = {
31
+ position: 'bottom',
32
+ alignment: 'left',
33
+ alwaysVisible: false,
34
+ showDone: true,
35
+ doneOn: 'blur',
36
+ };
37
+
38
+ const defaultResponseAreaProps = {
39
+ options: {},
40
+ respAreaToolbar: () => {},
41
+ onHandleAreaChange: () => {},
42
+ };
43
+
44
+ const DEFAULT_ACTIVE_PLUGINS = [
45
+ 'bold',
46
+ 'italic',
47
+ 'underline',
48
+ 'strikethrough',
49
+ 'code',
50
+ 'bulleted-list',
51
+ 'numbered-list',
52
+ 'image',
53
+ 'math',
54
+ 'languageCharacters',
55
+ 'text-align',
56
+ 'table',
57
+ 'video',
58
+ 'audio',
59
+ 'responseArea',
60
+ 'superscript',
61
+ 'subscript',
62
+ 'css',
63
+ 'h3',
64
+ 'undo',
65
+ 'redo',
66
+ ];
67
+
68
+ const cssVariables = {
69
+ '--white': '#fff',
70
+ '--black': '#2e2b29',
71
+ '--black-contrast': '#110f0e',
72
+ '--gray-1': 'rgba(61, 37, 20, .05)',
73
+ '--gray-2': 'rgba(61, 37, 20, .08)',
74
+ '--gray-3': 'rgba(61, 37, 20, .12)',
75
+ '--gray-4': 'rgba(53, 38, 28, .3)',
76
+ '--gray-5': 'rgba(28, 25, 23, .6)',
77
+ '--green': '#22c55e',
78
+ '--purple': '#6a00f5',
79
+ '--purple-contrast': '#5800cc',
80
+ '--purple-light': 'rgba(88, 5, 255, .05)',
81
+ '--yellow-contrast': '#facc15',
82
+ '--yellow': 'rgba(250, 204, 21, .4)',
83
+ '--yellow-light': '#fffae5',
84
+ '--red': '#ff5c33',
85
+ '--red-light': '#ffebe5',
86
+ '--shadow': `0px 12px 33px 0px rgba(0, 0, 0, .06),
87
+ 0px 3.618px 9.949px 0px rgba(0, 0, 0, .04)`,
88
+ };
89
+
90
+ export const EditableHtml = (props) => {
91
+ const [pendingImages, setPendingImages] = useState([]);
92
+ const [scheduled, setScheduled] = useState(false);
93
+ const { classes, toolbarOpts } = props;
94
+
95
+ const toolbarOptsToUse = {
96
+ ...defaultToolbarOpts,
97
+ ...toolbarOpts,
98
+ };
99
+
100
+ const activePluginsToUse = useMemo(() => {
101
+ let { customPlugins } = props.pluginProps || {};
102
+
103
+ customPlugins = customPlugins || [];
104
+
105
+ return buildExtensions(props.activePlugins, customPlugins, {
106
+ math: {},
107
+ textAlign: {},
108
+ html: {},
109
+ extraCSSRules: props.extraCSSRules || {},
110
+ image: {},
111
+ toolbar: {},
112
+ table: {},
113
+ responseArea: {
114
+ type: props.responseAreaProps?.type,
115
+ },
116
+ languageCharacters: props.languageCharactersProps,
117
+ keyPadCharacterRef: {},
118
+ setKeypadInteraction: {},
119
+ media: {},
120
+ });
121
+ }, [props]);
122
+
123
+ const extensions = [
124
+ TextStyleKit,
125
+ StarterKit,
126
+ ExtendedTable,
127
+ TableRow,
128
+ TableHeader,
129
+ TableCell,
130
+ ResponseAreaExtension,
131
+ ExplicitConstructedResponseNode.configure(props.responseAreaProps),
132
+ DragInTheBlankNode.configure(props.responseAreaProps),
133
+ InlineDropdownNode.configure(props.responseAreaProps),
134
+ MathNode.configure({
135
+ toolbarOpts: toolbarOptsToUse,
136
+ }),
137
+ SubScript,
138
+ SuperScript,
139
+ TextAlign.configure({
140
+ types: ['heading', 'paragraph'],
141
+ alignments: ['left', 'right', 'center'],
142
+ }),
143
+ Image,
144
+ ImageUploadNode.configure({
145
+ toolbarOpts: toolbarOptsToUse,
146
+ imageHandling: {
147
+ disableImageAlignmentButtons: props.disableImageAlignmentButtons,
148
+ onDone: () => props.onDone?.(editor.getHTML()),
149
+ onDelete:
150
+ props.imageSupport &&
151
+ props.imageSupport.delete &&
152
+ ((node, done) => {
153
+ const { src } = node.attrs;
154
+
155
+ props.imageSupport.delete(src, (e) => {
156
+ const newPendingImages = pendingImages.filter((img) => img.key !== node.key);
157
+ const newState = {
158
+ pendingImages: newPendingImages,
159
+ scheduled: scheduled && newPendingImages.length === 0 ? false : scheduled,
160
+ };
161
+
162
+ setPendingImages(newState.pendingImages);
163
+ setScheduled(newState.scheduled);
164
+ done();
165
+ });
166
+ }),
167
+ insertImageRequested:
168
+ props.imageSupport &&
169
+ ((addedImage, getHandler) => {
170
+ const onFinish = (result) => {
171
+ let cb;
172
+
173
+ if (scheduled && result) {
174
+ // finish editing only on success
175
+ cb = props.onChange;
176
+ }
177
+
178
+ const newPendingImages = pendingImages.filter((img) => img.key !== addedImage.key);
179
+ const newState = {
180
+ pendingImages: newPendingImages,
181
+ };
182
+
183
+ if (newPendingImages.length === 0) {
184
+ newState.scheduled = false;
185
+ }
186
+
187
+ setPendingImages(newState.pendingImages);
188
+ setScheduled(newState.scheduled);
189
+ cb?.(editor.getHTML());
190
+ };
191
+ const callback = () => {
192
+ /**
193
+ * The handler is the object through which the outer context
194
+ * communicates file upload events like: fileChosen, cancel, progress
195
+ */
196
+ const handler = getHandler(onFinish);
197
+ props.imageSupport.add(handler);
198
+ };
199
+
200
+ setPendingImages([...pendingImages, addedImage]);
201
+ callback();
202
+ }),
203
+ maxImageWidth: props.maxImageWidth,
204
+ maxImageHeight: props.maxImageHeight,
205
+ },
206
+ limit: 3,
207
+ }),
208
+ Media.configure({
209
+ uploadSoundSupport: props.uploadSoundSupport,
210
+ }),
211
+ CSSMark.configure({
212
+ extraCSSRules: props.extraCSSRules,
213
+ }),
214
+ ];
215
+
216
+ const editor = useEditor({
217
+ extensions,
218
+ immediatelyRender: false,
219
+ editable: !props.disabled,
220
+ content: props.markup,
221
+ onUpdate: ({ editor, transaction }) => transaction.isDone && props.onChange?.(editor.getHTML()),
222
+ onBlur: ({ editor }) => {
223
+ if (toolbarOptsToUse.doneOn === 'blur') {
224
+ props.onChange?.(editor.getHTML());
225
+ } else {
226
+ props.onDone?.(editor.getHTML());
227
+ }
228
+ },
229
+ });
230
+
231
+ useEffect(() => {
232
+ editor?.setEditable(!props.disabled);
233
+ }, [props.disabled, editor]);
234
+
235
+ useEffect(() => {
236
+ if (!editor) {
237
+ return;
238
+ }
239
+
240
+ if (props.markup !== editor.getHTML()) {
241
+ editor.commands.setContent(props.markup, false); // false = don’t emit update
242
+ }
243
+ }, [props.markup, editor]);
244
+
245
+ useEffect(() => {
246
+ Object.entries(cssVariables).forEach(([key, value]) => {
247
+ document.documentElement.style.setProperty(key, value);
248
+ });
249
+ }, []);
250
+
251
+ const editorState = useEditorState({
252
+ editor,
253
+ selector: (ctx) => ({
254
+ isFocused: ctx.editor?.isFocused,
255
+ }),
256
+ });
257
+
258
+ const sizeStyle = useMemo(() => {
259
+ const { minWidth, width, maxWidth, minHeight, height, maxHeight } = props;
260
+
261
+ return {
262
+ width: valueToSize(width),
263
+ minWidth: valueToSize(minWidth),
264
+ maxWidth: valueToSize(maxWidth),
265
+ height: valueToSize(height),
266
+ minHeight: valueToSize(minHeight),
267
+ maxHeight: valueToSize(maxHeight),
268
+ };
269
+ }, [props]);
270
+
271
+ return (
272
+ <EditorContainer
273
+ {...{
274
+ ...props,
275
+ activePlugins: activePluginsToUse,
276
+ toolbarOpts: toolbarOptsToUse,
277
+ }}
278
+ editorState={editorState}
279
+ editor={editor}
280
+ >
281
+ {editor && (
282
+ <EditorContent
283
+ style={{
284
+ minHeight: sizeStyle.minHeight,
285
+ height: sizeStyle.height,
286
+ maxHeight: sizeStyle.maxHeight,
287
+ }}
288
+ className={classes.root}
289
+ editor={editor}
290
+ />
291
+ )}
292
+ </EditorContainer>
293
+ );
294
+ };
295
+
296
+ const StyledEditor = withStyles({
297
+ root: {
298
+ outline: 'none !important',
299
+ '& .ProseMirror': {
300
+ outline: 'none !important',
301
+ position: 'initial',
302
+ },
303
+ },
304
+ })(EditableHtml);
305
+
306
+ export default StyledEditor;