@pie-lib/editable-html-tip-tap 1.0.2 → 1.0.4

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 (165) hide show
  1. package/lib/components/CharacterPicker.js +221 -0
  2. package/lib/components/CharacterPicker.js.map +1 -0
  3. package/lib/components/EditableHtml.js +323 -0
  4. package/lib/components/EditableHtml.js.map +1 -0
  5. package/lib/components/MenuBar.js +694 -0
  6. package/lib/components/MenuBar.js.map +1 -0
  7. package/lib/components/TiptapContainer.js +90 -0
  8. package/lib/components/TiptapContainer.js.map +1 -0
  9. package/lib/components/buttons/done-button.js +53 -0
  10. package/lib/components/characters/characterUtils.js +112 -0
  11. package/lib/components/characters/characterUtils.js.map +1 -0
  12. package/lib/components/characters/custom-popper.js +73 -0
  13. package/lib/components/characters/custom-popper.js.map +1 -0
  14. package/lib/components/common/done-button.js +53 -0
  15. package/lib/components/common/done-button.js.map +1 -0
  16. package/lib/components/common/toolbar-buttons.js +194 -0
  17. package/lib/components/icons/CssIcon.js +37 -0
  18. package/lib/components/icons/CssIcon.js.map +1 -0
  19. package/lib/components/icons/RespArea.js +95 -0
  20. package/lib/components/icons/RespArea.js.map +1 -0
  21. package/lib/components/icons/TableIcons.js +69 -0
  22. package/lib/components/icons/TableIcons.js.map +1 -0
  23. package/lib/components/icons/TextAlign.js +194 -0
  24. package/lib/components/icons/TextAlign.js.map +1 -0
  25. package/lib/components/icons/index.js +194 -0
  26. package/lib/components/image/AltDialog.js +129 -0
  27. package/lib/components/image/ImageToolbar.js +177 -0
  28. package/lib/components/image/ImageToolbar.js.map +1 -0
  29. package/lib/components/image/InsertImageHandler.js +115 -0
  30. package/lib/components/image/InsertImageHandler.js.map +1 -0
  31. package/lib/components/image/alt-dialog.js +2 -0
  32. package/lib/components/media/MediaDialog.js +709 -0
  33. package/lib/components/media/MediaDialog.js.map +1 -0
  34. package/lib/components/media/MediaToolbar.js +101 -0
  35. package/lib/components/media/MediaToolbar.js.map +1 -0
  36. package/lib/components/media/MediaWrapper.js +93 -0
  37. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +94 -0
  38. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js.map +1 -0
  39. package/lib/components/respArea/DragInTheBlank/choice.js +289 -0
  40. package/lib/components/respArea/DragInTheBlank/choice.js.map +1 -0
  41. package/lib/components/respArea/DragInTheBlank.js +94 -0
  42. package/lib/components/respArea/ExplicitConstructedResponse.js +120 -0
  43. package/lib/components/respArea/ExplicitConstructedResponse.js.map +1 -0
  44. package/lib/components/respArea/InlineDropdown.js +126 -0
  45. package/lib/components/respArea/InlineDropdown.js.map +1 -0
  46. package/lib/components/respArea/ToolbarIcon.js +105 -0
  47. package/lib/components/respArea/ToolbarIcon.js.map +1 -0
  48. package/lib/components/respArea/choice.js +2 -0
  49. package/lib/constants.js.map +1 -0
  50. package/lib/extensions/component.js +5 -5
  51. package/lib/extensions/component.js.map +1 -0
  52. package/lib/extensions/css.js.map +1 -0
  53. package/lib/extensions/custom-toolbar-wrapper.js +2 -4
  54. package/lib/extensions/custom-toolbar-wrapper.js.map +1 -0
  55. package/lib/extensions/extended-table.js +30 -0
  56. package/lib/extensions/extended-table.js.map +1 -0
  57. package/lib/extensions/image.js +2 -8
  58. package/lib/extensions/image.js.map +1 -0
  59. package/lib/extensions/index.js +52 -0
  60. package/lib/extensions/index.js.map +1 -0
  61. package/lib/extensions/math.js.map +1 -0
  62. package/lib/extensions/media.js +7 -7
  63. package/lib/extensions/media.js.map +1 -0
  64. package/lib/extensions/responseArea.js +7 -7
  65. package/lib/extensions/responseArea.js.map +1 -0
  66. package/lib/index.js +16 -1481
  67. package/lib/index.js.map +1 -0
  68. package/lib/plugins/index.js +8 -80
  69. package/lib/styles/editorContainerStyles.js +200 -0
  70. package/lib/styles/editorContainerStyles.js.map +1 -0
  71. package/lib/theme.js.map +1 -0
  72. package/lib/utils/size.js +34 -0
  73. package/lib/utils/size.js.map +1 -0
  74. package/package.json +1 -1
  75. package/src/components/CharacterPicker.jsx +185 -0
  76. package/src/components/EditableHtml.jsx +306 -0
  77. package/src/components/MenuBar.jsx +630 -0
  78. package/src/components/TiptapContainer.jsx +96 -0
  79. package/src/components/characters/characterUtils.js +127 -0
  80. package/src/{plugins/image/image-toolbar.jsx → components/image/ImageToolbar.jsx} +2 -2
  81. package/src/{plugins/image/insert-image-handler.js → components/image/InsertImageHandler.js} +0 -1
  82. package/src/{plugins/media/media-dialog.js → components/media/MediaDialog.js} +2 -2
  83. package/src/{plugins/respArea/drag-in-the-blank → components/respArea/DragInTheBlank}/choice.jsx +1 -1
  84. package/src/{plugins/respArea/inline-dropdown/index.jsx → components/respArea/InlineDropdown.jsx} +1 -1
  85. package/src/components/respArea/ToolbarIcon.jsx +68 -0
  86. package/src/extensions/component.jsx +2 -2
  87. package/src/extensions/custom-toolbar-wrapper.jsx +6 -7
  88. package/src/extensions/extended-table.js +27 -0
  89. package/src/extensions/image.js +2 -2
  90. package/src/extensions/index.js +76 -0
  91. package/src/extensions/media.js +12 -7
  92. package/src/extensions/responseArea.js +7 -7
  93. package/src/index.jsx +3 -1440
  94. package/src/styles/editorContainerStyles.js +203 -0
  95. package/src/utils/size.js +32 -0
  96. package/src/__tests__/editor.test.jsx +0 -363
  97. package/src/__tests__/serialization.test.js +0 -291
  98. package/src/block-tags.js +0 -17
  99. package/src/editor.jsx +0 -1197
  100. package/src/extensions/characters.js +0 -46
  101. package/src/old-index.jsx +0 -162
  102. package/src/parse-html.js +0 -8
  103. package/src/plugins/README.md +0 -27
  104. package/src/plugins/characters/index.jsx +0 -284
  105. package/src/plugins/characters/utils.js +0 -447
  106. package/src/plugins/css/index.jsx +0 -340
  107. package/src/plugins/customPlugin/index.jsx +0 -85
  108. package/src/plugins/html/icons/index.jsx +0 -19
  109. package/src/plugins/html/index.jsx +0 -72
  110. package/src/plugins/image/__tests__/__snapshots__/component.test.jsx.snap +0 -51
  111. package/src/plugins/image/__tests__/__snapshots__/image-toolbar-logic.test.jsx.snap +0 -27
  112. package/src/plugins/image/__tests__/__snapshots__/image-toolbar.test.jsx.snap +0 -44
  113. package/src/plugins/image/__tests__/component.test.jsx +0 -41
  114. package/src/plugins/image/__tests__/image-toolbar-logic.test.jsx +0 -42
  115. package/src/plugins/image/__tests__/image-toolbar.test.jsx +0 -11
  116. package/src/plugins/image/__tests__/index.test.js +0 -95
  117. package/src/plugins/image/__tests__/insert-image-handler.test.js +0 -113
  118. package/src/plugins/image/__tests__/mock-change.js +0 -15
  119. package/src/plugins/image/component.jsx +0 -343
  120. package/src/plugins/image/index.jsx +0 -227
  121. package/src/plugins/index.jsx +0 -377
  122. package/src/plugins/list/__tests__/index.test.js +0 -54
  123. package/src/plugins/list/index.jsx +0 -305
  124. package/src/plugins/math/__tests__/__snapshots__/index.test.jsx.snap +0 -48
  125. package/src/plugins/math/__tests__/index.test.jsx +0 -245
  126. package/src/plugins/math/index.jsx +0 -379
  127. package/src/plugins/media/__tests__/index.test.js +0 -75
  128. package/src/plugins/media/index.jsx +0 -325
  129. package/src/plugins/rendering/index.js +0 -31
  130. package/src/plugins/respArea/index.jsx +0 -299
  131. package/src/plugins/respArea/math-templated/index.jsx +0 -104
  132. package/src/plugins/respArea/utils.jsx +0 -90
  133. package/src/plugins/table/CustomTablePlugin.js +0 -113
  134. package/src/plugins/table/__tests__/__snapshots__/table-toolbar.test.jsx.snap +0 -44
  135. package/src/plugins/table/__tests__/index.test.jsx +0 -401
  136. package/src/plugins/table/__tests__/table-toolbar.test.jsx +0 -42
  137. package/src/plugins/table/index.jsx +0 -427
  138. package/src/plugins/table/table-toolbar.jsx +0 -136
  139. package/src/plugins/textAlign/index.jsx +0 -23
  140. package/src/plugins/toolbar/__tests__/__snapshots__/default-toolbar.test.jsx.snap +0 -923
  141. package/src/plugins/toolbar/__tests__/__snapshots__/editor-and-toolbar.test.jsx.snap +0 -20
  142. package/src/plugins/toolbar/__tests__/__snapshots__/toolbar-buttons.test.jsx.snap +0 -36
  143. package/src/plugins/toolbar/__tests__/__snapshots__/toolbar.test.jsx.snap +0 -46
  144. package/src/plugins/toolbar/__tests__/default-toolbar.test.jsx +0 -94
  145. package/src/plugins/toolbar/__tests__/editor-and-toolbar.test.jsx +0 -37
  146. package/src/plugins/toolbar/__tests__/toolbar-buttons.test.jsx +0 -51
  147. package/src/plugins/toolbar/__tests__/toolbar.test.jsx +0 -106
  148. package/src/plugins/toolbar/default-toolbar.jsx +0 -206
  149. package/src/plugins/toolbar/editor-and-toolbar.jsx +0 -257
  150. package/src/plugins/toolbar/index.jsx +0 -23
  151. package/src/plugins/toolbar/toolbar.jsx +0 -338
  152. package/src/plugins/utils.js +0 -31
  153. package/src/serialization.jsx +0 -621
  154. /package/src/{plugins → components}/characters/custom-popper.js +0 -0
  155. /package/src/{plugins/toolbar → components/common}/done-button.jsx +0 -0
  156. /package/src/{plugins/toolbar → components/common}/toolbar-buttons.jsx +0 -0
  157. /package/src/{plugins/css/icons/index.jsx → components/icons/CssIcon.jsx} +0 -0
  158. /package/src/{plugins/respArea/icons/index.jsx → components/icons/RespArea.jsx} +0 -0
  159. /package/src/{plugins/table/icons/index.jsx → components/icons/TableIcons.jsx} +0 -0
  160. /package/src/{plugins/textAlign/icons/index.jsx → components/icons/TextAlign.jsx} +0 -0
  161. /package/src/{plugins/image/alt-dialog.jsx → components/image/AltDialog.jsx} +0 -0
  162. /package/src/{plugins/media/media-toolbar.jsx → components/media/MediaToolbar.jsx} +0 -0
  163. /package/src/{plugins/media/media-wrapper.jsx → components/media/MediaWrapper.jsx} +0 -0
  164. /package/src/{plugins/respArea/drag-in-the-blank/index.jsx → components/respArea/DragInTheBlank/DragInTheBlank.jsx} +0 -0
  165. /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;