@baasix/lexical 0.0.12 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -58,16 +58,16 @@ import "./chunk-PZ5AY32C.js";
58
58
  // src/LexicalEditor.tsx
59
59
  import {
60
60
  useCallback as useCallback31,
61
- useEffect as useEffect48,
62
- useMemo as useMemo24,
63
- useRef as useRef20,
61
+ useEffect as useEffect49,
62
+ useMemo as useMemo23,
63
+ useRef as useRef21,
64
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";
68
68
  import { useLexicalComposerContext as useLexicalComposerContext50 } from "@lexical/react/LexicalComposerContext";
69
- import { $generateHtmlFromNodes, $generateNodesFromDOM } from "@lexical/html";
70
- import { $createParagraphNode as $createParagraphNode12, $getRoot as $getRoot3, $insertNodes as $insertNodes6, $setSelection as $setSelection7, COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW11, FOCUS_COMMAND as FOCUS_COMMAND2 } from "lexical";
69
+ import { $generateHtmlFromNodes, $generateNodesFromDOM as $generateNodesFromDOM2 } from "@lexical/html";
70
+ import { $createParagraphNode as $createParagraphNode12, $getRoot as $getRoot3, $insertNodes as $insertNodes7, $isTextNode as $isTextNode8, $setSelection as $setSelection7, COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW11, FOCUS_COMMAND as FOCUS_COMMAND2, TextNode as TextNode6 } from "lexical";
71
71
 
72
72
  // src/Editor.tsx
73
73
  import { CharacterLimitPlugin } from "@lexical/react/LexicalCharacterLimitPlugin";
@@ -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 useState43 } from "react";
90
+ import { useEffect as useEffect48, 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 useCallback23, useMemo as useMemo18, useState as useState31 } from "react";
6237
+ import { useCallback as useCallback23, useMemo as useMemo17, useState as useState31 } from "react";
6238
6238
  import * as ReactDOM2 from "react-dom";
6239
6239
 
6240
6240
  // src/plugins/DateTimePlugin/index.tsx
@@ -7645,8 +7645,9 @@ function PageBreakPlugin() {
7645
7645
  // src/plugins/NotesPlugin/index.tsx
7646
7646
  import { useLexicalComposerContext as useLexicalComposerContext21 } from "@lexical/react/LexicalComposerContext";
7647
7647
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot7 } from "@lexical/utils";
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, useRef as useRef9, useState as useState18 } from "react";
7648
+ import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR13, createCommand as createCommand13, $insertNodes as $insertNodes5 } from "lexical";
7649
+ import { $generateNodesFromDOM } from "@lexical/html";
7650
+ import { useCallback as useCallback12, useEffect as useEffect23, useRef as useRef9, useState as useState18 } from "react";
7650
7651
 
7651
7652
  // src/nodes/NotesNode.tsx
7652
7653
  import { $getNodeByKey as $getNodeByKey4 } from "lexical";
@@ -8490,37 +8491,14 @@ function parseQuestionsCardsHtml(html) {
8490
8491
  currentQA = { question: "", answer: "", sections: [] };
8491
8492
  const clone = el.cloneNode(true);
8492
8493
  clone.querySelector("h3")?.remove();
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
- }
8494
+ const contentDiv = clone.querySelector('div[style*="margin-top"]');
8495
+ currentQA.question = (contentDiv ? contentDiv.innerHTML : clone.innerHTML).trim();
8511
8496
  } else if (h3Text.includes("Answer")) {
8512
8497
  if (!currentQA) currentQA = { question: "", answer: "", sections: [] };
8513
8498
  const clone = el.cloneNode(true);
8514
8499
  clone.querySelector("h3")?.remove();
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
- }
8500
+ const p = clone.querySelector("p");
8501
+ currentQA.answer = (p ? p.innerHTML : clone.innerHTML).trim();
8524
8502
  } else if (el.children.length > 1) {
8525
8503
  if (!currentQA) currentQA = { question: "", answer: "", sections: [] };
8526
8504
  for (const card of Array.from(el.children)) {
@@ -8531,7 +8509,8 @@ function parseQuestionsCardsHtml(html) {
8531
8509
  const key = match ? match.key : "rubric";
8532
8510
  const clone = card.cloneNode(true);
8533
8511
  clone.querySelector("h3")?.remove();
8534
- currentQA.sections.push({ key, content: (clone.textContent || "").trim() });
8512
+ const p = clone.querySelector("p");
8513
+ currentQA.sections.push({ key, content: (p ? p.innerHTML : clone.innerHTML).trim() });
8535
8514
  }
8536
8515
  }
8537
8516
  }
@@ -8541,6 +8520,46 @@ function parseQuestionsCardsHtml(html) {
8541
8520
  }
8542
8521
  return result;
8543
8522
  }
8523
+ function buildQuestionsCardsHtml(pairs) {
8524
+ const styles = CARD_STYLES.questionsCards;
8525
+ let html = "";
8526
+ pairs.forEach((qa, idx) => {
8527
+ if (qa.question) {
8528
+ const c = styles.question;
8529
+ const qLabel = pairs.length > 1 ? `Question ${idx + 1}` : "Question";
8530
+ 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;">
8531
+ <h3 style="margin: 0; color: inherit;">${c.emoji} ${qLabel}</h3>
8532
+ <div style="margin-top: 8px; color: inherit;">${qa.question}</div>
8533
+ </div>
8534
+ `;
8535
+ }
8536
+ if (qa.answer) {
8537
+ const c = styles.answer;
8538
+ 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;">
8539
+ <h3 style="margin-top: 0; color: inherit;">${c.emoji} ${c.title}</h3>
8540
+ <p>${qa.answer}</p>
8541
+ </div>
8542
+ `;
8543
+ }
8544
+ const hasGridCards = qa.sections.some((s) => s.content);
8545
+ if (hasGridCards) {
8546
+ html += `<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 8px; margin-bottom: 24px;">
8547
+ `;
8548
+ qa.sections.forEach((s) => {
8549
+ if (!s.content) return;
8550
+ const c = styles[s.key];
8551
+ if (!c) return;
8552
+ 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;">
8553
+ <h3 style="margin-top: 0; color: inherit; font-size: 14px;">${c.emoji} ${c.number}. ${c.title}</h3>
8554
+ <p style="margin: 0; font-size: 13px;">${s.content}</p>
8555
+ </div>
8556
+ `;
8557
+ });
8558
+ html += "</div>\n";
8559
+ }
8560
+ });
8561
+ return compactHtml(html);
8562
+ }
8544
8563
 
8545
8564
  // src/nodes/NotesNode.tsx
8546
8565
  import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
@@ -8706,7 +8725,7 @@ function $isNotesNode(node) {
8706
8725
  }
8707
8726
 
8708
8727
  // src/plugins/NotesPlugin/index.tsx
8709
- import { jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
8728
+ import { Fragment as Fragment9, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
8710
8729
  var INSERT_NOTES_COMMAND = createCommand13(
8711
8730
  "INSERT_NOTES_COMMAND"
8712
8731
  );
@@ -8728,135 +8747,153 @@ function NotesPlugin() {
8728
8747
  }, [editor]);
8729
8748
  return null;
8730
8749
  }
8731
- function convertRichHtmlToNotes(htmlStr, baasixClient, folder) {
8732
- return new Promise(async (resolve) => {
8733
- const parser = new DOMParser();
8734
- const doc = parser.parseFromString(htmlStr, "text/html");
8735
- if (baasixClient) {
8736
- const imgs = doc.querySelectorAll("img");
8737
- for (let i = 0; i < imgs.length; i++) {
8738
- const img2 = imgs[i];
8739
- const src = img2.getAttribute("src") || "";
8740
- if (src.startsWith("data:")) {
8741
- try {
8742
- const resp = await fetch(src);
8743
- const blob = await resp.blob();
8744
- const ext = blob.type.split("/")[1] || "png";
8745
- const file = new File([blob], `note-image-${i}.${ext}`, { type: blob.type });
8746
- const uploadedUrl = await uploadImageToBaasix(baasixClient, file, folder);
8747
- img2.setAttribute("src", uploadedUrl);
8748
- } catch {
8749
- }
8750
+ async function processImagesInHtml(htmlStr, baasixClient, folder) {
8751
+ const parser = new DOMParser();
8752
+ const doc = parser.parseFromString(htmlStr, "text/html");
8753
+ if (baasixClient) {
8754
+ const imgs = doc.querySelectorAll("img");
8755
+ for (let i = 0; i < imgs.length; i++) {
8756
+ const img2 = imgs[i];
8757
+ const src = img2.getAttribute("src") || "";
8758
+ if (src.startsWith("data:")) {
8759
+ try {
8760
+ const resp = await fetch(src);
8761
+ const blob = await resp.blob();
8762
+ const ext = blob.type.split("/")[1] || "png";
8763
+ const file = new File([blob], `note-image-${i}.${ext}`, { type: blob.type });
8764
+ const uploadedUrl = await uploadImageToBaasix(baasixClient, file, folder);
8765
+ img2.setAttribute("src", uploadedUrl);
8766
+ img2.setAttribute("style", "max-width: 100%; height: auto;");
8767
+ } catch {
8750
8768
  }
8751
8769
  }
8752
8770
  }
8753
- let html = `<div style="font-family: sans-serif; line-height: 1.6; color: inherit;">`;
8754
- const children = Array.from(doc.body.childNodes);
8755
- for (const child of children) {
8756
- html += processNode(child);
8757
- }
8758
- html += "</div>";
8759
- resolve(html.replace(/>\s+</g, "><"));
8760
- });
8771
+ }
8772
+ return doc.body.innerHTML;
8761
8773
  }
8774
+ var HEADING_COLOR = "#6b5b95";
8762
8775
  function InsertNotesDialog({
8763
8776
  activeEditor,
8764
8777
  onClose
8765
8778
  }) {
8766
- const [input, setInput] = useState18("");
8767
- const [richHtml, setRichHtml] = useState18("");
8779
+ const [pastedHtml, setPastedHtml] = useState18("");
8768
8780
  const [isUploading, setIsUploading] = useState18(false);
8781
+ const [hasPasted, setHasPasted] = useState18(false);
8769
8782
  const pasteAreaRef = useRef9(null);
8770
8783
  let editorConfig = null;
8771
8784
  try {
8772
8785
  editorConfig = useEditorConfig();
8773
8786
  } catch {
8774
8787
  }
8775
- const handleRichPaste = useCallback12(async (e) => {
8788
+ const handlePaste = useCallback12(async (e) => {
8776
8789
  e.preventDefault();
8777
- const clipboardData = e.clipboardData;
8778
- const htmlData = clipboardData.getData("text/html");
8779
- const textData = clipboardData.getData("text/plain");
8780
- if (htmlData) {
8781
- setIsUploading(true);
8782
- try {
8783
- const processed = await convertRichHtmlToNotes(
8784
- htmlData,
8785
- editorConfig?.baasixClient,
8786
- editorConfig?.folder
8787
- );
8788
- setRichHtml(processed);
8789
- setInput("");
8790
- } finally {
8791
- setIsUploading(false);
8792
- }
8793
- } else if (textData) {
8794
- setInput((prev) => prev ? prev + "\n" + textData : textData);
8790
+ const htmlData = e.clipboardData.getData("text/html");
8791
+ const textData = e.clipboardData.getData("text/plain");
8792
+ const rawHtml = htmlData || (textData ? `<p>${textData.replace(/\n\n+/g, "</p><p>").replace(/\n/g, "<br>")}</p>` : "");
8793
+ if (!rawHtml) return;
8794
+ setIsUploading(true);
8795
+ try {
8796
+ const processed = await processImagesInHtml(rawHtml, editorConfig?.baasixClient, editorConfig?.folder);
8797
+ setPastedHtml(processed);
8798
+ setHasPasted(true);
8799
+ } finally {
8800
+ setIsUploading(false);
8795
8801
  }
8802
+ }, [editorConfig]);
8803
+ const handleClear = useCallback12(() => {
8804
+ setPastedHtml("");
8805
+ setHasPasted(false);
8796
8806
  if (pasteAreaRef.current) {
8797
- pasteAreaRef.current.innerHTML = '<span style="color: #9ca3af; pointer-events: none; user-select: none;">Paste from Word/Docs here (preserves formatting)</span>';
8807
+ pasteAreaRef.current.innerHTML = "";
8798
8808
  }
8799
- }, [editorConfig]);
8800
- const finalHtml = useMemo8(() => {
8801
- if (richHtml) return richHtml;
8802
- if (!input.trim()) return "";
8803
- return convertNotes(input);
8804
- }, [input, richHtml]);
8809
+ }, []);
8805
8810
  const handleInsert = useCallback12(() => {
8806
- if (!finalHtml) return;
8807
- activeEditor.dispatchCommand(INSERT_NOTES_COMMAND, finalHtml);
8808
- onClose();
8809
- }, [activeEditor, finalHtml, onClose]);
8810
- return /* @__PURE__ */ jsxs14("div", { style: { minWidth: 500 }, children: [
8811
- /* @__PURE__ */ jsx24(
8812
- "textarea",
8813
- {
8814
- value: input,
8815
- onChange: (e) => {
8816
- setInput(e.target.value);
8817
- setRichHtml("");
8818
- },
8819
- 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",
8820
- style: {
8821
- width: "100%",
8822
- minHeight: 120,
8823
- fontFamily: "monospace",
8824
- fontSize: 13,
8825
- padding: 8,
8826
- border: "1px solid #ddd",
8827
- borderRadius: 4,
8828
- resize: "vertical",
8829
- marginBottom: 8
8811
+ if (!pastedHtml) return;
8812
+ const parser = new DOMParser();
8813
+ const dom = parser.parseFromString(pastedHtml, "text/html");
8814
+ const isHeadingTag = (el) => /^H[1-6]$/.test(el.tagName);
8815
+ const isBoldOnlyParagraph = (el) => {
8816
+ if (el.tagName !== "P") return false;
8817
+ const text = el.textContent?.trim() || "";
8818
+ if (!text || text.length > 150) return false;
8819
+ const children = Array.from(el.childNodes);
8820
+ return children.every((child) => {
8821
+ if (child.nodeType === Node.TEXT_NODE) return !child.textContent?.trim();
8822
+ if (child.nodeType !== Node.ELEMENT_NODE) return true;
8823
+ const el2 = child;
8824
+ const tag = el2.tagName;
8825
+ if (tag === "STRONG" || tag === "B") return true;
8826
+ if (tag === "SPAN") {
8827
+ const fw = el2.style.fontWeight;
8828
+ return fw === "bold" || fw === "700";
8830
8829
  }
8830
+ return false;
8831
+ });
8832
+ };
8833
+ const colorizeContent = (el) => {
8834
+ const inner = el.innerHTML;
8835
+ el.innerHTML = `<span style="color: ${HEADING_COLOR};">${inner}</span>`;
8836
+ };
8837
+ const topChildren = Array.from(dom.body.children);
8838
+ for (const el of topChildren) {
8839
+ if (isHeadingTag(el) || isBoldOnlyParagraph(el)) {
8840
+ colorizeContent(el);
8841
+ const hr = dom.createElement("hr");
8842
+ el.insertAdjacentElement("afterend", hr);
8843
+ const emptyP = dom.createElement("p");
8844
+ hr.insertAdjacentElement("afterend", emptyP);
8831
8845
  }
8832
- ),
8833
- /* @__PURE__ */ jsx24(
8846
+ }
8847
+ activeEditor.update(() => {
8848
+ const nodes = $generateNodesFromDOM(activeEditor, dom);
8849
+ $insertNodes5(nodes);
8850
+ });
8851
+ onClose();
8852
+ }, [activeEditor, pastedHtml, onClose]);
8853
+ return /* @__PURE__ */ jsxs14("div", { style: { minWidth: 500 }, children: [
8854
+ !hasPasted && /* @__PURE__ */ jsx24(
8834
8855
  "div",
8835
8856
  {
8836
8857
  ref: pasteAreaRef,
8837
8858
  contentEditable: true,
8838
- onPaste: handleRichPaste,
8859
+ onPaste: handlePaste,
8839
8860
  onMouseDown: (e) => e.stopPropagation(),
8840
8861
  style: {
8841
8862
  width: "100%",
8842
- minHeight: 40,
8843
- padding: 8,
8863
+ minHeight: 160,
8864
+ padding: 12,
8844
8865
  border: "2px dashed #93c5fd",
8845
8866
  borderRadius: 4,
8846
- fontSize: 12,
8867
+ fontSize: 13,
8847
8868
  color: "#6b7280",
8848
8869
  marginBottom: 8,
8849
8870
  outline: "none",
8850
8871
  background: "#f0f7ff"
8851
8872
  },
8852
- suppressContentEditableWarning: true,
8853
- children: /* @__PURE__ */ jsx24("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: isUploading ? "Processing content..." : "Paste from Word/Docs here (preserves formatting)" })
8873
+ "data-placeholder": isUploading ? "Processing content..." : "Paste from Word/Docs here (preserves formatting)",
8874
+ suppressContentEditableWarning: true
8854
8875
  }
8855
8876
  ),
8856
- richHtml && /* @__PURE__ */ jsx24("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: "Rich content captured (formatting preserved)" }),
8857
- finalHtml && /* @__PURE__ */ jsxs14("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 200, overflow: "auto" }, children: [
8858
- /* @__PURE__ */ jsx24("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
8859
- /* @__PURE__ */ jsx24("div", { dangerouslySetInnerHTML: { __html: finalHtml } })
8877
+ hasPasted && /* @__PURE__ */ jsxs14(Fragment9, { children: [
8878
+ /* @__PURE__ */ jsxs14("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }, children: [
8879
+ /* @__PURE__ */ jsx24("span", { style: { fontSize: 11, color: "#6b7280" }, children: "Preview" }),
8880
+ /* @__PURE__ */ jsx24(
8881
+ "button",
8882
+ {
8883
+ type: "button",
8884
+ onClick: handleClear,
8885
+ style: { padding: "2px 10px", fontSize: 12, border: "1px solid #fca5a5", borderRadius: 4, background: "#fff", color: "#ef4444", cursor: "pointer" },
8886
+ children: "Clear"
8887
+ }
8888
+ )
8889
+ ] }),
8890
+ /* @__PURE__ */ jsx24(
8891
+ "div",
8892
+ {
8893
+ style: { padding: 12, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 300, overflow: "auto", marginBottom: 8 },
8894
+ dangerouslySetInnerHTML: { __html: pastedHtml }
8895
+ }
8896
+ )
8860
8897
  ] }),
8861
8898
  /* @__PURE__ */ jsxs14("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
8862
8899
  /* @__PURE__ */ jsx24(
@@ -8873,8 +8910,8 @@ function InsertNotesDialog({
8873
8910
  {
8874
8911
  type: "button",
8875
8912
  onClick: handleInsert,
8876
- disabled: !finalHtml || isUploading,
8877
- style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: finalHtml && !isUploading ? 1 : 0.5 },
8913
+ disabled: !pastedHtml || isUploading,
8914
+ style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: pastedHtml && !isUploading ? 1 : 0.5 },
8878
8915
  children: isUploading ? "Processing..." : "Insert"
8879
8916
  }
8880
8917
  )
@@ -8887,13 +8924,13 @@ import { useLexicalComposerContext as useLexicalComposerContext22 } from "@lexic
8887
8924
  import { $wrapNodeInElement as $wrapNodeInElement5 } from "@lexical/utils";
8888
8925
  import {
8889
8926
  $createParagraphNode as $createParagraphNode8,
8890
- $insertNodes as $insertNodes5,
8927
+ $insertNodes as $insertNodes6,
8891
8928
  $isRootOrShadowRoot as $isRootOrShadowRoot5,
8892
8929
  COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR14,
8893
8930
  createCommand as createCommand14
8894
8931
  } from "lexical";
8895
8932
  import { useEffect as useEffect24, useState as useState19 } from "react";
8896
- import { Fragment as Fragment9, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
8933
+ import { Fragment as Fragment10, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
8897
8934
  var INSERT_POLL_COMMAND = createCommand14(
8898
8935
  "INSERT_POLL_COMMAND"
8899
8936
  );
@@ -8906,7 +8943,7 @@ function InsertPollDialog({
8906
8943
  activeEditor.dispatchCommand(INSERT_POLL_COMMAND, question);
8907
8944
  onClose();
8908
8945
  };
8909
- return /* @__PURE__ */ jsxs15(Fragment9, { children: [
8946
+ return /* @__PURE__ */ jsxs15(Fragment10, { children: [
8910
8947
  /* @__PURE__ */ jsx25(TextInput, { label: "Question", onChange: setQuestion, value: question }),
8911
8948
  /* @__PURE__ */ jsx25(DialogActions, { children: /* @__PURE__ */ jsx25(Button, { disabled: question.trim() === "", onClick, children: "Confirm" }) })
8912
8949
  ] });
@@ -8924,7 +8961,7 @@ function PollPlugin() {
8924
8961
  createPollOption(),
8925
8962
  createPollOption()
8926
8963
  ]);
8927
- $insertNodes5([pollNode]);
8964
+ $insertNodes6([pollNode]);
8928
8965
  if ($isRootOrShadowRoot5(pollNode.getParentOrThrow())) {
8929
8966
  $wrapNodeInElement5(pollNode, $createParagraphNode8).selectEnd();
8930
8967
  }
@@ -8940,7 +8977,7 @@ function PollPlugin() {
8940
8977
  import { useLexicalComposerContext as useLexicalComposerContext24 } from "@lexical/react/LexicalComposerContext";
8941
8978
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot8 } from "@lexical/utils";
8942
8979
  import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR15, createCommand as createCommand15 } from "lexical";
8943
- import { useCallback as useCallback14, useEffect as useEffect25, useMemo as useMemo10, useState as useState21 } from "react";
8980
+ import { useCallback as useCallback14, useEffect as useEffect25, useMemo as useMemo9, useState as useState21 } from "react";
8944
8981
 
8945
8982
  // src/nodes/RevisionNode.tsx
8946
8983
  import { $getNodeByKey as $getNodeByKey5 } from "lexical";
@@ -8950,7 +8987,7 @@ import {
8950
8987
  } from "@lexical/react/LexicalDecoratorBlockNode";
8951
8988
  import { useLexicalComposerContext as useLexicalComposerContext23 } from "@lexical/react/LexicalComposerContext";
8952
8989
  import { useLexicalEditable as useLexicalEditable2 } from "@lexical/react/useLexicalEditable";
8953
- import { useCallback as useCallback13, useMemo as useMemo9, useState as useState20 } from "react";
8990
+ import { useCallback as useCallback13, useMemo as useMemo8, useState as useState20 } from "react";
8954
8991
  import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
8955
8992
  function RevisionComponent({
8956
8993
  className,
@@ -8966,7 +9003,7 @@ function RevisionComponent({
8966
9003
  setItems(parseRevisionHtml(html));
8967
9004
  setIsEditing(true);
8968
9005
  }, [html]);
8969
- const preview = useMemo9(() => {
9006
+ const preview = useMemo8(() => {
8970
9007
  if (!isEditing) return "";
8971
9008
  const filtered = items.filter((i) => i.trim());
8972
9009
  return filtered.length > 0 ? convertRevision(filtered.join("\n")) : "";
@@ -9020,8 +9057,9 @@ function RevisionComponent({
9020
9057
  }
9021
9058
  ),
9022
9059
  /* @__PURE__ */ jsx26("div", { dangerouslySetInnerHTML: { __html: html } }),
9023
- isEditing && /* @__PURE__ */ jsx26(Modal, { onClose: cancelEdit, title: "Edit Revision Points", children: /* @__PURE__ */ jsxs16("div", { style: { minWidth: 500 }, children: [
9024
- items.map((item, index) => /* @__PURE__ */ jsxs16("div", { style: { display: "flex", gap: 4, marginBottom: 4, alignItems: "center" }, children: [
9060
+ isEditing && /* @__PURE__ */ jsx26(Modal, { onClose: cancelEdit, title: "Edit Revision Points", children: /* @__PURE__ */ jsxs16("div", { style: { minWidth: 500, display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
9061
+ /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflowY: "auto", paddingRight: 4, minHeight: 0 }, children: items.map((item, index) => /* @__PURE__ */ jsxs16("div", { style: { display: "flex", gap: 4, marginBottom: 4, alignItems: "center" }, children: [
9062
+ /* @__PURE__ */ jsx26("span", { style: { fontSize: 14, flexShrink: 0 }, children: "\u2705" }),
9025
9063
  /* @__PURE__ */ jsx26(
9026
9064
  "input",
9027
9065
  {
@@ -9041,23 +9079,25 @@ function RevisionComponent({
9041
9079
  children: "\xD7"
9042
9080
  }
9043
9081
  )
9044
- ] }, index)),
9045
- /* @__PURE__ */ jsx26(
9046
- "button",
9047
- {
9048
- type: "button",
9049
- onClick: addItem,
9050
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginTop: 4 },
9051
- children: "+ Add Point"
9052
- }
9053
- ),
9054
- preview && /* @__PURE__ */ jsxs16("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 200, overflow: "auto" }, children: [
9055
- /* @__PURE__ */ jsx26("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9056
- /* @__PURE__ */ jsx26("div", { dangerouslySetInnerHTML: { __html: preview } })
9057
- ] }),
9058
- /* @__PURE__ */ jsxs16("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 12 }, children: [
9059
- /* @__PURE__ */ jsx26("button", { type: "button", onClick: cancelEdit, style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" }, children: "Cancel" }),
9060
- /* @__PURE__ */ jsx26("button", { type: "button", onClick: saveChanges, disabled: !preview, style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 }, children: "Save" })
9082
+ ] }, index)) }),
9083
+ /* @__PURE__ */ jsxs16("div", { style: { flexShrink: 0, paddingTop: 8 }, children: [
9084
+ /* @__PURE__ */ jsx26(
9085
+ "button",
9086
+ {
9087
+ type: "button",
9088
+ onClick: addItem,
9089
+ style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginBottom: 8 },
9090
+ children: "+ Add Point"
9091
+ }
9092
+ ),
9093
+ preview && /* @__PURE__ */ jsxs16("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 150, overflow: "auto" }, children: [
9094
+ /* @__PURE__ */ jsx26("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9095
+ /* @__PURE__ */ jsx26("div", { dangerouslySetInnerHTML: { __html: preview } })
9096
+ ] }),
9097
+ /* @__PURE__ */ jsxs16("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
9098
+ /* @__PURE__ */ jsx26("button", { type: "button", onClick: cancelEdit, style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" }, children: "Cancel" }),
9099
+ /* @__PURE__ */ jsx26("button", { type: "button", onClick: saveChanges, disabled: !preview, style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 }, children: "Save" })
9100
+ ] })
9061
9101
  ] })
9062
9102
  ] }) })
9063
9103
  ] }) });
@@ -9164,7 +9204,7 @@ function InsertRevisionDialog({
9164
9204
  onClose
9165
9205
  }) {
9166
9206
  const [input, setInput] = useState21("");
9167
- const preview = useMemo10(() => {
9207
+ const preview = useMemo9(() => {
9168
9208
  if (!input.trim()) return "";
9169
9209
  return convertRevision(input);
9170
9210
  }, [input]);
@@ -9225,7 +9265,7 @@ function InsertRevisionDialog({
9225
9265
  import { useLexicalComposerContext as useLexicalComposerContext26 } from "@lexical/react/LexicalComposerContext";
9226
9266
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot9 } from "@lexical/utils";
9227
9267
  import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR16, createCommand as createCommand16 } from "lexical";
9228
- import { useCallback as useCallback16, useEffect as useEffect26, useMemo as useMemo12, useState as useState23 } from "react";
9268
+ import { useCallback as useCallback16, useEffect as useEffect26, useMemo as useMemo11, useState as useState23 } from "react";
9229
9269
 
9230
9270
  // src/nodes/TerminologyNode.tsx
9231
9271
  import { $getNodeByKey as $getNodeByKey6 } from "lexical";
@@ -9235,7 +9275,7 @@ import {
9235
9275
  } from "@lexical/react/LexicalDecoratorBlockNode";
9236
9276
  import { useLexicalComposerContext as useLexicalComposerContext25 } from "@lexical/react/LexicalComposerContext";
9237
9277
  import { useLexicalEditable as useLexicalEditable3 } from "@lexical/react/useLexicalEditable";
9238
- import { useCallback as useCallback15, useMemo as useMemo11, useState as useState22 } from "react";
9278
+ import { useCallback as useCallback15, useMemo as useMemo10, useState as useState22 } from "react";
9239
9279
  import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
9240
9280
  function TerminologyComponent({
9241
9281
  className,
@@ -9251,7 +9291,7 @@ function TerminologyComponent({
9251
9291
  setItems(parseTerminologyHtml(html));
9252
9292
  setIsEditing(true);
9253
9293
  }, [html]);
9254
- const preview = useMemo11(() => {
9294
+ const preview = useMemo10(() => {
9255
9295
  if (!isEditing) return "";
9256
9296
  const text = items.filter((i) => i.term || i.definition).map((i) => i.term ? `${i.term}: ${i.definition}` : i.definition).join("\n");
9257
9297
  return text ? convertTerminology(text) : "";
@@ -9307,8 +9347,8 @@ function TerminologyComponent({
9307
9347
  ),
9308
9348
  /* @__PURE__ */ jsx28("div", { dangerouslySetInnerHTML: { __html: html } })
9309
9349
  ] }),
9310
- isEditing && /* @__PURE__ */ jsx28(Modal, { onClose: cancelEdit, title: "Edit Terminology", children: /* @__PURE__ */ jsxs18("div", { style: { minWidth: 500 }, children: [
9311
- items.map((item, index) => /* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: 4, marginBottom: 4, alignItems: "center" }, children: [
9350
+ isEditing && /* @__PURE__ */ jsx28(Modal, { onClose: cancelEdit, title: "Edit Terminology", children: /* @__PURE__ */ jsxs18("div", { style: { minWidth: 500, display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
9351
+ /* @__PURE__ */ jsx28("div", { style: { flex: 1, overflowY: "auto", paddingRight: 4, minHeight: 0 }, children: items.map((item, index) => /* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: 4, marginBottom: 4, alignItems: "center" }, children: [
9312
9352
  /* @__PURE__ */ jsx28(
9313
9353
  "input",
9314
9354
  {
@@ -9338,40 +9378,42 @@ function TerminologyComponent({
9338
9378
  children: "\xD7"
9339
9379
  }
9340
9380
  )
9341
- ] }, index)),
9342
- /* @__PURE__ */ jsx28(
9343
- "button",
9344
- {
9345
- type: "button",
9346
- onClick: addItem,
9347
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginTop: 4, marginBottom: 8 },
9348
- children: "+ Add Term"
9349
- }
9350
- ),
9351
- preview && /* @__PURE__ */ jsxs18("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 200, overflow: "auto" }, children: [
9352
- /* @__PURE__ */ jsx28("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9353
- /* @__PURE__ */ jsx28("div", { dangerouslySetInnerHTML: { __html: preview } })
9354
- ] }),
9355
- /* @__PURE__ */ jsxs18("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
9381
+ ] }, index)) }),
9382
+ /* @__PURE__ */ jsxs18("div", { style: { flexShrink: 0, paddingTop: 8 }, children: [
9356
9383
  /* @__PURE__ */ jsx28(
9357
9384
  "button",
9358
9385
  {
9359
9386
  type: "button",
9360
- onClick: cancelEdit,
9361
- style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" },
9362
- children: "Cancel"
9387
+ onClick: addItem,
9388
+ style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginBottom: 8 },
9389
+ children: "+ Add Term"
9363
9390
  }
9364
9391
  ),
9365
- /* @__PURE__ */ jsx28(
9366
- "button",
9367
- {
9368
- type: "button",
9369
- onClick: saveChanges,
9370
- disabled: !preview,
9371
- style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 },
9372
- children: "Save"
9373
- }
9374
- )
9392
+ preview && /* @__PURE__ */ jsxs18("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 150, overflow: "auto" }, children: [
9393
+ /* @__PURE__ */ jsx28("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9394
+ /* @__PURE__ */ jsx28("div", { dangerouslySetInnerHTML: { __html: preview } })
9395
+ ] }),
9396
+ /* @__PURE__ */ jsxs18("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
9397
+ /* @__PURE__ */ jsx28(
9398
+ "button",
9399
+ {
9400
+ type: "button",
9401
+ onClick: cancelEdit,
9402
+ style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" },
9403
+ children: "Cancel"
9404
+ }
9405
+ ),
9406
+ /* @__PURE__ */ jsx28(
9407
+ "button",
9408
+ {
9409
+ type: "button",
9410
+ onClick: saveChanges,
9411
+ disabled: !preview,
9412
+ style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 },
9413
+ children: "Save"
9414
+ }
9415
+ )
9416
+ ] })
9375
9417
  ] })
9376
9418
  ] }) })
9377
9419
  ] });
@@ -9478,7 +9520,7 @@ function InsertTerminologyDialog({
9478
9520
  onClose
9479
9521
  }) {
9480
9522
  const [input, setInput] = useState23("");
9481
- const preview = useMemo12(() => {
9523
+ const preview = useMemo11(() => {
9482
9524
  if (!input.trim()) return "";
9483
9525
  return convertTerminology(input);
9484
9526
  }, [input]);
@@ -9539,7 +9581,7 @@ function InsertTerminologyDialog({
9539
9581
  import { useLexicalComposerContext as useLexicalComposerContext28 } from "@lexical/react/LexicalComposerContext";
9540
9582
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot10 } from "@lexical/utils";
9541
9583
  import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR17, createCommand as createCommand17 } from "lexical";
9542
- import { useCallback as useCallback19, useEffect as useEffect27, useMemo as useMemo14, useState as useState26 } from "react";
9584
+ import { useCallback as useCallback19, useEffect as useEffect27, useMemo as useMemo13, useState as useState26 } from "react";
9543
9585
 
9544
9586
  // src/nodes/TextCardsNode.tsx
9545
9587
  import { $getNodeByKey as $getNodeByKey7 } from "lexical";
@@ -9549,7 +9591,7 @@ import {
9549
9591
  } from "@lexical/react/LexicalDecoratorBlockNode";
9550
9592
  import { useLexicalComposerContext as useLexicalComposerContext27 } from "@lexical/react/LexicalComposerContext";
9551
9593
  import { useLexicalEditable as useLexicalEditable4 } from "@lexical/react/useLexicalEditable";
9552
- import { useCallback as useCallback17, useMemo as useMemo13, useState as useState24 } from "react";
9594
+ import { useCallback as useCallback17, useMemo as useMemo12, useState as useState24 } from "react";
9553
9595
  import { jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
9554
9596
  var SECTION_KEYS = [
9555
9597
  "criticalThinking",
@@ -9587,7 +9629,7 @@ function TextCardsComponent({
9587
9629
  setConcepts(parsed);
9588
9630
  setIsEditing(true);
9589
9631
  }, [html]);
9590
- const preview = useMemo13(() => {
9632
+ const preview = useMemo12(() => {
9591
9633
  if (!isEditing) return "";
9592
9634
  const lines = [];
9593
9635
  concepts.forEach((concept, i) => {
@@ -9674,8 +9716,8 @@ function TextCardsComponent({
9674
9716
  }
9675
9717
  ),
9676
9718
  /* @__PURE__ */ jsx30("div", { dangerouslySetInnerHTML: { __html: html } }),
9677
- isEditing && /* @__PURE__ */ jsx30(Modal, { onClose: cancelEdit, title: "Edit Text Cards", children: /* @__PURE__ */ jsxs20("div", { style: { minWidth: 500 }, children: [
9678
- concepts.map((concept, cIdx) => /* @__PURE__ */ jsxs20("div", { style: { border: "1px solid #e5e7eb", borderRadius: 6, padding: 8, marginBottom: 8, background: "#fff" }, children: [
9719
+ isEditing && /* @__PURE__ */ jsx30(Modal, { onClose: cancelEdit, title: "Edit Text Cards", children: /* @__PURE__ */ jsxs20("div", { style: { minWidth: 500, display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
9720
+ /* @__PURE__ */ jsx30("div", { style: { flex: 1, overflowY: "auto", paddingRight: 4, minHeight: 0 }, children: concepts.map((concept, cIdx) => /* @__PURE__ */ jsxs20("div", { style: { border: "1px solid #e5e7eb", borderRadius: 6, padding: 8, marginBottom: 8, background: "#fff" }, children: [
9679
9721
  /* @__PURE__ */ jsxs20("div", { style: { display: "flex", gap: 4, marginBottom: 6, alignItems: "center" }, children: [
9680
9722
  /* @__PURE__ */ jsxs20("span", { style: { fontSize: 12, fontWeight: 600, color: "#4caf50", minWidth: 80 }, children: [
9681
9723
  "Concept ",
@@ -9718,23 +9760,25 @@ function TextCardsComponent({
9718
9760
  )
9719
9761
  ] }, sIdx);
9720
9762
  })
9721
- ] }, cIdx)),
9722
- /* @__PURE__ */ jsx30(
9723
- "button",
9724
- {
9725
- type: "button",
9726
- onClick: addConcept,
9727
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginTop: 4 },
9728
- children: "+ Add Concept"
9729
- }
9730
- ),
9731
- preview && /* @__PURE__ */ jsxs20("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 200, overflow: "auto" }, children: [
9732
- /* @__PURE__ */ jsx30("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9733
- /* @__PURE__ */ jsx30("div", { dangerouslySetInnerHTML: { __html: preview } })
9734
- ] }),
9735
- /* @__PURE__ */ jsxs20("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 12 }, children: [
9736
- /* @__PURE__ */ jsx30("button", { type: "button", onClick: cancelEdit, style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" }, children: "Cancel" }),
9737
- /* @__PURE__ */ jsx30("button", { type: "button", onClick: saveChanges, disabled: !preview, style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 }, children: "Save" })
9763
+ ] }, cIdx)) }),
9764
+ /* @__PURE__ */ jsxs20("div", { style: { flexShrink: 0, paddingTop: 8 }, children: [
9765
+ /* @__PURE__ */ jsx30(
9766
+ "button",
9767
+ {
9768
+ type: "button",
9769
+ onClick: addConcept,
9770
+ style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginBottom: 8 },
9771
+ children: "+ Add Concept"
9772
+ }
9773
+ ),
9774
+ preview && /* @__PURE__ */ jsxs20("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 150, overflow: "auto" }, children: [
9775
+ /* @__PURE__ */ jsx30("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9776
+ /* @__PURE__ */ jsx30("div", { dangerouslySetInnerHTML: { __html: preview } })
9777
+ ] }),
9778
+ /* @__PURE__ */ jsxs20("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
9779
+ /* @__PURE__ */ jsx30("button", { type: "button", onClick: cancelEdit, style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" }, children: "Cancel" }),
9780
+ /* @__PURE__ */ jsx30("button", { type: "button", onClick: saveChanges, disabled: !preview, style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 }, children: "Save" })
9781
+ ] })
9738
9782
  ] })
9739
9783
  ] }) })
9740
9784
  ] }) });
@@ -9942,7 +9986,7 @@ function useRichPaste(onText, baasixClient, folder) {
9942
9986
  }
9943
9987
 
9944
9988
  // src/plugins/TextCardsPlugin/index.tsx
9945
- import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
9989
+ import { Fragment as Fragment11, jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
9946
9990
  var INSERT_TEXT_CARDS_COMMAND = createCommand17(
9947
9991
  "INSERT_TEXT_CARDS_COMMAND"
9948
9992
  );
@@ -9969,17 +10013,25 @@ function InsertTextCardsDialog({
9969
10013
  onClose
9970
10014
  }) {
9971
10015
  const [input, setInput] = useState26("");
10016
+ const [hasPasted, setHasPasted] = useState26(false);
9972
10017
  let editorConfig = null;
9973
10018
  try {
9974
10019
  editorConfig = useEditorConfig();
9975
10020
  } catch {
9976
10021
  }
9977
10022
  const richPaste = useRichPaste(
9978
- (text) => setInput((prev) => prev ? prev + "\n" + text : text),
10023
+ (text) => {
10024
+ setInput((prev) => prev ? prev + "\n" + text : text);
10025
+ setHasPasted(true);
10026
+ },
9979
10027
  editorConfig?.baasixClient,
9980
10028
  editorConfig?.folder
9981
10029
  );
9982
- const finalHtml = useMemo14(() => {
10030
+ const handleClear = useCallback19(() => {
10031
+ setInput("");
10032
+ setHasPasted(false);
10033
+ }, []);
10034
+ const finalHtml = useMemo13(() => {
9983
10035
  if (!input.trim()) return "";
9984
10036
  const html = convertTextCards(input);
9985
10037
  return richPaste.replaceImagePlaceholders(html);
@@ -9990,70 +10042,60 @@ function InsertTextCardsDialog({
9990
10042
  onClose();
9991
10043
  }, [activeEditor, finalHtml, onClose]);
9992
10044
  return /* @__PURE__ */ jsxs21("div", { style: { minWidth: 500 }, children: [
9993
- /* @__PURE__ */ jsx31(
9994
- "textarea",
9995
- {
9996
- value: input,
9997
- onChange: (e) => setInput(e.target.value),
9998
- placeholder: `Paste concept content here...
9999
- Example:
10000
- CONCEPT 1: DIAGNOSTIC REASONING
10001
-
10002
- Critical Thinking Element
10003
- Pathologists must synthesize clinical history...
10004
-
10005
- Clinical Application
10006
- When examining a tissue specimen...
10007
-
10008
- Example
10009
- A 45-year-old presents with hemoptysis...
10010
-
10011
- Rationalization
10012
- Differential diagnosis prevents anchoring bias...
10013
-
10014
- Critical Insight
10015
- Pathology bridges clinical suspicion with molecular certainty...`,
10016
- style: {
10017
- width: "100%",
10018
- minHeight: 150,
10019
- fontFamily: "monospace",
10020
- fontSize: 13,
10021
- padding: 8,
10022
- border: "1px solid #ddd",
10023
- borderRadius: 4,
10024
- resize: "vertical",
10025
- marginBottom: 8
10026
- }
10027
- }
10028
- ),
10029
- /* @__PURE__ */ jsx31(
10045
+ !hasPasted && /* @__PURE__ */ jsx31(
10030
10046
  "div",
10031
10047
  {
10032
10048
  ref: richPaste.pasteAreaRef,
10033
10049
  contentEditable: true,
10034
10050
  onPaste: richPaste.handlePaste,
10035
10051
  onMouseDown: (e) => e.stopPropagation(),
10052
+ "data-placeholder": richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support",
10036
10053
  style: {
10037
10054
  width: "100%",
10038
- minHeight: 40,
10039
- padding: 8,
10055
+ minHeight: 160,
10056
+ padding: 12,
10040
10057
  border: "2px dashed #93c5fd",
10041
10058
  borderRadius: 4,
10042
- fontSize: 12,
10059
+ fontSize: 13,
10043
10060
  color: "#6b7280",
10044
10061
  marginBottom: 8,
10045
10062
  outline: "none",
10046
10063
  background: "#f0f7ff"
10047
10064
  },
10048
- suppressContentEditableWarning: true,
10049
- children: /* @__PURE__ */ jsx31("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support" })
10065
+ suppressContentEditableWarning: true
10050
10066
  }
10051
10067
  ),
10052
- richPaste.images.length > 0 && /* @__PURE__ */ jsxs21("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: [
10053
- richPaste.images.length,
10054
- " image",
10055
- richPaste.images.length > 1 ? "s" : "",
10056
- " captured"
10068
+ hasPasted && /* @__PURE__ */ jsxs21(Fragment11, { children: [
10069
+ /* @__PURE__ */ jsxs21("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }, children: [
10070
+ /* @__PURE__ */ jsx31("span", { style: { fontSize: 11, color: "#6b7280" }, children: "Edit content" }),
10071
+ /* @__PURE__ */ jsx31(
10072
+ "button",
10073
+ {
10074
+ type: "button",
10075
+ onClick: handleClear,
10076
+ style: { padding: "2px 10px", fontSize: 12, border: "1px solid #fca5a5", borderRadius: 4, background: "#fff", color: "#ef4444", cursor: "pointer" },
10077
+ children: "Clear"
10078
+ }
10079
+ )
10080
+ ] }),
10081
+ /* @__PURE__ */ jsx31(
10082
+ "textarea",
10083
+ {
10084
+ value: input,
10085
+ onChange: (e) => setInput(e.target.value),
10086
+ style: {
10087
+ width: "100%",
10088
+ minHeight: 150,
10089
+ fontFamily: "monospace",
10090
+ fontSize: 13,
10091
+ padding: 8,
10092
+ border: "1px solid #ddd",
10093
+ borderRadius: 4,
10094
+ resize: "vertical",
10095
+ marginBottom: 8
10096
+ }
10097
+ }
10098
+ )
10057
10099
  ] }),
10058
10100
  finalHtml && /* @__PURE__ */ jsxs21("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 250, overflow: "auto" }, children: [
10059
10101
  /* @__PURE__ */ jsx31("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
@@ -10087,7 +10129,7 @@ Pathology bridges clinical suspicion with molecular certainty...`,
10087
10129
  import { useLexicalComposerContext as useLexicalComposerContext30 } from "@lexical/react/LexicalComposerContext";
10088
10130
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot11 } from "@lexical/utils";
10089
10131
  import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR18, createCommand as createCommand18 } from "lexical";
10090
- import { useCallback as useCallback21, useEffect as useEffect28, useMemo as useMemo16, useState as useState28 } from "react";
10132
+ import { useCallback as useCallback21, useEffect as useEffect29, useMemo as useMemo15, useState as useState28 } from "react";
10091
10133
 
10092
10134
  // src/nodes/QuestionsCardsNode.tsx
10093
10135
  import { $getNodeByKey as $getNodeByKey8 } from "lexical";
@@ -10097,8 +10139,53 @@ import {
10097
10139
  } from "@lexical/react/LexicalDecoratorBlockNode";
10098
10140
  import { useLexicalComposerContext as useLexicalComposerContext29 } from "@lexical/react/LexicalComposerContext";
10099
10141
  import { useLexicalEditable as useLexicalEditable5 } from "@lexical/react/useLexicalEditable";
10100
- import { useCallback as useCallback20, useMemo as useMemo15, useState as useState27 } from "react";
10142
+ import { useCallback as useCallback20, useEffect as useEffect28, useMemo as useMemo14, useRef as useRef11, useState as useState27 } from "react";
10101
10143
  import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
10144
+ var PLACEHOLDER = "Paste from Word/Docs here for image support...";
10145
+ function HtmlEditableField({
10146
+ initialHtml,
10147
+ onCommit,
10148
+ minHeight = 40
10149
+ }) {
10150
+ const ref = useRef11(null);
10151
+ useEffect28(() => {
10152
+ if (ref.current) {
10153
+ ref.current.innerHTML = initialHtml;
10154
+ }
10155
+ }, []);
10156
+ const isEmpty = (el) => {
10157
+ const h = el.innerHTML;
10158
+ return h === "" || h === "<br>";
10159
+ };
10160
+ return /* @__PURE__ */ jsx32(
10161
+ "div",
10162
+ {
10163
+ ref,
10164
+ contentEditable: true,
10165
+ suppressContentEditableWarning: true,
10166
+ "data-placeholder": PLACEHOLDER,
10167
+ onBlur: (e) => {
10168
+ const el = e.currentTarget;
10169
+ if (isEmpty(el)) {
10170
+ el.innerHTML = "";
10171
+ onCommit("");
10172
+ } else {
10173
+ onCommit(el.innerHTML);
10174
+ }
10175
+ },
10176
+ style: {
10177
+ width: "100%",
10178
+ padding: "4px 6px",
10179
+ fontSize: 12,
10180
+ border: "1px solid #ddd",
10181
+ borderRadius: 4,
10182
+ minHeight,
10183
+ outline: "none",
10184
+ boxSizing: "border-box"
10185
+ }
10186
+ }
10187
+ );
10188
+ }
10102
10189
  var GRID_SECTION_KEYS = [
10103
10190
  "rubric",
10104
10191
  "mnemonics",
@@ -10121,9 +10208,9 @@ function QuestionsCardsComponent({
10121
10208
  const [isEditing, setIsEditing] = useState27(false);
10122
10209
  const [qaPairs, setQaPairs] = useState27([]);
10123
10210
  const makeEmptyQA = () => ({
10124
- question: "",
10125
- answer: "",
10126
- sections: GRID_SECTION_KEYS.map((k) => ({ key: k, content: "" }))
10211
+ questionHtml: "",
10212
+ answerHtml: "",
10213
+ sections: GRID_SECTION_KEYS.map((k) => ({ key: k, contentHtml: "" }))
10127
10214
  });
10128
10215
  const openEditor = useCallback20(() => {
10129
10216
  const parsed = parseQuestionsCardsHtml(html);
@@ -10131,30 +10218,22 @@ function QuestionsCardsComponent({
10131
10218
  const existing = qa.sections || [];
10132
10219
  const all = GRID_SECTION_KEYS.map((k) => {
10133
10220
  const found = existing.find((s) => s.key === k);
10134
- return found || { key: k, content: "" };
10221
+ return { key: k, contentHtml: found ? found.content : "" };
10135
10222
  });
10136
- return { question: qa.question, answer: qa.answer, sections: all };
10223
+ return { questionHtml: qa.question, answerHtml: qa.answer, sections: all };
10137
10224
  });
10138
10225
  setQaPairs(pairs.length > 0 ? pairs : [makeEmptyQA()]);
10139
10226
  setIsEditing(true);
10140
10227
  }, [html]);
10141
- const preview = useMemo15(() => {
10228
+ const preview = useMemo14(() => {
10142
10229
  if (!isEditing) return "";
10143
- const cStyles = CARD_STYLES.questionsCards;
10144
- const lines = [];
10145
- qaPairs.forEach((qa, idx) => {
10146
- if (qa.question) lines.push(`${idx + 1}. Question: ${qa.question}`);
10147
- if (qa.answer) lines.push(`Answer: ${qa.answer}`);
10148
- qa.sections.forEach((s) => {
10149
- const sStyle = cStyles[s.key];
10150
- if (sStyle && "title" in sStyle && s.content) {
10151
- lines.push(sStyle.title);
10152
- lines.push(s.content);
10153
- }
10154
- });
10155
- });
10156
- const text = lines.join("\n");
10157
- return text.trim() ? convertQuestionsCards(text) : "";
10230
+ const hasContent = qaPairs.some((qa) => qa.questionHtml || qa.answerHtml || qa.sections.some((s) => s.contentHtml));
10231
+ if (!hasContent) return "";
10232
+ return buildQuestionsCardsHtml(qaPairs.map((qa) => ({
10233
+ question: qa.questionHtml,
10234
+ answer: qa.answerHtml,
10235
+ sections: qa.sections.map((s) => ({ key: s.key, content: s.contentHtml }))
10236
+ })));
10158
10237
  }, [isEditing, qaPairs]);
10159
10238
  const saveChanges = useCallback20(() => {
10160
10239
  if (!preview) return;
@@ -10169,7 +10248,7 @@ function QuestionsCardsComponent({
10169
10248
  const cancelEdit = useCallback20(() => {
10170
10249
  setIsEditing(false);
10171
10250
  }, []);
10172
- const updateQA = useCallback20((idx, field, value) => {
10251
+ const updateQAHtml = useCallback20((idx, field, value) => {
10173
10252
  setQaPairs((prev) => prev.map((qa, i) => i === idx ? { ...qa, [field]: value } : qa));
10174
10253
  }, []);
10175
10254
  const addQAPair = useCallback20(() => {
@@ -10178,10 +10257,10 @@ function QuestionsCardsComponent({
10178
10257
  const removeQAPair = useCallback20((idx) => {
10179
10258
  setQaPairs((prev) => prev.filter((_, i) => i !== idx));
10180
10259
  }, []);
10181
- const updateSection = useCallback20((qIdx, sIdx, value) => {
10260
+ const updateSectionHtml = useCallback20((qIdx, sIdx, value) => {
10182
10261
  setQaPairs((prev) => prev.map((qa, i) => {
10183
10262
  if (i !== qIdx) return qa;
10184
- return { ...qa, sections: qa.sections.map((s, j) => j === sIdx ? { ...s, content: value } : s) };
10263
+ return { ...qa, sections: qa.sections.map((s, j) => j === sIdx ? { ...s, contentHtml: value } : s) };
10185
10264
  }));
10186
10265
  }, []);
10187
10266
  const styles = CARD_STYLES.questionsCards;
@@ -10212,8 +10291,8 @@ function QuestionsCardsComponent({
10212
10291
  }
10213
10292
  ),
10214
10293
  /* @__PURE__ */ jsx32("div", { dangerouslySetInnerHTML: { __html: html } }),
10215
- isEditing && /* @__PURE__ */ jsx32(Modal, { onClose: cancelEdit, title: "Edit Questions Card", children: /* @__PURE__ */ jsxs22("div", { style: { minWidth: 500 }, children: [
10216
- qaPairs.map((qa, qIdx) => /* @__PURE__ */ jsxs22("div", { style: { border: "1px solid #e5e7eb", borderRadius: 6, padding: 8, marginBottom: 8, background: "#fff" }, children: [
10294
+ isEditing && /* @__PURE__ */ jsx32(Modal, { onClose: cancelEdit, title: "Edit Questions Card", children: /* @__PURE__ */ jsxs22("div", { style: { minWidth: 500, display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
10295
+ /* @__PURE__ */ jsx32("div", { style: { flex: 1, overflowY: "auto", paddingRight: 4, minHeight: 0 }, children: qaPairs.map((qa, qIdx) => /* @__PURE__ */ jsxs22("div", { style: { border: "1px solid #e5e7eb", borderRadius: 6, padding: 8, marginBottom: 8, background: "#fff" }, children: [
10217
10296
  /* @__PURE__ */ jsxs22("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }, children: [
10218
10297
  /* @__PURE__ */ jsxs22("span", { style: { fontSize: 12, fontWeight: 600, color: "#1976d2" }, children: [
10219
10298
  "Q",
@@ -10232,25 +10311,25 @@ function QuestionsCardsComponent({
10232
10311
  /* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
10233
10312
  /* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#1976d2", fontWeight: 600, display: "block", marginBottom: 2 }, children: "Question" }),
10234
10313
  /* @__PURE__ */ jsx32(
10235
- "textarea",
10314
+ HtmlEditableField,
10236
10315
  {
10237
- placeholder: "Enter question text...",
10238
- value: qa.question,
10239
- onChange: (e) => updateQA(qIdx, "question", e.target.value),
10240
- style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 40, resize: "vertical" }
10241
- }
10316
+ initialHtml: qa.questionHtml,
10317
+ onCommit: (v) => updateQAHtml(qIdx, "questionHtml", v),
10318
+ minHeight: 40
10319
+ },
10320
+ `q-${qIdx}-question`
10242
10321
  )
10243
10322
  ] }),
10244
10323
  /* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
10245
10324
  /* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#666", fontWeight: 600, display: "block", marginBottom: 2 }, children: "Answer" }),
10246
10325
  /* @__PURE__ */ jsx32(
10247
- "textarea",
10326
+ HtmlEditableField,
10248
10327
  {
10249
- placeholder: "Enter answer text...",
10250
- value: qa.answer,
10251
- onChange: (e) => updateQA(qIdx, "answer", e.target.value),
10252
- style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 60, resize: "vertical" }
10253
- }
10328
+ initialHtml: qa.answerHtml,
10329
+ onCommit: (v) => updateQAHtml(qIdx, "answerHtml", v),
10330
+ minHeight: 60
10331
+ },
10332
+ `q-${qIdx}-answer`
10254
10333
  )
10255
10334
  ] }),
10256
10335
  /* @__PURE__ */ jsxs22("details", { style: { marginTop: 4 }, children: [
@@ -10261,34 +10340,36 @@ function QuestionsCardsComponent({
10261
10340
  return /* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
10262
10341
  /* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#666", display: "block", marginBottom: 2 }, children: label }),
10263
10342
  /* @__PURE__ */ jsx32(
10264
- "textarea",
10343
+ HtmlEditableField,
10265
10344
  {
10266
- placeholder: `${label} content...`,
10267
- value: section.content,
10268
- onChange: (e) => updateSection(qIdx, sIdx, e.target.value),
10269
- style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 40, resize: "vertical" }
10270
- }
10345
+ initialHtml: section.contentHtml,
10346
+ onCommit: (v) => updateSectionHtml(qIdx, sIdx, v),
10347
+ minHeight: 40
10348
+ },
10349
+ `q-${qIdx}-s-${sIdx}`
10271
10350
  )
10272
10351
  ] }, sIdx);
10273
10352
  }) })
10274
10353
  ] })
10275
- ] }, qIdx)),
10276
- /* @__PURE__ */ jsx32(
10277
- "button",
10278
- {
10279
- type: "button",
10280
- onClick: addQAPair,
10281
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginBottom: 8 },
10282
- children: "+ Add Question"
10283
- }
10284
- ),
10285
- preview && /* @__PURE__ */ jsxs22("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 200, overflow: "auto" }, children: [
10286
- /* @__PURE__ */ jsx32("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
10287
- /* @__PURE__ */ jsx32("div", { dangerouslySetInnerHTML: { __html: preview } })
10288
- ] }),
10289
- /* @__PURE__ */ jsxs22("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 12 }, children: [
10290
- /* @__PURE__ */ jsx32("button", { type: "button", onClick: cancelEdit, style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" }, children: "Cancel" }),
10291
- /* @__PURE__ */ jsx32("button", { type: "button", onClick: saveChanges, disabled: !preview, style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 }, children: "Save" })
10354
+ ] }, qIdx)) }),
10355
+ /* @__PURE__ */ jsxs22("div", { style: { flexShrink: 0, paddingTop: 8 }, children: [
10356
+ /* @__PURE__ */ jsx32(
10357
+ "button",
10358
+ {
10359
+ type: "button",
10360
+ onClick: addQAPair,
10361
+ style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginBottom: 8 },
10362
+ children: "+ Add Question"
10363
+ }
10364
+ ),
10365
+ preview && /* @__PURE__ */ jsxs22("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 150, overflow: "auto" }, children: [
10366
+ /* @__PURE__ */ jsx32("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
10367
+ /* @__PURE__ */ jsx32("div", { dangerouslySetInnerHTML: { __html: preview } })
10368
+ ] }),
10369
+ /* @__PURE__ */ jsxs22("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
10370
+ /* @__PURE__ */ jsx32("button", { type: "button", onClick: cancelEdit, style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" }, children: "Cancel" }),
10371
+ /* @__PURE__ */ jsx32("button", { type: "button", onClick: saveChanges, disabled: !preview, style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 }, children: "Save" })
10372
+ ] })
10292
10373
  ] })
10293
10374
  ] }) })
10294
10375
  ] }) });
@@ -10368,13 +10449,13 @@ function $isQuestionsCardsNode(node) {
10368
10449
  }
10369
10450
 
10370
10451
  // src/plugins/QuestionsCardsPlugin/index.tsx
10371
- import { jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
10452
+ import { Fragment as Fragment12, jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
10372
10453
  var INSERT_QUESTIONS_CARDS_COMMAND = createCommand18(
10373
10454
  "INSERT_QUESTIONS_CARDS_COMMAND"
10374
10455
  );
10375
10456
  function QuestionsCardsPlugin() {
10376
10457
  const [editor] = useLexicalComposerContext30();
10377
- useEffect28(() => {
10458
+ useEffect29(() => {
10378
10459
  if (!editor.hasNodes([QuestionsCardsNode])) {
10379
10460
  throw new Error("QuestionsCardsPlugin: QuestionsCardsNode not registered on editor");
10380
10461
  }
@@ -10395,17 +10476,25 @@ function InsertQuestionsCardsDialog({
10395
10476
  onClose
10396
10477
  }) {
10397
10478
  const [input, setInput] = useState28("");
10479
+ const [hasPasted, setHasPasted] = useState28(false);
10398
10480
  let editorConfig = null;
10399
10481
  try {
10400
10482
  editorConfig = useEditorConfig();
10401
10483
  } catch {
10402
10484
  }
10403
10485
  const richPaste = useRichPaste(
10404
- (text) => setInput((prev) => prev ? prev + "\n" + text : text),
10486
+ (text) => {
10487
+ setInput((prev) => prev ? prev + "\n" + text : text);
10488
+ setHasPasted(true);
10489
+ },
10405
10490
  editorConfig?.baasixClient,
10406
10491
  editorConfig?.folder
10407
10492
  );
10408
- const finalHtml = useMemo16(() => {
10493
+ const handleClear = useCallback21(() => {
10494
+ setInput("");
10495
+ setHasPasted(false);
10496
+ }, []);
10497
+ const finalHtml = useMemo15(() => {
10409
10498
  if (!input.trim()) return "";
10410
10499
  const html = convertQuestionsCards(input);
10411
10500
  return richPaste.replaceImagePlaceholders(html);
@@ -10416,36 +10505,7 @@ function InsertQuestionsCardsDialog({
10416
10505
  onClose();
10417
10506
  }, [activeEditor, finalHtml, onClose]);
10418
10507
  return /* @__PURE__ */ jsxs23("div", { style: { minWidth: 500 }, children: [
10419
- /* @__PURE__ */ jsx33(
10420
- "textarea",
10421
- {
10422
- value: input,
10423
- onChange: (e) => setInput(e.target.value),
10424
- placeholder: `Paste question content here...
10425
- Example:
10426
- Q1 : Describe the pathogenesis of tuberculosis.
10427
-
10428
- Answer: Tuberculosis is caused by Mycobacterium tuberculosis...
10429
-
10430
- 1. MARKING RUBRIC
10431
- Definition: 2 marks, Pathogenesis: 5 marks...
10432
-
10433
- 2. MNEMONICS
10434
- Remember TB pathogenesis with "IGRA"...`,
10435
- style: {
10436
- width: "100%",
10437
- minHeight: 150,
10438
- fontFamily: "monospace",
10439
- fontSize: 13,
10440
- padding: 8,
10441
- border: "1px solid #ddd",
10442
- borderRadius: 4,
10443
- resize: "vertical",
10444
- marginBottom: 8
10445
- }
10446
- }
10447
- ),
10448
- /* @__PURE__ */ jsx33(
10508
+ !hasPasted && /* @__PURE__ */ jsx33(
10449
10509
  "div",
10450
10510
  {
10451
10511
  ref: richPaste.pasteAreaRef,
@@ -10454,25 +10514,51 @@ Remember TB pathogenesis with "IGRA"...`,
10454
10514
  onMouseDown: (e) => e.stopPropagation(),
10455
10515
  style: {
10456
10516
  width: "100%",
10457
- minHeight: 40,
10458
- padding: 8,
10517
+ minHeight: 160,
10518
+ padding: 12,
10459
10519
  border: "2px dashed #93c5fd",
10460
10520
  borderRadius: 4,
10461
- fontSize: 12,
10521
+ fontSize: 13,
10462
10522
  color: "#6b7280",
10463
10523
  marginBottom: 8,
10464
10524
  outline: "none",
10465
10525
  background: "#f0f7ff"
10466
10526
  },
10467
- suppressContentEditableWarning: true,
10468
- children: /* @__PURE__ */ jsx33("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support" })
10527
+ "data-placeholder": richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support",
10528
+ suppressContentEditableWarning: true
10469
10529
  }
10470
10530
  ),
10471
- richPaste.images.length > 0 && /* @__PURE__ */ jsxs23("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: [
10472
- richPaste.images.length,
10473
- " image",
10474
- richPaste.images.length > 1 ? "s" : "",
10475
- " captured"
10531
+ hasPasted && /* @__PURE__ */ jsxs23(Fragment12, { children: [
10532
+ /* @__PURE__ */ jsxs23("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }, children: [
10533
+ /* @__PURE__ */ jsx33("span", { style: { fontSize: 11, color: "#6b7280" }, children: "Edit content" }),
10534
+ /* @__PURE__ */ jsx33(
10535
+ "button",
10536
+ {
10537
+ type: "button",
10538
+ onClick: handleClear,
10539
+ style: { padding: "2px 10px", fontSize: 12, border: "1px solid #fca5a5", borderRadius: 4, background: "#fff", color: "#ef4444", cursor: "pointer" },
10540
+ children: "Clear"
10541
+ }
10542
+ )
10543
+ ] }),
10544
+ /* @__PURE__ */ jsx33(
10545
+ "textarea",
10546
+ {
10547
+ value: input,
10548
+ onChange: (e) => setInput(e.target.value),
10549
+ style: {
10550
+ width: "100%",
10551
+ minHeight: 150,
10552
+ fontFamily: "monospace",
10553
+ fontSize: 13,
10554
+ padding: 8,
10555
+ border: "1px solid #ddd",
10556
+ borderRadius: 4,
10557
+ resize: "vertical",
10558
+ marginBottom: 8
10559
+ }
10560
+ }
10561
+ )
10476
10562
  ] }),
10477
10563
  finalHtml && /* @__PURE__ */ jsxs23("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 250, overflow: "auto" }, children: [
10478
10564
  /* @__PURE__ */ jsx33("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
@@ -10510,8 +10596,8 @@ import {
10510
10596
  TableNode as TableNode2,
10511
10597
  TableRowNode as TableRowNode2
10512
10598
  } from "@lexical/table";
10513
- import { createContext as createContext4, useContext as useContext4, useEffect as useEffect29, useMemo as useMemo17, useState as useState29 } from "react";
10514
- import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
10599
+ import { createContext as createContext4, useContext as useContext4, useEffect as useEffect30, useMemo as useMemo16, useState as useState29 } from "react";
10600
+ import { Fragment as Fragment13, jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
10515
10601
  var CellContext = createContext4({
10516
10602
  cellEditorConfig: null,
10517
10603
  cellEditorPlugins: null,
@@ -10525,7 +10611,7 @@ function InsertTableDialog({
10525
10611
  const [rows, setRows] = useState29("5");
10526
10612
  const [columns, setColumns] = useState29("5");
10527
10613
  const [isDisabled, setIsDisabled] = useState29(true);
10528
- useEffect29(() => {
10614
+ useEffect30(() => {
10529
10615
  const row = Number(rows);
10530
10616
  const column = Number(columns);
10531
10617
  if (row && row > 0 && row <= 500 && column && column > 0 && column <= 50) {
@@ -10541,7 +10627,7 @@ function InsertTableDialog({
10541
10627
  });
10542
10628
  onClose();
10543
10629
  };
10544
- return /* @__PURE__ */ jsxs24(Fragment10, { children: [
10630
+ return /* @__PURE__ */ jsxs24(Fragment13, { children: [
10545
10631
  /* @__PURE__ */ jsx34(
10546
10632
  TextInput,
10547
10633
  {
@@ -10576,7 +10662,7 @@ import {
10576
10662
  } from "@lexical/react/LexicalDecoratorBlockNode";
10577
10663
  import { useLexicalComposerContext as useLexicalComposerContext32 } from "@lexical/react/LexicalComposerContext";
10578
10664
  import { useLexicalEditable as useLexicalEditable6 } from "@lexical/react/useLexicalEditable";
10579
- import { useCallback as useCallback22, useRef as useRef11, useState as useState30 } from "react";
10665
+ import { useCallback as useCallback22, useRef as useRef12, useState as useState30 } from "react";
10580
10666
  import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
10581
10667
  function HtmlBlockComponent({
10582
10668
  className,
@@ -10588,7 +10674,7 @@ function HtmlBlockComponent({
10588
10674
  const isEditable = useLexicalEditable6();
10589
10675
  const [isEditing, setIsEditing] = useState30(false);
10590
10676
  const [editValue, setEditValue] = useState30("");
10591
- const textareaRef = useRef11(null);
10677
+ const textareaRef = useRef12(null);
10592
10678
  const openEditor = useCallback22(() => {
10593
10679
  setEditValue(html);
10594
10680
  setIsEditing(true);
@@ -10778,7 +10864,7 @@ function $isHtmlBlockNode(node) {
10778
10864
  }
10779
10865
 
10780
10866
  // src/plugins/ComponentPickerPlugin/index.tsx
10781
- import { Fragment as Fragment11, jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
10867
+ import { Fragment as Fragment14, jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
10782
10868
  var ComponentPickerOption = class extends MenuOption {
10783
10869
  // What shows up in the editor
10784
10870
  title;
@@ -11064,7 +11150,7 @@ function ComponentPickerMenuPlugin() {
11064
11150
  allowWhitespace: true,
11065
11151
  minLength: 0
11066
11152
  });
11067
- const options = useMemo18(() => {
11153
+ const options = useMemo17(() => {
11068
11154
  const baseOptions = getBaseOptions(editor, showModal);
11069
11155
  if (!queryString) {
11070
11156
  return baseOptions;
@@ -11087,7 +11173,7 @@ function ComponentPickerMenuPlugin() {
11087
11173
  },
11088
11174
  [editor]
11089
11175
  );
11090
- return /* @__PURE__ */ jsxs26(Fragment11, { children: [
11176
+ return /* @__PURE__ */ jsxs26(Fragment14, { children: [
11091
11177
  modal,
11092
11178
  /* @__PURE__ */ jsx36(
11093
11179
  LexicalTypeaheadMenuPlugin,
@@ -11137,11 +11223,11 @@ import {
11137
11223
  CUT_COMMAND,
11138
11224
  PASTE_COMMAND
11139
11225
  } from "lexical";
11140
- import { useMemo as useMemo19 } from "react";
11226
+ import { useMemo as useMemo18 } from "react";
11141
11227
  import { jsx as jsx37 } from "react/jsx-runtime";
11142
11228
  function ContextMenuPlugin() {
11143
11229
  const [editor] = useLexicalComposerContext34();
11144
- const items = useMemo19(() => {
11230
+ const items = useMemo18(() => {
11145
11231
  return [
11146
11232
  new NodeContextMenuOption(`Remove Link`, {
11147
11233
  $onSelect: () => {
@@ -11256,7 +11342,7 @@ import { useLexicalComposerContext as useLexicalComposerContext35 } from "@lexic
11256
11342
  import { DRAG_DROP_PASTE } from "@lexical/rich-text";
11257
11343
  import { isMimeType, mediaFileReader } from "@lexical/utils";
11258
11344
  import { COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW7 } from "lexical";
11259
- import { useEffect as useEffect30 } from "react";
11345
+ import { useEffect as useEffect31 } from "react";
11260
11346
  var ACCEPTABLE_IMAGE_TYPES = [
11261
11347
  "image/",
11262
11348
  "image/heic",
@@ -11267,7 +11353,7 @@ var ACCEPTABLE_IMAGE_TYPES = [
11267
11353
  function DragDropPaste() {
11268
11354
  const [editor] = useLexicalComposerContext35();
11269
11355
  const { baasixClient, folder } = useEditorConfig();
11270
- useEffect30(() => {
11356
+ useEffect31(() => {
11271
11357
  return editor.registerCommand(
11272
11358
  DRAG_DROP_PASTE,
11273
11359
  (files) => {
@@ -11310,9 +11396,9 @@ import {
11310
11396
  $isParagraphNode as $isParagraphNode4,
11311
11397
  $isTextNode as $isTextNode4
11312
11398
  } from "lexical";
11313
- import { useCallback as useCallback24, useEffect as useEffect31, useMemo as useMemo20, useRef as useRef12, useState as useState32 } from "react";
11399
+ import { useCallback as useCallback24, useEffect as useEffect32, useMemo as useMemo19, useRef as useRef13, useState as useState32 } from "react";
11314
11400
  import * as ReactDOM3 from "react-dom";
11315
- import { Fragment as Fragment12, jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
11401
+ import { Fragment as Fragment15, jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
11316
11402
  var DRAGGABLE_BLOCK_MENU_CLASSNAME = "draggable-block-menu";
11317
11403
  function isOnMenu(element) {
11318
11404
  return !!element.closest(`.${DRAGGABLE_BLOCK_MENU_CLASSNAME}`);
@@ -11322,10 +11408,10 @@ function DraggableBlockPlugin({
11322
11408
  }) {
11323
11409
  const [editor] = useLexicalComposerContext36();
11324
11410
  const [modal, showModal] = useModal();
11325
- const menuRef = useRef12(null);
11326
- const pickerRef = useRef12(null);
11327
- const searchInputRef = useRef12(null);
11328
- const targetLineRef = useRef12(null);
11411
+ const menuRef = useRef13(null);
11412
+ const pickerRef = useRef13(null);
11413
+ const searchInputRef = useRef13(null);
11414
+ const targetLineRef = useRef13(null);
11329
11415
  const [draggableElement, setDraggableElement] = useState32(
11330
11416
  null
11331
11417
  );
@@ -11334,7 +11420,7 @@ function DraggableBlockPlugin({
11334
11420
  const [queryString, setQueryString] = useState32("");
11335
11421
  const [highlightedIndex, setHighlightedIndex] = useState32(0);
11336
11422
  const [pickerPosition, setPickerPosition] = useState32(null);
11337
- const options = useMemo20(() => {
11423
+ const options = useMemo19(() => {
11338
11424
  const baseOptions = getBaseOptions(editor, showModal);
11339
11425
  if (!queryString) {
11340
11426
  return baseOptions;
@@ -11347,12 +11433,12 @@ function DraggableBlockPlugin({
11347
11433
  )
11348
11434
  ];
11349
11435
  }, [editor, queryString, showModal]);
11350
- useEffect31(() => {
11436
+ useEffect32(() => {
11351
11437
  if (isPickerOpen && searchInputRef.current) {
11352
11438
  searchInputRef.current.focus({ preventScroll: true });
11353
11439
  }
11354
11440
  }, [isPickerOpen]);
11355
- useEffect31(() => {
11441
+ useEffect32(() => {
11356
11442
  if (!isPickerOpen || !options.length) {
11357
11443
  return;
11358
11444
  }
@@ -11360,7 +11446,7 @@ function DraggableBlockPlugin({
11360
11446
  (current) => Math.min(current, Math.max(options.length - 1, 0))
11361
11447
  );
11362
11448
  }, [isPickerOpen, options.length]);
11363
- useEffect31(() => {
11449
+ useEffect32(() => {
11364
11450
  if (!isPickerOpen) {
11365
11451
  return;
11366
11452
  }
@@ -11410,7 +11496,7 @@ function DraggableBlockPlugin({
11410
11496
  },
11411
11497
  [editor, pickerState, queryString]
11412
11498
  );
11413
- useEffect31(() => {
11499
+ useEffect32(() => {
11414
11500
  if (!isPickerOpen) {
11415
11501
  return;
11416
11502
  }
@@ -11472,7 +11558,7 @@ function DraggableBlockPlugin({
11472
11558
  setHighlightedIndex(0);
11473
11559
  setIsPickerOpen(true);
11474
11560
  }
11475
- return /* @__PURE__ */ jsxs27(Fragment12, { children: [
11561
+ return /* @__PURE__ */ jsxs27(Fragment15, { children: [
11476
11562
  modal,
11477
11563
  isPickerOpen && pickerPosition ? ReactDOM3.createPortal(
11478
11564
  /* @__PURE__ */ jsxs27(
@@ -11554,7 +11640,7 @@ import {
11554
11640
  $getSelection as $getSelection11,
11555
11641
  $isRangeSelection as $isRangeSelection9
11556
11642
  } from "lexical";
11557
- import { useCallback as useCallback25, useEffect as useEffect32, useMemo as useMemo21, useState as useState33 } from "react";
11643
+ import { useCallback as useCallback25, useEffect as useEffect33, useMemo as useMemo20, useState as useState33 } from "react";
11558
11644
  import * as ReactDOM4 from "react-dom";
11559
11645
  import { jsx as jsx39, jsxs as jsxs28 } from "react/jsx-runtime";
11560
11646
  var EmojiOption = class extends MenuOption2 {
@@ -11604,10 +11690,10 @@ function EmojiPickerPlugin() {
11604
11690
  const [editor] = useLexicalComposerContext37();
11605
11691
  const [queryString, setQueryString] = useState33(null);
11606
11692
  const [emojis, setEmojis] = useState33([]);
11607
- useEffect32(() => {
11693
+ useEffect33(() => {
11608
11694
  import("./emoji-list-MUV74SND.js").then((file) => setEmojis(file.default));
11609
11695
  }, []);
11610
- const emojiOptions = useMemo21(
11696
+ const emojiOptions = useMemo20(
11611
11697
  () => emojis != null ? emojis.map(
11612
11698
  ({ emoji, aliases, tags }) => new EmojiOption(aliases[0], emoji, {
11613
11699
  keywords: [...aliases, ...tags]
@@ -11620,7 +11706,7 @@ function EmojiPickerPlugin() {
11620
11706
  punctuation: `\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\[\\]\\\\/!%'"~=<>:;`
11621
11707
  // allow _ and -
11622
11708
  });
11623
- const options = useMemo21(() => {
11709
+ const options = useMemo20(() => {
11624
11710
  return emojiOptions.filter((option) => {
11625
11711
  return queryString != null ? new RegExp(queryString, "gi").exec(option.title) || option.keywords != null ? option.keywords.some(
11626
11712
  (keyword) => new RegExp(queryString, "gi").exec(keyword)
@@ -11700,7 +11786,7 @@ import {
11700
11786
  KEY_ESCAPE_COMMAND as KEY_ESCAPE_COMMAND2,
11701
11787
  SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND2
11702
11788
  } from "lexical";
11703
- import { useCallback as useCallback26, useEffect as useEffect33, useRef as useRef13, useState as useState34 } from "react";
11789
+ import { useCallback as useCallback26, useEffect as useEffect34, useRef as useRef14, useState as useState34 } from "react";
11704
11790
  import { createPortal as createPortal8 } from "react-dom";
11705
11791
 
11706
11792
  // src/utils/getSelectedNode.ts
@@ -11749,7 +11835,7 @@ function setFloatingElemPositionForLinkEditor(targetRect, floatingElem, anchorEl
11749
11835
  }
11750
11836
 
11751
11837
  // src/plugins/FloatingLinkEditorPlugin/index.tsx
11752
- import { Fragment as Fragment13, jsx as jsx40, jsxs as jsxs29 } from "react/jsx-runtime";
11838
+ import { Fragment as Fragment16, jsx as jsx40, jsxs as jsxs29 } from "react/jsx-runtime";
11753
11839
  function preventDefault(event) {
11754
11840
  event.preventDefault();
11755
11841
  }
@@ -11761,8 +11847,8 @@ function FloatingLinkEditor({
11761
11847
  isLinkEditMode,
11762
11848
  setIsLinkEditMode
11763
11849
  }) {
11764
- const editorRef = useRef13(null);
11765
- const inputRef = useRef13(null);
11850
+ const editorRef = useRef14(null);
11851
+ const inputRef = useRef14(null);
11766
11852
  const [linkUrl, setLinkUrl] = useState34("");
11767
11853
  const [editedLinkUrl, setEditedLinkUrl] = useState34("https://");
11768
11854
  const [lastSelection, setLastSelection] = useState34(
@@ -11835,7 +11921,7 @@ function FloatingLinkEditor({
11835
11921
  }
11836
11922
  return true;
11837
11923
  }, [anchorElem, editor, setIsLinkEditMode, isLinkEditMode, linkUrl]);
11838
- useEffect33(() => {
11924
+ useEffect34(() => {
11839
11925
  const scrollerElem = anchorElem.parentElement;
11840
11926
  const update = () => {
11841
11927
  editor.getEditorState().read(() => {
@@ -11853,7 +11939,7 @@ function FloatingLinkEditor({
11853
11939
  }
11854
11940
  };
11855
11941
  }, [anchorElem.parentElement, editor, $updateLinkEditor]);
11856
- useEffect33(() => {
11942
+ useEffect34(() => {
11857
11943
  return mergeRegister10(
11858
11944
  editor.registerUpdateListener(({ editorState }) => {
11859
11945
  editorState.read(() => {
@@ -11881,17 +11967,17 @@ function FloatingLinkEditor({
11881
11967
  )
11882
11968
  );
11883
11969
  }, [editor, $updateLinkEditor, setIsLink, isLink]);
11884
- useEffect33(() => {
11970
+ useEffect34(() => {
11885
11971
  editor.getEditorState().read(() => {
11886
11972
  $updateLinkEditor();
11887
11973
  });
11888
11974
  }, [editor, $updateLinkEditor]);
11889
- useEffect33(() => {
11975
+ useEffect34(() => {
11890
11976
  if (isLinkEditMode && inputRef.current) {
11891
11977
  inputRef.current.focus();
11892
11978
  }
11893
11979
  }, [isLinkEditMode, isLink]);
11894
- useEffect33(() => {
11980
+ useEffect34(() => {
11895
11981
  const editorElement = editorRef.current;
11896
11982
  if (editorElement === null) {
11897
11983
  return;
@@ -11942,7 +12028,7 @@ function FloatingLinkEditor({
11942
12028
  setIsLinkEditMode(false);
11943
12029
  }
11944
12030
  };
11945
- return /* @__PURE__ */ jsx40("div", { ref: editorRef, className: "link-editor", children: !isLink ? null : isLinkEditMode ? /* @__PURE__ */ jsxs29(Fragment13, { children: [
12031
+ return /* @__PURE__ */ jsx40("div", { ref: editorRef, className: "link-editor", children: !isLink ? null : isLinkEditMode ? /* @__PURE__ */ jsxs29(Fragment16, { children: [
11946
12032
  /* @__PURE__ */ jsx40(
11947
12033
  "input",
11948
12034
  {
@@ -12022,7 +12108,7 @@ function FloatingLinkEditor({
12022
12108
  function useFloatingLinkEditorToolbar(editor, anchorElem, isLinkEditMode, setIsLinkEditMode) {
12023
12109
  const [activeEditor, setActiveEditor] = useState34(editor);
12024
12110
  const [isLink, setIsLink] = useState34(false);
12025
- useEffect33(() => {
12111
+ useEffect34(() => {
12026
12112
  function $updateToolbar() {
12027
12113
  const selection = $getSelection12();
12028
12114
  if ($isRangeSelection10(selection)) {
@@ -12138,7 +12224,7 @@ import {
12138
12224
  getDOMSelection as getDOMSelection3,
12139
12225
  SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND3
12140
12226
  } from "lexical";
12141
- import { useCallback as useCallback27, useEffect as useEffect34, useRef as useRef14, useState as useState35 } from "react";
12227
+ import { useCallback as useCallback27, useEffect as useEffect35, useRef as useRef15, useState as useState35 } from "react";
12142
12228
  import { createPortal as createPortal9 } from "react-dom";
12143
12229
 
12144
12230
  // src/utils/getDOMRangeRect.ts
@@ -12200,7 +12286,7 @@ function setFloatingElemPosition(targetRect, floatingElem, anchorElem, isLink =
12200
12286
  }
12201
12287
 
12202
12288
  // src/plugins/FloatingTextFormatToolbarPlugin/index.tsx
12203
- import { Fragment as Fragment14, jsx as jsx41, jsxs as jsxs30 } from "react/jsx-runtime";
12289
+ import { Fragment as Fragment17, jsx as jsx41, jsxs as jsxs30 } from "react/jsx-runtime";
12204
12290
  function TextFormatFloatingToolbar({
12205
12291
  editor,
12206
12292
  anchorElem,
@@ -12217,7 +12303,7 @@ function TextFormatFloatingToolbar({
12217
12303
  isSuperscript: isSuperscript2,
12218
12304
  setIsLinkEditMode
12219
12305
  }) {
12220
- const popupCharStylesEditorRef = useRef14(null);
12306
+ const popupCharStylesEditorRef = useRef15(null);
12221
12307
  const insertLink = useCallback27(() => {
12222
12308
  if (!isLink) {
12223
12309
  setIsLinkEditMode(true);
@@ -12249,7 +12335,7 @@ function TextFormatFloatingToolbar({
12249
12335
  }
12250
12336
  }
12251
12337
  }
12252
- useEffect34(() => {
12338
+ useEffect35(() => {
12253
12339
  if (popupCharStylesEditorRef?.current) {
12254
12340
  document.addEventListener("mousemove", mouseMoveListener);
12255
12341
  document.addEventListener("mouseup", mouseUpListener);
@@ -12277,7 +12363,7 @@ function TextFormatFloatingToolbar({
12277
12363
  );
12278
12364
  }
12279
12365
  }, [editor, anchorElem, isLink]);
12280
- useEffect34(() => {
12366
+ useEffect35(() => {
12281
12367
  const scrollerElem = anchorElem.parentElement;
12282
12368
  const update = () => {
12283
12369
  editor.getEditorState().read(() => {
@@ -12295,7 +12381,7 @@ function TextFormatFloatingToolbar({
12295
12381
  }
12296
12382
  };
12297
12383
  }, [editor, $updateTextFormatFloatingToolbar, anchorElem]);
12298
- useEffect34(() => {
12384
+ useEffect35(() => {
12299
12385
  editor.getEditorState().read(() => {
12300
12386
  $updateTextFormatFloatingToolbar();
12301
12387
  });
@@ -12316,7 +12402,7 @@ function TextFormatFloatingToolbar({
12316
12402
  );
12317
12403
  }, [editor, $updateTextFormatFloatingToolbar]);
12318
12404
  return /* @__PURE__ */ jsxs30("div", { ref: popupCharStylesEditorRef, className: "floating-text-format-popup", children: [
12319
- editor.isEditable() && /* @__PURE__ */ jsxs30(Fragment14, { children: [
12405
+ editor.isEditable() && /* @__PURE__ */ jsxs30(Fragment17, { children: [
12320
12406
  /* @__PURE__ */ jsx41(
12321
12407
  "button",
12322
12408
  {
@@ -12529,13 +12615,13 @@ function useFloatingTextFormatToolbar(editor, anchorElem, setIsLinkEditMode) {
12529
12615
  }
12530
12616
  });
12531
12617
  }, [editor]);
12532
- useEffect34(() => {
12618
+ useEffect35(() => {
12533
12619
  document.addEventListener("selectionchange", updatePopup);
12534
12620
  return () => {
12535
12621
  document.removeEventListener("selectionchange", updatePopup);
12536
12622
  };
12537
12623
  }, [updatePopup]);
12538
- useEffect34(() => {
12624
+ useEffect35(() => {
12539
12625
  return mergeRegister11(
12540
12626
  editor.registerUpdateListener(() => {
12541
12627
  updatePopup();
@@ -12593,10 +12679,10 @@ import { useLexicalComposerContext as useLexicalComposerContext40 } from "@lexic
12593
12679
  import { $trimTextContentFromAnchor } from "@lexical/selection";
12594
12680
  import { $restoreEditorState } from "@lexical/utils";
12595
12681
  import { $getSelection as $getSelection14, $isRangeSelection as $isRangeSelection12, RootNode } from "lexical";
12596
- import { useEffect as useEffect35 } from "react";
12682
+ import { useEffect as useEffect36 } from "react";
12597
12683
  function MaxLengthPlugin({ maxLength }) {
12598
12684
  const [editor] = useLexicalComposerContext40();
12599
- useEffect35(() => {
12685
+ useEffect36(() => {
12600
12686
  let lastRestoredEditorState = null;
12601
12687
  return editor.registerNodeTransform(RootNode, (rootNode) => {
12602
12688
  const selection = $getSelection14();
@@ -12636,7 +12722,7 @@ import {
12636
12722
  KEY_DOWN_COMMAND,
12637
12723
  OUTDENT_CONTENT_COMMAND
12638
12724
  } from "lexical";
12639
- import { useEffect as useEffect36 } from "react";
12725
+ import { useEffect as useEffect37 } from "react";
12640
12726
 
12641
12727
  // src/plugins/ToolbarPlugin/utils.ts
12642
12728
  import { $createCodeNode as $createCodeNode3 } from "@lexical/code";
@@ -13103,7 +13189,7 @@ function ShortcutsPlugin({
13103
13189
  setIsLinkEditMode
13104
13190
  }) {
13105
13191
  const { toolbarState } = useToolbarState();
13106
- useEffect36(() => {
13192
+ useEffect37(() => {
13107
13193
  const keyboardShortcutsHandler = (event) => {
13108
13194
  if (isModifierMatch2(event, {})) {
13109
13195
  return false;
@@ -13193,7 +13279,7 @@ function ShortcutsPlugin({
13193
13279
  // src/plugins/SpecialTextPlugin/index.ts
13194
13280
  import { useLexicalComposerContext as useLexicalComposerContext41 } from "@lexical/react/LexicalComposerContext";
13195
13281
  import { TextNode as TextNode5 } from "lexical";
13196
- import { useEffect as useEffect37 } from "react";
13282
+ import { useEffect as useEffect38 } from "react";
13197
13283
 
13198
13284
  // src/nodes/SpecialTextNode.tsx
13199
13285
  import { addClassNamesToElement as addClassNamesToElement3 } from "@lexical/utils";
@@ -13263,7 +13349,7 @@ function $textNodeTransform(node) {
13263
13349
  }
13264
13350
  }
13265
13351
  function useTextTransformation(editor) {
13266
- useEffect37(() => {
13352
+ useEffect38(() => {
13267
13353
  if (!editor.hasNodes([SpecialTextNode])) {
13268
13354
  throw new Error(
13269
13355
  "SpecialTextPlugin: SpecialTextNode not registered on editor"
@@ -13287,7 +13373,7 @@ import {
13287
13373
  COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW10,
13288
13374
  FOCUS_COMMAND
13289
13375
  } from "lexical";
13290
- import { useEffect as useEffect38 } from "react";
13376
+ import { useEffect as useEffect39 } from "react";
13291
13377
  var TAB_TO_FOCUS_INTERVAL = 100;
13292
13378
  var lastTabKeyDownTimestamp = 0;
13293
13379
  var hasRegisteredKeyDownListener = false;
@@ -13304,7 +13390,7 @@ function registerKeyTimeStampTracker() {
13304
13390
  }
13305
13391
  function TabFocusPlugin() {
13306
13392
  const [editor] = useLexicalComposerContext42();
13307
- useEffect38(() => {
13393
+ useEffect39(() => {
13308
13394
  if (!hasRegisteredKeyDownListener) {
13309
13395
  registerKeyTimeStampTracker();
13310
13396
  hasRegisteredKeyDownListener = true;
@@ -13361,12 +13447,12 @@ import {
13361
13447
  isDOMNode as isDOMNode2,
13362
13448
  SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND4
13363
13449
  } from "lexical";
13364
- import { useCallback as useCallback28, useEffect as useEffect39, useRef as useRef16, useState as useState37 } from "react";
13450
+ import { useCallback as useCallback28, useEffect as useEffect40, useRef as useRef17, useState as useState37 } from "react";
13365
13451
  import { createPortal as createPortal10 } from "react-dom";
13366
13452
 
13367
13453
  // src/ui/ColorPicker.tsx
13368
13454
  import { calculateZoomLevel as calculateZoomLevel2 } from "@lexical/utils";
13369
- import { useMemo as useMemo22, useRef as useRef15, useState as useState36 } from "react";
13455
+ import { useMemo as useMemo21, useRef as useRef16, useState as useState36 } from "react";
13370
13456
  import { jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
13371
13457
  var skipAddingToHistoryStack = false;
13372
13458
  var basicColors = [
@@ -13396,15 +13482,15 @@ function ColorPicker({
13396
13482
  const [inputColor, setInputColor] = useState36(
13397
13483
  transformColor("hex", color).hex
13398
13484
  );
13399
- const innerDivRef = useRef15(null);
13400
- const saturationPosition = useMemo22(
13485
+ const innerDivRef = useRef16(null);
13486
+ const saturationPosition = useMemo21(
13401
13487
  () => ({
13402
13488
  x: selfColor.hsv.s / 100 * WIDTH,
13403
13489
  y: (100 - selfColor.hsv.v) / 100 * HEIGHT
13404
13490
  }),
13405
13491
  [selfColor.hsv.s, selfColor.hsv.v]
13406
13492
  );
13407
- const huePosition = useMemo22(
13493
+ const huePosition = useMemo21(
13408
13494
  () => ({
13409
13495
  x: selfColor.hsv.h / 360 * WIDTH
13410
13496
  }),
@@ -13506,8 +13592,8 @@ function ColorPicker({
13506
13592
  );
13507
13593
  }
13508
13594
  function MoveWrapper({ className, style, onChange, children }) {
13509
- const divRef = useRef15(null);
13510
- const draggedRef = useRef15(false);
13595
+ const divRef = useRef16(null);
13596
+ const draggedRef = useRef16(false);
13511
13597
  const move = (e) => {
13512
13598
  if (divRef.current) {
13513
13599
  const { current: div } = divRef;
@@ -13633,7 +13719,7 @@ function transformColor(format, color) {
13633
13719
  }
13634
13720
 
13635
13721
  // src/plugins/TableActionMenuPlugin/index.tsx
13636
- import { Fragment as Fragment15, jsx as jsx44, jsxs as jsxs32 } from "react/jsx-runtime";
13722
+ import { Fragment as Fragment18, jsx as jsx44, jsxs as jsxs32 } from "react/jsx-runtime";
13637
13723
  function computeSelectionCount(selection) {
13638
13724
  const selectionShape = selection.getShape();
13639
13725
  return {
@@ -13680,7 +13766,7 @@ function TableActionMenu({
13680
13766
  showColorPickerModal
13681
13767
  }) {
13682
13768
  const [editor] = useLexicalComposerContext43();
13683
- const dropDownRef = useRef16(null);
13769
+ const dropDownRef = useRef17(null);
13684
13770
  const [tableCellNode, updateTableCellNode] = useState37(_tableCellNode);
13685
13771
  const [selectionCounts, updateSelectionCounts] = useState37({
13686
13772
  columns: 1,
@@ -13691,7 +13777,7 @@ function TableActionMenu({
13691
13777
  const [backgroundColor, setBackgroundColor] = useState37(
13692
13778
  () => currentCellBackgroundColor(editor) || ""
13693
13779
  );
13694
- useEffect39(() => {
13780
+ useEffect40(() => {
13695
13781
  return editor.registerMutationListener(
13696
13782
  TableCellNode3,
13697
13783
  (nodeMutations) => {
@@ -13706,7 +13792,7 @@ function TableActionMenu({
13706
13792
  { skipInitialization: true }
13707
13793
  );
13708
13794
  }, [editor, tableCellNode]);
13709
- useEffect39(() => {
13795
+ useEffect40(() => {
13710
13796
  editor.getEditorState().read(() => {
13711
13797
  const selection = $getSelection17();
13712
13798
  if ($isTableSelection2(selection)) {
@@ -13719,7 +13805,7 @@ function TableActionMenu({
13719
13805
  setCanUnmergeCell($canUnmerge());
13720
13806
  });
13721
13807
  }, [editor]);
13722
- useEffect39(() => {
13808
+ useEffect40(() => {
13723
13809
  const menuButtonElement = contextRef.current;
13724
13810
  const dropDownElement = dropDownRef.current;
13725
13811
  const rootElement = editor.getRootElement();
@@ -13743,7 +13829,7 @@ function TableActionMenu({
13743
13829
  dropDownElement.style.top = `${topPosition}px`;
13744
13830
  }
13745
13831
  }, [contextRef, dropDownRef, editor]);
13746
- useEffect39(() => {
13832
+ useEffect40(() => {
13747
13833
  function handleClickOutside(event) {
13748
13834
  if (dropDownRef.current != null && contextRef.current != null && isDOMNode2(event.target) && !dropDownRef.current.contains(event.target) && !contextRef.current.contains(event.target)) {
13749
13835
  setIsMenuOpen(false);
@@ -14230,8 +14316,8 @@ function TableCellActionMenuContainer({
14230
14316
  cellMerge
14231
14317
  }) {
14232
14318
  const [editor] = useLexicalComposerContext43();
14233
- const menuButtonRef = useRef16(null);
14234
- const menuRootRef = useRef16(null);
14319
+ const menuButtonRef = useRef17(null);
14320
+ const menuRootRef = useRef17(null);
14235
14321
  const [isMenuOpen, setIsMenuOpen] = useState37(false);
14236
14322
  const [tableCellNode, setTableMenuCellNode] = useState37(
14237
14323
  null
@@ -14351,7 +14437,7 @@ function TableCellActionMenuContainer({
14351
14437
  menu.style.transform = `translate(${left}px, ${top}px)`;
14352
14438
  }
14353
14439
  }, [editor, anchorElem, checkTableCellOverflow]);
14354
- useEffect39(() => {
14440
+ useEffect40(() => {
14355
14441
  let timeoutId = void 0;
14356
14442
  const callback = () => {
14357
14443
  timeoutId = void 0;
@@ -14382,14 +14468,14 @@ function TableCellActionMenuContainer({
14382
14468
  () => clearTimeout(timeoutId)
14383
14469
  );
14384
14470
  });
14385
- const prevTableCellDOM = useRef16(tableCellNode);
14386
- useEffect39(() => {
14471
+ const prevTableCellDOM = useRef17(tableCellNode);
14472
+ useEffect40(() => {
14387
14473
  if (prevTableCellDOM.current !== tableCellNode) {
14388
14474
  setIsMenuOpen(false);
14389
14475
  }
14390
14476
  prevTableCellDOM.current = tableCellNode;
14391
14477
  }, [prevTableCellDOM, tableCellNode]);
14392
- return /* @__PURE__ */ jsx44("div", { className: "table-cell-action-button-container", ref: menuButtonRef, children: tableCellNode != null && /* @__PURE__ */ jsxs32(Fragment15, { children: [
14478
+ return /* @__PURE__ */ jsx44("div", { className: "table-cell-action-button-container", ref: menuButtonRef, children: tableCellNode != null && /* @__PURE__ */ jsxs32(Fragment18, { children: [
14393
14479
  /* @__PURE__ */ jsx44(
14394
14480
  "button",
14395
14481
  {
@@ -14455,22 +14541,22 @@ import {
14455
14541
  } from "lexical";
14456
14542
  import {
14457
14543
  useCallback as useCallback29,
14458
- useEffect as useEffect40,
14459
- useMemo as useMemo23,
14460
- useRef as useRef17,
14544
+ useEffect as useEffect41,
14545
+ useMemo as useMemo22,
14546
+ useRef as useRef18,
14461
14547
  useState as useState38
14462
14548
  } from "react";
14463
14549
  import { createPortal as createPortal11 } from "react-dom";
14464
- import { Fragment as Fragment16, jsx as jsx45, jsxs as jsxs33 } from "react/jsx-runtime";
14550
+ import { Fragment as Fragment19, jsx as jsx45, jsxs as jsxs33 } from "react/jsx-runtime";
14465
14551
  var MIN_ROW_HEIGHT = 33;
14466
14552
  var MIN_COLUMN_WIDTH = 92;
14467
14553
  var ACTIVE_RESIZER_COLOR = "#76b6ff";
14468
14554
  function TableCellResizer({ editor }) {
14469
- const targetRef = useRef17(null);
14470
- const resizerRef = useRef17(null);
14471
- const tableRectRef = useRef17(null);
14555
+ const targetRef = useRef18(null);
14556
+ const resizerRef = useRef18(null);
14557
+ const tableRectRef = useRef18(null);
14472
14558
  const [hasTable, setHasTable] = useState38(false);
14473
- const pointerStartPosRef = useRef17(null);
14559
+ const pointerStartPosRef = useRef18(null);
14474
14560
  const [pointerCurrentPos, updatePointerCurrentPos] = useState38(null);
14475
14561
  const [activeCell, updateActiveCell] = useState38(null);
14476
14562
  const [draggingDirection, updateDraggingDirection] = useState38(null);
@@ -14483,7 +14569,7 @@ function TableCellResizer({ editor }) {
14483
14569
  pointerStartPosRef.current = null;
14484
14570
  tableRectRef.current = null;
14485
14571
  }, []);
14486
- useEffect40(() => {
14572
+ useEffect41(() => {
14487
14573
  const tableKeys = /* @__PURE__ */ new Set();
14488
14574
  return mergeRegister13(
14489
14575
  editor.registerMutationListener(TableNode3, (nodeMutations) => {
@@ -14507,7 +14593,7 @@ function TableCellResizer({ editor }) {
14507
14593
  })
14508
14594
  );
14509
14595
  }, [editor]);
14510
- useEffect40(() => {
14596
+ useEffect41(() => {
14511
14597
  if (!hasTable) {
14512
14598
  return;
14513
14599
  }
@@ -14796,7 +14882,7 @@ function TableCellResizer({ editor }) {
14796
14882
  }
14797
14883
  }, [draggingDirection]);
14798
14884
  const resizerStyles = getResizers();
14799
- return /* @__PURE__ */ jsx45("div", { ref: resizerRef, children: activeCell != null && /* @__PURE__ */ jsxs33(Fragment16, { children: [
14885
+ return /* @__PURE__ */ jsx45("div", { ref: resizerRef, children: activeCell != null && /* @__PURE__ */ jsxs33(Fragment19, { children: [
14800
14886
  /* @__PURE__ */ jsx45(
14801
14887
  "div",
14802
14888
  {
@@ -14820,7 +14906,7 @@ function TableCellResizer({ editor }) {
14820
14906
  function TableCellResizerPlugin() {
14821
14907
  const [editor] = useLexicalComposerContext44();
14822
14908
  const isEditable = useLexicalEditable8();
14823
- return useMemo23(
14909
+ return useMemo22(
14824
14910
  () => isEditable ? createPortal11(/* @__PURE__ */ jsx45(TableCellResizer, { editor }), document.body) : null,
14825
14911
  [editor, isEditable]
14826
14912
  );
@@ -14856,7 +14942,7 @@ import {
14856
14942
  $getSiblingCaret as $getSiblingCaret2,
14857
14943
  isHTMLElement as isHTMLElement5
14858
14944
  } from "lexical";
14859
- import { useEffect as useEffect41, useRef as useRef18, useState as useState39 } from "react";
14945
+ import { useEffect as useEffect42, useRef as useRef19, useState as useState39 } from "react";
14860
14946
  import { createPortal as createPortal12 } from "react-dom";
14861
14947
 
14862
14948
  // src/utils/getThemeSelector.ts
@@ -14871,7 +14957,7 @@ function getThemeSelector(getTheme, name) {
14871
14957
  }
14872
14958
 
14873
14959
  // src/plugins/TableHoverActionsV2Plugin/index.tsx
14874
- import { Fragment as Fragment17, jsx as jsx46, jsxs as jsxs34 } from "react/jsx-runtime";
14960
+ import { Fragment as Fragment20, jsx as jsx46, jsxs as jsxs34 } from "react/jsx-runtime";
14875
14961
  var INDICATOR_SIZE_PX = 18;
14876
14962
  var SIDE_INDICATOR_SIZE_PX = 18;
14877
14963
  var TOP_BUTTON_OVERHANG = INDICATOR_SIZE_PX / 2;
@@ -14962,21 +15048,21 @@ function TableHoverActionsV2({
14962
15048
  const isEditable = useLexicalEditable9();
14963
15049
  const [isVisible, setIsVisible] = useState39(false);
14964
15050
  const [isLeftVisible, setIsLeftVisible] = useState39(false);
14965
- const virtualRef = useRef18({
15051
+ const virtualRef = useRef19({
14966
15052
  getBoundingClientRect: () => new DOMRect()
14967
15053
  });
14968
- const leftVirtualRef = useRef18({
15054
+ const leftVirtualRef = useRef19({
14969
15055
  getBoundingClientRect: () => new DOMRect()
14970
15056
  });
14971
- const floatingElemRef = useRef18(null);
14972
- const leftFloatingElemRef = useRef18(null);
14973
- const dragHandleRef = useRef18(null);
14974
- const hoveredLeftCellRef = useRef18(null);
14975
- const hoveredTopCellRef = useRef18(null);
14976
- const handleMouseLeaveRef = useRef18(
15057
+ const floatingElemRef = useRef19(null);
15058
+ const leftFloatingElemRef = useRef19(null);
15059
+ const dragHandleRef = useRef19(null);
15060
+ const hoveredLeftCellRef = useRef19(null);
15061
+ const hoveredTopCellRef = useRef19(null);
15062
+ const handleMouseLeaveRef = useRef19(
14977
15063
  null
14978
15064
  );
14979
- const dropIndicatorCleanupRef = useRef18([]);
15065
+ const dropIndicatorCleanupRef = useRef19([]);
14980
15066
  const [hoveredTable, setHoveredTable] = useState39(
14981
15067
  null
14982
15068
  );
@@ -15011,7 +15097,7 @@ function TableHoverActionsV2({
15011
15097
  strategy: "fixed",
15012
15098
  whileElementsMounted: autoUpdate
15013
15099
  });
15014
- useEffect41(() => {
15100
+ useEffect42(() => {
15015
15101
  if (!isEditable) {
15016
15102
  return;
15017
15103
  }
@@ -15078,7 +15164,7 @@ function TableHoverActionsV2({
15078
15164
  setIsLeftVisible(false);
15079
15165
  };
15080
15166
  }, [anchorElem, getTheme, isEditable, leftRefs, refs, update, updateLeft]);
15081
- useEffect41(() => {
15167
+ useEffect42(() => {
15082
15168
  const handleMouseLeave = (event) => {
15083
15169
  const nextTarget = event.relatedTarget;
15084
15170
  if (nextTarget && floatingElemRef.current && floatingElemRef.current.contains(nextTarget)) {
@@ -15103,7 +15189,7 @@ function TableHoverActionsV2({
15103
15189
  }
15104
15190
  });
15105
15191
  }, [editor]);
15106
- useEffect41(() => {
15192
+ useEffect42(() => {
15107
15193
  if (!hoveredTable) {
15108
15194
  setCanReorder(false);
15109
15195
  return;
@@ -15120,7 +15206,7 @@ function TableHoverActionsV2({
15120
15206
  { editor }
15121
15207
  );
15122
15208
  }, [editor, hoveredTable]);
15123
- useEffect41(() => {
15209
+ useEffect42(() => {
15124
15210
  const handle = dragHandleRef.current;
15125
15211
  const tableElement = hoveredTable;
15126
15212
  const columnIndex = hoveredColumnIndex;
@@ -15139,7 +15225,7 @@ function TableHoverActionsV2({
15139
15225
  });
15140
15226
  return cleanup;
15141
15227
  }, [canReorder, hoveredColumnIndex, hoveredTable]);
15142
- useEffect41(() => {
15228
+ useEffect42(() => {
15143
15229
  dropIndicatorCleanupRef.current.forEach((cleanup) => cleanup());
15144
15230
  dropIndicatorCleanupRef.current = [];
15145
15231
  if (!hoveredTable || !canReorder) {
@@ -15304,7 +15390,7 @@ function TableHoverActionsV2({
15304
15390
  insertionCaret?.splice(0, sortableRows);
15305
15391
  });
15306
15392
  };
15307
- return /* @__PURE__ */ jsxs34(Fragment17, { children: [
15393
+ return /* @__PURE__ */ jsxs34(Fragment20, { children: [
15308
15394
  /* @__PURE__ */ jsxs34(
15309
15395
  "div",
15310
15396
  {
@@ -15409,7 +15495,7 @@ function TableHoverActionsV2Plugin({
15409
15495
  // src/plugins/TableOfContentsPlugin/index.tsx
15410
15496
  import { useLexicalComposerContext as useLexicalComposerContext46 } from "@lexical/react/LexicalComposerContext";
15411
15497
  import { TableOfContentsPlugin as LexicalTableOfContentsPlugin } from "@lexical/react/LexicalTableOfContentsPlugin";
15412
- import { useEffect as useEffect42, useRef as useRef19, useState as useState40 } from "react";
15498
+ import { useEffect as useEffect43, useRef as useRef20, useState as useState40 } from "react";
15413
15499
  import { jsx as jsx47, jsxs as jsxs35 } from "react/jsx-runtime";
15414
15500
  var MARGIN_ABOVE_EDITOR = 624;
15415
15501
  var HEADING_WIDTH = 9;
@@ -15436,7 +15522,7 @@ function TableOfContentsList({
15436
15522
  tableOfContents
15437
15523
  }) {
15438
15524
  const [selectedKey, setSelectedKey] = useState40("");
15439
- const selectedIndex = useRef19(0);
15525
+ const selectedIndex = useRef20(0);
15440
15526
  const [editor] = useLexicalComposerContext46();
15441
15527
  function scrollToNode(key, currIndex) {
15442
15528
  editor.getEditorState().read(() => {
@@ -15448,7 +15534,7 @@ function TableOfContentsList({
15448
15534
  }
15449
15535
  });
15450
15536
  }
15451
- useEffect42(() => {
15537
+ useEffect43(() => {
15452
15538
  function scrollCallback() {
15453
15539
  if (tableOfContents.length !== 0 && selectedIndex.current < tableOfContents.length - 1) {
15454
15540
  let currentHeading = editor.getElementByKey(
@@ -15547,7 +15633,7 @@ function TableOfContentsPlugin() {
15547
15633
 
15548
15634
  // src/plugins/TableScrollShadowPlugin/index.tsx
15549
15635
  import { useLexicalComposerContext as useLexicalComposerContext47 } from "@lexical/react/LexicalComposerContext";
15550
- import { useEffect as useEffect43 } from "react";
15636
+ import { useEffect as useEffect44 } from "react";
15551
15637
  var SCROLLABLE_WRAPPER_CLASS = "PlaygroundEditorTheme__tableScrollableWrapper";
15552
15638
  var HAS_SCROLL_RIGHT_CLASS = "PlaygroundEditorTheme__tableScrollRight";
15553
15639
  var HAS_SCROLL_LEFT_CLASS = "PlaygroundEditorTheme__tableScrollLeft";
@@ -15571,7 +15657,7 @@ function updateTableScrollState(element) {
15571
15657
  }
15572
15658
  function TableScrollShadowPlugin() {
15573
15659
  const [editor] = useLexicalComposerContext47();
15574
- useEffect43(() => {
15660
+ useEffect44(() => {
15575
15661
  const editorElement = editor.getRootElement();
15576
15662
  if (!editorElement) {
15577
15663
  return;
@@ -15701,7 +15787,7 @@ import {
15701
15787
  SKIP_SELECTION_FOCUS_TAG as SKIP_SELECTION_FOCUS_TAG2,
15702
15788
  UNDO_COMMAND as UNDO_COMMAND2
15703
15789
  } from "lexical";
15704
- import { useCallback as useCallback30, useEffect as useEffect45, useState as useState42 } from "react";
15790
+ import { useCallback as useCallback30, useEffect as useEffect46, useState as useState42 } from "react";
15705
15791
 
15706
15792
  // src/ui/DropdownColorPicker.tsx
15707
15793
  import { jsx as jsx48 } from "react/jsx-runtime";
@@ -15725,7 +15811,7 @@ function DropdownColorPicker({
15725
15811
 
15726
15812
  // src/plugins/ToolbarPlugin/fontSize.tsx
15727
15813
  import * as React3 from "react";
15728
- import { Fragment as Fragment18, jsx as jsx49, jsxs as jsxs36 } from "react/jsx-runtime";
15814
+ import { Fragment as Fragment21, jsx as jsx49, jsxs as jsxs36 } from "react/jsx-runtime";
15729
15815
  function parseFontSize(input) {
15730
15816
  const match = input.match(/^(\d+(?:\.\d+)?)(px|pt)$/);
15731
15817
  return match ? [Number(match[1]), match[2]] : null;
@@ -15795,7 +15881,7 @@ function FontSize({
15795
15881
  React3.useEffect(() => {
15796
15882
  setInputValue(selectionFontSize);
15797
15883
  }, [selectionFontSize]);
15798
- return /* @__PURE__ */ jsxs36(Fragment18, { children: [
15884
+ return /* @__PURE__ */ jsxs36(Fragment21, { children: [
15799
15885
  /* @__PURE__ */ jsx49(
15800
15886
  "button",
15801
15887
  {
@@ -15854,7 +15940,7 @@ function FontSize({
15854
15940
  }
15855
15941
 
15856
15942
  // src/plugins/ToolbarPlugin/index.tsx
15857
- import { Fragment as Fragment19, jsx as jsx50, jsxs as jsxs37 } from "react/jsx-runtime";
15943
+ import { Fragment as Fragment22, jsx as jsx50, jsxs as jsxs37 } from "react/jsx-runtime";
15858
15944
  var CODE_LANGUAGE_OPTIONS_PRISM = getCodeLanguageOptionsPrism().filter(
15859
15945
  (option) => [
15860
15946
  "c",
@@ -16510,7 +16596,7 @@ function ToolbarPlugin({
16510
16596
  $handleHeadingNode,
16511
16597
  $handleCodeNode
16512
16598
  ]);
16513
- useEffect45(() => {
16599
+ useEffect46(() => {
16514
16600
  return editor.registerCommand(
16515
16601
  SELECTION_CHANGE_COMMAND5,
16516
16602
  (_payload, newEditor) => {
@@ -16521,7 +16607,7 @@ function ToolbarPlugin({
16521
16607
  COMMAND_PRIORITY_CRITICAL3
16522
16608
  );
16523
16609
  }, [editor, $updateToolbar, setActiveEditor]);
16524
- useEffect45(() => {
16610
+ useEffect46(() => {
16525
16611
  activeEditor.getEditorState().read(
16526
16612
  () => {
16527
16613
  $updateToolbar();
@@ -16529,7 +16615,7 @@ function ToolbarPlugin({
16529
16615
  { editor: activeEditor }
16530
16616
  );
16531
16617
  }, [activeEditor, $updateToolbar]);
16532
- useEffect45(() => {
16618
+ useEffect46(() => {
16533
16619
  return mergeRegister14(
16534
16620
  editor.registerEditableListener((editable) => {
16535
16621
  setIsEditable(editable);
@@ -16660,7 +16746,7 @@ function ToolbarPlugin({
16660
16746
  }
16661
16747
  ),
16662
16748
  /* @__PURE__ */ jsx50(Divider, {}),
16663
- toolbarState.blockType in blockTypeToBlockName && activeEditor === editor && /* @__PURE__ */ jsxs37(Fragment19, { children: [
16749
+ toolbarState.blockType in blockTypeToBlockName && activeEditor === editor && /* @__PURE__ */ jsxs37(Fragment22, { children: [
16664
16750
  /* @__PURE__ */ jsx50(
16665
16751
  BlockFormatDropDown,
16666
16752
  {
@@ -16672,7 +16758,7 @@ function ToolbarPlugin({
16672
16758
  ),
16673
16759
  /* @__PURE__ */ jsx50(Divider, {})
16674
16760
  ] }),
16675
- toolbarState.blockType === "code" && isCodeHighlighted ? /* @__PURE__ */ jsxs37(Fragment19, { children: [
16761
+ toolbarState.blockType === "code" && isCodeHighlighted ? /* @__PURE__ */ jsxs37(Fragment22, { children: [
16676
16762
  !isCodeShiki && /* @__PURE__ */ jsx50(
16677
16763
  DropDown,
16678
16764
  {
@@ -16697,7 +16783,7 @@ function ToolbarPlugin({
16697
16783
  })
16698
16784
  }
16699
16785
  ),
16700
- isCodeShiki && /* @__PURE__ */ jsxs37(Fragment19, { children: [
16786
+ isCodeShiki && /* @__PURE__ */ jsxs37(Fragment22, { children: [
16701
16787
  /* @__PURE__ */ jsx50(
16702
16788
  DropDown,
16703
16789
  {
@@ -16747,7 +16833,7 @@ function ToolbarPlugin({
16747
16833
  }
16748
16834
  )
16749
16835
  ] })
16750
- ] }) : /* @__PURE__ */ jsxs37(Fragment19, { children: [
16836
+ ] }) : /* @__PURE__ */ jsxs37(Fragment22, { children: [
16751
16837
  /* @__PURE__ */ jsx50(
16752
16838
  FontDropDown,
16753
16839
  {
@@ -16990,7 +17076,7 @@ function ToolbarPlugin({
16990
17076
  ]
16991
17077
  }
16992
17078
  ),
16993
- canViewerSeeInsertDropdown && /* @__PURE__ */ jsxs37(Fragment19, { children: [
17079
+ canViewerSeeInsertDropdown && /* @__PURE__ */ jsxs37(Fragment22, { children: [
16994
17080
  /* @__PURE__ */ jsx50(Divider, {}),
16995
17081
  /* @__PURE__ */ jsxs37(
16996
17082
  DropDown,
@@ -17312,10 +17398,10 @@ function ToolbarPlugin({
17312
17398
 
17313
17399
  // src/plugins/StickyPlugin/index.ts
17314
17400
  import { useLexicalComposerContext as useLexicalComposerContext48 } from "@lexical/react/LexicalComposerContext";
17315
- import { useEffect as useEffect46 } from "react";
17401
+ import { useEffect as useEffect47 } from "react";
17316
17402
  function StickyPlugin() {
17317
17403
  const [editor] = useLexicalComposerContext48();
17318
- useEffect46(() => {
17404
+ useEffect47(() => {
17319
17405
  if (!editor.hasNodes([StickyNode])) {
17320
17406
  throw new Error("StickyPlugin: StickyNode not registered on editor");
17321
17407
  }
@@ -17324,7 +17410,7 @@ function StickyPlugin() {
17324
17410
  }
17325
17411
 
17326
17412
  // src/Editor.tsx
17327
- import { Fragment as Fragment20, jsx as jsx51, jsxs as jsxs38 } from "react/jsx-runtime";
17413
+ import { Fragment as Fragment23, jsx as jsx51, jsxs as jsxs38 } from "react/jsx-runtime";
17328
17414
  function Editor({ placeholder: placeholderProp, maxLength }) {
17329
17415
  const { historyState } = useSharedHistoryContext();
17330
17416
  const {
@@ -17363,7 +17449,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17363
17449
  setFloatingAnchorElem(_floatingAnchorElem);
17364
17450
  }
17365
17451
  };
17366
- useEffect47(() => {
17452
+ useEffect48(() => {
17367
17453
  const updateViewPortWidth = () => {
17368
17454
  const isNextSmallWidthViewport = CAN_USE_DOM && window.matchMedia("(max-width: 1025px)").matches;
17369
17455
  if (isNextSmallWidthViewport !== isSmallWidthViewport) {
@@ -17376,7 +17462,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17376
17462
  window.removeEventListener("resize", updateViewPortWidth);
17377
17463
  };
17378
17464
  }, [isSmallWidthViewport]);
17379
- return /* @__PURE__ */ jsxs38(Fragment20, { children: [
17465
+ return /* @__PURE__ */ jsxs38(Fragment23, { children: [
17380
17466
  isRichText && /* @__PURE__ */ jsx51(
17381
17467
  ToolbarPlugin,
17382
17468
  {
@@ -17413,7 +17499,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17413
17499
  /* @__PURE__ */ jsx51(LexicalAutoLinkPlugin, {}),
17414
17500
  /* @__PURE__ */ jsx51(DateTimePlugin, {}),
17415
17501
  /* @__PURE__ */ jsx51(CommentPlugin, {}),
17416
- isRichText ? /* @__PURE__ */ jsxs38(Fragment20, { children: [
17502
+ isRichText ? /* @__PURE__ */ jsxs38(Fragment23, { children: [
17417
17503
  /* @__PURE__ */ jsx51(HistoryPlugin2, { externalHistoryState: historyState }),
17418
17504
  /* @__PURE__ */ jsx51(
17419
17505
  RichTextPlugin,
@@ -17470,7 +17556,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17470
17556
  /* @__PURE__ */ jsx51(RevisionPlugin, {}),
17471
17557
  /* @__PURE__ */ jsx51(TextCardsPlugin, {}),
17472
17558
  /* @__PURE__ */ jsx51(QuestionsCardsPlugin, {}),
17473
- floatingAnchorElem && /* @__PURE__ */ jsxs38(Fragment20, { children: [
17559
+ floatingAnchorElem && /* @__PURE__ */ jsxs38(Fragment23, { children: [
17474
17560
  /* @__PURE__ */ jsx51(
17475
17561
  FloatingLinkEditorPlugin,
17476
17562
  {
@@ -17487,7 +17573,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17487
17573
  }
17488
17574
  )
17489
17575
  ] }),
17490
- floatingAnchorElem && !isSmallWidthViewport && /* @__PURE__ */ jsxs38(Fragment20, { children: [
17576
+ floatingAnchorElem && !isSmallWidthViewport && /* @__PURE__ */ jsxs38(Fragment23, { children: [
17491
17577
  /* @__PURE__ */ jsx51(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }),
17492
17578
  /* @__PURE__ */ jsx51(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }),
17493
17579
  /* @__PURE__ */ jsx51(TableHoverActionsV2Plugin, { anchorElem: floatingAnchorElem }),
@@ -17499,7 +17585,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17499
17585
  }
17500
17586
  )
17501
17587
  ] })
17502
- ] }) : /* @__PURE__ */ jsxs38(Fragment20, { children: [
17588
+ ] }) : /* @__PURE__ */ jsxs38(Fragment23, { children: [
17503
17589
  /* @__PURE__ */ jsx51(
17504
17590
  PlainTextPlugin2,
17505
17591
  {
@@ -17639,6 +17725,14 @@ function hasComplexStyles(el) {
17639
17725
  return COMPLEX_STYLE_PATTERNS.some((re) => re.test(style));
17640
17726
  }
17641
17727
  var DATA_ATTR7 = "data-lexical-html-block";
17728
+ var LEXICAL_NODE_ATTRS = [
17729
+ "data-lexical-notes",
17730
+ "data-lexical-terminology",
17731
+ "data-lexical-revision",
17732
+ "data-lexical-text-cards",
17733
+ "data-lexical-questions-cards",
17734
+ "data-lexical-html-block"
17735
+ ];
17642
17736
  function preprocessHtmlForImport(doc) {
17643
17737
  processChildren(doc.body);
17644
17738
  }
@@ -17646,6 +17740,7 @@ function processChildren(parent) {
17646
17740
  const children = Array.from(parent.children);
17647
17741
  for (const child of children) {
17648
17742
  if (child.hasAttribute(DATA_ATTR7)) continue;
17743
+ if (LEXICAL_NODE_ATTRS.some((attr) => child.hasAttribute(attr))) continue;
17649
17744
  const tag = child.tagName;
17650
17745
  if (tag === "DIV") {
17651
17746
  if (hasComplexStyles(child)) {
@@ -17687,10 +17782,10 @@ function HtmlPlugin({
17687
17782
  debounceMs = 300
17688
17783
  }) {
17689
17784
  const [editor] = useLexicalComposerContext50();
17690
- const lastSyncedValue = useRef20(null);
17691
- const hasUserEdited = useRef20(false);
17692
- const debounceTimer = useRef20(null);
17693
- useEffect48(() => {
17785
+ const lastSyncedValue = useRef21(null);
17786
+ const hasUserEdited = useRef21(false);
17787
+ const debounceTimer = useRef21(null);
17788
+ useEffect49(() => {
17694
17789
  return editor.registerCommand(
17695
17790
  FOCUS_COMMAND2,
17696
17791
  () => {
@@ -17712,7 +17807,7 @@ function HtmlPlugin({
17712
17807
  COMMAND_PRIORITY_LOW11
17713
17808
  );
17714
17809
  }, [editor]);
17715
- useEffect48(() => {
17810
+ useEffect49(() => {
17716
17811
  if (value === lastSyncedValue.current) {
17717
17812
  return;
17718
17813
  }
@@ -17731,9 +17826,9 @@ function HtmlPlugin({
17731
17826
  const parser = new DOMParser();
17732
17827
  const dom = parser.parseFromString(value, "text/html");
17733
17828
  preprocessHtmlForImport(dom);
17734
- const nodes = $generateNodesFromDOM(editor, dom);
17829
+ const nodes = $generateNodesFromDOM2(editor, dom);
17735
17830
  root.clear();
17736
- $insertNodes6(nodes);
17831
+ $insertNodes7(nodes);
17737
17832
  },
17738
17833
  // Prevent scroll-to-top when loading content inside a Sheet
17739
17834
  { tag: "historic" }
@@ -17763,7 +17858,7 @@ function HtmlPlugin({
17763
17858
  },
17764
17859
  [editor, onChange, debounceMs]
17765
17860
  );
17766
- useEffect48(() => {
17861
+ useEffect49(() => {
17767
17862
  return () => {
17768
17863
  if (debounceTimer.current) {
17769
17864
  clearTimeout(debounceTimer.current);
@@ -17774,7 +17869,7 @@ function HtmlPlugin({
17774
17869
  }
17775
17870
  function ReadOnlyController({ readOnly }) {
17776
17871
  const [editor] = useLexicalComposerContext50();
17777
- useEffect48(() => {
17872
+ useEffect49(() => {
17778
17873
  editor.setEditable(!readOnly);
17779
17874
  }, [editor, readOnly]);
17780
17875
  return null;
@@ -17797,6 +17892,51 @@ function LexicalEditor20({
17797
17892
  theme: PlaygroundEditorTheme_default,
17798
17893
  onError: (error) => {
17799
17894
  console.error("[LexicalEditor]", error);
17895
+ },
17896
+ html: {
17897
+ // Custom TextNode export: preserve inline style (e.g. color) in the HTML output.
17898
+ // Lexical's default TextNode.exportDOM() does not write __style to the element,
17899
+ // so colored text is lost when saving. This override wraps styled text in a
17900
+ // <span style="..."> so the color survives save/reload cycles.
17901
+ export: /* @__PURE__ */ new Map([
17902
+ [TextNode6, (editor, node) => {
17903
+ const { element } = node.exportDOM(editor);
17904
+ const style2 = node.getStyle();
17905
+ if (element && style2) {
17906
+ const el = element;
17907
+ style2.split(";").forEach((decl) => {
17908
+ const [prop, val] = decl.split(":").map((s) => s.trim());
17909
+ if (prop && val) el.style.setProperty(prop, val);
17910
+ });
17911
+ }
17912
+ return { element };
17913
+ }]
17914
+ ]),
17915
+ // Custom import: read inline color style from span/b/strong/i/u back into TextNode.setStyle().
17916
+ // Lexical's default converters only read bold/italic/underline formats, not color.
17917
+ import: ["span", "b", "strong", "i", "u", "s"].reduce((acc, tag) => {
17918
+ acc[tag] = (domNode) => {
17919
+ const style2 = domNode.style?.cssText;
17920
+ if (!style2) return null;
17921
+ return {
17922
+ conversion: (node) => ({
17923
+ forChild: (lexicalNode) => {
17924
+ if ($isTextNode8(lexicalNode)) {
17925
+ const filtered = node.style.cssText.split(";").map((d) => d.trim()).filter((d) => d && !/^white-space\s*:/i.test(d)).join("; ");
17926
+ if (filtered) {
17927
+ const existing = lexicalNode.getStyle() || "";
17928
+ lexicalNode.setStyle(existing ? existing + "; " + filtered : filtered);
17929
+ }
17930
+ }
17931
+ return lexicalNode;
17932
+ },
17933
+ node: null
17934
+ }),
17935
+ priority: 2
17936
+ };
17937
+ };
17938
+ return acc;
17939
+ }, {})
17800
17940
  }
17801
17941
  };
17802
17942
  const style = isFullscreen ? {
@@ -17811,7 +17951,7 @@ function LexicalEditor20({
17811
17951
  position: "relative",
17812
17952
  overflow: "auto"
17813
17953
  };
17814
- useEffect48(() => {
17954
+ useEffect49(() => {
17815
17955
  if (!isFullscreen) return;
17816
17956
  const handleEsc = (e) => {
17817
17957
  if (e.key === "Escape") setIsFullscreen(false);
@@ -17823,11 +17963,11 @@ function LexicalEditor20({
17823
17963
  () => setIsFullscreen((f) => !f),
17824
17964
  []
17825
17965
  );
17826
- const fullscreenValue = useMemo24(
17966
+ const fullscreenValue = useMemo23(
17827
17967
  () => ({ isFullscreen, toggleFullscreen }),
17828
17968
  [isFullscreen, toggleFullscreen]
17829
17969
  );
17830
- const collabContextValue = useMemo24(
17970
+ const collabContextValue = useMemo23(
17831
17971
  () => ({
17832
17972
  color: "#000",
17833
17973
  isCollabActive: false,