@baasix/lexical 0.0.10 → 0.0.11
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/dist/index.js +865 -359
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -57,11 +57,11 @@ import "./chunk-PZ5AY32C.js";
|
|
|
57
57
|
|
|
58
58
|
// src/LexicalEditor.tsx
|
|
59
59
|
import {
|
|
60
|
-
useCallback as
|
|
60
|
+
useCallback as useCallback31,
|
|
61
61
|
useEffect as useEffect48,
|
|
62
62
|
useMemo as useMemo24,
|
|
63
|
-
useRef as
|
|
64
|
-
useState as
|
|
63
|
+
useRef as useRef20,
|
|
64
|
+
useState as useState44
|
|
65
65
|
} from "react";
|
|
66
66
|
import { LexicalComposer as LexicalComposer2 } from "@lexical/react/LexicalComposer";
|
|
67
67
|
import { OnChangePlugin as OnChangePlugin2 } from "@lexical/react/LexicalOnChangePlugin";
|
|
@@ -87,7 +87,7 @@ import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin
|
|
|
87
87
|
import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
|
|
88
88
|
import { useLexicalEditable as useLexicalEditable10 } from "@lexical/react/useLexicalEditable";
|
|
89
89
|
import { CAN_USE_DOM } from "@lexical/utils";
|
|
90
|
-
import { useEffect as useEffect47, useState as
|
|
90
|
+
import { useEffect as useEffect47, useState as useState43 } from "react";
|
|
91
91
|
|
|
92
92
|
// src/plugins/ActionsPlugin/index.tsx
|
|
93
93
|
import { $createCodeNode, $isCodeNode } from "@lexical/code";
|
|
@@ -6234,7 +6234,7 @@ import {
|
|
|
6234
6234
|
$isRangeSelection as $isRangeSelection7,
|
|
6235
6235
|
FORMAT_ELEMENT_COMMAND
|
|
6236
6236
|
} from "lexical";
|
|
6237
|
-
import { useCallback as
|
|
6237
|
+
import { useCallback as useCallback23, useMemo as useMemo18, useState as useState31 } from "react";
|
|
6238
6238
|
import * as ReactDOM2 from "react-dom";
|
|
6239
6239
|
|
|
6240
6240
|
// src/plugins/DateTimePlugin/index.tsx
|
|
@@ -7646,7 +7646,7 @@ function PageBreakPlugin() {
|
|
|
7646
7646
|
import { useLexicalComposerContext as useLexicalComposerContext21 } from "@lexical/react/LexicalComposerContext";
|
|
7647
7647
|
import { $insertNodeToNearestRoot as $insertNodeToNearestRoot7 } from "@lexical/utils";
|
|
7648
7648
|
import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR13, createCommand as createCommand13 } from "lexical";
|
|
7649
|
-
import { useCallback as useCallback12, useEffect as useEffect23, useMemo as useMemo8, useState as useState18 } from "react";
|
|
7649
|
+
import { useCallback as useCallback12, useEffect as useEffect23, useMemo as useMemo8, useRef as useRef9, useState as useState18 } from "react";
|
|
7650
7650
|
|
|
7651
7651
|
// src/nodes/NotesNode.tsx
|
|
7652
7652
|
import { $getNodeByKey as $getNodeByKey4 } from "lexical";
|
|
@@ -7942,34 +7942,68 @@ function convertNotes(input) {
|
|
|
7942
7942
|
const doc = parser.parseFromString(input, "text/html");
|
|
7943
7943
|
html += Array.from(doc.body.childNodes).map(processNode).join("");
|
|
7944
7944
|
} else {
|
|
7945
|
-
const paragraphs = input.split(/\n\s*\n/);
|
|
7946
7945
|
const style = CARD_STYLES.notes;
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
if (
|
|
7951
|
-
|
|
7952
|
-
const isOrdered = p.match(/^\d+\./);
|
|
7953
|
-
const tag = isOrdered ? "ol" : "ul";
|
|
7954
|
-
html += ` <${tag} style="margin-left: 20px; padding-left: 20px; margin-bottom: 15px;">
|
|
7946
|
+
const lines = input.split("\n");
|
|
7947
|
+
let inList = null;
|
|
7948
|
+
const closeList = () => {
|
|
7949
|
+
if (inList) {
|
|
7950
|
+
html += ` </${inList}>
|
|
7955
7951
|
`;
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7952
|
+
inList = null;
|
|
7953
|
+
}
|
|
7954
|
+
};
|
|
7955
|
+
const isBullet = (line) => /^[\s]*[-•*]\s/.test(line);
|
|
7956
|
+
const isOrdered = (line) => /^[\s]*\d+[.)]\s/.test(line);
|
|
7957
|
+
const isHeading = (line) => {
|
|
7958
|
+
const t = line.trim();
|
|
7959
|
+
if (t.length > 120 || t.length < 2) return false;
|
|
7960
|
+
if (t.endsWith(".") || t.endsWith(",")) return false;
|
|
7961
|
+
if (isBullet(t) || isOrdered(t)) return false;
|
|
7962
|
+
if (t.endsWith(":")) return true;
|
|
7963
|
+
if (t.length < 80 && !/[.!?,;]$/.test(t)) return true;
|
|
7964
|
+
return false;
|
|
7965
|
+
};
|
|
7966
|
+
for (let i = 0; i < lines.length; i++) {
|
|
7967
|
+
const line = lines[i];
|
|
7968
|
+
const trimmed = line.trim();
|
|
7969
|
+
if (!trimmed) {
|
|
7970
|
+
closeList();
|
|
7971
|
+
continue;
|
|
7972
|
+
}
|
|
7973
|
+
if (isBullet(trimmed)) {
|
|
7974
|
+
if (inList !== "ul") {
|
|
7975
|
+
closeList();
|
|
7976
|
+
inList = "ul";
|
|
7977
|
+
html += ` <ul style="margin-left: 20px; padding-left: 20px; margin-bottom: 15px;">
|
|
7960
7978
|
`;
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
html += `
|
|
7979
|
+
}
|
|
7980
|
+
const cleanItem = trimmed.replace(/^[-•*]\s*/, "");
|
|
7981
|
+
html += ` <li style="margin-bottom: 5px;">${cleanItem}</li>
|
|
7964
7982
|
`;
|
|
7965
|
-
|
|
7966
|
-
|
|
7983
|
+
continue;
|
|
7984
|
+
}
|
|
7985
|
+
if (isOrdered(trimmed)) {
|
|
7986
|
+
if (inList !== "ol") {
|
|
7987
|
+
closeList();
|
|
7988
|
+
inList = "ol";
|
|
7989
|
+
html += ` <ol style="margin-left: 20px; padding-left: 20px; margin-bottom: 15px;">
|
|
7967
7990
|
`;
|
|
7968
|
-
|
|
7969
|
-
|
|
7991
|
+
}
|
|
7992
|
+
const cleanItem = trimmed.replace(/^\d+[.)]\s*/, "");
|
|
7993
|
+
html += ` <li style="margin-bottom: 5px;">${cleanItem}</li>
|
|
7970
7994
|
`;
|
|
7995
|
+
continue;
|
|
7971
7996
|
}
|
|
7972
|
-
|
|
7997
|
+
closeList();
|
|
7998
|
+
if (isHeading(trimmed)) {
|
|
7999
|
+
html += ` <h3 style="color: ${style.headingColor}; border-bottom: 2px solid ${style.headingBorder}; padding-bottom: 5px; margin-top: 25px; margin-bottom: 15px;">${trimmed}</h3>
|
|
8000
|
+
`;
|
|
8001
|
+
continue;
|
|
8002
|
+
}
|
|
8003
|
+
html += ` <p style="margin-bottom: 15px;">${trimmed}</p>
|
|
8004
|
+
`;
|
|
8005
|
+
}
|
|
8006
|
+
closeList();
|
|
7973
8007
|
}
|
|
7974
8008
|
html += "</div>";
|
|
7975
8009
|
return compactHtml(html);
|
|
@@ -8133,7 +8167,7 @@ function convertTextCards(input) {
|
|
|
8133
8167
|
const c = styles[key];
|
|
8134
8168
|
html += ` <div style="background: ${c.light}; border: 2px solid ${c.border}; border-left: 4px solid ${c.border}; padding: 16px; border-radius: 12px; min-height: 120px;">
|
|
8135
8169
|
<h3 style="margin-top: 0; color: inherit; font-size: 14px;">${c.emoji} ${c.number}. ${c.title}</h3>
|
|
8136
|
-
<p style="margin: 0; font-size: 13px;">${content}</p>
|
|
8170
|
+
<p style="margin: 0; font-size: 13px;">${nl2br(content)}</p>
|
|
8137
8171
|
</div>
|
|
8138
8172
|
`;
|
|
8139
8173
|
});
|
|
@@ -8239,8 +8273,8 @@ var QUESTIONS_CARD_GRID_SECTIONS = [
|
|
|
8239
8273
|
"tips"
|
|
8240
8274
|
];
|
|
8241
8275
|
var QUESTIONS_SECTION_PATTERNS = {
|
|
8242
|
-
question: /^Q\
|
|
8243
|
-
answer: /^Answer:\s
|
|
8276
|
+
question: /^(\d+\.\s*)?Q(uestion|\d+)\s*[\s.:]/i,
|
|
8277
|
+
answer: /^(Model\s+)?Answer:\s*/i,
|
|
8244
8278
|
rubric: /^(\d+\.\s*)?MARKING\s+RUBRIC/i,
|
|
8245
8279
|
mnemonics: /^(\d+\.\s*)?MNEMONIC/i,
|
|
8246
8280
|
examiner: /^(\d+\.\s*)?EXAMINER/i,
|
|
@@ -8251,103 +8285,244 @@ var QUESTIONS_SECTION_PATTERNS = {
|
|
|
8251
8285
|
variations: /^(\d+\.\s*)?EXAM\s+VARIATION/i,
|
|
8252
8286
|
tips: /^(\d+\.\s*)?(HIGH-YIELD|EXAM\s+TIP)/i
|
|
8253
8287
|
};
|
|
8288
|
+
function formatMcqQuestion(text) {
|
|
8289
|
+
const optionMatch = text.match(/\s+[a-eA-E][)]\s/);
|
|
8290
|
+
if (!optionMatch || optionMatch.index === void 0) return text;
|
|
8291
|
+
const questionPart = text.substring(0, optionMatch.index).trim();
|
|
8292
|
+
const optionsPart = text.substring(optionMatch.index).trim();
|
|
8293
|
+
const options = optionsPart.split(/(?=\s*[a-eA-E][)]\s)/).map((o) => o.trim()).filter(Boolean);
|
|
8294
|
+
if (options.length < 2) return text;
|
|
8295
|
+
let optionsHtml = '<div style="margin-top: 10px; display: flex; flex-direction: column; gap: 6px;">';
|
|
8296
|
+
options.forEach((opt) => {
|
|
8297
|
+
const letter = opt.charAt(0).toUpperCase();
|
|
8298
|
+
const optText = opt.replace(/^[a-eA-E][)]\s*/, "").trim();
|
|
8299
|
+
optionsHtml += `<div style="display: flex; align-items: baseline; gap: 8px;">
|
|
8300
|
+
<span style="background: rgba(0,0,0,0.08); border-radius: 4px; padding: 2px 8px; font-weight: 600; font-size: 13px; min-width: 24px; text-align: center;">${letter}</span>
|
|
8301
|
+
<span style="font-size: 14px;">${optText}</span>
|
|
8302
|
+
</div>`;
|
|
8303
|
+
});
|
|
8304
|
+
optionsHtml += "</div>";
|
|
8305
|
+
return `${questionPart}${optionsHtml}`;
|
|
8306
|
+
}
|
|
8307
|
+
function formatMcqAnswer(text) {
|
|
8308
|
+
const match = text.match(/^([a-eA-E])[)]\s*/);
|
|
8309
|
+
if (!match) return text;
|
|
8310
|
+
const letter = match[1].toUpperCase();
|
|
8311
|
+
const explanation = text.substring(match[0].length).trim();
|
|
8312
|
+
return `<span style="background: rgba(76, 175, 80, 0.15); border: 1px solid rgba(76, 175, 80, 0.4); border-radius: 4px; padding: 2px 8px; font-weight: 700; font-size: 14px; margin-right: 8px;">${letter}</span> ${explanation}`;
|
|
8313
|
+
}
|
|
8314
|
+
function nl2br(text) {
|
|
8315
|
+
return text.replace(/\n/g, "<br>");
|
|
8316
|
+
}
|
|
8254
8317
|
function convertQuestionsCards(input) {
|
|
8255
8318
|
if (!input.trim()) return "";
|
|
8256
|
-
const
|
|
8319
|
+
const parsed = parseQuestionsInput(input);
|
|
8257
8320
|
const styles = CARD_STYLES.questionsCards;
|
|
8258
8321
|
let html = "";
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
|
|
8263
|
-
|
|
8322
|
+
parsed.qaPairs.forEach((qa, idx) => {
|
|
8323
|
+
if (qa.question) {
|
|
8324
|
+
const c = styles.question;
|
|
8325
|
+
const qLabel = parsed.qaPairs.length > 1 ? `Question ${idx + 1}` : "Question";
|
|
8326
|
+
const formattedQ = formatMcqQuestion(nl2br(qa.question));
|
|
8327
|
+
html += `<div style="background: ${c.light}; border: 2px solid ${c.border}; border-left: 4px solid ${c.border}; padding: 16px 20px; border-radius: 12px; margin-bottom: 20px;">
|
|
8328
|
+
<h3 style="margin: 0; color: inherit;">${c.emoji} ${qLabel}</h3>
|
|
8329
|
+
<div style="margin-top: 8px; color: inherit;">${formattedQ}</div>
|
|
8264
8330
|
</div>
|
|
8265
8331
|
`;
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8332
|
+
}
|
|
8333
|
+
if (qa.answer) {
|
|
8334
|
+
const c = styles.answer;
|
|
8335
|
+
const formattedA = formatMcqAnswer(nl2br(qa.answer));
|
|
8336
|
+
html += `<div style="background: ${c.light}; border: 2px solid ${c.border}; border-left: 4px solid ${c.border}; padding: 16px 20px; border-radius: 12px; margin-bottom: 20px;">
|
|
8270
8337
|
<h3 style="margin-top: 0; color: inherit;">${c.emoji} ${c.title}</h3>
|
|
8271
|
-
<p>${
|
|
8338
|
+
<p>${formattedA}</p>
|
|
8272
8339
|
</div>
|
|
8273
8340
|
`;
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8341
|
+
}
|
|
8342
|
+
const qaSections = qa.sections || {};
|
|
8343
|
+
const hasGridCards = QUESTIONS_CARD_GRID_SECTIONS.some((k) => qaSections[k]);
|
|
8344
|
+
if (hasGridCards) {
|
|
8345
|
+
html += `<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 8px; margin-bottom: 24px;">
|
|
8278
8346
|
`;
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8347
|
+
QUESTIONS_CARD_GRID_SECTIONS.forEach((key) => {
|
|
8348
|
+
const content = qaSections[key];
|
|
8349
|
+
if (!content) return;
|
|
8350
|
+
const c = styles[key];
|
|
8351
|
+
html += ` <div style="background: ${c.light}; border: 2px solid ${c.border}; border-left: 4px solid ${c.border}; padding: 16px; border-radius: 12px; min-height: 120px;">
|
|
8284
8352
|
<h3 style="margin-top: 0; color: inherit; font-size: 14px;">${c.emoji} ${c.number}. ${c.title}</h3>
|
|
8285
|
-
<p style="margin: 0; font-size: 13px;">${content}</p>
|
|
8353
|
+
<p style="margin: 0; font-size: 13px;">${nl2br(content)}</p>
|
|
8286
8354
|
</div>
|
|
8287
8355
|
`;
|
|
8288
|
-
|
|
8289
|
-
|
|
8290
|
-
|
|
8356
|
+
});
|
|
8357
|
+
html += "</div>\n";
|
|
8358
|
+
}
|
|
8359
|
+
});
|
|
8291
8360
|
return compactHtml(html);
|
|
8292
8361
|
}
|
|
8362
|
+
var INLINE_ANSWER_PATTERNS = [
|
|
8363
|
+
/\s+Correct\s+Answer:\s*/i,
|
|
8364
|
+
/\s+Model\s+Answer:\s*/i
|
|
8365
|
+
];
|
|
8366
|
+
var MCQ_LINE_PATTERN = /^\d+[.)]\s+/;
|
|
8293
8367
|
function parseQuestionsInput(input) {
|
|
8294
8368
|
const lines = input.split("\n").filter((l) => l.trim());
|
|
8295
|
-
const
|
|
8369
|
+
const result = { qaPairs: [] };
|
|
8296
8370
|
let currentSection = null;
|
|
8297
8371
|
let contentBuffer = [];
|
|
8298
|
-
|
|
8372
|
+
let currentQA = { question: "", answer: "", sections: {} };
|
|
8373
|
+
let inQASection = null;
|
|
8374
|
+
const flushQA = () => {
|
|
8375
|
+
if (inQASection === "question") {
|
|
8376
|
+
currentQA.question = contentBuffer.join("\n").trim();
|
|
8377
|
+
} else if (inQASection === "answer") {
|
|
8378
|
+
currentQA.answer = contentBuffer.join("\n").trim();
|
|
8379
|
+
}
|
|
8380
|
+
contentBuffer = [];
|
|
8381
|
+
};
|
|
8382
|
+
const flushSection = () => {
|
|
8299
8383
|
if (currentSection && contentBuffer.length > 0) {
|
|
8300
|
-
sections[currentSection] = contentBuffer.join("
|
|
8384
|
+
currentQA.sections[currentSection] = contentBuffer.join("\n").trim();
|
|
8301
8385
|
}
|
|
8302
8386
|
contentBuffer = [];
|
|
8303
8387
|
};
|
|
8388
|
+
const pushCurrentQA = () => {
|
|
8389
|
+
if (currentQA.question || currentQA.answer || Object.keys(currentQA.sections).length > 0) {
|
|
8390
|
+
result.qaPairs.push({ ...currentQA, sections: { ...currentQA.sections } });
|
|
8391
|
+
currentQA = { question: "", answer: "", sections: {} };
|
|
8392
|
+
}
|
|
8393
|
+
};
|
|
8394
|
+
const trySplitInline = (line) => {
|
|
8395
|
+
for (const pattern of INLINE_ANSWER_PATTERNS) {
|
|
8396
|
+
const match = line.match(pattern);
|
|
8397
|
+
if (match && match.index !== void 0) {
|
|
8398
|
+
return {
|
|
8399
|
+
question: line.substring(0, match.index).trim(),
|
|
8400
|
+
answer: line.substring(match.index + match[0].length).trim()
|
|
8401
|
+
};
|
|
8402
|
+
}
|
|
8403
|
+
}
|
|
8404
|
+
return null;
|
|
8405
|
+
};
|
|
8304
8406
|
for (const line of lines) {
|
|
8305
8407
|
const trimmed = line.trim();
|
|
8408
|
+
if (QUESTIONS_SECTION_PATTERNS.question.test(trimmed)) {
|
|
8409
|
+
if (inQASection) flushQA();
|
|
8410
|
+
if (currentSection) {
|
|
8411
|
+
flushSection();
|
|
8412
|
+
currentSection = null;
|
|
8413
|
+
}
|
|
8414
|
+
pushCurrentQA();
|
|
8415
|
+
const qText = trimmed.replace(/^(\d+\.\s*)?Q(uestion|\d+)\s*[\s.:]+/i, "").trim();
|
|
8416
|
+
const inlineSplit = trySplitInline(qText);
|
|
8417
|
+
if (inlineSplit) {
|
|
8418
|
+
currentQA = { question: inlineSplit.question, answer: inlineSplit.answer, sections: {} };
|
|
8419
|
+
inQASection = null;
|
|
8420
|
+
} else {
|
|
8421
|
+
inQASection = "question";
|
|
8422
|
+
if (qText) contentBuffer.push(qText);
|
|
8423
|
+
}
|
|
8424
|
+
continue;
|
|
8425
|
+
}
|
|
8426
|
+
if (QUESTIONS_SECTION_PATTERNS.answer.test(trimmed)) {
|
|
8427
|
+
if (inQASection) flushQA();
|
|
8428
|
+
if (currentSection) {
|
|
8429
|
+
flushSection();
|
|
8430
|
+
currentSection = null;
|
|
8431
|
+
}
|
|
8432
|
+
inQASection = "answer";
|
|
8433
|
+
const aText = trimmed.replace(/^(Model\s+)?Answer:\s*/i, "").trim();
|
|
8434
|
+
if (aText) contentBuffer.push(aText);
|
|
8435
|
+
continue;
|
|
8436
|
+
}
|
|
8437
|
+
if (MCQ_LINE_PATTERN.test(trimmed) && !QUESTIONS_SECTION_PATTERNS.question.test(trimmed)) {
|
|
8438
|
+
const inlineSplit = trySplitInline(trimmed);
|
|
8439
|
+
if (inlineSplit) {
|
|
8440
|
+
if (inQASection) flushQA();
|
|
8441
|
+
if (currentSection) {
|
|
8442
|
+
flushSection();
|
|
8443
|
+
currentSection = null;
|
|
8444
|
+
}
|
|
8445
|
+
pushCurrentQA();
|
|
8446
|
+
const qText = inlineSplit.question.replace(/^\d+[.)]\s*/, "").trim();
|
|
8447
|
+
currentQA = { question: qText, answer: inlineSplit.answer, sections: {} };
|
|
8448
|
+
inQASection = null;
|
|
8449
|
+
continue;
|
|
8450
|
+
}
|
|
8451
|
+
}
|
|
8306
8452
|
let foundSection = false;
|
|
8307
8453
|
for (const [key, pattern] of Object.entries(QUESTIONS_SECTION_PATTERNS)) {
|
|
8454
|
+
if (key === "question" || key === "answer") continue;
|
|
8308
8455
|
if (pattern.test(trimmed)) {
|
|
8309
|
-
|
|
8456
|
+
if (inQASection) {
|
|
8457
|
+
flushQA();
|
|
8458
|
+
inQASection = null;
|
|
8459
|
+
}
|
|
8460
|
+
if (currentSection) flushSection();
|
|
8310
8461
|
currentSection = key;
|
|
8311
8462
|
foundSection = true;
|
|
8312
|
-
if (key === "question") {
|
|
8313
|
-
const qText = trimmed.replace(/^Q\d+\.\s*/, "").trim();
|
|
8314
|
-
if (qText) contentBuffer.push(qText);
|
|
8315
|
-
}
|
|
8316
8463
|
break;
|
|
8317
8464
|
}
|
|
8318
8465
|
}
|
|
8319
8466
|
if (foundSection) continue;
|
|
8320
|
-
|
|
8321
|
-
contentBuffer.push(trimmed);
|
|
8322
|
-
}
|
|
8467
|
+
contentBuffer.push(trimmed);
|
|
8323
8468
|
}
|
|
8324
|
-
|
|
8325
|
-
|
|
8469
|
+
if (inQASection) flushQA();
|
|
8470
|
+
if (currentSection) flushSection();
|
|
8471
|
+
pushCurrentQA();
|
|
8472
|
+
return result;
|
|
8326
8473
|
}
|
|
8327
8474
|
function parseQuestionsCardsHtml(html) {
|
|
8328
8475
|
const parser = new DOMParser();
|
|
8329
8476
|
const doc = parser.parseFromString(html, "text/html");
|
|
8330
8477
|
const result = {
|
|
8331
|
-
|
|
8332
|
-
answer: "",
|
|
8333
|
-
sections: []
|
|
8478
|
+
qaPairs: []
|
|
8334
8479
|
};
|
|
8335
8480
|
const styles = CARD_STYLES.questionsCards;
|
|
8336
8481
|
const gridEntries = QUESTIONS_CARD_GRID_SECTIONS.map((k) => ({ key: k, title: styles[k].title }));
|
|
8482
|
+
let currentQA = null;
|
|
8337
8483
|
const children = Array.from(doc.body.children);
|
|
8338
8484
|
for (const el of children) {
|
|
8339
8485
|
const h3 = el.querySelector("h3");
|
|
8340
8486
|
if (!h3) continue;
|
|
8341
8487
|
const h3Text = (h3.textContent || "").trim();
|
|
8342
8488
|
if (h3Text.includes("Question")) {
|
|
8489
|
+
if (currentQA) result.qaPairs.push(currentQA);
|
|
8490
|
+
currentQA = { question: "", answer: "", sections: [] };
|
|
8343
8491
|
const clone = el.cloneNode(true);
|
|
8344
8492
|
clone.querySelector("h3")?.remove();
|
|
8345
|
-
|
|
8493
|
+
const optionsContainer = clone.querySelector('div[style*="flex-direction"]');
|
|
8494
|
+
if (optionsContainer) {
|
|
8495
|
+
const optionDivs = optionsContainer.querySelectorAll("div");
|
|
8496
|
+
const options = [];
|
|
8497
|
+
optionDivs.forEach((optDiv) => {
|
|
8498
|
+
const spans = optDiv.querySelectorAll("span");
|
|
8499
|
+
if (spans.length >= 2) {
|
|
8500
|
+
const letter = (spans[0].textContent || "").trim().toLowerCase();
|
|
8501
|
+
const text = (spans[1].textContent || "").trim();
|
|
8502
|
+
options.push(`${letter}) ${text}`);
|
|
8503
|
+
}
|
|
8504
|
+
});
|
|
8505
|
+
optionsContainer.remove();
|
|
8506
|
+
const qText = (clone.textContent || "").trim();
|
|
8507
|
+
currentQA.question = qText + (options.length > 0 ? " " + options.join(" ") : "");
|
|
8508
|
+
} else {
|
|
8509
|
+
currentQA.question = (clone.textContent || "").trim();
|
|
8510
|
+
}
|
|
8346
8511
|
} else if (h3Text.includes("Answer")) {
|
|
8512
|
+
if (!currentQA) currentQA = { question: "", answer: "", sections: [] };
|
|
8347
8513
|
const clone = el.cloneNode(true);
|
|
8348
8514
|
clone.querySelector("h3")?.remove();
|
|
8349
|
-
|
|
8515
|
+
const badge = clone.querySelector('span[style*="rgba(76"]');
|
|
8516
|
+
if (badge) {
|
|
8517
|
+
const letter = (badge.textContent || "").trim().toLowerCase();
|
|
8518
|
+
badge.remove();
|
|
8519
|
+
const explanation = (clone.textContent || "").trim();
|
|
8520
|
+
currentQA.answer = `${letter}) ${explanation}`;
|
|
8521
|
+
} else {
|
|
8522
|
+
currentQA.answer = (clone.textContent || "").trim();
|
|
8523
|
+
}
|
|
8350
8524
|
} else if (el.children.length > 1) {
|
|
8525
|
+
if (!currentQA) currentQA = { question: "", answer: "", sections: [] };
|
|
8351
8526
|
for (const card of Array.from(el.children)) {
|
|
8352
8527
|
const cardH3 = card.querySelector("h3");
|
|
8353
8528
|
if (!cardH3) continue;
|
|
@@ -8356,10 +8531,14 @@ function parseQuestionsCardsHtml(html) {
|
|
|
8356
8531
|
const key = match ? match.key : "rubric";
|
|
8357
8532
|
const clone = card.cloneNode(true);
|
|
8358
8533
|
clone.querySelector("h3")?.remove();
|
|
8359
|
-
|
|
8534
|
+
currentQA.sections.push({ key, content: (clone.textContent || "").trim() });
|
|
8360
8535
|
}
|
|
8361
8536
|
}
|
|
8362
8537
|
}
|
|
8538
|
+
if (currentQA) result.qaPairs.push(currentQA);
|
|
8539
|
+
if (result.qaPairs.length === 0) {
|
|
8540
|
+
result.qaPairs.push({ question: "", answer: "", sections: [] });
|
|
8541
|
+
}
|
|
8363
8542
|
return result;
|
|
8364
8543
|
}
|
|
8365
8544
|
|
|
@@ -8569,27 +8748,95 @@ function NotesPlugin() {
|
|
|
8569
8748
|
}, [editor]);
|
|
8570
8749
|
return null;
|
|
8571
8750
|
}
|
|
8751
|
+
function convertRichHtmlToNotes(htmlStr, baasixClient, folder) {
|
|
8752
|
+
return new Promise(async (resolve) => {
|
|
8753
|
+
const parser = new DOMParser();
|
|
8754
|
+
const doc = parser.parseFromString(htmlStr, "text/html");
|
|
8755
|
+
if (baasixClient) {
|
|
8756
|
+
const imgs = doc.querySelectorAll("img");
|
|
8757
|
+
for (let i = 0; i < imgs.length; i++) {
|
|
8758
|
+
const img2 = imgs[i];
|
|
8759
|
+
const src = img2.getAttribute("src") || "";
|
|
8760
|
+
if (src.startsWith("data:")) {
|
|
8761
|
+
try {
|
|
8762
|
+
const resp = await fetch(src);
|
|
8763
|
+
const blob = await resp.blob();
|
|
8764
|
+
const ext = blob.type.split("/")[1] || "png";
|
|
8765
|
+
const file = new File([blob], `note-image-${i}.${ext}`, { type: blob.type });
|
|
8766
|
+
const uploadedUrl = await uploadImageToBaasix(baasixClient, file, folder);
|
|
8767
|
+
img2.setAttribute("src", uploadedUrl);
|
|
8768
|
+
} catch {
|
|
8769
|
+
}
|
|
8770
|
+
}
|
|
8771
|
+
}
|
|
8772
|
+
}
|
|
8773
|
+
let html = `<div style="font-family: sans-serif; line-height: 1.6; color: inherit;">`;
|
|
8774
|
+
const children = Array.from(doc.body.childNodes);
|
|
8775
|
+
for (const child of children) {
|
|
8776
|
+
html += processNode(child);
|
|
8777
|
+
}
|
|
8778
|
+
html += "</div>";
|
|
8779
|
+
resolve(html.replace(/>\s+</g, "><"));
|
|
8780
|
+
});
|
|
8781
|
+
}
|
|
8572
8782
|
function InsertNotesDialog({
|
|
8573
8783
|
activeEditor,
|
|
8574
8784
|
onClose
|
|
8575
8785
|
}) {
|
|
8576
8786
|
const [input, setInput] = useState18("");
|
|
8577
|
-
const
|
|
8787
|
+
const [richHtml, setRichHtml] = useState18("");
|
|
8788
|
+
const [isUploading, setIsUploading] = useState18(false);
|
|
8789
|
+
const pasteAreaRef = useRef9(null);
|
|
8790
|
+
let editorConfig = null;
|
|
8791
|
+
try {
|
|
8792
|
+
editorConfig = useEditorConfig();
|
|
8793
|
+
} catch {
|
|
8794
|
+
}
|
|
8795
|
+
const handleRichPaste = useCallback12(async (e) => {
|
|
8796
|
+
e.preventDefault();
|
|
8797
|
+
const clipboardData = e.clipboardData;
|
|
8798
|
+
const htmlData = clipboardData.getData("text/html");
|
|
8799
|
+
const textData = clipboardData.getData("text/plain");
|
|
8800
|
+
if (htmlData) {
|
|
8801
|
+
setIsUploading(true);
|
|
8802
|
+
try {
|
|
8803
|
+
const processed = await convertRichHtmlToNotes(
|
|
8804
|
+
htmlData,
|
|
8805
|
+
editorConfig?.baasixClient,
|
|
8806
|
+
editorConfig?.folder
|
|
8807
|
+
);
|
|
8808
|
+
setRichHtml(processed);
|
|
8809
|
+
setInput("");
|
|
8810
|
+
} finally {
|
|
8811
|
+
setIsUploading(false);
|
|
8812
|
+
}
|
|
8813
|
+
} else if (textData) {
|
|
8814
|
+
setInput((prev) => prev ? prev + "\n" + textData : textData);
|
|
8815
|
+
}
|
|
8816
|
+
if (pasteAreaRef.current) {
|
|
8817
|
+
pasteAreaRef.current.innerHTML = '<span style="color: #9ca3af; pointer-events: none; user-select: none;">Paste from Word/Docs here (preserves formatting)</span>';
|
|
8818
|
+
}
|
|
8819
|
+
}, [editorConfig]);
|
|
8820
|
+
const finalHtml = useMemo8(() => {
|
|
8821
|
+
if (richHtml) return richHtml;
|
|
8578
8822
|
if (!input.trim()) return "";
|
|
8579
8823
|
return convertNotes(input);
|
|
8580
|
-
}, [input]);
|
|
8824
|
+
}, [input, richHtml]);
|
|
8581
8825
|
const handleInsert = useCallback12(() => {
|
|
8582
|
-
if (!
|
|
8583
|
-
activeEditor.dispatchCommand(INSERT_NOTES_COMMAND,
|
|
8826
|
+
if (!finalHtml) return;
|
|
8827
|
+
activeEditor.dispatchCommand(INSERT_NOTES_COMMAND, finalHtml);
|
|
8584
8828
|
onClose();
|
|
8585
|
-
}, [activeEditor,
|
|
8829
|
+
}, [activeEditor, finalHtml, onClose]);
|
|
8586
8830
|
return /* @__PURE__ */ jsxs14("div", { style: { minWidth: 500 }, children: [
|
|
8587
8831
|
/* @__PURE__ */ jsx24(
|
|
8588
8832
|
"textarea",
|
|
8589
8833
|
{
|
|
8590
8834
|
value: input,
|
|
8591
|
-
onChange: (e) =>
|
|
8592
|
-
|
|
8835
|
+
onChange: (e) => {
|
|
8836
|
+
setInput(e.target.value);
|
|
8837
|
+
setRichHtml("");
|
|
8838
|
+
},
|
|
8839
|
+
placeholder: "Paste or type notes here (plain text)...\nExample:\nSuperficial Fascia\nThe superficial fascia is a layer of loose...\n\nFunctions\n- Passageway for vessels\n- Insulation",
|
|
8593
8840
|
style: {
|
|
8594
8841
|
width: "100%",
|
|
8595
8842
|
minHeight: 120,
|
|
@@ -8603,9 +8850,33 @@ function InsertNotesDialog({
|
|
|
8603
8850
|
}
|
|
8604
8851
|
}
|
|
8605
8852
|
),
|
|
8606
|
-
|
|
8853
|
+
/* @__PURE__ */ jsx24(
|
|
8854
|
+
"div",
|
|
8855
|
+
{
|
|
8856
|
+
ref: pasteAreaRef,
|
|
8857
|
+
contentEditable: true,
|
|
8858
|
+
onPaste: handleRichPaste,
|
|
8859
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
8860
|
+
style: {
|
|
8861
|
+
width: "100%",
|
|
8862
|
+
minHeight: 40,
|
|
8863
|
+
padding: 8,
|
|
8864
|
+
border: "2px dashed #93c5fd",
|
|
8865
|
+
borderRadius: 4,
|
|
8866
|
+
fontSize: 12,
|
|
8867
|
+
color: "#6b7280",
|
|
8868
|
+
marginBottom: 8,
|
|
8869
|
+
outline: "none",
|
|
8870
|
+
background: "#f0f7ff"
|
|
8871
|
+
},
|
|
8872
|
+
suppressContentEditableWarning: true,
|
|
8873
|
+
children: /* @__PURE__ */ jsx24("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: isUploading ? "Processing content..." : "Paste from Word/Docs here (preserves formatting)" })
|
|
8874
|
+
}
|
|
8875
|
+
),
|
|
8876
|
+
richHtml && /* @__PURE__ */ jsx24("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: "Rich content captured (formatting preserved)" }),
|
|
8877
|
+
finalHtml && /* @__PURE__ */ jsxs14("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 200, overflow: "auto" }, children: [
|
|
8607
8878
|
/* @__PURE__ */ jsx24("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
|
|
8608
|
-
/* @__PURE__ */ jsx24("div", { dangerouslySetInnerHTML: { __html:
|
|
8879
|
+
/* @__PURE__ */ jsx24("div", { dangerouslySetInnerHTML: { __html: finalHtml } })
|
|
8609
8880
|
] }),
|
|
8610
8881
|
/* @__PURE__ */ jsxs14("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
|
|
8611
8882
|
/* @__PURE__ */ jsx24(
|
|
@@ -8622,9 +8893,9 @@ function InsertNotesDialog({
|
|
|
8622
8893
|
{
|
|
8623
8894
|
type: "button",
|
|
8624
8895
|
onClick: handleInsert,
|
|
8625
|
-
disabled: !
|
|
8626
|
-
style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity:
|
|
8627
|
-
children: "Insert"
|
|
8896
|
+
disabled: !finalHtml || isUploading,
|
|
8897
|
+
style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: finalHtml && !isUploading ? 1 : 0.5 },
|
|
8898
|
+
children: isUploading ? "Processing..." : "Insert"
|
|
8628
8899
|
}
|
|
8629
8900
|
)
|
|
8630
8901
|
] })
|
|
@@ -9310,7 +9581,7 @@ function InsertTerminologyDialog({
|
|
|
9310
9581
|
import { useLexicalComposerContext as useLexicalComposerContext28 } from "@lexical/react/LexicalComposerContext";
|
|
9311
9582
|
import { $insertNodeToNearestRoot as $insertNodeToNearestRoot10 } from "@lexical/utils";
|
|
9312
9583
|
import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR17, createCommand as createCommand17 } from "lexical";
|
|
9313
|
-
import { useCallback as
|
|
9584
|
+
import { useCallback as useCallback19, useEffect as useEffect27, useMemo as useMemo14, useState as useState26 } from "react";
|
|
9314
9585
|
|
|
9315
9586
|
// src/nodes/TextCardsNode.tsx
|
|
9316
9587
|
import { $getNodeByKey as $getNodeByKey7 } from "lexical";
|
|
@@ -9605,6 +9876,134 @@ function $isTextCardsNode(node) {
|
|
|
9605
9876
|
return node instanceof TextCardsNode;
|
|
9606
9877
|
}
|
|
9607
9878
|
|
|
9879
|
+
// src/utils/useRichPaste.ts
|
|
9880
|
+
import { useCallback as useCallback18, useRef as useRef10, useState as useState25 } from "react";
|
|
9881
|
+
function useRichPaste(onText, baasixClient, folder) {
|
|
9882
|
+
const [images, setImages] = useState25([]);
|
|
9883
|
+
const [isUploading, setIsUploading] = useState25(false);
|
|
9884
|
+
const pasteAreaRef = useRef10(null);
|
|
9885
|
+
const extractImages = useCallback18(
|
|
9886
|
+
async (htmlStr) => {
|
|
9887
|
+
const parser = new DOMParser();
|
|
9888
|
+
const doc = parser.parseFromString(htmlStr, "text/html");
|
|
9889
|
+
const imgs = doc.querySelectorAll("img");
|
|
9890
|
+
const newImages = [];
|
|
9891
|
+
for (let i = 0; i < imgs.length; i++) {
|
|
9892
|
+
const img2 = imgs[i];
|
|
9893
|
+
const src = img2.getAttribute("src") || "";
|
|
9894
|
+
const placeholder = `__IMG_${Date.now()}_${i}__`;
|
|
9895
|
+
if (src.startsWith("data:") && baasixClient) {
|
|
9896
|
+
try {
|
|
9897
|
+
const resp = await fetch(src);
|
|
9898
|
+
const blob = await resp.blob();
|
|
9899
|
+
const ext = blob.type.split("/")[1] || "png";
|
|
9900
|
+
const file = new File([blob], `pasted-image-${i}.${ext}`, { type: blob.type });
|
|
9901
|
+
const uploadedUrl = await uploadImageToBaasix(baasixClient, file, folder);
|
|
9902
|
+
newImages.push({ placeholder, src: uploadedUrl });
|
|
9903
|
+
} catch {
|
|
9904
|
+
newImages.push({ placeholder, src });
|
|
9905
|
+
}
|
|
9906
|
+
} else if (src) {
|
|
9907
|
+
newImages.push({ placeholder, src });
|
|
9908
|
+
}
|
|
9909
|
+
}
|
|
9910
|
+
return newImages;
|
|
9911
|
+
},
|
|
9912
|
+
[baasixClient, folder]
|
|
9913
|
+
);
|
|
9914
|
+
const insertPlaceholders = useCallback18(
|
|
9915
|
+
(plainText, htmlStr, imgPlaceholders) => {
|
|
9916
|
+
if (imgPlaceholders.length === 0) return plainText;
|
|
9917
|
+
const parser = new DOMParser();
|
|
9918
|
+
const doc = parser.parseFromString(htmlStr, "text/html");
|
|
9919
|
+
const segments = [];
|
|
9920
|
+
let imgIdx = 0;
|
|
9921
|
+
const blockTags = /* @__PURE__ */ new Set(["P", "DIV", "LI", "TR", "H1", "H2", "H3", "H4", "H5", "H6", "BLOCKQUOTE", "PRE", "TABLE"]);
|
|
9922
|
+
const walkNode = (node) => {
|
|
9923
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
9924
|
+
const t = (node.textContent || "").trim();
|
|
9925
|
+
if (t) segments.push({ type: "text", text: t });
|
|
9926
|
+
return;
|
|
9927
|
+
}
|
|
9928
|
+
if (node.nodeType !== Node.ELEMENT_NODE) return;
|
|
9929
|
+
const el = node;
|
|
9930
|
+
if (el.tagName === "IMG") {
|
|
9931
|
+
segments.push({ type: "img", idx: imgIdx++ });
|
|
9932
|
+
return;
|
|
9933
|
+
}
|
|
9934
|
+
for (const child of Array.from(el.childNodes)) walkNode(child);
|
|
9935
|
+
};
|
|
9936
|
+
walkNode(doc.body);
|
|
9937
|
+
const textCountBeforeImg = [];
|
|
9938
|
+
let textCount = 0;
|
|
9939
|
+
for (const seg of segments) {
|
|
9940
|
+
if (seg.type === "text") {
|
|
9941
|
+
textCount++;
|
|
9942
|
+
} else {
|
|
9943
|
+
textCountBeforeImg.push(textCount);
|
|
9944
|
+
}
|
|
9945
|
+
}
|
|
9946
|
+
const lines = plainText.split("\n");
|
|
9947
|
+
const nonEmptyLineIndices = [];
|
|
9948
|
+
for (let i = 0; i < lines.length; i++) {
|
|
9949
|
+
if (lines[i].trim()) nonEmptyLineIndices.push(i);
|
|
9950
|
+
}
|
|
9951
|
+
for (let i = textCountBeforeImg.length - 1; i >= 0; i--) {
|
|
9952
|
+
const placeholder = imgPlaceholders[i]?.placeholder;
|
|
9953
|
+
if (!placeholder) continue;
|
|
9954
|
+
const tc = textCountBeforeImg[i];
|
|
9955
|
+
const lineIdx = tc > 0 && tc <= nonEmptyLineIndices.length ? nonEmptyLineIndices[tc - 1] : nonEmptyLineIndices.length > 0 ? nonEmptyLineIndices[nonEmptyLineIndices.length - 1] : lines.length - 1;
|
|
9956
|
+
lines.splice(lineIdx + 1, 0, placeholder);
|
|
9957
|
+
for (let j = 0; j < nonEmptyLineIndices.length; j++) {
|
|
9958
|
+
if (nonEmptyLineIndices[j] > lineIdx) nonEmptyLineIndices[j]++;
|
|
9959
|
+
}
|
|
9960
|
+
}
|
|
9961
|
+
return lines.join("\n");
|
|
9962
|
+
},
|
|
9963
|
+
[]
|
|
9964
|
+
);
|
|
9965
|
+
const handlePaste = useCallback18(
|
|
9966
|
+
async (e) => {
|
|
9967
|
+
e.preventDefault();
|
|
9968
|
+
const clipboardData = e.clipboardData;
|
|
9969
|
+
const htmlData = clipboardData.getData("text/html");
|
|
9970
|
+
const textData = clipboardData.getData("text/plain");
|
|
9971
|
+
if (htmlData && htmlData.includes("<img")) {
|
|
9972
|
+
setIsUploading(true);
|
|
9973
|
+
try {
|
|
9974
|
+
const processedImages = await extractImages(htmlData);
|
|
9975
|
+
let text = textData || "";
|
|
9976
|
+
text = insertPlaceholders(text, htmlData, processedImages);
|
|
9977
|
+
onText(text);
|
|
9978
|
+
setImages((prev) => [...prev, ...processedImages]);
|
|
9979
|
+
} finally {
|
|
9980
|
+
setIsUploading(false);
|
|
9981
|
+
}
|
|
9982
|
+
} else {
|
|
9983
|
+
onText(textData || "");
|
|
9984
|
+
}
|
|
9985
|
+
if (pasteAreaRef.current) {
|
|
9986
|
+
pasteAreaRef.current.textContent = "";
|
|
9987
|
+
}
|
|
9988
|
+
},
|
|
9989
|
+
[extractImages, insertPlaceholders, onText]
|
|
9990
|
+
);
|
|
9991
|
+
const replaceImagePlaceholders = useCallback18(
|
|
9992
|
+
(html) => {
|
|
9993
|
+
let result = html;
|
|
9994
|
+
images.forEach(({ placeholder, src }) => {
|
|
9995
|
+
result = result.replace(
|
|
9996
|
+
new RegExp(placeholder.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"),
|
|
9997
|
+
`<img src="${src}" style="max-width: 100%; border-radius: 8px; margin: 8px 0;" />`
|
|
9998
|
+
);
|
|
9999
|
+
});
|
|
10000
|
+
return result;
|
|
10001
|
+
},
|
|
10002
|
+
[images]
|
|
10003
|
+
);
|
|
10004
|
+
return { images, isUploading, pasteAreaRef, handlePaste, replaceImagePlaceholders };
|
|
10005
|
+
}
|
|
10006
|
+
|
|
9608
10007
|
// src/plugins/TextCardsPlugin/index.tsx
|
|
9609
10008
|
import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
9610
10009
|
var INSERT_TEXT_CARDS_COMMAND = createCommand17(
|
|
@@ -9632,16 +10031,27 @@ function InsertTextCardsDialog({
|
|
|
9632
10031
|
activeEditor,
|
|
9633
10032
|
onClose
|
|
9634
10033
|
}) {
|
|
9635
|
-
const [input, setInput] =
|
|
9636
|
-
|
|
10034
|
+
const [input, setInput] = useState26("");
|
|
10035
|
+
let editorConfig = null;
|
|
10036
|
+
try {
|
|
10037
|
+
editorConfig = useEditorConfig();
|
|
10038
|
+
} catch {
|
|
10039
|
+
}
|
|
10040
|
+
const richPaste = useRichPaste(
|
|
10041
|
+
(text) => setInput((prev) => prev ? prev + "\n" + text : text),
|
|
10042
|
+
editorConfig?.baasixClient,
|
|
10043
|
+
editorConfig?.folder
|
|
10044
|
+
);
|
|
10045
|
+
const finalHtml = useMemo14(() => {
|
|
9637
10046
|
if (!input.trim()) return "";
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
10047
|
+
const html = convertTextCards(input);
|
|
10048
|
+
return richPaste.replaceImagePlaceholders(html);
|
|
10049
|
+
}, [input, richPaste]);
|
|
10050
|
+
const handleInsert = useCallback19(() => {
|
|
10051
|
+
if (!finalHtml) return;
|
|
10052
|
+
activeEditor.dispatchCommand(INSERT_TEXT_CARDS_COMMAND, finalHtml);
|
|
9643
10053
|
onClose();
|
|
9644
|
-
}, [activeEditor,
|
|
10054
|
+
}, [activeEditor, finalHtml, onClose]);
|
|
9645
10055
|
return /* @__PURE__ */ jsxs21("div", { style: { minWidth: 500 }, children: [
|
|
9646
10056
|
/* @__PURE__ */ jsx31(
|
|
9647
10057
|
"textarea",
|
|
@@ -9668,7 +10078,7 @@ Critical Insight
|
|
|
9668
10078
|
Pathology bridges clinical suspicion with molecular certainty...`,
|
|
9669
10079
|
style: {
|
|
9670
10080
|
width: "100%",
|
|
9671
|
-
minHeight:
|
|
10081
|
+
minHeight: 150,
|
|
9672
10082
|
fontFamily: "monospace",
|
|
9673
10083
|
fontSize: 13,
|
|
9674
10084
|
padding: 8,
|
|
@@ -9679,9 +10089,38 @@ Pathology bridges clinical suspicion with molecular certainty...`,
|
|
|
9679
10089
|
}
|
|
9680
10090
|
}
|
|
9681
10091
|
),
|
|
9682
|
-
|
|
10092
|
+
/* @__PURE__ */ jsx31(
|
|
10093
|
+
"div",
|
|
10094
|
+
{
|
|
10095
|
+
ref: richPaste.pasteAreaRef,
|
|
10096
|
+
contentEditable: true,
|
|
10097
|
+
onPaste: richPaste.handlePaste,
|
|
10098
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
10099
|
+
style: {
|
|
10100
|
+
width: "100%",
|
|
10101
|
+
minHeight: 40,
|
|
10102
|
+
padding: 8,
|
|
10103
|
+
border: "2px dashed #93c5fd",
|
|
10104
|
+
borderRadius: 4,
|
|
10105
|
+
fontSize: 12,
|
|
10106
|
+
color: "#6b7280",
|
|
10107
|
+
marginBottom: 8,
|
|
10108
|
+
outline: "none",
|
|
10109
|
+
background: "#f0f7ff"
|
|
10110
|
+
},
|
|
10111
|
+
suppressContentEditableWarning: true,
|
|
10112
|
+
children: /* @__PURE__ */ jsx31("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support" })
|
|
10113
|
+
}
|
|
10114
|
+
),
|
|
10115
|
+
richPaste.images.length > 0 && /* @__PURE__ */ jsxs21("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: [
|
|
10116
|
+
richPaste.images.length,
|
|
10117
|
+
" image",
|
|
10118
|
+
richPaste.images.length > 1 ? "s" : "",
|
|
10119
|
+
" captured"
|
|
10120
|
+
] }),
|
|
10121
|
+
finalHtml && /* @__PURE__ */ jsxs21("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 250, overflow: "auto" }, children: [
|
|
9683
10122
|
/* @__PURE__ */ jsx31("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
|
|
9684
|
-
/* @__PURE__ */ jsx31("div", { dangerouslySetInnerHTML: { __html:
|
|
10123
|
+
/* @__PURE__ */ jsx31("div", { dangerouslySetInnerHTML: { __html: finalHtml } })
|
|
9685
10124
|
] }),
|
|
9686
10125
|
/* @__PURE__ */ jsxs21("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
|
|
9687
10126
|
/* @__PURE__ */ jsx31(
|
|
@@ -9698,9 +10137,9 @@ Pathology bridges clinical suspicion with molecular certainty...`,
|
|
|
9698
10137
|
{
|
|
9699
10138
|
type: "button",
|
|
9700
10139
|
onClick: handleInsert,
|
|
9701
|
-
disabled: !
|
|
9702
|
-
style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity:
|
|
9703
|
-
children: "Insert"
|
|
10140
|
+
disabled: !finalHtml || richPaste.isUploading,
|
|
10141
|
+
style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: finalHtml && !richPaste.isUploading ? 1 : 0.5 },
|
|
10142
|
+
children: richPaste.isUploading ? "Uploading..." : "Insert"
|
|
9704
10143
|
}
|
|
9705
10144
|
)
|
|
9706
10145
|
] })
|
|
@@ -9711,7 +10150,7 @@ Pathology bridges clinical suspicion with molecular certainty...`,
|
|
|
9711
10150
|
import { useLexicalComposerContext as useLexicalComposerContext30 } from "@lexical/react/LexicalComposerContext";
|
|
9712
10151
|
import { $insertNodeToNearestRoot as $insertNodeToNearestRoot11 } from "@lexical/utils";
|
|
9713
10152
|
import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR18, createCommand as createCommand18 } from "lexical";
|
|
9714
|
-
import { useCallback as
|
|
10153
|
+
import { useCallback as useCallback21, useEffect as useEffect28, useMemo as useMemo16, useState as useState28 } from "react";
|
|
9715
10154
|
|
|
9716
10155
|
// src/nodes/QuestionsCardsNode.tsx
|
|
9717
10156
|
import { $getNodeByKey as $getNodeByKey8 } from "lexical";
|
|
@@ -9721,7 +10160,7 @@ import {
|
|
|
9721
10160
|
} from "@lexical/react/LexicalDecoratorBlockNode";
|
|
9722
10161
|
import { useLexicalComposerContext as useLexicalComposerContext29 } from "@lexical/react/LexicalComposerContext";
|
|
9723
10162
|
import { useLexicalEditable as useLexicalEditable5 } from "@lexical/react/useLexicalEditable";
|
|
9724
|
-
import { useCallback as
|
|
10163
|
+
import { useCallback as useCallback20, useMemo as useMemo15, useState as useState27 } from "react";
|
|
9725
10164
|
import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
9726
10165
|
var GRID_SECTION_KEYS = [
|
|
9727
10166
|
"rubric",
|
|
@@ -9742,44 +10181,45 @@ function QuestionsCardsComponent({
|
|
|
9742
10181
|
}) {
|
|
9743
10182
|
const [editor] = useLexicalComposerContext29();
|
|
9744
10183
|
const isEditable = useLexicalEditable5();
|
|
9745
|
-
const [isEditing, setIsEditing] =
|
|
9746
|
-
const [
|
|
9747
|
-
const
|
|
9748
|
-
|
|
9749
|
-
|
|
10184
|
+
const [isEditing, setIsEditing] = useState27(false);
|
|
10185
|
+
const [qaPairs, setQaPairs] = useState27([]);
|
|
10186
|
+
const makeEmptyQA = () => ({
|
|
10187
|
+
question: "",
|
|
10188
|
+
answer: "",
|
|
10189
|
+
sections: GRID_SECTION_KEYS.map((k) => ({ key: k, content: "" }))
|
|
10190
|
+
});
|
|
10191
|
+
const openEditor = useCallback20(() => {
|
|
9750
10192
|
const parsed = parseQuestionsCardsHtml(html);
|
|
9751
|
-
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
10193
|
+
const pairs = parsed.qaPairs.map((qa) => {
|
|
10194
|
+
const existing = qa.sections || [];
|
|
10195
|
+
const all = GRID_SECTION_KEYS.map((k) => {
|
|
10196
|
+
const found = existing.find((s) => s.key === k);
|
|
10197
|
+
return found || { key: k, content: "" };
|
|
10198
|
+
});
|
|
10199
|
+
return { question: qa.question, answer: qa.answer, sections: all };
|
|
9757
10200
|
});
|
|
9758
|
-
|
|
10201
|
+
setQaPairs(pairs.length > 0 ? pairs : [makeEmptyQA()]);
|
|
9759
10202
|
setIsEditing(true);
|
|
9760
10203
|
}, [html]);
|
|
9761
10204
|
const preview = useMemo15(() => {
|
|
9762
10205
|
if (!isEditing) return "";
|
|
9763
|
-
const
|
|
10206
|
+
const cStyles = CARD_STYLES.questionsCards;
|
|
9764
10207
|
const lines = [];
|
|
9765
|
-
|
|
9766
|
-
lines.push(
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
lines.push(sStyle.title);
|
|
9776
|
-
lines.push(s.content);
|
|
9777
|
-
}
|
|
10208
|
+
qaPairs.forEach((qa, idx) => {
|
|
10209
|
+
if (qa.question) lines.push(`${idx + 1}. Question: ${qa.question}`);
|
|
10210
|
+
if (qa.answer) lines.push(`Answer: ${qa.answer}`);
|
|
10211
|
+
qa.sections.forEach((s) => {
|
|
10212
|
+
const sStyle = cStyles[s.key];
|
|
10213
|
+
if (sStyle && "title" in sStyle && s.content) {
|
|
10214
|
+
lines.push(sStyle.title);
|
|
10215
|
+
lines.push(s.content);
|
|
10216
|
+
}
|
|
10217
|
+
});
|
|
9778
10218
|
});
|
|
9779
10219
|
const text = lines.join("\n");
|
|
9780
10220
|
return text.trim() ? convertQuestionsCards(text) : "";
|
|
9781
|
-
}, [isEditing,
|
|
9782
|
-
const saveChanges =
|
|
10221
|
+
}, [isEditing, qaPairs]);
|
|
10222
|
+
const saveChanges = useCallback20(() => {
|
|
9783
10223
|
if (!preview) return;
|
|
9784
10224
|
editor.update(() => {
|
|
9785
10225
|
const node = $getNodeByKey8(nodeKey);
|
|
@@ -9789,13 +10229,23 @@ function QuestionsCardsComponent({
|
|
|
9789
10229
|
});
|
|
9790
10230
|
setIsEditing(false);
|
|
9791
10231
|
}, [editor, nodeKey, preview]);
|
|
9792
|
-
const cancelEdit =
|
|
10232
|
+
const cancelEdit = useCallback20(() => {
|
|
9793
10233
|
setIsEditing(false);
|
|
9794
10234
|
}, []);
|
|
9795
|
-
const
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
10235
|
+
const updateQA = useCallback20((idx, field, value) => {
|
|
10236
|
+
setQaPairs((prev) => prev.map((qa, i) => i === idx ? { ...qa, [field]: value } : qa));
|
|
10237
|
+
}, []);
|
|
10238
|
+
const addQAPair = useCallback20(() => {
|
|
10239
|
+
setQaPairs((prev) => [...prev, makeEmptyQA()]);
|
|
10240
|
+
}, []);
|
|
10241
|
+
const removeQAPair = useCallback20((idx) => {
|
|
10242
|
+
setQaPairs((prev) => prev.filter((_, i) => i !== idx));
|
|
10243
|
+
}, []);
|
|
10244
|
+
const updateSection = useCallback20((qIdx, sIdx, value) => {
|
|
10245
|
+
setQaPairs((prev) => prev.map((qa, i) => {
|
|
10246
|
+
if (i !== qIdx) return qa;
|
|
10247
|
+
return { ...qa, sections: qa.sections.map((s, j) => j === sIdx ? { ...s, content: value } : s) };
|
|
10248
|
+
}));
|
|
9799
10249
|
}, []);
|
|
9800
10250
|
const styles = CARD_STYLES.questionsCards;
|
|
9801
10251
|
return /* @__PURE__ */ jsx32(BlockWithAlignableContents8, { className, format, nodeKey, children: /* @__PURE__ */ jsxs22("div", { style: { position: "relative" }, children: [
|
|
@@ -9849,52 +10299,78 @@ function QuestionsCardsComponent({
|
|
|
9849
10299
|
)
|
|
9850
10300
|
] })
|
|
9851
10301
|
] }),
|
|
9852
|
-
/* @__PURE__ */ jsxs22("div", { style: {
|
|
9853
|
-
/* @__PURE__ */
|
|
9854
|
-
|
|
9855
|
-
|
|
9856
|
-
|
|
9857
|
-
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
{
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
"
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
|
|
10302
|
+
qaPairs.map((qa, qIdx) => /* @__PURE__ */ jsxs22("div", { style: { border: "1px solid #e5e7eb", borderRadius: 6, padding: 8, marginBottom: 8, background: "#fff" }, children: [
|
|
10303
|
+
/* @__PURE__ */ jsxs22("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }, children: [
|
|
10304
|
+
/* @__PURE__ */ jsxs22("span", { style: { fontSize: 12, fontWeight: 600, color: "#1976d2" }, children: [
|
|
10305
|
+
"Q",
|
|
10306
|
+
qIdx + 1
|
|
10307
|
+
] }),
|
|
10308
|
+
qaPairs.length > 1 && /* @__PURE__ */ jsx32(
|
|
10309
|
+
"button",
|
|
10310
|
+
{
|
|
10311
|
+
type: "button",
|
|
10312
|
+
onClick: () => removeQAPair(qIdx),
|
|
10313
|
+
style: { padding: "2px 6px", fontSize: 14, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", color: "#e11d48" },
|
|
10314
|
+
children: "\xD7"
|
|
10315
|
+
}
|
|
10316
|
+
)
|
|
10317
|
+
] }),
|
|
10318
|
+
/* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
|
|
10319
|
+
/* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#1976d2", fontWeight: 600, display: "block", marginBottom: 2 }, children: "Question" }),
|
|
10320
|
+
/* @__PURE__ */ jsx32(
|
|
10321
|
+
"textarea",
|
|
10322
|
+
{
|
|
10323
|
+
placeholder: "Enter question text...",
|
|
10324
|
+
value: qa.question,
|
|
10325
|
+
onChange: (e) => updateQA(qIdx, "question", e.target.value),
|
|
10326
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
10327
|
+
style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 40, resize: "vertical" }
|
|
10328
|
+
}
|
|
10329
|
+
)
|
|
10330
|
+
] }),
|
|
10331
|
+
/* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
|
|
10332
|
+
/* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#666", fontWeight: 600, display: "block", marginBottom: 2 }, children: "Answer" }),
|
|
10333
|
+
/* @__PURE__ */ jsx32(
|
|
10334
|
+
"textarea",
|
|
10335
|
+
{
|
|
10336
|
+
placeholder: "Enter answer text...",
|
|
10337
|
+
value: qa.answer,
|
|
10338
|
+
onChange: (e) => updateQA(qIdx, "answer", e.target.value),
|
|
10339
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
10340
|
+
style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 60, resize: "vertical" }
|
|
10341
|
+
}
|
|
10342
|
+
)
|
|
10343
|
+
] }),
|
|
10344
|
+
/* @__PURE__ */ jsxs22("details", { style: { marginTop: 4 }, children: [
|
|
10345
|
+
/* @__PURE__ */ jsx32("summary", { style: { fontSize: 11, color: "#666", fontWeight: 600, cursor: "pointer" }, children: "Card Sections" }),
|
|
10346
|
+
/* @__PURE__ */ jsx32("div", { style: { marginTop: 4 }, children: qa.sections.map((section, sIdx) => {
|
|
10347
|
+
const sStyle = styles[section.key];
|
|
10348
|
+
const label = sStyle && "title" in sStyle ? sStyle.title : section.key;
|
|
10349
|
+
return /* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
|
|
10350
|
+
/* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#666", display: "block", marginBottom: 2 }, children: label }),
|
|
10351
|
+
/* @__PURE__ */ jsx32(
|
|
10352
|
+
"textarea",
|
|
10353
|
+
{
|
|
10354
|
+
placeholder: `${label} content...`,
|
|
10355
|
+
value: section.content,
|
|
10356
|
+
onChange: (e) => updateSection(qIdx, sIdx, e.target.value),
|
|
10357
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
10358
|
+
style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 40, resize: "vertical" }
|
|
10359
|
+
}
|
|
10360
|
+
)
|
|
10361
|
+
] }, sIdx);
|
|
10362
|
+
}) })
|
|
10363
|
+
] })
|
|
10364
|
+
] }, qIdx)),
|
|
10365
|
+
/* @__PURE__ */ jsx32(
|
|
10366
|
+
"button",
|
|
10367
|
+
{
|
|
10368
|
+
type: "button",
|
|
10369
|
+
onClick: addQAPair,
|
|
10370
|
+
style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginBottom: 8 },
|
|
10371
|
+
children: "+ Add Question"
|
|
10372
|
+
}
|
|
10373
|
+
),
|
|
9898
10374
|
preview && /* @__PURE__ */ jsxs22("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff" }, children: [
|
|
9899
10375
|
/* @__PURE__ */ jsx32("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
|
|
9900
10376
|
/* @__PURE__ */ jsx32("div", { dangerouslySetInnerHTML: { __html: preview } })
|
|
@@ -10003,16 +10479,27 @@ function InsertQuestionsCardsDialog({
|
|
|
10003
10479
|
activeEditor,
|
|
10004
10480
|
onClose
|
|
10005
10481
|
}) {
|
|
10006
|
-
const [input, setInput] =
|
|
10007
|
-
|
|
10482
|
+
const [input, setInput] = useState28("");
|
|
10483
|
+
let editorConfig = null;
|
|
10484
|
+
try {
|
|
10485
|
+
editorConfig = useEditorConfig();
|
|
10486
|
+
} catch {
|
|
10487
|
+
}
|
|
10488
|
+
const richPaste = useRichPaste(
|
|
10489
|
+
(text) => setInput((prev) => prev ? prev + "\n" + text : text),
|
|
10490
|
+
editorConfig?.baasixClient,
|
|
10491
|
+
editorConfig?.folder
|
|
10492
|
+
);
|
|
10493
|
+
const finalHtml = useMemo16(() => {
|
|
10008
10494
|
if (!input.trim()) return "";
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
|
|
10495
|
+
const html = convertQuestionsCards(input);
|
|
10496
|
+
return richPaste.replaceImagePlaceholders(html);
|
|
10497
|
+
}, [input, richPaste]);
|
|
10498
|
+
const handleInsert = useCallback21(() => {
|
|
10499
|
+
if (!finalHtml) return;
|
|
10500
|
+
activeEditor.dispatchCommand(INSERT_QUESTIONS_CARDS_COMMAND, finalHtml);
|
|
10014
10501
|
onClose();
|
|
10015
|
-
}, [activeEditor,
|
|
10502
|
+
}, [activeEditor, finalHtml, onClose]);
|
|
10016
10503
|
return /* @__PURE__ */ jsxs23("div", { style: { minWidth: 500 }, children: [
|
|
10017
10504
|
/* @__PURE__ */ jsx33(
|
|
10018
10505
|
"textarea",
|
|
@@ -10021,28 +10508,18 @@ function InsertQuestionsCardsDialog({
|
|
|
10021
10508
|
onChange: (e) => setInput(e.target.value),
|
|
10022
10509
|
placeholder: `Paste question content here...
|
|
10023
10510
|
Example:
|
|
10024
|
-
Q1
|
|
10511
|
+
Q1 : Describe the pathogenesis of tuberculosis.
|
|
10025
10512
|
|
|
10026
|
-
Answer:
|
|
10027
|
-
Tuberculosis is caused by Mycobacterium tuberculosis...
|
|
10513
|
+
Answer: Tuberculosis is caused by Mycobacterium tuberculosis...
|
|
10028
10514
|
|
|
10029
|
-
MARKING RUBRIC
|
|
10515
|
+
1. MARKING RUBRIC
|
|
10030
10516
|
Definition: 2 marks, Pathogenesis: 5 marks...
|
|
10031
10517
|
|
|
10032
|
-
MNEMONICS
|
|
10033
|
-
Remember TB pathogenesis with "IGRA"
|
|
10034
|
-
|
|
10035
|
-
EXAMINER'S PERSPECTIVE
|
|
10036
|
-
Examiners look for systematic approach...
|
|
10037
|
-
|
|
10038
|
-
CLINICAL CORRELATION
|
|
10039
|
-
TB commonly presents with...
|
|
10040
|
-
|
|
10041
|
-
HIGH-YIELD EXAM TIP
|
|
10042
|
-
Always mention Ghon complex...`,
|
|
10518
|
+
2. MNEMONICS
|
|
10519
|
+
Remember TB pathogenesis with "IGRA"...`,
|
|
10043
10520
|
style: {
|
|
10044
10521
|
width: "100%",
|
|
10045
|
-
minHeight:
|
|
10522
|
+
minHeight: 150,
|
|
10046
10523
|
fontFamily: "monospace",
|
|
10047
10524
|
fontSize: 13,
|
|
10048
10525
|
padding: 8,
|
|
@@ -10053,9 +10530,38 @@ Always mention Ghon complex...`,
|
|
|
10053
10530
|
}
|
|
10054
10531
|
}
|
|
10055
10532
|
),
|
|
10056
|
-
|
|
10533
|
+
/* @__PURE__ */ jsx33(
|
|
10534
|
+
"div",
|
|
10535
|
+
{
|
|
10536
|
+
ref: richPaste.pasteAreaRef,
|
|
10537
|
+
contentEditable: true,
|
|
10538
|
+
onPaste: richPaste.handlePaste,
|
|
10539
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
10540
|
+
style: {
|
|
10541
|
+
width: "100%",
|
|
10542
|
+
minHeight: 40,
|
|
10543
|
+
padding: 8,
|
|
10544
|
+
border: "2px dashed #93c5fd",
|
|
10545
|
+
borderRadius: 4,
|
|
10546
|
+
fontSize: 12,
|
|
10547
|
+
color: "#6b7280",
|
|
10548
|
+
marginBottom: 8,
|
|
10549
|
+
outline: "none",
|
|
10550
|
+
background: "#f0f7ff"
|
|
10551
|
+
},
|
|
10552
|
+
suppressContentEditableWarning: true,
|
|
10553
|
+
children: /* @__PURE__ */ jsx33("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support" })
|
|
10554
|
+
}
|
|
10555
|
+
),
|
|
10556
|
+
richPaste.images.length > 0 && /* @__PURE__ */ jsxs23("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: [
|
|
10557
|
+
richPaste.images.length,
|
|
10558
|
+
" image",
|
|
10559
|
+
richPaste.images.length > 1 ? "s" : "",
|
|
10560
|
+
" captured"
|
|
10561
|
+
] }),
|
|
10562
|
+
finalHtml && /* @__PURE__ */ jsxs23("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 250, overflow: "auto" }, children: [
|
|
10057
10563
|
/* @__PURE__ */ jsx33("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
|
|
10058
|
-
/* @__PURE__ */ jsx33("div", { dangerouslySetInnerHTML: { __html:
|
|
10564
|
+
/* @__PURE__ */ jsx33("div", { dangerouslySetInnerHTML: { __html: finalHtml } })
|
|
10059
10565
|
] }),
|
|
10060
10566
|
/* @__PURE__ */ jsxs23("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
|
|
10061
10567
|
/* @__PURE__ */ jsx33(
|
|
@@ -10072,9 +10578,9 @@ Always mention Ghon complex...`,
|
|
|
10072
10578
|
{
|
|
10073
10579
|
type: "button",
|
|
10074
10580
|
onClick: handleInsert,
|
|
10075
|
-
disabled: !
|
|
10076
|
-
style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity:
|
|
10077
|
-
children: "Insert"
|
|
10581
|
+
disabled: !finalHtml || richPaste.isUploading,
|
|
10582
|
+
style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: finalHtml && !richPaste.isUploading ? 1 : 0.5 },
|
|
10583
|
+
children: richPaste.isUploading ? "Uploading..." : "Insert"
|
|
10078
10584
|
}
|
|
10079
10585
|
)
|
|
10080
10586
|
] })
|
|
@@ -10089,7 +10595,7 @@ import {
|
|
|
10089
10595
|
TableNode as TableNode2,
|
|
10090
10596
|
TableRowNode as TableRowNode2
|
|
10091
10597
|
} from "@lexical/table";
|
|
10092
|
-
import { createContext as createContext4, useContext as useContext4, useEffect as useEffect29, useMemo as useMemo17, useState as
|
|
10598
|
+
import { createContext as createContext4, useContext as useContext4, useEffect as useEffect29, useMemo as useMemo17, useState as useState29 } from "react";
|
|
10093
10599
|
import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
10094
10600
|
var CellContext = createContext4({
|
|
10095
10601
|
cellEditorConfig: null,
|
|
@@ -10101,9 +10607,9 @@ function InsertTableDialog({
|
|
|
10101
10607
|
activeEditor,
|
|
10102
10608
|
onClose
|
|
10103
10609
|
}) {
|
|
10104
|
-
const [rows, setRows] =
|
|
10105
|
-
const [columns, setColumns] =
|
|
10106
|
-
const [isDisabled, setIsDisabled] =
|
|
10610
|
+
const [rows, setRows] = useState29("5");
|
|
10611
|
+
const [columns, setColumns] = useState29("5");
|
|
10612
|
+
const [isDisabled, setIsDisabled] = useState29(true);
|
|
10107
10613
|
useEffect29(() => {
|
|
10108
10614
|
const row = Number(rows);
|
|
10109
10615
|
const column = Number(columns);
|
|
@@ -10155,7 +10661,7 @@ import {
|
|
|
10155
10661
|
} from "@lexical/react/LexicalDecoratorBlockNode";
|
|
10156
10662
|
import { useLexicalComposerContext as useLexicalComposerContext32 } from "@lexical/react/LexicalComposerContext";
|
|
10157
10663
|
import { useLexicalEditable as useLexicalEditable6 } from "@lexical/react/useLexicalEditable";
|
|
10158
|
-
import { useCallback as
|
|
10664
|
+
import { useCallback as useCallback22, useRef as useRef11, useState as useState30 } from "react";
|
|
10159
10665
|
import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
10160
10666
|
function HtmlBlockComponent({
|
|
10161
10667
|
className,
|
|
@@ -10165,15 +10671,15 @@ function HtmlBlockComponent({
|
|
|
10165
10671
|
}) {
|
|
10166
10672
|
const [editor] = useLexicalComposerContext32();
|
|
10167
10673
|
const isEditable = useLexicalEditable6();
|
|
10168
|
-
const [isEditing, setIsEditing] =
|
|
10169
|
-
const [editValue, setEditValue] =
|
|
10170
|
-
const textareaRef =
|
|
10171
|
-
const openEditor =
|
|
10674
|
+
const [isEditing, setIsEditing] = useState30(false);
|
|
10675
|
+
const [editValue, setEditValue] = useState30("");
|
|
10676
|
+
const textareaRef = useRef11(null);
|
|
10677
|
+
const openEditor = useCallback22(() => {
|
|
10172
10678
|
setEditValue(html);
|
|
10173
10679
|
setIsEditing(true);
|
|
10174
10680
|
setTimeout(() => textareaRef.current?.focus(), 50);
|
|
10175
10681
|
}, [html]);
|
|
10176
|
-
const saveHtml =
|
|
10682
|
+
const saveHtml = useCallback22(() => {
|
|
10177
10683
|
editor.update(() => {
|
|
10178
10684
|
const node = $getNodeByKey9(nodeKey);
|
|
10179
10685
|
if ($isHtmlBlockNode(node)) {
|
|
@@ -10182,7 +10688,7 @@ function HtmlBlockComponent({
|
|
|
10182
10688
|
});
|
|
10183
10689
|
setIsEditing(false);
|
|
10184
10690
|
}, [editor, nodeKey, editValue]);
|
|
10185
|
-
const cancelEdit =
|
|
10691
|
+
const cancelEdit = useCallback22(() => {
|
|
10186
10692
|
setIsEditing(false);
|
|
10187
10693
|
}, []);
|
|
10188
10694
|
return /* @__PURE__ */ jsx35(
|
|
@@ -10661,7 +11167,7 @@ function getBaseOptions(editor, showModal) {
|
|
|
10661
11167
|
function ComponentPickerMenuPlugin() {
|
|
10662
11168
|
const [editor] = useLexicalComposerContext33();
|
|
10663
11169
|
const [modal, showModal] = useModal();
|
|
10664
|
-
const [queryString, setQueryString] =
|
|
11170
|
+
const [queryString, setQueryString] = useState31(null);
|
|
10665
11171
|
const checkForTriggerMatch = useBasicTypeaheadTriggerMatch("/", {
|
|
10666
11172
|
allowWhitespace: true,
|
|
10667
11173
|
minLength: 0
|
|
@@ -10679,7 +11185,7 @@ function ComponentPickerMenuPlugin() {
|
|
|
10679
11185
|
)
|
|
10680
11186
|
];
|
|
10681
11187
|
}, [editor, queryString, showModal]);
|
|
10682
|
-
const onSelectOption =
|
|
11188
|
+
const onSelectOption = useCallback23(
|
|
10683
11189
|
(selectedOption, nodeToRemove, closeMenu, matchingString) => {
|
|
10684
11190
|
editor.update(() => {
|
|
10685
11191
|
nodeToRemove?.remove();
|
|
@@ -10912,7 +11418,7 @@ import {
|
|
|
10912
11418
|
$isParagraphNode as $isParagraphNode4,
|
|
10913
11419
|
$isTextNode as $isTextNode4
|
|
10914
11420
|
} from "lexical";
|
|
10915
|
-
import { useCallback as
|
|
11421
|
+
import { useCallback as useCallback24, useEffect as useEffect31, useMemo as useMemo20, useRef as useRef12, useState as useState32 } from "react";
|
|
10916
11422
|
import * as ReactDOM3 from "react-dom";
|
|
10917
11423
|
import { Fragment as Fragment12, jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
10918
11424
|
var DRAGGABLE_BLOCK_MENU_CLASSNAME = "draggable-block-menu";
|
|
@@ -10924,18 +11430,18 @@ function DraggableBlockPlugin({
|
|
|
10924
11430
|
}) {
|
|
10925
11431
|
const [editor] = useLexicalComposerContext36();
|
|
10926
11432
|
const [modal, showModal] = useModal();
|
|
10927
|
-
const menuRef =
|
|
10928
|
-
const pickerRef =
|
|
10929
|
-
const searchInputRef =
|
|
10930
|
-
const targetLineRef =
|
|
10931
|
-
const [draggableElement, setDraggableElement] =
|
|
11433
|
+
const menuRef = useRef12(null);
|
|
11434
|
+
const pickerRef = useRef12(null);
|
|
11435
|
+
const searchInputRef = useRef12(null);
|
|
11436
|
+
const targetLineRef = useRef12(null);
|
|
11437
|
+
const [draggableElement, setDraggableElement] = useState32(
|
|
10932
11438
|
null
|
|
10933
11439
|
);
|
|
10934
|
-
const [pickerState, setPickerState] =
|
|
10935
|
-
const [isPickerOpen, setIsPickerOpen] =
|
|
10936
|
-
const [queryString, setQueryString] =
|
|
10937
|
-
const [highlightedIndex, setHighlightedIndex] =
|
|
10938
|
-
const [pickerPosition, setPickerPosition] =
|
|
11440
|
+
const [pickerState, setPickerState] = useState32(null);
|
|
11441
|
+
const [isPickerOpen, setIsPickerOpen] = useState32(false);
|
|
11442
|
+
const [queryString, setQueryString] = useState32("");
|
|
11443
|
+
const [highlightedIndex, setHighlightedIndex] = useState32(0);
|
|
11444
|
+
const [pickerPosition, setPickerPosition] = useState32(null);
|
|
10939
11445
|
const options = useMemo20(() => {
|
|
10940
11446
|
const baseOptions = getBaseOptions(editor, showModal);
|
|
10941
11447
|
if (!queryString) {
|
|
@@ -10979,7 +11485,7 @@ function DraggableBlockPlugin({
|
|
|
10979
11485
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
10980
11486
|
};
|
|
10981
11487
|
}, [isPickerOpen]);
|
|
10982
|
-
const selectOption =
|
|
11488
|
+
const selectOption = useCallback24(
|
|
10983
11489
|
(option) => {
|
|
10984
11490
|
if (!pickerState) {
|
|
10985
11491
|
setIsPickerOpen(false);
|
|
@@ -11156,7 +11662,7 @@ import {
|
|
|
11156
11662
|
$getSelection as $getSelection11,
|
|
11157
11663
|
$isRangeSelection as $isRangeSelection9
|
|
11158
11664
|
} from "lexical";
|
|
11159
|
-
import { useCallback as
|
|
11665
|
+
import { useCallback as useCallback25, useEffect as useEffect32, useMemo as useMemo21, useState as useState33 } from "react";
|
|
11160
11666
|
import * as ReactDOM4 from "react-dom";
|
|
11161
11667
|
import { jsx as jsx39, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
11162
11668
|
var EmojiOption = class extends MenuOption2 {
|
|
@@ -11204,8 +11710,8 @@ function EmojiMenuItem({
|
|
|
11204
11710
|
var MAX_EMOJI_SUGGESTION_COUNT = 10;
|
|
11205
11711
|
function EmojiPickerPlugin() {
|
|
11206
11712
|
const [editor] = useLexicalComposerContext37();
|
|
11207
|
-
const [queryString, setQueryString] =
|
|
11208
|
-
const [emojis, setEmojis] =
|
|
11713
|
+
const [queryString, setQueryString] = useState33(null);
|
|
11714
|
+
const [emojis, setEmojis] = useState33([]);
|
|
11209
11715
|
useEffect32(() => {
|
|
11210
11716
|
import("./emoji-list-MUV74SND.js").then((file) => setEmojis(file.default));
|
|
11211
11717
|
}, []);
|
|
@@ -11229,7 +11735,7 @@ function EmojiPickerPlugin() {
|
|
|
11229
11735
|
) : false : emojiOptions;
|
|
11230
11736
|
}).slice(0, MAX_EMOJI_SUGGESTION_COUNT);
|
|
11231
11737
|
}, [emojiOptions, queryString]);
|
|
11232
|
-
const onSelectOption =
|
|
11738
|
+
const onSelectOption = useCallback25(
|
|
11233
11739
|
(selectedOption, nodeToRemove, closeMenu) => {
|
|
11234
11740
|
editor.update(() => {
|
|
11235
11741
|
const selection = $getSelection11();
|
|
@@ -11302,7 +11808,7 @@ import {
|
|
|
11302
11808
|
KEY_ESCAPE_COMMAND as KEY_ESCAPE_COMMAND2,
|
|
11303
11809
|
SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND2
|
|
11304
11810
|
} from "lexical";
|
|
11305
|
-
import { useCallback as
|
|
11811
|
+
import { useCallback as useCallback26, useEffect as useEffect33, useRef as useRef13, useState as useState34 } from "react";
|
|
11306
11812
|
import { createPortal as createPortal8 } from "react-dom";
|
|
11307
11813
|
|
|
11308
11814
|
// src/utils/getSelectedNode.ts
|
|
@@ -11363,14 +11869,14 @@ function FloatingLinkEditor({
|
|
|
11363
11869
|
isLinkEditMode,
|
|
11364
11870
|
setIsLinkEditMode
|
|
11365
11871
|
}) {
|
|
11366
|
-
const editorRef =
|
|
11367
|
-
const inputRef =
|
|
11368
|
-
const [linkUrl, setLinkUrl] =
|
|
11369
|
-
const [editedLinkUrl, setEditedLinkUrl] =
|
|
11370
|
-
const [lastSelection, setLastSelection] =
|
|
11872
|
+
const editorRef = useRef13(null);
|
|
11873
|
+
const inputRef = useRef13(null);
|
|
11874
|
+
const [linkUrl, setLinkUrl] = useState34("");
|
|
11875
|
+
const [editedLinkUrl, setEditedLinkUrl] = useState34("https://");
|
|
11876
|
+
const [lastSelection, setLastSelection] = useState34(
|
|
11371
11877
|
null
|
|
11372
11878
|
);
|
|
11373
|
-
const $updateLinkEditor =
|
|
11879
|
+
const $updateLinkEditor = useCallback26(() => {
|
|
11374
11880
|
const selection = $getSelection12();
|
|
11375
11881
|
if ($isRangeSelection10(selection)) {
|
|
11376
11882
|
const node = getSelectedNode(selection);
|
|
@@ -11622,8 +12128,8 @@ function FloatingLinkEditor({
|
|
|
11622
12128
|
] }) });
|
|
11623
12129
|
}
|
|
11624
12130
|
function useFloatingLinkEditorToolbar(editor, anchorElem, isLinkEditMode, setIsLinkEditMode) {
|
|
11625
|
-
const [activeEditor, setActiveEditor] =
|
|
11626
|
-
const [isLink, setIsLink] =
|
|
12131
|
+
const [activeEditor, setActiveEditor] = useState34(editor);
|
|
12132
|
+
const [isLink, setIsLink] = useState34(false);
|
|
11627
12133
|
useEffect33(() => {
|
|
11628
12134
|
function $updateToolbar() {
|
|
11629
12135
|
const selection = $getSelection12();
|
|
@@ -11740,7 +12246,7 @@ import {
|
|
|
11740
12246
|
getDOMSelection as getDOMSelection3,
|
|
11741
12247
|
SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND3
|
|
11742
12248
|
} from "lexical";
|
|
11743
|
-
import { useCallback as
|
|
12249
|
+
import { useCallback as useCallback27, useEffect as useEffect34, useRef as useRef14, useState as useState35 } from "react";
|
|
11744
12250
|
import { createPortal as createPortal9 } from "react-dom";
|
|
11745
12251
|
|
|
11746
12252
|
// src/utils/getDOMRangeRect.ts
|
|
@@ -11819,8 +12325,8 @@ function TextFormatFloatingToolbar({
|
|
|
11819
12325
|
isSuperscript: isSuperscript2,
|
|
11820
12326
|
setIsLinkEditMode
|
|
11821
12327
|
}) {
|
|
11822
|
-
const popupCharStylesEditorRef =
|
|
11823
|
-
const insertLink =
|
|
12328
|
+
const popupCharStylesEditorRef = useRef14(null);
|
|
12329
|
+
const insertLink = useCallback27(() => {
|
|
11824
12330
|
if (!isLink) {
|
|
11825
12331
|
setIsLinkEditMode(true);
|
|
11826
12332
|
editor.dispatchCommand(TOGGLE_LINK_COMMAND4, "https://");
|
|
@@ -11861,7 +12367,7 @@ function TextFormatFloatingToolbar({
|
|
|
11861
12367
|
};
|
|
11862
12368
|
}
|
|
11863
12369
|
}, [popupCharStylesEditorRef]);
|
|
11864
|
-
const $updateTextFormatFloatingToolbar =
|
|
12370
|
+
const $updateTextFormatFloatingToolbar = useCallback27(() => {
|
|
11865
12371
|
const selection = $getSelection13();
|
|
11866
12372
|
const popupCharStylesEditorElem = popupCharStylesEditorRef.current;
|
|
11867
12373
|
const nativeSelection = getDOMSelection3(editor._window);
|
|
@@ -12075,19 +12581,19 @@ function TextFormatFloatingToolbar({
|
|
|
12075
12581
|
] });
|
|
12076
12582
|
}
|
|
12077
12583
|
function useFloatingTextFormatToolbar(editor, anchorElem, setIsLinkEditMode) {
|
|
12078
|
-
const [isText, setIsText] =
|
|
12079
|
-
const [isLink, setIsLink] =
|
|
12080
|
-
const [isBold, setIsBold] =
|
|
12081
|
-
const [isItalic, setIsItalic] =
|
|
12082
|
-
const [isUnderline, setIsUnderline] =
|
|
12083
|
-
const [isUppercase2, setIsUppercase] =
|
|
12084
|
-
const [isLowercase2, setIsLowercase] =
|
|
12085
|
-
const [isCapitalize2, setIsCapitalize] =
|
|
12086
|
-
const [isStrikethrough, setIsStrikethrough] =
|
|
12087
|
-
const [isSubscript2, setIsSubscript] =
|
|
12088
|
-
const [isSuperscript2, setIsSuperscript] =
|
|
12089
|
-
const [isCode, setIsCode] =
|
|
12090
|
-
const updatePopup =
|
|
12584
|
+
const [isText, setIsText] = useState35(false);
|
|
12585
|
+
const [isLink, setIsLink] = useState35(false);
|
|
12586
|
+
const [isBold, setIsBold] = useState35(false);
|
|
12587
|
+
const [isItalic, setIsItalic] = useState35(false);
|
|
12588
|
+
const [isUnderline, setIsUnderline] = useState35(false);
|
|
12589
|
+
const [isUppercase2, setIsUppercase] = useState35(false);
|
|
12590
|
+
const [isLowercase2, setIsLowercase] = useState35(false);
|
|
12591
|
+
const [isCapitalize2, setIsCapitalize] = useState35(false);
|
|
12592
|
+
const [isStrikethrough, setIsStrikethrough] = useState35(false);
|
|
12593
|
+
const [isSubscript2, setIsSubscript] = useState35(false);
|
|
12594
|
+
const [isSuperscript2, setIsSuperscript] = useState35(false);
|
|
12595
|
+
const [isCode, setIsCode] = useState35(false);
|
|
12596
|
+
const updatePopup = useCallback27(() => {
|
|
12091
12597
|
editor.getEditorState().read(() => {
|
|
12092
12598
|
if (editor.isComposing()) {
|
|
12093
12599
|
return;
|
|
@@ -12963,12 +13469,12 @@ import {
|
|
|
12963
13469
|
isDOMNode as isDOMNode2,
|
|
12964
13470
|
SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND4
|
|
12965
13471
|
} from "lexical";
|
|
12966
|
-
import { useCallback as
|
|
13472
|
+
import { useCallback as useCallback28, useEffect as useEffect39, useRef as useRef16, useState as useState37 } from "react";
|
|
12967
13473
|
import { createPortal as createPortal10 } from "react-dom";
|
|
12968
13474
|
|
|
12969
13475
|
// src/ui/ColorPicker.tsx
|
|
12970
13476
|
import { calculateZoomLevel as calculateZoomLevel2 } from "@lexical/utils";
|
|
12971
|
-
import { useMemo as useMemo22, useRef as
|
|
13477
|
+
import { useMemo as useMemo22, useRef as useRef15, useState as useState36 } from "react";
|
|
12972
13478
|
import { jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
12973
13479
|
var skipAddingToHistoryStack = false;
|
|
12974
13480
|
var basicColors = [
|
|
@@ -12994,11 +13500,11 @@ function ColorPicker({
|
|
|
12994
13500
|
color,
|
|
12995
13501
|
onChange
|
|
12996
13502
|
}) {
|
|
12997
|
-
const [selfColor, setSelfColor] =
|
|
12998
|
-
const [inputColor, setInputColor] =
|
|
13503
|
+
const [selfColor, setSelfColor] = useState36(transformColor("hex", color));
|
|
13504
|
+
const [inputColor, setInputColor] = useState36(
|
|
12999
13505
|
transformColor("hex", color).hex
|
|
13000
13506
|
);
|
|
13001
|
-
const innerDivRef =
|
|
13507
|
+
const innerDivRef = useRef15(null);
|
|
13002
13508
|
const saturationPosition = useMemo22(
|
|
13003
13509
|
() => ({
|
|
13004
13510
|
x: selfColor.hsv.s / 100 * WIDTH,
|
|
@@ -13108,8 +13614,8 @@ function ColorPicker({
|
|
|
13108
13614
|
);
|
|
13109
13615
|
}
|
|
13110
13616
|
function MoveWrapper({ className, style, onChange, children }) {
|
|
13111
|
-
const divRef =
|
|
13112
|
-
const draggedRef =
|
|
13617
|
+
const divRef = useRef15(null);
|
|
13618
|
+
const draggedRef = useRef15(false);
|
|
13113
13619
|
const move = (e) => {
|
|
13114
13620
|
if (divRef.current) {
|
|
13115
13621
|
const { current: div } = divRef;
|
|
@@ -13282,15 +13788,15 @@ function TableActionMenu({
|
|
|
13282
13788
|
showColorPickerModal
|
|
13283
13789
|
}) {
|
|
13284
13790
|
const [editor] = useLexicalComposerContext43();
|
|
13285
|
-
const dropDownRef =
|
|
13286
|
-
const [tableCellNode, updateTableCellNode] =
|
|
13287
|
-
const [selectionCounts, updateSelectionCounts] =
|
|
13791
|
+
const dropDownRef = useRef16(null);
|
|
13792
|
+
const [tableCellNode, updateTableCellNode] = useState37(_tableCellNode);
|
|
13793
|
+
const [selectionCounts, updateSelectionCounts] = useState37({
|
|
13288
13794
|
columns: 1,
|
|
13289
13795
|
rows: 1
|
|
13290
13796
|
});
|
|
13291
|
-
const [canMergeCells, setCanMergeCells] =
|
|
13292
|
-
const [canUnmergeCell, setCanUnmergeCell] =
|
|
13293
|
-
const [backgroundColor, setBackgroundColor] =
|
|
13797
|
+
const [canMergeCells, setCanMergeCells] = useState37(false);
|
|
13798
|
+
const [canUnmergeCell, setCanUnmergeCell] = useState37(false);
|
|
13799
|
+
const [backgroundColor, setBackgroundColor] = useState37(
|
|
13294
13800
|
() => currentCellBackgroundColor(editor) || ""
|
|
13295
13801
|
);
|
|
13296
13802
|
useEffect39(() => {
|
|
@@ -13354,7 +13860,7 @@ function TableActionMenu({
|
|
|
13354
13860
|
window.addEventListener("click", handleClickOutside);
|
|
13355
13861
|
return () => window.removeEventListener("click", handleClickOutside);
|
|
13356
13862
|
}, [setIsMenuOpen, contextRef]);
|
|
13357
|
-
const clearTableSelection =
|
|
13863
|
+
const clearTableSelection = useCallback28(() => {
|
|
13358
13864
|
editor.update(() => {
|
|
13359
13865
|
if (tableCellNode.isAttached()) {
|
|
13360
13866
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
@@ -13397,7 +13903,7 @@ function TableActionMenu({
|
|
|
13397
13903
|
$unmergeCell();
|
|
13398
13904
|
});
|
|
13399
13905
|
};
|
|
13400
|
-
const insertTableRowAtSelection =
|
|
13906
|
+
const insertTableRowAtSelection = useCallback28(
|
|
13401
13907
|
(shouldInsertAfter) => {
|
|
13402
13908
|
editor.update(() => {
|
|
13403
13909
|
for (let i = 0; i < selectionCounts.rows; i++) {
|
|
@@ -13408,7 +13914,7 @@ function TableActionMenu({
|
|
|
13408
13914
|
},
|
|
13409
13915
|
[editor, onClose, selectionCounts.rows]
|
|
13410
13916
|
);
|
|
13411
|
-
const insertTableColumnAtSelection =
|
|
13917
|
+
const insertTableColumnAtSelection = useCallback28(
|
|
13412
13918
|
(shouldInsertAfter) => {
|
|
13413
13919
|
editor.update(() => {
|
|
13414
13920
|
for (let i = 0; i < selectionCounts.columns; i++) {
|
|
@@ -13419,13 +13925,13 @@ function TableActionMenu({
|
|
|
13419
13925
|
},
|
|
13420
13926
|
[editor, onClose, selectionCounts.columns]
|
|
13421
13927
|
);
|
|
13422
|
-
const deleteTableRowAtSelection =
|
|
13928
|
+
const deleteTableRowAtSelection = useCallback28(() => {
|
|
13423
13929
|
editor.update(() => {
|
|
13424
13930
|
$deleteTableRowAtSelection();
|
|
13425
13931
|
onClose();
|
|
13426
13932
|
});
|
|
13427
13933
|
}, [editor, onClose]);
|
|
13428
|
-
const deleteTableAtSelection =
|
|
13934
|
+
const deleteTableAtSelection = useCallback28(() => {
|
|
13429
13935
|
editor.update(() => {
|
|
13430
13936
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
13431
13937
|
tableNode.remove();
|
|
@@ -13433,13 +13939,13 @@ function TableActionMenu({
|
|
|
13433
13939
|
onClose();
|
|
13434
13940
|
});
|
|
13435
13941
|
}, [editor, tableCellNode, clearTableSelection, onClose]);
|
|
13436
|
-
const deleteTableColumnAtSelection =
|
|
13942
|
+
const deleteTableColumnAtSelection = useCallback28(() => {
|
|
13437
13943
|
editor.update(() => {
|
|
13438
13944
|
$deleteTableColumnAtSelection();
|
|
13439
13945
|
onClose();
|
|
13440
13946
|
});
|
|
13441
13947
|
}, [editor, onClose]);
|
|
13442
|
-
const toggleTableRowIsHeader =
|
|
13948
|
+
const toggleTableRowIsHeader = useCallback28(() => {
|
|
13443
13949
|
editor.update(() => {
|
|
13444
13950
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
13445
13951
|
const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
|
|
@@ -13460,7 +13966,7 @@ function TableActionMenu({
|
|
|
13460
13966
|
onClose();
|
|
13461
13967
|
});
|
|
13462
13968
|
}, [editor, tableCellNode, clearTableSelection, onClose]);
|
|
13463
|
-
const toggleTableColumnIsHeader =
|
|
13969
|
+
const toggleTableColumnIsHeader = useCallback28(() => {
|
|
13464
13970
|
editor.update(() => {
|
|
13465
13971
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
13466
13972
|
const tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
|
|
@@ -13481,7 +13987,7 @@ function TableActionMenu({
|
|
|
13481
13987
|
onClose();
|
|
13482
13988
|
});
|
|
13483
13989
|
}, [editor, tableCellNode, clearTableSelection, onClose]);
|
|
13484
|
-
const toggleRowStriping =
|
|
13990
|
+
const toggleRowStriping = useCallback28(() => {
|
|
13485
13991
|
editor.update(() => {
|
|
13486
13992
|
if (tableCellNode.isAttached()) {
|
|
13487
13993
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
@@ -13493,7 +13999,7 @@ function TableActionMenu({
|
|
|
13493
13999
|
onClose();
|
|
13494
14000
|
});
|
|
13495
14001
|
}, [editor, tableCellNode, clearTableSelection, onClose]);
|
|
13496
|
-
const toggleFirstRowFreeze =
|
|
14002
|
+
const toggleFirstRowFreeze = useCallback28(() => {
|
|
13497
14003
|
editor.update(() => {
|
|
13498
14004
|
if (tableCellNode.isAttached()) {
|
|
13499
14005
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
@@ -13505,7 +14011,7 @@ function TableActionMenu({
|
|
|
13505
14011
|
onClose();
|
|
13506
14012
|
});
|
|
13507
14013
|
}, [editor, tableCellNode, clearTableSelection, onClose]);
|
|
13508
|
-
const toggleFirstColumnFreeze =
|
|
14014
|
+
const toggleFirstColumnFreeze = useCallback28(() => {
|
|
13509
14015
|
editor.update(() => {
|
|
13510
14016
|
if (tableCellNode.isAttached()) {
|
|
13511
14017
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
@@ -13519,7 +14025,7 @@ function TableActionMenu({
|
|
|
13519
14025
|
onClose();
|
|
13520
14026
|
});
|
|
13521
14027
|
}, [editor, tableCellNode, clearTableSelection, onClose]);
|
|
13522
|
-
const handleCellBackgroundColor =
|
|
14028
|
+
const handleCellBackgroundColor = useCallback28(
|
|
13523
14029
|
(value) => {
|
|
13524
14030
|
editor.update(() => {
|
|
13525
14031
|
const selection = $getSelection17();
|
|
@@ -13832,14 +14338,14 @@ function TableCellActionMenuContainer({
|
|
|
13832
14338
|
cellMerge
|
|
13833
14339
|
}) {
|
|
13834
14340
|
const [editor] = useLexicalComposerContext43();
|
|
13835
|
-
const menuButtonRef =
|
|
13836
|
-
const menuRootRef =
|
|
13837
|
-
const [isMenuOpen, setIsMenuOpen] =
|
|
13838
|
-
const [tableCellNode, setTableMenuCellNode] =
|
|
14341
|
+
const menuButtonRef = useRef16(null);
|
|
14342
|
+
const menuRootRef = useRef16(null);
|
|
14343
|
+
const [isMenuOpen, setIsMenuOpen] = useState37(false);
|
|
14344
|
+
const [tableCellNode, setTableMenuCellNode] = useState37(
|
|
13839
14345
|
null
|
|
13840
14346
|
);
|
|
13841
14347
|
const [colorPickerModal, showColorPickerModal] = useModal();
|
|
13842
|
-
const checkTableCellOverflow =
|
|
14348
|
+
const checkTableCellOverflow = useCallback28(
|
|
13843
14349
|
(tableCellParentNodeDOM) => {
|
|
13844
14350
|
const scrollableContainer = tableCellParentNodeDOM.closest(
|
|
13845
14351
|
".PlaygroundEditorTheme__tableScrollableWrapper"
|
|
@@ -13857,7 +14363,7 @@ function TableCellActionMenuContainer({
|
|
|
13857
14363
|
},
|
|
13858
14364
|
[]
|
|
13859
14365
|
);
|
|
13860
|
-
const $moveMenu =
|
|
14366
|
+
const $moveMenu = useCallback28(() => {
|
|
13861
14367
|
const menu = menuButtonRef.current;
|
|
13862
14368
|
const selection = $getSelection17();
|
|
13863
14369
|
const nativeSelection = getDOMSelection4(editor._window);
|
|
@@ -13984,7 +14490,7 @@ function TableCellActionMenuContainer({
|
|
|
13984
14490
|
() => clearTimeout(timeoutId)
|
|
13985
14491
|
);
|
|
13986
14492
|
});
|
|
13987
|
-
const prevTableCellDOM =
|
|
14493
|
+
const prevTableCellDOM = useRef16(tableCellNode);
|
|
13988
14494
|
useEffect39(() => {
|
|
13989
14495
|
if (prevTableCellDOM.current !== tableCellNode) {
|
|
13990
14496
|
setIsMenuOpen(false);
|
|
@@ -14056,11 +14562,11 @@ import {
|
|
|
14056
14562
|
SKIP_SCROLL_INTO_VIEW_TAG
|
|
14057
14563
|
} from "lexical";
|
|
14058
14564
|
import {
|
|
14059
|
-
useCallback as
|
|
14565
|
+
useCallback as useCallback29,
|
|
14060
14566
|
useEffect as useEffect40,
|
|
14061
14567
|
useMemo as useMemo23,
|
|
14062
|
-
useRef as
|
|
14063
|
-
useState as
|
|
14568
|
+
useRef as useRef17,
|
|
14569
|
+
useState as useState38
|
|
14064
14570
|
} from "react";
|
|
14065
14571
|
import { createPortal as createPortal11 } from "react-dom";
|
|
14066
14572
|
import { Fragment as Fragment16, jsx as jsx45, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
@@ -14068,16 +14574,16 @@ var MIN_ROW_HEIGHT = 33;
|
|
|
14068
14574
|
var MIN_COLUMN_WIDTH = 92;
|
|
14069
14575
|
var ACTIVE_RESIZER_COLOR = "#76b6ff";
|
|
14070
14576
|
function TableCellResizer({ editor }) {
|
|
14071
|
-
const targetRef =
|
|
14072
|
-
const resizerRef =
|
|
14073
|
-
const tableRectRef =
|
|
14074
|
-
const [hasTable, setHasTable] =
|
|
14075
|
-
const pointerStartPosRef =
|
|
14076
|
-
const [pointerCurrentPos, updatePointerCurrentPos] =
|
|
14077
|
-
const [activeCell, updateActiveCell] =
|
|
14078
|
-
const [draggingDirection, updateDraggingDirection] =
|
|
14079
|
-
const [hoveredDirection, updateHoveredDirection] =
|
|
14080
|
-
const resetState =
|
|
14577
|
+
const targetRef = useRef17(null);
|
|
14578
|
+
const resizerRef = useRef17(null);
|
|
14579
|
+
const tableRectRef = useRef17(null);
|
|
14580
|
+
const [hasTable, setHasTable] = useState38(false);
|
|
14581
|
+
const pointerStartPosRef = useRef17(null);
|
|
14582
|
+
const [pointerCurrentPos, updatePointerCurrentPos] = useState38(null);
|
|
14583
|
+
const [activeCell, updateActiveCell] = useState38(null);
|
|
14584
|
+
const [draggingDirection, updateDraggingDirection] = useState38(null);
|
|
14585
|
+
const [hoveredDirection, updateHoveredDirection] = useState38(null);
|
|
14586
|
+
const resetState = useCallback29(() => {
|
|
14081
14587
|
updateActiveCell(null);
|
|
14082
14588
|
targetRef.current = null;
|
|
14083
14589
|
updateDraggingDirection(null);
|
|
@@ -14188,7 +14694,7 @@ function TableCellResizer({ editor }) {
|
|
|
14188
14694
|
}
|
|
14189
14695
|
return false;
|
|
14190
14696
|
};
|
|
14191
|
-
const updateRowHeight =
|
|
14697
|
+
const updateRowHeight = useCallback29(
|
|
14192
14698
|
(heightChange) => {
|
|
14193
14699
|
if (!activeCell) {
|
|
14194
14700
|
throw new Error("TableCellResizer: Expected active cell.");
|
|
@@ -14241,7 +14747,7 @@ function TableCellResizer({ editor }) {
|
|
|
14241
14747
|
}
|
|
14242
14748
|
}
|
|
14243
14749
|
};
|
|
14244
|
-
const updateColumnWidth =
|
|
14750
|
+
const updateColumnWidth = useCallback29(
|
|
14245
14751
|
(widthChange) => {
|
|
14246
14752
|
if (!activeCell) {
|
|
14247
14753
|
throw new Error("TableCellResizer: Expected active cell.");
|
|
@@ -14280,7 +14786,7 @@ function TableCellResizer({ editor }) {
|
|
|
14280
14786
|
},
|
|
14281
14787
|
[activeCell, editor]
|
|
14282
14788
|
);
|
|
14283
|
-
const pointerUpHandler =
|
|
14789
|
+
const pointerUpHandler = useCallback29(
|
|
14284
14790
|
(direction) => {
|
|
14285
14791
|
const handler = (event) => {
|
|
14286
14792
|
event.preventDefault();
|
|
@@ -14309,7 +14815,7 @@ function TableCellResizer({ editor }) {
|
|
|
14309
14815
|
},
|
|
14310
14816
|
[activeCell, resetState, updateColumnWidth, updateRowHeight]
|
|
14311
14817
|
);
|
|
14312
|
-
const toggleResize =
|
|
14818
|
+
const toggleResize = useCallback29(
|
|
14313
14819
|
(direction) => (event) => {
|
|
14314
14820
|
event.preventDefault();
|
|
14315
14821
|
event.stopPropagation();
|
|
@@ -14326,7 +14832,7 @@ function TableCellResizer({ editor }) {
|
|
|
14326
14832
|
},
|
|
14327
14833
|
[activeCell, pointerUpHandler]
|
|
14328
14834
|
);
|
|
14329
|
-
const getResizers =
|
|
14835
|
+
const getResizers = useCallback29(() => {
|
|
14330
14836
|
if (activeCell) {
|
|
14331
14837
|
const { height, width, top, left } = activeCell.elem.getBoundingClientRect();
|
|
14332
14838
|
const zoom = calculateZoomLevel3(activeCell.elem);
|
|
@@ -14384,7 +14890,7 @@ function TableCellResizer({ editor }) {
|
|
|
14384
14890
|
top: null
|
|
14385
14891
|
};
|
|
14386
14892
|
}, [activeCell, draggingDirection, hoveredDirection, pointerCurrentPos]);
|
|
14387
|
-
const handlePointerEnter =
|
|
14893
|
+
const handlePointerEnter = useCallback29(
|
|
14388
14894
|
(direction) => () => {
|
|
14389
14895
|
if (!draggingDirection) {
|
|
14390
14896
|
updateHoveredDirection(direction);
|
|
@@ -14392,7 +14898,7 @@ function TableCellResizer({ editor }) {
|
|
|
14392
14898
|
},
|
|
14393
14899
|
[draggingDirection]
|
|
14394
14900
|
);
|
|
14395
|
-
const handlePointerLeave =
|
|
14901
|
+
const handlePointerLeave = useCallback29(() => {
|
|
14396
14902
|
if (!draggingDirection) {
|
|
14397
14903
|
updateHoveredDirection(null);
|
|
14398
14904
|
}
|
|
@@ -14458,7 +14964,7 @@ import {
|
|
|
14458
14964
|
$getSiblingCaret as $getSiblingCaret2,
|
|
14459
14965
|
isHTMLElement as isHTMLElement5
|
|
14460
14966
|
} from "lexical";
|
|
14461
|
-
import { useEffect as useEffect41, useRef as
|
|
14967
|
+
import { useEffect as useEffect41, useRef as useRef18, useState as useState39 } from "react";
|
|
14462
14968
|
import { createPortal as createPortal12 } from "react-dom";
|
|
14463
14969
|
|
|
14464
14970
|
// src/utils/getThemeSelector.ts
|
|
@@ -14562,31 +15068,31 @@ function TableHoverActionsV2({
|
|
|
14562
15068
|
}) {
|
|
14563
15069
|
const [editor, { getTheme }] = useLexicalComposerContext45();
|
|
14564
15070
|
const isEditable = useLexicalEditable9();
|
|
14565
|
-
const [isVisible, setIsVisible] =
|
|
14566
|
-
const [isLeftVisible, setIsLeftVisible] =
|
|
14567
|
-
const virtualRef =
|
|
15071
|
+
const [isVisible, setIsVisible] = useState39(false);
|
|
15072
|
+
const [isLeftVisible, setIsLeftVisible] = useState39(false);
|
|
15073
|
+
const virtualRef = useRef18({
|
|
14568
15074
|
getBoundingClientRect: () => new DOMRect()
|
|
14569
15075
|
});
|
|
14570
|
-
const leftVirtualRef =
|
|
15076
|
+
const leftVirtualRef = useRef18({
|
|
14571
15077
|
getBoundingClientRect: () => new DOMRect()
|
|
14572
15078
|
});
|
|
14573
|
-
const floatingElemRef =
|
|
14574
|
-
const leftFloatingElemRef =
|
|
14575
|
-
const dragHandleRef =
|
|
14576
|
-
const hoveredLeftCellRef =
|
|
14577
|
-
const hoveredTopCellRef =
|
|
14578
|
-
const handleMouseLeaveRef =
|
|
15079
|
+
const floatingElemRef = useRef18(null);
|
|
15080
|
+
const leftFloatingElemRef = useRef18(null);
|
|
15081
|
+
const dragHandleRef = useRef18(null);
|
|
15082
|
+
const hoveredLeftCellRef = useRef18(null);
|
|
15083
|
+
const hoveredTopCellRef = useRef18(null);
|
|
15084
|
+
const handleMouseLeaveRef = useRef18(
|
|
14579
15085
|
null
|
|
14580
15086
|
);
|
|
14581
|
-
const dropIndicatorCleanupRef =
|
|
14582
|
-
const [hoveredTable, setHoveredTable] =
|
|
15087
|
+
const dropIndicatorCleanupRef = useRef18([]);
|
|
15088
|
+
const [hoveredTable, setHoveredTable] = useState39(
|
|
14583
15089
|
null
|
|
14584
15090
|
);
|
|
14585
|
-
const [hoveredColumnIndex, setHoveredColumnIndex] =
|
|
15091
|
+
const [hoveredColumnIndex, setHoveredColumnIndex] = useState39(
|
|
14586
15092
|
null
|
|
14587
15093
|
);
|
|
14588
|
-
const [canReorder, setCanReorder] =
|
|
14589
|
-
const [dropIndicatorState, setDropIndicatorState] =
|
|
15094
|
+
const [canReorder, setCanReorder] = useState39(false);
|
|
15095
|
+
const [dropIndicatorState, setDropIndicatorState] = useState39(null);
|
|
14590
15096
|
const { refs, floatingStyles, update } = useFloating({
|
|
14591
15097
|
middleware: [
|
|
14592
15098
|
offset({ mainAxis: -TOP_BUTTON_OVERHANG }),
|
|
@@ -15011,7 +15517,7 @@ function TableHoverActionsV2Plugin({
|
|
|
15011
15517
|
// src/plugins/TableOfContentsPlugin/index.tsx
|
|
15012
15518
|
import { useLexicalComposerContext as useLexicalComposerContext46 } from "@lexical/react/LexicalComposerContext";
|
|
15013
15519
|
import { TableOfContentsPlugin as LexicalTableOfContentsPlugin } from "@lexical/react/LexicalTableOfContentsPlugin";
|
|
15014
|
-
import { useEffect as useEffect42, useRef as
|
|
15520
|
+
import { useEffect as useEffect42, useRef as useRef19, useState as useState40 } from "react";
|
|
15015
15521
|
import { jsx as jsx47, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
15016
15522
|
var MARGIN_ABOVE_EDITOR = 624;
|
|
15017
15523
|
var HEADING_WIDTH = 9;
|
|
@@ -15037,8 +15543,8 @@ function isHeadingBelowTheTopOfThePage(element) {
|
|
|
15037
15543
|
function TableOfContentsList({
|
|
15038
15544
|
tableOfContents
|
|
15039
15545
|
}) {
|
|
15040
|
-
const [selectedKey, setSelectedKey] =
|
|
15041
|
-
const selectedIndex =
|
|
15546
|
+
const [selectedKey, setSelectedKey] = useState40("");
|
|
15547
|
+
const selectedIndex = useRef19(0);
|
|
15042
15548
|
const [editor] = useLexicalComposerContext46();
|
|
15043
15549
|
function scrollToNode(key, currIndex) {
|
|
15044
15550
|
editor.getEditorState().read(() => {
|
|
@@ -15303,7 +15809,7 @@ import {
|
|
|
15303
15809
|
SKIP_SELECTION_FOCUS_TAG as SKIP_SELECTION_FOCUS_TAG2,
|
|
15304
15810
|
UNDO_COMMAND as UNDO_COMMAND2
|
|
15305
15811
|
} from "lexical";
|
|
15306
|
-
import { useCallback as
|
|
15812
|
+
import { useCallback as useCallback30, useEffect as useEffect45, useState as useState42 } from "react";
|
|
15307
15813
|
|
|
15308
15814
|
// src/ui/DropdownColorPicker.tsx
|
|
15309
15815
|
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
@@ -15737,7 +16243,7 @@ function FontDropDown({
|
|
|
15737
16243
|
style,
|
|
15738
16244
|
disabled = false
|
|
15739
16245
|
}) {
|
|
15740
|
-
const handleClick =
|
|
16246
|
+
const handleClick = useCallback30(
|
|
15741
16247
|
(option) => {
|
|
15742
16248
|
editor.update(() => {
|
|
15743
16249
|
$addUpdateTag3(SKIP_SELECTION_FOCUS_TAG2);
|
|
@@ -15943,11 +16449,11 @@ function ToolbarPlugin({
|
|
|
15943
16449
|
setActiveEditor,
|
|
15944
16450
|
setIsLinkEditMode
|
|
15945
16451
|
}) {
|
|
15946
|
-
const [selectedElementKey, setSelectedElementKey] =
|
|
16452
|
+
const [selectedElementKey, setSelectedElementKey] = useState42(
|
|
15947
16453
|
null
|
|
15948
16454
|
);
|
|
15949
16455
|
const [modal, showModal] = useModal();
|
|
15950
|
-
const [isEditable, setIsEditable] =
|
|
16456
|
+
const [isEditable, setIsEditable] = useState42(() => editor.isEditable());
|
|
15951
16457
|
const { toolbarState, updateToolbarState } = useToolbarState();
|
|
15952
16458
|
const dispatchToolbarCommand = (command, payload = void 0, skipRefocus = false) => {
|
|
15953
16459
|
activeEditor.update(() => {
|
|
@@ -15958,7 +16464,7 @@ function ToolbarPlugin({
|
|
|
15958
16464
|
});
|
|
15959
16465
|
};
|
|
15960
16466
|
const dispatchFormatTextCommand = (payload, skipRefocus = false) => dispatchToolbarCommand(FORMAT_TEXT_COMMAND3, payload, skipRefocus);
|
|
15961
|
-
const $handleHeadingNode =
|
|
16467
|
+
const $handleHeadingNode = useCallback30(
|
|
15962
16468
|
(selectedElement) => {
|
|
15963
16469
|
const type = $isHeadingNode2(selectedElement) ? selectedElement.getTag() : selectedElement.getType();
|
|
15964
16470
|
if (type in blockTypeToBlockName) {
|
|
@@ -15973,7 +16479,7 @@ function ToolbarPlugin({
|
|
|
15973
16479
|
const {
|
|
15974
16480
|
settings: { isCodeHighlighted, isCodeShiki }
|
|
15975
16481
|
} = useSettings();
|
|
15976
|
-
const $handleCodeNode =
|
|
16482
|
+
const $handleCodeNode = useCallback30(
|
|
15977
16483
|
(element) => {
|
|
15978
16484
|
if ($isCodeNode6(element)) {
|
|
15979
16485
|
const language = element.getLanguage();
|
|
@@ -15989,7 +16495,7 @@ function ToolbarPlugin({
|
|
|
15989
16495
|
},
|
|
15990
16496
|
[updateToolbarState, isCodeHighlighted, isCodeShiki]
|
|
15991
16497
|
);
|
|
15992
|
-
const $updateToolbar =
|
|
16498
|
+
const $updateToolbar = useCallback30(() => {
|
|
15993
16499
|
const selection = $getSelection18();
|
|
15994
16500
|
if ($isRangeSelection16(selection)) {
|
|
15995
16501
|
if (activeEditor !== editor && $isEditorIsNestedEditor(activeEditor)) {
|
|
@@ -16162,7 +16668,7 @@ function ToolbarPlugin({
|
|
|
16162
16668
|
)
|
|
16163
16669
|
);
|
|
16164
16670
|
}, [$updateToolbar, activeEditor, editor, updateToolbarState]);
|
|
16165
|
-
const applyStyleText =
|
|
16671
|
+
const applyStyleText = useCallback30(
|
|
16166
16672
|
(styles, skipHistoryStack, skipRefocus = false) => {
|
|
16167
16673
|
activeEditor.update(
|
|
16168
16674
|
() => {
|
|
@@ -16179,13 +16685,13 @@ function ToolbarPlugin({
|
|
|
16179
16685
|
},
|
|
16180
16686
|
[activeEditor]
|
|
16181
16687
|
);
|
|
16182
|
-
const onFontColorSelect =
|
|
16688
|
+
const onFontColorSelect = useCallback30(
|
|
16183
16689
|
(value, skipHistoryStack, skipRefocus) => {
|
|
16184
16690
|
applyStyleText({ color: value }, skipHistoryStack, skipRefocus);
|
|
16185
16691
|
},
|
|
16186
16692
|
[applyStyleText]
|
|
16187
16693
|
);
|
|
16188
|
-
const onBgColorSelect =
|
|
16694
|
+
const onBgColorSelect = useCallback30(
|
|
16189
16695
|
(value, skipHistoryStack, skipRefocus) => {
|
|
16190
16696
|
applyStyleText(
|
|
16191
16697
|
{ "background-color": value },
|
|
@@ -16195,7 +16701,7 @@ function ToolbarPlugin({
|
|
|
16195
16701
|
},
|
|
16196
16702
|
[applyStyleText]
|
|
16197
16703
|
);
|
|
16198
|
-
const insertLink =
|
|
16704
|
+
const insertLink = useCallback30(() => {
|
|
16199
16705
|
if (!toolbarState.isLink) {
|
|
16200
16706
|
setIsLinkEditMode(true);
|
|
16201
16707
|
activeEditor.dispatchCommand(
|
|
@@ -16207,7 +16713,7 @@ function ToolbarPlugin({
|
|
|
16207
16713
|
activeEditor.dispatchCommand(TOGGLE_LINK_COMMAND6, null);
|
|
16208
16714
|
}
|
|
16209
16715
|
}, [activeEditor, setIsLinkEditMode, toolbarState.isLink]);
|
|
16210
|
-
const onCodeLanguageSelect =
|
|
16716
|
+
const onCodeLanguageSelect = useCallback30(
|
|
16211
16717
|
(value) => {
|
|
16212
16718
|
activeEditor.update(() => {
|
|
16213
16719
|
$addUpdateTag3(SKIP_SELECTION_FOCUS_TAG2);
|
|
@@ -16221,7 +16727,7 @@ function ToolbarPlugin({
|
|
|
16221
16727
|
},
|
|
16222
16728
|
[activeEditor, selectedElementKey]
|
|
16223
16729
|
);
|
|
16224
|
-
const onCodeThemeSelect =
|
|
16730
|
+
const onCodeThemeSelect = useCallback30(
|
|
16225
16731
|
(value) => {
|
|
16226
16732
|
activeEditor.update(() => {
|
|
16227
16733
|
if (selectedElementKey !== null) {
|
|
@@ -16955,11 +17461,11 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
|
|
|
16955
17461
|
} = useSettings();
|
|
16956
17462
|
const isEditable = useLexicalEditable10();
|
|
16957
17463
|
const placeholder = placeholderProp ?? (isRichText ? "Enter some rich text..." : "Enter some plain text...");
|
|
16958
|
-
const [floatingAnchorElem, setFloatingAnchorElem] =
|
|
16959
|
-
const [isSmallWidthViewport, setIsSmallWidthViewport] =
|
|
17464
|
+
const [floatingAnchorElem, setFloatingAnchorElem] = useState43(null);
|
|
17465
|
+
const [isSmallWidthViewport, setIsSmallWidthViewport] = useState43(false);
|
|
16960
17466
|
const [editor] = useLexicalComposerContext49();
|
|
16961
|
-
const [activeEditor, setActiveEditor] =
|
|
16962
|
-
const [isLinkEditMode, setIsLinkEditMode] =
|
|
17467
|
+
const [activeEditor, setActiveEditor] = useState43(editor);
|
|
17468
|
+
const [isLinkEditMode, setIsLinkEditMode] = useState43(false);
|
|
16963
17469
|
const onRef = (_floatingAnchorElem) => {
|
|
16964
17470
|
if (_floatingAnchorElem !== null) {
|
|
16965
17471
|
setFloatingAnchorElem(_floatingAnchorElem);
|
|
@@ -17289,9 +17795,9 @@ function HtmlPlugin({
|
|
|
17289
17795
|
debounceMs = 300
|
|
17290
17796
|
}) {
|
|
17291
17797
|
const [editor] = useLexicalComposerContext50();
|
|
17292
|
-
const lastSyncedValue =
|
|
17293
|
-
const hasUserEdited =
|
|
17294
|
-
const debounceTimer =
|
|
17798
|
+
const lastSyncedValue = useRef20(null);
|
|
17799
|
+
const hasUserEdited = useRef20(false);
|
|
17800
|
+
const debounceTimer = useRef20(null);
|
|
17295
17801
|
useEffect48(() => {
|
|
17296
17802
|
return editor.registerCommand(
|
|
17297
17803
|
FOCUS_COMMAND2,
|
|
@@ -17341,7 +17847,7 @@ function HtmlPlugin({
|
|
|
17341
17847
|
{ tag: "historic" }
|
|
17342
17848
|
);
|
|
17343
17849
|
}, [editor, value]);
|
|
17344
|
-
const handleChange =
|
|
17850
|
+
const handleChange = useCallback31(
|
|
17345
17851
|
(_editorState, _editor, tags) => {
|
|
17346
17852
|
if (!tags.has("historic")) {
|
|
17347
17853
|
hasUserEdited.current = true;
|
|
@@ -17392,7 +17898,7 @@ function LexicalEditor20({
|
|
|
17392
17898
|
readOnly,
|
|
17393
17899
|
maxLength
|
|
17394
17900
|
}) {
|
|
17395
|
-
const [isFullscreen, setIsFullscreen] =
|
|
17901
|
+
const [isFullscreen, setIsFullscreen] = useState44(false);
|
|
17396
17902
|
const initialConfig = {
|
|
17397
17903
|
namespace: "LexicalEditor",
|
|
17398
17904
|
nodes: [...PlaygroundNodes_default],
|
|
@@ -17421,7 +17927,7 @@ function LexicalEditor20({
|
|
|
17421
17927
|
document.addEventListener("keydown", handleEsc);
|
|
17422
17928
|
return () => document.removeEventListener("keydown", handleEsc);
|
|
17423
17929
|
}, [isFullscreen]);
|
|
17424
|
-
const toggleFullscreen =
|
|
17930
|
+
const toggleFullscreen = useCallback31(
|
|
17425
17931
|
() => setIsFullscreen((f) => !f),
|
|
17426
17932
|
[]
|
|
17427
17933
|
);
|