questionlayoutrefactoring 0.1.12 → 0.1.13
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/README.md +2 -0
- package/dist/components/Atoms/AssistantImageModal/ImageModal.js +2 -1
- package/dist/components/Atoms/AssistantImageModal/ImageModal.js.map +1 -1
- package/dist/components/Atoms/GlobalButton/GlobalButton.d.ts +1 -1
- package/dist/components/Atoms/GlobalButton/GlobalButton.js +25 -7
- package/dist/components/Atoms/GlobalButton/GlobalButton.js.map +1 -1
- package/dist/components/Molecules/ActivityBanner/ActivityBanner.js +1 -1
- package/dist/components/Molecules/ActivityBanner/ActivityBanner.js.map +1 -1
- package/dist/components/Molecules/DashPlayer/DashPlayer.stories.js +1 -1
- package/dist/components/Molecules/DashPlayer/DashPlayer.stories.js.map +1 -1
- package/dist/components/Molecules/DescriptiveAnswer/DescriptiveAnswerV1.js +1 -1
- package/dist/components/Molecules/DescriptiveAnswer/DescriptiveAnswerV1.js.map +1 -1
- package/dist/components/Molecules/FactualCard/FactualCard.d.ts +3 -1
- package/dist/components/Molecules/FactualCard/FactualCard.js +15 -9
- package/dist/components/Molecules/FactualCard/FactualCard.js.map +1 -1
- package/dist/components/Molecules/RecapNode/ContentView.js +2 -2
- package/dist/components/Molecules/RecapNode/ContentView.js.map +1 -1
- package/dist/components/Molecules/RecapNode/VideoView.d.ts +4 -2
- package/dist/components/Molecules/RecapNode/VideoView.js +14 -4
- package/dist/components/Molecules/RecapNode/VideoView.js.map +1 -1
- package/dist/components/Molecules/Revision/Revision.js +2 -2
- package/dist/components/Molecules/Revision/Revision.js.map +1 -1
- package/dist/components/Molecules/SmartLearn/SmartLearn.stories.js +10 -10
- package/dist/components/Molecules/SmartLearn/SmartLearn.stories.js.map +1 -1
- package/dist/components/Molecules/Tutor/User/User.js +1 -1
- package/dist/components/Molecules/Tutor/User/User.js.map +1 -1
- package/dist/components/Molecules/VideoView/VideoModal.js +2 -2
- package/dist/components/Molecules/VideoView/VideoModal.js.map +1 -1
- package/dist/components/Molecules/comprehension/ComprehensionLayout.js +10 -6
- package/dist/components/Molecules/comprehension/ComprehensionLayout.js.map +1 -1
- package/dist/components/Molecules/comprehension/SubQuestionLayout.js +1 -1
- package/dist/components/Molecules/comprehension/SubQuestionLayout.js.map +1 -1
- package/dist/components/Molecules/optionLayouts/Scq.js +0 -1
- package/dist/components/Molecules/optionLayouts/Scq.js.map +1 -1
- package/dist/components/Organisms/FlashCardNode/FlashCardNode.js +2 -2
- package/dist/components/Organisms/FlashCardNode/FlashCardNode.js.map +1 -1
- package/dist/components/Organisms/FlashCardNode/FlashcardContainer.d.ts +1 -2
- package/dist/components/Organisms/FlashCardNode/FlashcardContainer.js +2 -2
- package/dist/components/Organisms/FlashCardNode/FlashcardContainer.js.map +1 -1
- package/dist/components/Organisms/FlashCardNode/MobileAccordionView.d.ts +1 -2
- package/dist/components/Organisms/FlashCardNode/MobileAccordionView.js +5 -7
- package/dist/components/Organisms/FlashCardNode/MobileAccordionView.js.map +1 -1
- package/dist/components/Organisms/RecapGraph/Reactgraphflow.js +21 -44
- package/dist/components/Organisms/RecapGraph/Reactgraphflow.js.map +1 -1
- package/dist/components/Organisms/RecapGraph/useRecapGraphLogic.js +0 -8
- package/dist/components/Organisms/RecapGraph/useRecapGraphLogic.js.map +1 -1
- package/dist/components/Organisms/ReviewComponent/ReviewPresenter.d.ts +2 -1
- package/dist/components/Organisms/ReviewComponent/ReviewPresenter.js +3 -2
- package/dist/components/Organisms/ReviewComponent/ReviewPresenter.js.map +1 -1
- package/dist/components/Organisms/StudentEditor/StudentEditor.stories.d.ts +1 -0
- package/dist/components/Organisms/StudentEditor/StudentEditor.stories.js +92 -4
- package/dist/components/Organisms/StudentEditor/StudentEditor.stories.js.map +1 -1
- package/dist/components/Organisms/StudentEditor/components/MathModal.js +21 -2
- package/dist/components/Organisms/StudentEditor/components/MathModal.js.map +1 -1
- package/dist/components/Organisms/StudentEditor/components/TextEditor.js +176 -343
- package/dist/components/Organisms/StudentEditor/components/TextEditor.js.map +1 -1
- package/dist/components/Organisms/TableComponent/TableComponent.js +22 -2
- package/dist/components/Organisms/TableComponent/TableComponent.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/common-utils.js.map +1 -1
- package/package.json +7 -2
|
@@ -39,6 +39,7 @@ const slate_conversions_1 = require("../utils/slate-conversions");
|
|
|
39
39
|
const common_utils_1 = require("../../../../utils/common-utils");
|
|
40
40
|
const EditorStyles_1 = require("./EditorStyles");
|
|
41
41
|
const LearningPathUtils_1 = require("../../../../utils/LearningPathUtils");
|
|
42
|
+
const EditorComponent_1 = require("./EditorComponent");
|
|
42
43
|
const InvalidSession_1 = __importDefault(require("../../../Molecules/InvalidSession/InvalidSession"));
|
|
43
44
|
// Theme customization without placeholder styling
|
|
44
45
|
const theme = (0, react_2.extendTheme)({
|
|
@@ -61,7 +62,7 @@ const theme = (0, react_2.extendTheme)({
|
|
|
61
62
|
},
|
|
62
63
|
});
|
|
63
64
|
const TextEditor = (props) => {
|
|
64
|
-
const { data, handleChange, onSubmit, icons, isDisabled = false, disablePaste = false, addImageRender = undefined, height = undefined, handleOpenMath, handleCloseMath, showBottomBar = true, isMobile, tutorMode = true, taskType,
|
|
65
|
+
const { data, handleChange, onSubmit, icons, isDisabled = false, disablePaste = false, addImageRender = undefined, height = undefined, handleOpenMath, handleCloseMath, showBottomBar = true, isMobile, tutorMode = true, taskType, isRevision = false, isDescAnsQues = false, handleClick: propHandleClick, showerrorpopup, } = props;
|
|
65
66
|
// Initialize the Slate editor with our custom plugins
|
|
66
67
|
const editor = (0, react_1.useMemo)(() => (0, slate_plugins_1.withMath)((0, slate_history_1.withHistory)((0, slate_react_1.withReact)((0, slate_1.createEditor)()))), []);
|
|
67
68
|
const [value, setValue] = (0, react_1.useState)((0, slate_conversions_1.textToSlate)(data));
|
|
@@ -69,11 +70,19 @@ const TextEditor = (props) => {
|
|
|
69
70
|
const [currentLatex, setCurrentLatex] = (0, react_1.useState)("");
|
|
70
71
|
const [editingPath, setEditingPath] = (0, react_1.useState)(null);
|
|
71
72
|
const [isFocused, setIsFocused] = (0, react_1.useState)(false);
|
|
72
|
-
const [
|
|
73
|
+
const [tabFocusedElement, setTabFocusedElement] = (0, react_1.useState)(null);
|
|
74
|
+
const formulaIconRef = (0, react_1.useRef)(null);
|
|
75
|
+
const submitButtonRef = (0, react_1.useRef)(null);
|
|
76
|
+
const addImageNavRef = (0, react_1.useRef)({ focusFirst: null });
|
|
73
77
|
const editorRef = (0, react_1.useRef)(null);
|
|
78
|
+
const isDisabledRevision = isDisabled && isRevision;
|
|
79
|
+
const isInitialMount = (0, react_1.useRef)(true);
|
|
74
80
|
(0, react_1.useEffect)(() => {
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
if (isInitialMount.current) {
|
|
82
|
+
setValue((0, slate_conversions_1.textToSlate)(data));
|
|
83
|
+
isInitialMount.current = false;
|
|
84
|
+
}
|
|
85
|
+
else if ((0, common_utils_1.isEmptyOrNull)(data) && !(0, common_utils_1.isEmptyOrNull)((0, slate_conversions_1.slateToText)(value))) {
|
|
77
86
|
handleClear();
|
|
78
87
|
}
|
|
79
88
|
}, [data]);
|
|
@@ -81,17 +90,18 @@ const TextEditor = (props) => {
|
|
|
81
90
|
handleOpenMath && openMathEditor();
|
|
82
91
|
}, [handleOpenMath]);
|
|
83
92
|
// Focus the editor when it first mounts
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
(0, react_1.useEffect)(() => {
|
|
94
|
+
if (!isDisabled) {
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
try {
|
|
97
|
+
slate_react_1.ReactEditor.focus(editor);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error("Error focusing editor on mount:", error);
|
|
101
|
+
}
|
|
102
|
+
}, 100);
|
|
103
|
+
}
|
|
104
|
+
}, [editor, isDisabled]);
|
|
95
105
|
// Function to open the math editor modal for new entries
|
|
96
106
|
const openMathEditor = (0, react_1.useCallback)(() => {
|
|
97
107
|
const { selection } = editor;
|
|
@@ -235,7 +245,7 @@ const TextEditor = (props) => {
|
|
|
235
245
|
case "math":
|
|
236
246
|
return ((0, jsx_runtime_1.jsx)(MathElement_1.default, { "data-testid": "math-element", ...props, onEdit: () => editMath(element) }));
|
|
237
247
|
default:
|
|
238
|
-
return ((0, jsx_runtime_1.jsx)(react_2.
|
|
248
|
+
return ((0, jsx_runtime_1.jsx)(react_2.Text, { "data-testid": "text-element", ...attributes, children: children }));
|
|
239
249
|
}
|
|
240
250
|
}, [editMath]);
|
|
241
251
|
// Handle click on editable area
|
|
@@ -249,368 +259,191 @@ const TextEditor = (props) => {
|
|
|
249
259
|
}
|
|
250
260
|
}
|
|
251
261
|
}, [editor]);
|
|
252
|
-
|
|
253
|
-
const handlePaste = async (event) => {
|
|
262
|
+
const handlePaste = (0, react_1.useCallback)((event) => {
|
|
254
263
|
if (disablePaste) {
|
|
255
264
|
event.preventDefault();
|
|
256
265
|
}
|
|
257
|
-
};
|
|
258
|
-
const
|
|
259
|
-
event.preventDefault();
|
|
260
|
-
// Clear clipboard to prevent copying
|
|
261
|
-
try {
|
|
262
|
-
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
263
|
-
await navigator.clipboard.writeText("");
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
catch (error) {
|
|
267
|
-
console.error("Could not clear clipboard:", error);
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
const handleCut = async (event) => {
|
|
266
|
+
}, [disablePaste]);
|
|
267
|
+
const handleDragStart = (0, react_1.useCallback)((event) => {
|
|
271
268
|
event.preventDefault();
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
275
|
-
await navigator.clipboard.writeText("");
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
catch (error) {
|
|
279
|
-
console.error("Could not clear clipboard:", error);
|
|
280
|
-
}
|
|
281
|
-
};
|
|
282
|
-
// Enhanced drag and drop handlers
|
|
283
|
-
const handleDragStart = (event) => {
|
|
284
|
-
event.preventDefault();
|
|
285
|
-
};
|
|
286
|
-
const handleDrop = (event) => {
|
|
287
|
-
event.preventDefault();
|
|
288
|
-
};
|
|
289
|
-
const handleDragOver = (event) => {
|
|
269
|
+
}, []);
|
|
270
|
+
const handleDrop = (0, react_1.useCallback)((event) => {
|
|
290
271
|
event.preventDefault();
|
|
291
|
-
};
|
|
292
|
-
const
|
|
272
|
+
}, []);
|
|
273
|
+
const handleDragOver = (0, react_1.useCallback)((event) => {
|
|
293
274
|
event.preventDefault();
|
|
294
|
-
};
|
|
295
|
-
const
|
|
275
|
+
}, []);
|
|
276
|
+
const handleDragEnter = (0, react_1.useCallback)((event) => {
|
|
296
277
|
event.preventDefault();
|
|
297
|
-
};
|
|
298
|
-
const handleFocus = (0, react_1.useCallback)(() => {
|
|
299
|
-
setIsFocused(true);
|
|
300
278
|
}, []);
|
|
301
|
-
const
|
|
302
|
-
|
|
279
|
+
const handleDragLeave = (0, react_1.useCallback)((event) => {
|
|
280
|
+
event.preventDefault();
|
|
303
281
|
}, []);
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
282
|
+
const handleTabNavigation = (0, react_1.useCallback)((event) => {
|
|
283
|
+
if (event.key !== "Tab" || event.shiftKey)
|
|
284
|
+
return; // Only handle forward Tab
|
|
285
|
+
// Define tab order elements based on what's available
|
|
286
|
+
const tabElements = [];
|
|
287
|
+
if (icons?.formula && !isDisabled) {
|
|
288
|
+
tabElements.push({ name: "formula", ref: formulaIconRef });
|
|
310
289
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
290
|
+
// Add placeholder for addImageRender - it will handle its own internal navigation
|
|
291
|
+
// but we need to know it exists for proper tab order coordination
|
|
292
|
+
if (addImageRender && !isDisabled) {
|
|
293
|
+
tabElements.push({ name: "addImageRender", ref: null });
|
|
294
|
+
}
|
|
295
|
+
if (icons?.submit && !isDisabled && !(0, common_utils_1.isEmptyOrNull)(data?.trim())) {
|
|
296
|
+
tabElements.push({ name: "submit", ref: submitButtonRef });
|
|
297
|
+
}
|
|
298
|
+
if (tabElements.length === 0)
|
|
299
|
+
return; // No focusable elements, let browser handle
|
|
300
|
+
const currentIndex = tabElements.findIndex((el) => el.name === tabFocusedElement);
|
|
301
|
+
let nextIndex;
|
|
302
|
+
if (currentIndex === -1) {
|
|
303
|
+
// Not currently focused on any element, start from first
|
|
304
|
+
event.preventDefault();
|
|
305
|
+
nextIndex = 0;
|
|
306
|
+
}
|
|
307
|
+
else if (currentIndex === tabElements.length - 1) {
|
|
308
|
+
// At last element, tab out (clear focus and let browser handle)
|
|
309
|
+
setTabFocusedElement(null);
|
|
310
|
+
return; // Don't preventDefault, let browser handle tab out
|
|
316
311
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
setIsFocused(false);
|
|
312
|
+
else {
|
|
313
|
+
// Go to next element
|
|
314
|
+
event.preventDefault();
|
|
315
|
+
nextIndex = currentIndex + 1;
|
|
322
316
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
317
|
+
const nextElement = tabElements[nextIndex];
|
|
318
|
+
// Handle addImageRender specially - it manages its own internal focus
|
|
319
|
+
if (nextElement.name === "addImageRender") {
|
|
320
|
+
setTabFocusedElement("addImageRender");
|
|
321
|
+
// Coming from formula, focus first image element
|
|
322
|
+
if (addImageNavRef.current.focusFirst) {
|
|
323
|
+
addImageNavRef.current.focusFirst();
|
|
324
|
+
}
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
// For formula and submit elements, use their refs
|
|
328
|
+
setTabFocusedElement(nextElement.name);
|
|
329
|
+
nextElement.ref.current?.focus();
|
|
330
|
+
}, [tabFocusedElement, icons, isDisabled, data, addImageRender]);
|
|
331
|
+
// Helper function to check if current focus is within addImageRender elements
|
|
332
|
+
const isCurrentlyInAddImageRender = (0, react_1.useCallback)(() => {
|
|
333
|
+
if (!addImageRender)
|
|
334
|
+
return false;
|
|
335
|
+
const focusedElement = document.activeElement;
|
|
336
|
+
if (!focusedElement || !editorRef.current)
|
|
337
|
+
return false;
|
|
338
|
+
// Check if focused element is within the editor but not formula or submit icons
|
|
339
|
+
const isInEditor = editorRef.current.contains(focusedElement);
|
|
340
|
+
const isFormulaIcon = focusedElement === formulaIconRef.current;
|
|
341
|
+
const isSubmitIcon = focusedElement === submitButtonRef.current;
|
|
342
|
+
const isEditorItself = focusedElement === editorRef.current;
|
|
343
|
+
return isInEditor && !isFormulaIcon && !isSubmitIcon && !isEditorItself;
|
|
344
|
+
}, [addImageRender]);
|
|
351
345
|
// Alternative onKeyDown handler approach for the Editable component
|
|
352
|
-
const handleKeyDown = (0, react_1.useCallback)(
|
|
346
|
+
const handleKeyDown = (0, react_1.useCallback)((event) => {
|
|
353
347
|
if (isDisabled || !onSubmit)
|
|
354
348
|
return;
|
|
355
|
-
// Block common clipboard keyboard shortcuts
|
|
356
349
|
if (disablePaste &&
|
|
357
350
|
(event.ctrlKey || event.metaKey) &&
|
|
358
351
|
(event.key === "v" || event.key === "c" || event.key === "x")) {
|
|
359
352
|
event.preventDefault();
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
await navigator.clipboard.writeText("");
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
catch (error) {
|
|
367
|
-
console.log("Could not clear clipboard:", error);
|
|
368
|
-
}
|
|
369
|
-
console.log("Clipboard keyboard shortcut disabled");
|
|
353
|
+
}
|
|
354
|
+
if (event.key === "Tab" && !isCurrentlyInAddImageRender()) {
|
|
355
|
+
handleTabNavigation(event);
|
|
370
356
|
return;
|
|
371
357
|
}
|
|
372
358
|
if (event.key === "Enter") {
|
|
373
|
-
if (isMobile) {
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
if (event.shiftKey) {
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
// Regular Enter should submit
|
|
380
|
-
event.preventDefault();
|
|
381
|
-
const currentText =
|
|
382
|
-
if (!
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
359
|
+
// if (isMobile) {
|
|
360
|
+
return; // Let the default behavior happen (new line)
|
|
361
|
+
// }
|
|
362
|
+
// if (event.shiftKey) {
|
|
363
|
+
// return; // Let the default behavior happen (new line)
|
|
364
|
+
// }
|
|
365
|
+
// // Regular Enter should submit
|
|
366
|
+
// event.preventDefault();
|
|
367
|
+
// const currentText = slateToText(value);
|
|
368
|
+
// if (!isEmptyOrNull(currentText?.trim()) && showBottomBar == true) {
|
|
369
|
+
// handleSubmit();
|
|
370
|
+
// handleChange && handleChange("");
|
|
371
|
+
// }
|
|
386
372
|
}
|
|
387
|
-
}, [value, handleSubmit, handleChange, isDisabled]);
|
|
388
|
-
const isDataEmpty = (0, react_1.useMemo)(() => (0, common_utils_1.isEmptyOrNull)(data), [data]);
|
|
389
|
-
// Mobile bottom icons section
|
|
390
|
-
const MobileBottomIcons = (0, react_1.useMemo)(() => {
|
|
391
|
-
if (!isMobile || !tutorMode)
|
|
392
|
-
return null;
|
|
393
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.Box, { sx: {
|
|
394
|
-
height: "1px",
|
|
395
|
-
backgroundColor: "#E0DBDB",
|
|
396
|
-
width: "100%",
|
|
397
|
-
mt: 3,
|
|
398
|
-
mb: 3,
|
|
399
|
-
} }), (0, jsx_runtime_1.jsxs)(react_2.HStack, { justifyContent: "flex-end", alignItems: "center", width: "100%", spacing: 2, children: [(0, jsx_runtime_1.jsx)(react_2.HStack, { spacing: 3, children: (tutorMode ||
|
|
400
|
-
(!tutorMode && taskType === LearningPathUtils_1.taskTypes.assessment)) && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [memoizedIcons?.formula && ((0, jsx_runtime_1.jsx)(react_2.Image, { sx: {
|
|
401
|
-
h: "28px",
|
|
402
|
-
w: "28px",
|
|
403
|
-
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
404
|
-
}, src: memoizedIcons?.formula, alt: "Add formula", onClick: () => {
|
|
405
|
-
!isDisabled && openMathEditor();
|
|
406
|
-
} })), addImageRender && addImageRender()] })) }), memoizedIcons?.submit && ((0, jsx_runtime_1.jsx)(react_2.Image, { "data-testid": "submit-icon", sx: {
|
|
407
|
-
h: "48px",
|
|
408
|
-
w: "48px",
|
|
409
|
-
cursor: isDataEmpty ? "not-allowed" : "pointer",
|
|
410
|
-
opacity: isDataEmpty ? 0.6 : 1,
|
|
411
|
-
}, src: memoizedIcons?.submit, alt: "submit", onClick: () => {
|
|
412
|
-
if (!(0, common_utils_1.isEmptyOrNull)(data?.trim())) {
|
|
413
|
-
handleSubmit();
|
|
414
|
-
handleChange && handleChange("");
|
|
415
|
-
}
|
|
416
|
-
} }))] })] }));
|
|
417
373
|
}, [
|
|
374
|
+
value,
|
|
375
|
+
handleSubmit,
|
|
376
|
+
handleChange,
|
|
377
|
+
isDisabled,
|
|
378
|
+
handleTabNavigation,
|
|
379
|
+
isCurrentlyInAddImageRender,
|
|
380
|
+
]);
|
|
381
|
+
const editorBoxProps = (0, react_1.useMemo)(() => ({
|
|
382
|
+
editorRef,
|
|
383
|
+
handleClick,
|
|
384
|
+
height,
|
|
385
|
+
handleKeyDown,
|
|
386
|
+
handlePaste,
|
|
387
|
+
handleDrop,
|
|
388
|
+
handleDragOver,
|
|
389
|
+
handleDragEnter,
|
|
390
|
+
handleDragLeave,
|
|
391
|
+
handleDragStart,
|
|
392
|
+
isDisabled,
|
|
393
|
+
showBottomBar,
|
|
394
|
+
isRevision,
|
|
395
|
+
renderElement,
|
|
418
396
|
isMobile,
|
|
397
|
+
isDescAnsQues,
|
|
398
|
+
}), [
|
|
399
|
+
editorRef,
|
|
400
|
+
handleClick,
|
|
401
|
+
height,
|
|
402
|
+
handleKeyDown,
|
|
403
|
+
handlePaste,
|
|
404
|
+
handleDrop,
|
|
405
|
+
handleDragOver,
|
|
406
|
+
handleDragEnter,
|
|
407
|
+
handleDragLeave,
|
|
408
|
+
handleDragStart,
|
|
409
|
+
isDisabled,
|
|
410
|
+
showBottomBar,
|
|
411
|
+
isRevision,
|
|
412
|
+
renderElement,
|
|
413
|
+
isMobile,
|
|
414
|
+
isDescAnsQues,
|
|
415
|
+
]);
|
|
416
|
+
const iconProps = {
|
|
419
417
|
tutorMode,
|
|
420
418
|
taskType,
|
|
421
|
-
|
|
419
|
+
icons,
|
|
422
420
|
isDisabled,
|
|
423
|
-
isDataEmpty,
|
|
424
|
-
addImageRender,
|
|
425
421
|
openMathEditor,
|
|
426
|
-
|
|
422
|
+
addImageRender,
|
|
427
423
|
data,
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}, children: (0, jsx_runtime_1.jsxs)(react_2.Box, { sx: {
|
|
441
|
-
transform: shouldShowTopSection
|
|
442
|
-
? "translateY(0)"
|
|
443
|
-
: "translateY(-100%)",
|
|
444
|
-
// Smooth slide transition with delay
|
|
445
|
-
transition: shouldShowTopSection
|
|
446
|
-
? "transform 0.3s ease-out 0.15s"
|
|
447
|
-
: "transform 0.2s ease-in",
|
|
448
|
-
backgroundColor: tutorMode || (!tutorMode && taskType === LearningPathUtils_1.taskTypes.assessment)
|
|
424
|
+
handleSubmit,
|
|
425
|
+
handleChange,
|
|
426
|
+
formulaIconRef,
|
|
427
|
+
submitButtonRef,
|
|
428
|
+
addImageNavRef,
|
|
429
|
+
tabFocusedElement,
|
|
430
|
+
setTabFocusedElement,
|
|
431
|
+
handleTabNavigation,
|
|
432
|
+
};
|
|
433
|
+
const StackWrapper = isMobile ? react_2.VStack : react_2.HStack;
|
|
434
|
+
const IconsComponent = EditorComponent_1.Icons;
|
|
435
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showerrorpopup && (0, jsx_runtime_1.jsx)(InvalidSession_1.default, { handleClick: propHandleClick }), (0, jsx_runtime_1.jsx)(react_2.ChakraProvider, { theme: theme, children: (0, jsx_runtime_1.jsxs)(react_2.Box, { "data-testid": "studenteditor", w: "100%", borderRadius: "16px", p: isMobile ? "8px" : "16px", border: showBottomBar ? "1px solid #BFBEDC" : "none", pointerEvents: isDisabled ? "none" : "auto", opacity: tutorMode === false ? 1 : isDisabled ? 0.5 : 1, bg: tutorMode || (!tutorMode && taskType === LearningPathUtils_1.taskTypes.assessment)
|
|
449
436
|
? "white"
|
|
450
|
-
: "#F8F3D8",
|
|
451
|
-
borderRadius: "12px 12px 0 0",
|
|
452
|
-
px: 4,
|
|
453
|
-
pt: 3,
|
|
454
|
-
}, children: [(0, jsx_runtime_1.jsxs)(react_2.HStack, { justifyContent: "space-between", position: "relative", userSelect: "none", pb: 2, children: [(0, jsx_runtime_1.jsx)(react_2.Box, { ml: 2, display: "flex", children: !isDisabled && ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "div", sx: EditorStyles_1.styles.multiLineText, children: "Press Enter to send, Shift+Enter for new line" })) }), (0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: "0px", display: ["none", "flex"], mr: 2, children: [(0, jsx_runtime_1.jsx)(react_2.Text, { as: "div", sx: EditorStyles_1.styles.multiLineBox, children: (0, jsx_runtime_1.jsx)(react_2.Image, { sx: {
|
|
455
|
-
h: "16px",
|
|
456
|
-
w: "16px",
|
|
457
|
-
cursor: "not-allowed",
|
|
458
|
-
}, src: icons?.shift, alt: "info" }) }), (0, jsx_runtime_1.jsx)(react_2.Text, { as: "div", ml: 2, mr: 2, children: "+" }), (0, jsx_runtime_1.jsx)(react_2.Text, { as: "div", sx: EditorStyles_1.styles.multiLineBox, children: "Enter" })] })] }), (0, jsx_runtime_1.jsx)(react_2.Box, { sx: {
|
|
459
|
-
height: "1px",
|
|
460
|
-
backgroundColor: "#E0DBDB",
|
|
461
|
-
width: "100%",
|
|
462
|
-
opacity: shouldShowTopSection ? 1 : 0,
|
|
463
|
-
// Smooth line transition
|
|
464
|
-
transition: "opacity 0.2s ease-in-out",
|
|
465
|
-
} })] }) }));
|
|
466
|
-
}, [
|
|
467
|
-
isMobile,
|
|
468
|
-
shouldShowTopSection,
|
|
469
|
-
isDisabled,
|
|
470
|
-
icons?.shift,
|
|
471
|
-
EditorStyles_1.styles.multiLineText,
|
|
472
|
-
EditorStyles_1.styles.multiLineBox,
|
|
473
|
-
]);
|
|
474
|
-
const LearningCreditsWarning = () => ((0, jsx_runtime_1.jsxs)(react_2.HStack, { sx: { opacity: "1", zIndex: 2, width: "100%" }, spacing: 3, justifyContent: "space-between", children: [(0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: 3, children: [icons?.info && ((0, jsx_runtime_1.jsx)(react_2.Image, { sx: {
|
|
475
|
-
h: "28px",
|
|
476
|
-
w: "28px",
|
|
477
|
-
cursor: "not-allowed",
|
|
478
|
-
color: "#D0392E",
|
|
479
|
-
transform: "rotate(180deg)",
|
|
480
|
-
}, src: icons?.info, alt: "info" })), (0, jsx_runtime_1.jsxs)(react_2.Text, { as: "div", sx: {
|
|
481
|
-
...EditorStyles_1.styles.multiLineText,
|
|
482
|
-
...EditorStyles_1.styles.multiLineRed,
|
|
483
|
-
}, children: ["Since you do not have enough", " ", (0, jsx_runtime_1.jsx)(react_2.Text, { as: "span", sx: { ...EditorStyles_1.styles.multiLineBold }, children: "Learning Credits Vin wont be able to help you." })] })] }), icons?.submit && ((0, jsx_runtime_1.jsx)(react_2.Image, { "data-testid": "submit-icon", sx: {
|
|
484
|
-
h: "48px",
|
|
485
|
-
w: "48px",
|
|
486
|
-
zIndex: 2,
|
|
487
|
-
cursor: (0, common_utils_1.isEmptyOrNull)(data) ? "not-allowed" : "pointer",
|
|
488
|
-
opacity: (0, common_utils_1.isEmptyOrNull)(data) ? 0.6 : 1,
|
|
489
|
-
}, src: icons?.submit, alt: "submit", onClick: () => {
|
|
490
|
-
if (!(0, common_utils_1.isEmptyOrNull)(data?.trim())) {
|
|
491
|
-
handleSubmit();
|
|
492
|
-
handleChange && handleChange("");
|
|
493
|
-
}
|
|
494
|
-
} }))] }));
|
|
495
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [props?.showerrorpopup && ((0, jsx_runtime_1.jsx)(InvalidSession_1.default, { handleClick: propHandleClick })), (0, jsx_runtime_1.jsx)(react_2.ChakraProvider, { theme: theme, children: (0, jsx_runtime_1.jsxs)(react_2.Box, { "data-testid": "studenteditor", w: "100%", borderRadius: "8px", p: "24px", border: showBottomBar ? "1px solid var(--Text-100, #BFBEDC)" : "none", pointerEvents: isDisabled ? "none" : "auto", opacity: tutorMode === false ? 1 : isDisabled ? 0.5 : 1, bg: isDisabledRevision
|
|
496
|
-
? "transparent"
|
|
497
|
-
: tutorMode || (!tutorMode && taskType === LearningPathUtils_1.taskTypes.assessment)
|
|
498
|
-
? "white"
|
|
499
|
-
: "#F8F3D8", onMouseEnter: handleEditorMouseEnter, onMouseLeave: handleEditorMouseLeave, position: "relative", children: [TopSection, tutorMode && ((0, jsx_runtime_1.jsx)(slate_react_1.Slate, { editor: editor, initialValue: value, onChange: (newValue) => {
|
|
437
|
+
: "#F8F3D8", children: [(tutorMode || (!tutorMode && taskType === LearningPathUtils_1.taskTypes.assessment)) && ((0, jsx_runtime_1.jsx)(slate_react_1.Slate, { editor: editor, initialValue: value, onChange: (newValue) => {
|
|
500
438
|
setValue(newValue);
|
|
501
439
|
handleChange && handleChange((0, slate_conversions_1.slateToText)(newValue));
|
|
502
|
-
}, children:
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
maxH: height ?? "200px",
|
|
506
|
-
overflow: "auto",
|
|
507
|
-
cursor: "text",
|
|
440
|
+
}, children: (0, jsx_runtime_1.jsxs)(StackWrapper, { spacing: 0, alignItems: isMobile ? "stretch" : "flex-end", width: "100%", children: [(0, jsx_runtime_1.jsx)(EditorComponent_1.EditorBox, { ...editorBoxProps }), isMobile && ((0, jsx_runtime_1.jsx)(react_2.Box, { sx: {
|
|
441
|
+
height: "1px",
|
|
442
|
+
backgroundColor: "#E0DBDB",
|
|
508
443
|
width: "100%",
|
|
509
|
-
}, children: (0, jsx_runtime_1.jsx)(react_2.chakra.div, { sx: {
|
|
510
|
-
"[data-slate-placeholder]": {
|
|
511
|
-
display: isDisabled || isFocused
|
|
512
|
-
? "none !important"
|
|
513
|
-
: "inline-block !important",
|
|
514
|
-
color: "black !important",
|
|
515
|
-
pointerEvents: "none !important",
|
|
516
|
-
fontWeight: "400 !important",
|
|
517
|
-
fontSize: "16px !important",
|
|
518
|
-
top: "0px !important",
|
|
519
|
-
left: "4px !important",
|
|
520
|
-
position: "absolute !important",
|
|
521
|
-
// width: "calc(100% - 8px) !important",
|
|
522
|
-
lineHeight: "1.5 !important",
|
|
523
|
-
whiteSpace: "pre-wrap !important",
|
|
524
|
-
},
|
|
525
|
-
}, children: (0, jsx_runtime_1.jsx)(slate_react_1.Editable, { "data-testid": "input-editor", renderElement: renderElement, placeholder: showBottomBar
|
|
526
|
-
? isRevision
|
|
527
|
-
? "Write your answer first — that's where real learning happens."
|
|
528
|
-
: "Ask Vin any question, use voice, or upload your work!"
|
|
529
|
-
: "", readOnly: isDisabled, onKeyDown: handleKeyDown, onPaste: handlePaste, onCopy: handleCopy, onCut: handleCut, onFocus: handleFocus, onBlur: handleBlur, onDrop: handleDrop, onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragStart: handleDragStart, draggable: false, style: {
|
|
530
|
-
position: "relative",
|
|
531
|
-
// outline: "none",
|
|
532
|
-
minHeight: "50px",
|
|
533
|
-
zIndex: 1,
|
|
534
|
-
cursor: isDisabled ? "not-allowed" : "text",
|
|
535
|
-
userSelect: isDisabled ? "none" : "auto",
|
|
536
|
-
pointerEvents: isDisabled ? "none" : "auto",
|
|
537
|
-
paddingLeft: "4px",
|
|
538
|
-
overflow: "auto",
|
|
539
|
-
"&::-webkit-scrollbar": {
|
|
540
|
-
width: "0px",
|
|
541
|
-
height: "0px",
|
|
542
|
-
},
|
|
543
|
-
scrollbarWidth: "none",
|
|
544
|
-
} }) }) }), isMobile && MobileBottomIcons] })) : (
|
|
545
|
-
/* Desktop Layout (original) */
|
|
546
|
-
(0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: 0, alignItems: "flex-end", children: [(0, jsx_runtime_1.jsx)(react_2.Box, { ref: editorRef, onClick: handleClick, flex: 1, sx: {
|
|
547
|
-
position: "relative",
|
|
548
|
-
minH: "0px",
|
|
549
|
-
maxH: height ?? "200px",
|
|
550
|
-
overflow: "auto",
|
|
551
|
-
cursor: "text",
|
|
552
444
|
mt: 2,
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
transition: "padding-top 0.3s ease-in-out",
|
|
556
|
-
}, children: (0, jsx_runtime_1.jsx)(react_2.chakra.div, { sx: {
|
|
557
|
-
"[data-slate-placeholder]": {
|
|
558
|
-
display: isDisabled || isFocused
|
|
559
|
-
? "none !important"
|
|
560
|
-
: "inline-block !important",
|
|
561
|
-
color: "black !important",
|
|
562
|
-
pointerEvents: "none !important",
|
|
563
|
-
fontWeight: "400 !important",
|
|
564
|
-
fontSize: "16px !important",
|
|
565
|
-
position: "absolute !important",
|
|
566
|
-
// Position at top of container
|
|
567
|
-
top: "0px !important",
|
|
568
|
-
left: "4px !important",
|
|
569
|
-
// Add smooth placeholder transitions
|
|
570
|
-
// transition: "all 0.2s ease-in-out !important",
|
|
571
|
-
},
|
|
572
|
-
}, children: (0, jsx_runtime_1.jsx)(slate_react_1.Editable, { "data-testid": "input-editor", renderElement: renderElement, placeholder: showBottomBar
|
|
573
|
-
? isRevision
|
|
574
|
-
? "Write your answer first — that's where real learning happens."
|
|
575
|
-
: "Ask Vin any question, use voice, or upload your work!"
|
|
576
|
-
: "", readOnly: isDisabled, onKeyDown: handleKeyDown, onPaste: handlePaste, onCopy: handleCopy, onCut: handleCut, onFocus: handleFocus, onBlur: handleBlur, onDrop: handleDrop, onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragStart: handleDragStart, draggable: false, style: {
|
|
577
|
-
position: "relative",
|
|
578
|
-
outline: "none",
|
|
579
|
-
minHeight: "50px",
|
|
580
|
-
zIndex: 1,
|
|
581
|
-
cursor: isDisabled ? "not-allowed" : "text",
|
|
582
|
-
pointerEvents: isDisabled ? "none" : "auto",
|
|
583
|
-
paddingLeft: "4px",
|
|
584
|
-
width: "100%",
|
|
585
|
-
display: "block",
|
|
586
|
-
overflow: "auto",
|
|
587
|
-
"&::-webkit-scrollbar": {
|
|
588
|
-
width: "0px",
|
|
589
|
-
height: "0px",
|
|
590
|
-
},
|
|
591
|
-
scrollbarWidth: "none",
|
|
592
|
-
} }) }) }), (0, jsx_runtime_1.jsxs)(react_2.HStack, { justifyContent: "flex-end", position: "relative", ml: 2, userSelect: "none", spacing: 5, children: [(tutorMode ||
|
|
593
|
-
(!tutorMode && taskType === LearningPathUtils_1.taskTypes.assessment) ||
|
|
594
|
-
isDisabledRevision) && ((0, jsx_runtime_1.jsxs)(react_2.HStack, { sx: { opacity: "1", zIndex: 2 }, spacing: 5, children: [icons?.formula && ((0, jsx_runtime_1.jsx)(react_2.Image, { sx: {
|
|
595
|
-
h: "28px",
|
|
596
|
-
w: "28px",
|
|
597
|
-
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
598
|
-
}, src: icons?.formula, alt: "Add formula", onClick: () => {
|
|
599
|
-
!isDisabled && openMathEditor();
|
|
600
|
-
} })), addImageRender && addImageRender()] })), icons?.submit && ((0, jsx_runtime_1.jsx)(react_2.Image, { "data-testid": "submit-icon", sx: {
|
|
601
|
-
h: "48px",
|
|
602
|
-
w: "48px",
|
|
603
|
-
zIndex: 2,
|
|
604
|
-
cursor: (0, common_utils_1.isEmptyOrNull)(data)
|
|
605
|
-
? "not-allowed"
|
|
606
|
-
: "pointer",
|
|
607
|
-
opacity: (0, common_utils_1.isEmptyOrNull)(data) ? 0.6 : 1,
|
|
608
|
-
}, src: icons?.submit, alt: "submit", onClick: () => {
|
|
609
|
-
if (!(0, common_utils_1.isEmptyOrNull)(data?.trim())) {
|
|
610
|
-
handleSubmit();
|
|
611
|
-
handleChange && handleChange("");
|
|
612
|
-
}
|
|
613
|
-
} }))] })] })) })), !tutorMode && taskType !== LearningPathUtils_1.taskTypes.assessment && !isRevision && ((0, jsx_runtime_1.jsx)(LearningCreditsWarning, {})), (0, jsx_runtime_1.jsx)(MathModal_1.default, { isOpen: isModalOpen, onClose: handleModalClose, onSave: handleSaveMath, initialLatex: currentLatex, subject: props.subject })] }) })] }));
|
|
445
|
+
mb: 2,
|
|
446
|
+
} })), (0, jsx_runtime_1.jsx)(IconsComponent, { ...iconProps, isDisabledRevision: !isMobile ? isDisabledRevision : "" })] }) })), !tutorMode && taskType !== LearningPathUtils_1.taskTypes.assessment && !isRevision && ((0, jsx_runtime_1.jsx)(EditorComponent_1.LearningCreditsWarning, { icons: icons, data: data, handleSubmit: handleSubmit, handleChange: handleChange })), (0, jsx_runtime_1.jsx)(MathModal_1.default, { isOpen: isModalOpen, onClose: handleModalClose, onSave: handleSaveMath, initialLatex: currentLatex, subject: props.subject })] }) })] }));
|
|
614
447
|
};
|
|
615
448
|
exports.default = TextEditor;
|
|
616
449
|
//# sourceMappingURL=TextEditor.js.map
|