@madie/madie-design-system 1.2.56 → 1.2.57
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/components/MadieAlert/index.jsx +323 -168
- package/components/RichTextEditor/index.jsx +3 -3
- package/dist/browser.js +1 -1
- package/dist/index.js +1 -1
- package/dist/react/index.js +2 -2
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components/_madie-alert.scss +4 -1
- package/styles/components/_rich-text-editor.scss +160 -158
- package/styles/qppds/components/_rich-text-editor.scss +160 -159
- package/test/components/MadieAlert.test.js +312 -23
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
|
1
|
+
import React, { useEffect, useState, useMemo } from "react";
|
|
2
2
|
|
|
3
3
|
import ErrorIcon from "@mui/icons-material/Error"; // warning
|
|
4
4
|
import InfoIcon from "@mui/icons-material/Info"; // info
|
|
@@ -6,6 +6,7 @@ import CancelIcon from "@mui/icons-material/Cancel"; // error
|
|
|
6
6
|
import CheckCircleIcon from "@mui/icons-material/CheckCircle"; //success
|
|
7
7
|
import ContentCopyIcon from "@mui/icons-material/ContentCopy"; //copy
|
|
8
8
|
import FullscreenExitRoundedIcon from '@mui/icons-material/FullscreenExitRounded';
|
|
9
|
+
import WarningRoundedIcon from '@mui/icons-material/WarningRounded';
|
|
9
10
|
import Tooltip from "@mui/material/Tooltip";
|
|
10
11
|
import { IconButton } from "@mui/material";
|
|
11
12
|
import ClearIcon from "@mui/icons-material/Clear";
|
|
@@ -13,184 +14,338 @@ import Toast from "../Toast/index";
|
|
|
13
14
|
import classNames from "classnames";
|
|
14
15
|
import PropTypes from "prop-types";
|
|
15
16
|
|
|
16
|
-
//
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
17
|
+
// Define icon mapping outside component to avoid recreation on each render
|
|
18
|
+
const typeToIconMap = {
|
|
19
|
+
warning: ErrorIcon,
|
|
20
|
+
info: InfoIcon,
|
|
21
|
+
error: CancelIcon,
|
|
22
|
+
success: CheckCircleIcon,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Common button styles
|
|
26
|
+
const buttonBaseSx = {
|
|
27
|
+
marginLeft: "auto",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const buttonWithDividerSx = {
|
|
31
|
+
...buttonBaseSx,
|
|
32
|
+
"&:after": {
|
|
33
|
+
content: `''`,
|
|
34
|
+
position: "absolute",
|
|
35
|
+
left: "0px",
|
|
36
|
+
width: "1px",
|
|
37
|
+
height: "40px",
|
|
38
|
+
backgroundColor: "#B0B0B0",
|
|
39
|
+
pointerEvents: "none",
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Extract alert content processing to a separate function
|
|
44
|
+
const processContent = (content) => {
|
|
45
|
+
// Counts errors/warnings in ul/li elements
|
|
46
|
+
const countUlLiChildren = (element) => {
|
|
47
|
+
const counts = { ul: 0, li: 0 };
|
|
48
|
+
|
|
49
|
+
const traverse = (el) => {
|
|
50
|
+
if (!el || typeof el !== 'object') return;
|
|
51
|
+
|
|
52
|
+
if (el.type === 'ul' || el.type === 'li') {
|
|
53
|
+
const children = el.props?.children;
|
|
54
|
+
const childCount = Array.isArray(children) ? children.length : (children ? 1 : 0);
|
|
55
|
+
counts[el.type] += childCount;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const children = el.props?.children;
|
|
59
|
+
if (Array.isArray(children)) {
|
|
60
|
+
children.forEach(traverse);
|
|
61
|
+
} else if (children && typeof children === 'object') {
|
|
62
|
+
traverse(children);
|
|
63
|
+
}
|
|
61
64
|
};
|
|
65
|
+
|
|
66
|
+
traverse(element);
|
|
67
|
+
|
|
68
|
+
return counts.li > counts.ul ? counts.li : counts.ul;
|
|
69
|
+
};
|
|
62
70
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
// Converts content to text for copying - improved to avoid unwanted characters
|
|
72
|
+
const buildCopyText = (contentNode, parentNode = true) => {
|
|
73
|
+
if (!contentNode) return "";
|
|
74
|
+
|
|
75
|
+
// Initialize result string
|
|
76
|
+
let result = "";
|
|
77
|
+
|
|
78
|
+
// Handle specific node types that need special formatting
|
|
79
|
+
if (contentNode.type === "ul") {
|
|
80
|
+
// Start ul with a newline
|
|
81
|
+
result = "\n";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Process children based on their type
|
|
85
|
+
if (Array.isArray(contentNode.props?.children)) {
|
|
86
|
+
contentNode.props.children.forEach((child, index) => {
|
|
87
|
+
const childText = buildCopyText(child, false);
|
|
88
|
+
// Only add non-empty text
|
|
89
|
+
if (childText.trim()) {
|
|
90
|
+
result += childText;
|
|
91
|
+
|
|
92
|
+
// Add line breaks after certain elements
|
|
93
|
+
if ((parentNode && index === 1) || contentNode.type === "ul") {
|
|
94
|
+
result += "\n";
|
|
95
|
+
}
|
|
66
96
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
97
|
+
});
|
|
98
|
+
} else if (typeof contentNode.props?.children === "object") {
|
|
99
|
+
result += buildCopyText(contentNode.props.children, false);
|
|
100
|
+
} else if (typeof contentNode.props?.children === "string" ||
|
|
101
|
+
typeof contentNode.props?.children === "number") {
|
|
102
|
+
// Clean the string by trimming and normalizing whitespace
|
|
103
|
+
result += contentNode.props.children.toString().replace(/\s+/g, ' ').trim();
|
|
104
|
+
} else if (typeof contentNode === "string" || typeof contentNode === "number") {
|
|
105
|
+
// Clean the string by trimming and normalizing whitespace
|
|
106
|
+
result += contentNode.toString().replace(/\s+/g, ' ').trim();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return result;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Process content and ensure we trim the final result
|
|
113
|
+
const rawText = buildCopyText(content, false);
|
|
114
|
+
return {
|
|
115
|
+
errorCount: countUlLiChildren(content),
|
|
116
|
+
copyText: rawText.replace(/\s+\n/g, '\n').replace(/\n\s+/g, '\n').trim()
|
|
117
|
+
};
|
|
118
|
+
};
|
|
78
119
|
|
|
120
|
+
// Define ActionButton as a separate component outside MadieAlert
|
|
121
|
+
const ActionButton = ({ tooltip, onClick, icon, testId, sx }) => (
|
|
122
|
+
<Tooltip title={tooltip} data-testid={`${testId}-tooltip`} arrow>
|
|
123
|
+
<IconButton
|
|
124
|
+
onClick={onClick}
|
|
125
|
+
sx={sx}
|
|
126
|
+
data-testid={testId}
|
|
127
|
+
>
|
|
128
|
+
{icon}
|
|
129
|
+
</IconButton>
|
|
130
|
+
</Tooltip>
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// Add PropTypes for ActionButton
|
|
134
|
+
ActionButton.propTypes = {
|
|
135
|
+
tooltip: PropTypes.string.isRequired,
|
|
136
|
+
onClick: PropTypes.func.isRequired,
|
|
137
|
+
icon: PropTypes.node.isRequired,
|
|
138
|
+
testId: PropTypes.string.isRequired,
|
|
139
|
+
sx: PropTypes.object
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const MadieAlert = ({
|
|
143
|
+
type = "warning",
|
|
144
|
+
visible = true,
|
|
145
|
+
content,
|
|
146
|
+
canClose = true,
|
|
147
|
+
minimizeAlerts = false,
|
|
148
|
+
alertProps,
|
|
149
|
+
closeButtonProps,
|
|
150
|
+
copyButton,
|
|
151
|
+
alerts = null,
|
|
152
|
+
}) => {
|
|
153
|
+
// Consolidate related state
|
|
154
|
+
const [state, setState] = useState({
|
|
155
|
+
toastOpen: false,
|
|
156
|
+
copyText: "",
|
|
157
|
+
minimizedAlerts: {},
|
|
158
|
+
individualErrors: {},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Create alias for readability
|
|
162
|
+
const { toastOpen, copyText, minimizedAlerts, individualErrors } = state;
|
|
163
|
+
|
|
164
|
+
// Use a single update function
|
|
165
|
+
const updateState = (updates) => {
|
|
166
|
+
setState(prev => ({ ...prev, ...updates }));
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// Prepare alerts array once
|
|
170
|
+
const alertsArray = useMemo(() => {
|
|
171
|
+
return alerts || [{
|
|
172
|
+
type, visible, content, canClose, alertProps, closeButtonProps, copyButton
|
|
173
|
+
}];
|
|
174
|
+
}, [alerts, type, visible, content, canClose, alertProps, closeButtonProps, copyButton]);
|
|
175
|
+
|
|
176
|
+
// Process all alerts content once
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
const newIndividualErrors = {};
|
|
179
|
+
let totalCopyText = "";
|
|
180
|
+
|
|
181
|
+
alertsArray.forEach((alert, index) => {
|
|
182
|
+
if (alert.content && alert.visible !== false) {
|
|
183
|
+
const processed = processContent(alert.content);
|
|
184
|
+
newIndividualErrors[index] = processed.errorCount;
|
|
185
|
+
|
|
186
|
+
if (alert.copyButton) {
|
|
187
|
+
totalCopyText += processed.copyText + "\n\n";
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
updateState({
|
|
193
|
+
individualErrors: newIndividualErrors,
|
|
194
|
+
copyText: totalCopyText.trim(),
|
|
195
|
+
});
|
|
196
|
+
}, [alertsArray]);
|
|
197
|
+
|
|
198
|
+
// Utility functions for managing minimized state
|
|
199
|
+
const minimizeAlert = (index) => {
|
|
200
|
+
updateState({
|
|
201
|
+
minimizedAlerts: { ...minimizedAlerts, [index]: true }
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const restoreAllAlerts = () => {
|
|
206
|
+
updateState({ minimizedAlerts: {} });
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Calculate minimized alerts info
|
|
210
|
+
const minimizedIndices = Object.keys(minimizedAlerts)
|
|
211
|
+
.filter(key => minimizedAlerts[key])
|
|
212
|
+
.map(key => parseInt(key));
|
|
213
|
+
|
|
214
|
+
const totalMinimizedErrors = minimizedIndices.reduce(
|
|
215
|
+
(sum, index) => sum + (individualErrors[index] || 0),
|
|
216
|
+
0
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
// Render alert content
|
|
220
|
+
const renderAlert = (alert, index) => {
|
|
221
|
+
const {
|
|
222
|
+
type = "warning",
|
|
223
|
+
visible = true,
|
|
224
|
+
content,
|
|
225
|
+
canClose = true,
|
|
226
|
+
alertProps = {},
|
|
227
|
+
closeButtonProps = {},
|
|
228
|
+
copyButton = false
|
|
229
|
+
} = alert;
|
|
230
|
+
|
|
231
|
+
if (!visible || minimizedAlerts[index]) return null;
|
|
232
|
+
|
|
233
|
+
const Icon = typeToIconMap[type];
|
|
234
|
+
const alertClass = classNames("madie-alert", type);
|
|
235
|
+
|
|
79
236
|
return (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
</IconButton>
|
|
121
|
-
</Tooltip>
|
|
122
|
-
)}
|
|
123
|
-
{copyButton && (
|
|
124
|
-
<Tooltip
|
|
125
|
-
data-testid="copy-button-tooltip"
|
|
126
|
-
title={"Copy"}
|
|
127
|
-
arrow
|
|
128
|
-
>
|
|
129
|
-
<IconButton
|
|
130
|
-
sx={{
|
|
131
|
-
marginLeft: "auto",
|
|
132
|
-
...(!minimizeAlerts && {
|
|
133
|
-
"&:after": {
|
|
134
|
-
content: `''`,
|
|
135
|
-
position: "absolute",
|
|
136
|
-
left: "0px",
|
|
137
|
-
width: "1px",
|
|
138
|
-
height: "40px",
|
|
139
|
-
backgroundColor: "#B0B0B0",
|
|
140
|
-
pointerEvents: "none",
|
|
141
|
-
}
|
|
142
|
-
})
|
|
143
|
-
}}
|
|
144
|
-
>
|
|
145
|
-
<ContentCopyIcon
|
|
146
|
-
onClick={(e) => {
|
|
147
|
-
e.preventDefault();
|
|
148
|
-
navigator.clipboard.writeText(copyText);
|
|
149
|
-
setToastOpen(true);
|
|
150
|
-
}}
|
|
151
|
-
sx={{ color: "#242424" }}
|
|
152
|
-
/>
|
|
153
|
-
</IconButton>
|
|
154
|
-
</Tooltip>
|
|
155
|
-
)}
|
|
156
|
-
|
|
157
|
-
{canClose && (
|
|
158
|
-
<IconButton
|
|
159
|
-
sx={{
|
|
160
|
-
marginLeft: "auto",
|
|
161
|
-
"&:after": {
|
|
162
|
-
content: `''`,
|
|
163
|
-
position: "absolute",
|
|
164
|
-
left: "0px",
|
|
165
|
-
width: "1px",
|
|
166
|
-
height: "40px",
|
|
167
|
-
backgroundColor: "#B0B0B0",
|
|
168
|
-
pointerEvents: "none",
|
|
169
|
-
},
|
|
170
|
-
}}
|
|
171
|
-
{...closeButtonProps}
|
|
172
|
-
>
|
|
173
|
-
<ClearIcon sx={{ color: "#242424" }} />
|
|
174
|
-
</IconButton>
|
|
175
|
-
)}
|
|
176
|
-
</div>
|
|
177
|
-
)
|
|
237
|
+
<div key={index} className={alertClass} {...alertProps}>
|
|
238
|
+
<Icon className={classNames("alert-icon", type)} />
|
|
239
|
+
<div id="content" data-alert-index={index}>{content}</div>
|
|
240
|
+
|
|
241
|
+
{minimizeAlerts && (
|
|
242
|
+
<ActionButton
|
|
243
|
+
tooltip="Minimize"
|
|
244
|
+
onClick={(e) => {
|
|
245
|
+
e.preventDefault();
|
|
246
|
+
minimizeAlert(index);
|
|
247
|
+
}}
|
|
248
|
+
icon={<FullscreenExitRoundedIcon sx={{ color: "#242424" }} />}
|
|
249
|
+
testId={`minimize-button-${index}`}
|
|
250
|
+
sx={buttonWithDividerSx}
|
|
251
|
+
/>
|
|
252
|
+
)}
|
|
253
|
+
|
|
254
|
+
{copyButton && (
|
|
255
|
+
<ActionButton
|
|
256
|
+
tooltip="Copy"
|
|
257
|
+
onClick={(e) => {
|
|
258
|
+
e.preventDefault();
|
|
259
|
+
navigator.clipboard.writeText(copyButton ? processContent(content).copyText : copyText);
|
|
260
|
+
updateState({ toastOpen: true });
|
|
261
|
+
}}
|
|
262
|
+
icon={<ContentCopyIcon sx={{ color: "#242424" }} />}
|
|
263
|
+
testId="copy-button"
|
|
264
|
+
sx={!minimizeAlerts ? buttonWithDividerSx : buttonBaseSx}
|
|
265
|
+
/>
|
|
266
|
+
)}
|
|
267
|
+
|
|
268
|
+
{canClose && (
|
|
269
|
+
<IconButton
|
|
270
|
+
sx={buttonWithDividerSx}
|
|
271
|
+
{...closeButtonProps}
|
|
272
|
+
>
|
|
273
|
+
<ClearIcon sx={{ color: "#242424" }} />
|
|
274
|
+
</IconButton>
|
|
275
|
+
)}
|
|
276
|
+
</div>
|
|
178
277
|
);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
return (
|
|
281
|
+
<div>
|
|
282
|
+
<Toast
|
|
283
|
+
toastKey="copy-success-toast"
|
|
284
|
+
data-testid="copy-success"
|
|
285
|
+
toastType="success"
|
|
286
|
+
open={toastOpen}
|
|
287
|
+
message="Copied to clipboard!"
|
|
288
|
+
onClose={() => updateState({ toastOpen: false })}
|
|
289
|
+
autoHideDuration={1500}
|
|
290
|
+
/>
|
|
291
|
+
|
|
292
|
+
{/* Render visible alerts */}
|
|
293
|
+
{alertsArray.map((alert, index) => renderAlert(alert, index))}
|
|
294
|
+
|
|
295
|
+
{/* Show minimized indicator if any alerts are minimized */}
|
|
296
|
+
{minimizedIndices.length > 0 && (
|
|
297
|
+
<div
|
|
298
|
+
style={{
|
|
299
|
+
position: "absolute",
|
|
300
|
+
right: "32px",
|
|
301
|
+
top: "10px",
|
|
302
|
+
display: "flex",
|
|
303
|
+
alignItems: "center",
|
|
304
|
+
cursor: "pointer"
|
|
305
|
+
}}
|
|
306
|
+
data-testid="minimized-alert"
|
|
307
|
+
onClick={(e) => {
|
|
308
|
+
e.preventDefault();
|
|
309
|
+
restoreAllAlerts();
|
|
310
|
+
}}
|
|
311
|
+
>
|
|
312
|
+
<WarningRoundedIcon sx={{ color: "yellow", marginRight: "5px" }}/>
|
|
313
|
+
<span data-testid="minimized-alert-text" style={{ color: "white", fontSize: "16px" }}>
|
|
314
|
+
Display Alerts {totalMinimizedErrors > 0 ? `(${totalMinimizedErrors})` : ""}
|
|
315
|
+
</span>
|
|
316
|
+
</div>
|
|
317
|
+
)}
|
|
318
|
+
</div>
|
|
319
|
+
);
|
|
179
320
|
};
|
|
180
321
|
|
|
322
|
+
// PropTypes definition
|
|
181
323
|
MadieAlert.propTypes = {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
324
|
+
type: PropTypes.string,
|
|
325
|
+
visible: PropTypes.bool,
|
|
326
|
+
content: PropTypes.node,
|
|
327
|
+
canClose: PropTypes.bool,
|
|
328
|
+
alertProps: PropTypes.object,
|
|
329
|
+
closeButtonProps: PropTypes.object,
|
|
330
|
+
copyButton: PropTypes.bool,
|
|
331
|
+
minimizeAlerts: PropTypes.bool,
|
|
332
|
+
alerts: PropTypes.arrayOf(
|
|
333
|
+
PropTypes.shape({
|
|
334
|
+
type: PropTypes.string,
|
|
335
|
+
visible: PropTypes.bool,
|
|
336
|
+
content: PropTypes.node,
|
|
337
|
+
canClose: PropTypes.bool,
|
|
338
|
+
alertProps: PropTypes.object,
|
|
339
|
+
closeButtonProps: PropTypes.object,
|
|
340
|
+
copyButton: PropTypes.bool,
|
|
341
|
+
})
|
|
342
|
+
)
|
|
190
343
|
};
|
|
344
|
+
|
|
191
345
|
MadieAlert.defaultProps = {
|
|
192
|
-
|
|
193
|
-
|
|
346
|
+
copyButton: false,
|
|
347
|
+
minimizeAlerts: false,
|
|
348
|
+
alerts: null,
|
|
194
349
|
};
|
|
195
350
|
|
|
196
351
|
export default MadieAlert;
|
|
@@ -179,6 +179,7 @@ const RichTextEditor = ({
|
|
|
179
179
|
{
|
|
180
180
|
extensions: [
|
|
181
181
|
StarterKit,
|
|
182
|
+
Markdown,
|
|
182
183
|
Gapcursor,
|
|
183
184
|
Table.configure({
|
|
184
185
|
resizable: true,
|
|
@@ -187,7 +188,6 @@ const RichTextEditor = ({
|
|
|
187
188
|
TableHeader,
|
|
188
189
|
TableCell,
|
|
189
190
|
Underline,
|
|
190
|
-
Markdown,
|
|
191
191
|
],
|
|
192
192
|
shouldRerenderOnTransaction: false,
|
|
193
193
|
content,
|
|
@@ -200,7 +200,7 @@ const RichTextEditor = ({
|
|
|
200
200
|
[content]
|
|
201
201
|
);
|
|
202
202
|
return (
|
|
203
|
-
|
|
203
|
+
<div className="rich-text-editor">
|
|
204
204
|
<InputLabel
|
|
205
205
|
shrink
|
|
206
206
|
required={required}
|
|
@@ -243,7 +243,7 @@ const RichTextEditor = ({
|
|
|
243
243
|
</InputLabel>
|
|
244
244
|
<MenuBar editor={editor} />
|
|
245
245
|
<EditorContent editor={editor} />
|
|
246
|
-
|
|
246
|
+
</div>
|
|
247
247
|
);
|
|
248
248
|
};
|
|
249
249
|
|