@baasix/lexical 0.0.11 → 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";
@@ -8576,7 +8595,7 @@ function NotesComponent({
8576
8595
  setIsEditing(false);
8577
8596
  }, []);
8578
8597
  return /* @__PURE__ */ jsx23(BlockWithAlignableContents4, { className, format, nodeKey, children: /* @__PURE__ */ jsxs13("div", { style: { position: "relative" }, children: [
8579
- isEditable && !isEditing && /* @__PURE__ */ jsx23(
8598
+ isEditable && /* @__PURE__ */ jsx23(
8580
8599
  "button",
8581
8600
  {
8582
8601
  type: "button",
@@ -8601,37 +8620,13 @@ function NotesComponent({
8601
8620
  children: "Edit Notes"
8602
8621
  }
8603
8622
  ),
8604
- isEditing ? /* @__PURE__ */ jsxs13("div", { style: { border: "1px solid #ccc", borderRadius: 4, padding: 8, background: "#f9f9f9" }, children: [
8605
- /* @__PURE__ */ jsxs13("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }, children: [
8606
- /* @__PURE__ */ jsx23("span", { style: { fontSize: 13, fontWeight: 600, color: CARD_STYLES.notes.headingColor }, children: "Edit Notes" }),
8607
- /* @__PURE__ */ jsxs13("div", { style: { display: "flex", gap: 4 }, children: [
8608
- /* @__PURE__ */ jsx23(
8609
- "button",
8610
- {
8611
- type: "button",
8612
- onClick: cancelEdit,
8613
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" },
8614
- children: "Cancel"
8615
- }
8616
- ),
8617
- /* @__PURE__ */ jsx23(
8618
- "button",
8619
- {
8620
- type: "button",
8621
- onClick: saveChanges,
8622
- disabled: !preview,
8623
- style: { padding: "2px 10px", fontSize: 12, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 },
8624
- children: "Save"
8625
- }
8626
- )
8627
- ] })
8628
- ] }),
8623
+ /* @__PURE__ */ jsx23("div", { dangerouslySetInnerHTML: { __html: html } }),
8624
+ isEditing && /* @__PURE__ */ jsx23(Modal, { onClose: cancelEdit, title: "Edit Notes", children: /* @__PURE__ */ jsxs13("div", { style: { minWidth: 500 }, children: [
8629
8625
  /* @__PURE__ */ jsx23(
8630
8626
  "textarea",
8631
8627
  {
8632
8628
  value: editText,
8633
8629
  onChange: (e) => setEditText(e.target.value),
8634
- onMouseDown: (e) => e.stopPropagation(),
8635
8630
  style: {
8636
8631
  width: "100%",
8637
8632
  minHeight: 150,
@@ -8644,11 +8639,15 @@ function NotesComponent({
8644
8639
  }
8645
8640
  }
8646
8641
  ),
8647
- preview && /* @__PURE__ */ jsxs13("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff" }, children: [
8642
+ preview && /* @__PURE__ */ jsxs13("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 200, overflow: "auto" }, children: [
8648
8643
  /* @__PURE__ */ jsx23("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
8649
8644
  /* @__PURE__ */ jsx23("div", { dangerouslySetInnerHTML: { __html: preview } })
8645
+ ] }),
8646
+ /* @__PURE__ */ jsxs13("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 12 }, children: [
8647
+ /* @__PURE__ */ jsx23("button", { type: "button", onClick: cancelEdit, style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" }, children: "Cancel" }),
8648
+ /* @__PURE__ */ jsx23("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" })
8650
8649
  ] })
8651
- ] }) : /* @__PURE__ */ jsx23("div", { dangerouslySetInnerHTML: { __html: html } })
8650
+ ] }) })
8652
8651
  ] }) });
8653
8652
  }
8654
8653
  var DATA_ATTR = "data-lexical-notes";
@@ -8726,7 +8725,7 @@ function $isNotesNode(node) {
8726
8725
  }
8727
8726
 
8728
8727
  // src/plugins/NotesPlugin/index.tsx
8729
- 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";
8730
8729
  var INSERT_NOTES_COMMAND = createCommand13(
8731
8730
  "INSERT_NOTES_COMMAND"
8732
8731
  );
@@ -8748,135 +8747,153 @@ function NotesPlugin() {
8748
8747
  }, [editor]);
8749
8748
  return null;
8750
8749
  }
8751
- function convertRichHtmlToNotes(htmlStr, baasixClient, folder) {
8752
- return new Promise(async (resolve) => {
8753
- const parser = new DOMParser();
8754
- const doc = parser.parseFromString(htmlStr, "text/html");
8755
- if (baasixClient) {
8756
- const imgs = doc.querySelectorAll("img");
8757
- for (let i = 0; i < imgs.length; i++) {
8758
- const img2 = imgs[i];
8759
- const src = img2.getAttribute("src") || "";
8760
- if (src.startsWith("data:")) {
8761
- try {
8762
- const resp = await fetch(src);
8763
- const blob = await resp.blob();
8764
- const ext = blob.type.split("/")[1] || "png";
8765
- const file = new File([blob], `note-image-${i}.${ext}`, { type: blob.type });
8766
- const uploadedUrl = await uploadImageToBaasix(baasixClient, file, folder);
8767
- img2.setAttribute("src", uploadedUrl);
8768
- } catch {
8769
- }
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 {
8770
8768
  }
8771
8769
  }
8772
8770
  }
8773
- let html = `<div style="font-family: sans-serif; line-height: 1.6; color: inherit;">`;
8774
- const children = Array.from(doc.body.childNodes);
8775
- for (const child of children) {
8776
- html += processNode(child);
8777
- }
8778
- html += "</div>";
8779
- resolve(html.replace(/>\s+</g, "><"));
8780
- });
8771
+ }
8772
+ return doc.body.innerHTML;
8781
8773
  }
8774
+ var HEADING_COLOR = "#6b5b95";
8782
8775
  function InsertNotesDialog({
8783
8776
  activeEditor,
8784
8777
  onClose
8785
8778
  }) {
8786
- const [input, setInput] = useState18("");
8787
- const [richHtml, setRichHtml] = useState18("");
8779
+ const [pastedHtml, setPastedHtml] = useState18("");
8788
8780
  const [isUploading, setIsUploading] = useState18(false);
8781
+ const [hasPasted, setHasPasted] = useState18(false);
8789
8782
  const pasteAreaRef = useRef9(null);
8790
8783
  let editorConfig = null;
8791
8784
  try {
8792
8785
  editorConfig = useEditorConfig();
8793
8786
  } catch {
8794
8787
  }
8795
- const handleRichPaste = useCallback12(async (e) => {
8788
+ const handlePaste = useCallback12(async (e) => {
8796
8789
  e.preventDefault();
8797
- const clipboardData = e.clipboardData;
8798
- const htmlData = clipboardData.getData("text/html");
8799
- const textData = clipboardData.getData("text/plain");
8800
- if (htmlData) {
8801
- setIsUploading(true);
8802
- try {
8803
- const processed = await convertRichHtmlToNotes(
8804
- htmlData,
8805
- editorConfig?.baasixClient,
8806
- editorConfig?.folder
8807
- );
8808
- setRichHtml(processed);
8809
- setInput("");
8810
- } finally {
8811
- setIsUploading(false);
8812
- }
8813
- } else if (textData) {
8814
- setInput((prev) => prev ? prev + "\n" + textData : textData);
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);
8815
8801
  }
8802
+ }, [editorConfig]);
8803
+ const handleClear = useCallback12(() => {
8804
+ setPastedHtml("");
8805
+ setHasPasted(false);
8816
8806
  if (pasteAreaRef.current) {
8817
- pasteAreaRef.current.innerHTML = '<span style="color: #9ca3af; pointer-events: none; user-select: none;">Paste from Word/Docs here (preserves formatting)</span>';
8807
+ pasteAreaRef.current.innerHTML = "";
8818
8808
  }
8819
- }, [editorConfig]);
8820
- const finalHtml = useMemo8(() => {
8821
- if (richHtml) return richHtml;
8822
- if (!input.trim()) return "";
8823
- return convertNotes(input);
8824
- }, [input, richHtml]);
8809
+ }, []);
8825
8810
  const handleInsert = useCallback12(() => {
8826
- if (!finalHtml) return;
8827
- activeEditor.dispatchCommand(INSERT_NOTES_COMMAND, finalHtml);
8828
- onClose();
8829
- }, [activeEditor, finalHtml, onClose]);
8830
- return /* @__PURE__ */ jsxs14("div", { style: { minWidth: 500 }, children: [
8831
- /* @__PURE__ */ jsx24(
8832
- "textarea",
8833
- {
8834
- value: input,
8835
- onChange: (e) => {
8836
- setInput(e.target.value);
8837
- setRichHtml("");
8838
- },
8839
- placeholder: "Paste or type notes here (plain text)...\nExample:\nSuperficial Fascia\nThe superficial fascia is a layer of loose...\n\nFunctions\n- Passageway for vessels\n- Insulation",
8840
- style: {
8841
- width: "100%",
8842
- minHeight: 120,
8843
- fontFamily: "monospace",
8844
- fontSize: 13,
8845
- padding: 8,
8846
- border: "1px solid #ddd",
8847
- borderRadius: 4,
8848
- resize: "vertical",
8849
- 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";
8850
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);
8851
8845
  }
8852
- ),
8853
- /* @__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(
8854
8855
  "div",
8855
8856
  {
8856
8857
  ref: pasteAreaRef,
8857
8858
  contentEditable: true,
8858
- onPaste: handleRichPaste,
8859
+ onPaste: handlePaste,
8859
8860
  onMouseDown: (e) => e.stopPropagation(),
8860
8861
  style: {
8861
8862
  width: "100%",
8862
- minHeight: 40,
8863
- padding: 8,
8863
+ minHeight: 160,
8864
+ padding: 12,
8864
8865
  border: "2px dashed #93c5fd",
8865
8866
  borderRadius: 4,
8866
- fontSize: 12,
8867
+ fontSize: 13,
8867
8868
  color: "#6b7280",
8868
8869
  marginBottom: 8,
8869
8870
  outline: "none",
8870
8871
  background: "#f0f7ff"
8871
8872
  },
8872
- suppressContentEditableWarning: true,
8873
- children: /* @__PURE__ */ jsx24("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: isUploading ? "Processing content..." : "Paste from Word/Docs here (preserves formatting)" })
8873
+ "data-placeholder": isUploading ? "Processing content..." : "Paste from Word/Docs here (preserves formatting)",
8874
+ suppressContentEditableWarning: true
8874
8875
  }
8875
8876
  ),
8876
- richHtml && /* @__PURE__ */ jsx24("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: "Rich content captured (formatting preserved)" }),
8877
- finalHtml && /* @__PURE__ */ jsxs14("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 200, overflow: "auto" }, children: [
8878
- /* @__PURE__ */ jsx24("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
8879
- /* @__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
+ )
8880
8897
  ] }),
8881
8898
  /* @__PURE__ */ jsxs14("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
8882
8899
  /* @__PURE__ */ jsx24(
@@ -8893,8 +8910,8 @@ function InsertNotesDialog({
8893
8910
  {
8894
8911
  type: "button",
8895
8912
  onClick: handleInsert,
8896
- disabled: !finalHtml || isUploading,
8897
- style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: finalHtml && !isUploading ? 1 : 0.5 },
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 },
8898
8915
  children: isUploading ? "Processing..." : "Insert"
8899
8916
  }
8900
8917
  )
@@ -8907,13 +8924,13 @@ import { useLexicalComposerContext as useLexicalComposerContext22 } from "@lexic
8907
8924
  import { $wrapNodeInElement as $wrapNodeInElement5 } from "@lexical/utils";
8908
8925
  import {
8909
8926
  $createParagraphNode as $createParagraphNode8,
8910
- $insertNodes as $insertNodes5,
8927
+ $insertNodes as $insertNodes6,
8911
8928
  $isRootOrShadowRoot as $isRootOrShadowRoot5,
8912
8929
  COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR14,
8913
8930
  createCommand as createCommand14
8914
8931
  } from "lexical";
8915
8932
  import { useEffect as useEffect24, useState as useState19 } from "react";
8916
- 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";
8917
8934
  var INSERT_POLL_COMMAND = createCommand14(
8918
8935
  "INSERT_POLL_COMMAND"
8919
8936
  );
@@ -8926,7 +8943,7 @@ function InsertPollDialog({
8926
8943
  activeEditor.dispatchCommand(INSERT_POLL_COMMAND, question);
8927
8944
  onClose();
8928
8945
  };
8929
- return /* @__PURE__ */ jsxs15(Fragment9, { children: [
8946
+ return /* @__PURE__ */ jsxs15(Fragment10, { children: [
8930
8947
  /* @__PURE__ */ jsx25(TextInput, { label: "Question", onChange: setQuestion, value: question }),
8931
8948
  /* @__PURE__ */ jsx25(DialogActions, { children: /* @__PURE__ */ jsx25(Button, { disabled: question.trim() === "", onClick, children: "Confirm" }) })
8932
8949
  ] });
@@ -8944,7 +8961,7 @@ function PollPlugin() {
8944
8961
  createPollOption(),
8945
8962
  createPollOption()
8946
8963
  ]);
8947
- $insertNodes5([pollNode]);
8964
+ $insertNodes6([pollNode]);
8948
8965
  if ($isRootOrShadowRoot5(pollNode.getParentOrThrow())) {
8949
8966
  $wrapNodeInElement5(pollNode, $createParagraphNode8).selectEnd();
8950
8967
  }
@@ -8960,7 +8977,7 @@ function PollPlugin() {
8960
8977
  import { useLexicalComposerContext as useLexicalComposerContext24 } from "@lexical/react/LexicalComposerContext";
8961
8978
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot8 } from "@lexical/utils";
8962
8979
  import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR15, createCommand as createCommand15 } from "lexical";
8963
- 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";
8964
8981
 
8965
8982
  // src/nodes/RevisionNode.tsx
8966
8983
  import { $getNodeByKey as $getNodeByKey5 } from "lexical";
@@ -8970,7 +8987,7 @@ import {
8970
8987
  } from "@lexical/react/LexicalDecoratorBlockNode";
8971
8988
  import { useLexicalComposerContext as useLexicalComposerContext23 } from "@lexical/react/LexicalComposerContext";
8972
8989
  import { useLexicalEditable as useLexicalEditable2 } from "@lexical/react/useLexicalEditable";
8973
- 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";
8974
8991
  import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
8975
8992
  function RevisionComponent({
8976
8993
  className,
@@ -8986,7 +9003,7 @@ function RevisionComponent({
8986
9003
  setItems(parseRevisionHtml(html));
8987
9004
  setIsEditing(true);
8988
9005
  }, [html]);
8989
- const preview = useMemo9(() => {
9006
+ const preview = useMemo8(() => {
8990
9007
  if (!isEditing) return "";
8991
9008
  const filtered = items.filter((i) => i.trim());
8992
9009
  return filtered.length > 0 ? convertRevision(filtered.join("\n")) : "";
@@ -9014,7 +9031,7 @@ function RevisionComponent({
9014
9031
  setItems((prev) => prev.filter((_, i) => i !== index));
9015
9032
  }, []);
9016
9033
  return /* @__PURE__ */ jsx26(BlockWithAlignableContents5, { className, format, nodeKey, children: /* @__PURE__ */ jsxs16("div", { style: { position: "relative" }, children: [
9017
- isEditable && !isEditing && /* @__PURE__ */ jsx26(
9034
+ isEditable && /* @__PURE__ */ jsx26(
9018
9035
  "button",
9019
9036
  {
9020
9037
  type: "button",
@@ -9039,32 +9056,10 @@ function RevisionComponent({
9039
9056
  children: "Edit Revision"
9040
9057
  }
9041
9058
  ),
9042
- isEditing ? /* @__PURE__ */ jsxs16("div", { style: { border: "1px solid #ccc", borderRadius: 4, padding: 8, background: "#f9f9f9" }, children: [
9043
- /* @__PURE__ */ jsxs16("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }, children: [
9044
- /* @__PURE__ */ jsx26("span", { style: { fontSize: 13, fontWeight: 600, color: "#c2703a" }, children: "Edit Revision Points" }),
9045
- /* @__PURE__ */ jsxs16("div", { style: { display: "flex", gap: 4 }, children: [
9046
- /* @__PURE__ */ jsx26(
9047
- "button",
9048
- {
9049
- type: "button",
9050
- onClick: cancelEdit,
9051
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" },
9052
- children: "Cancel"
9053
- }
9054
- ),
9055
- /* @__PURE__ */ jsx26(
9056
- "button",
9057
- {
9058
- type: "button",
9059
- onClick: saveChanges,
9060
- disabled: !preview,
9061
- style: { padding: "2px 10px", fontSize: 12, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 },
9062
- children: "Save"
9063
- }
9064
- )
9065
- ] })
9066
- ] }),
9067
- items.map((item, index) => /* @__PURE__ */ jsxs16("div", { style: { display: "flex", gap: 4, marginBottom: 4, alignItems: "center" }, children: [
9059
+ /* @__PURE__ */ jsx26("div", { dangerouslySetInnerHTML: { __html: html } }),
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" }),
9068
9063
  /* @__PURE__ */ jsx26(
9069
9064
  "input",
9070
9065
  {
@@ -9072,7 +9067,6 @@ function RevisionComponent({
9072
9067
  placeholder: "Revision point",
9073
9068
  value: item,
9074
9069
  onChange: (e) => updateItem(index, e.target.value),
9075
- onMouseDown: (e) => e.stopPropagation(),
9076
9070
  style: { flex: 1, padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4 }
9077
9071
  }
9078
9072
  ),
@@ -9085,21 +9079,27 @@ function RevisionComponent({
9085
9079
  children: "\xD7"
9086
9080
  }
9087
9081
  )
9088
- ] }, index)),
9089
- /* @__PURE__ */ jsx26(
9090
- "button",
9091
- {
9092
- type: "button",
9093
- onClick: addItem,
9094
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginTop: 4 },
9095
- children: "+ Add Point"
9096
- }
9097
- ),
9098
- preview && /* @__PURE__ */ jsxs16("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff" }, children: [
9099
- /* @__PURE__ */ jsx26("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9100
- /* @__PURE__ */ jsx26("div", { dangerouslySetInnerHTML: { __html: preview } })
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
+ ] })
9101
9101
  ] })
9102
- ] }) : /* @__PURE__ */ jsx26("div", { dangerouslySetInnerHTML: { __html: html } })
9102
+ ] }) })
9103
9103
  ] }) });
9104
9104
  }
9105
9105
  var DATA_ATTR2 = "data-lexical-revision";
@@ -9204,7 +9204,7 @@ function InsertRevisionDialog({
9204
9204
  onClose
9205
9205
  }) {
9206
9206
  const [input, setInput] = useState21("");
9207
- const preview = useMemo10(() => {
9207
+ const preview = useMemo9(() => {
9208
9208
  if (!input.trim()) return "";
9209
9209
  return convertRevision(input);
9210
9210
  }, [input]);
@@ -9265,7 +9265,7 @@ function InsertRevisionDialog({
9265
9265
  import { useLexicalComposerContext as useLexicalComposerContext26 } from "@lexical/react/LexicalComposerContext";
9266
9266
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot9 } from "@lexical/utils";
9267
9267
  import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR16, createCommand as createCommand16 } from "lexical";
9268
- 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";
9269
9269
 
9270
9270
  // src/nodes/TerminologyNode.tsx
9271
9271
  import { $getNodeByKey as $getNodeByKey6 } from "lexical";
@@ -9275,7 +9275,7 @@ import {
9275
9275
  } from "@lexical/react/LexicalDecoratorBlockNode";
9276
9276
  import { useLexicalComposerContext as useLexicalComposerContext25 } from "@lexical/react/LexicalComposerContext";
9277
9277
  import { useLexicalEditable as useLexicalEditable3 } from "@lexical/react/useLexicalEditable";
9278
- 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";
9279
9279
  import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
9280
9280
  function TerminologyComponent({
9281
9281
  className,
@@ -9291,7 +9291,7 @@ function TerminologyComponent({
9291
9291
  setItems(parseTerminologyHtml(html));
9292
9292
  setIsEditing(true);
9293
9293
  }, [html]);
9294
- const preview = useMemo11(() => {
9294
+ const preview = useMemo10(() => {
9295
9295
  if (!isEditing) return "";
9296
9296
  const text = items.filter((i) => i.term || i.definition).map((i) => i.term ? `${i.term}: ${i.definition}` : i.definition).join("\n");
9297
9297
  return text ? convertTerminology(text) : "";
@@ -9318,58 +9318,37 @@ function TerminologyComponent({
9318
9318
  const removeItem = useCallback15((index) => {
9319
9319
  setItems((prev) => prev.filter((_, i) => i !== index));
9320
9320
  }, []);
9321
- return /* @__PURE__ */ jsx28(BlockWithAlignableContents6, { className, format, nodeKey, children: /* @__PURE__ */ jsxs18("div", { style: { position: "relative" }, children: [
9322
- isEditable && !isEditing && /* @__PURE__ */ jsx28(
9323
- "button",
9324
- {
9325
- type: "button",
9326
- onClick: openEditor,
9327
- onMouseDown: (e) => e.preventDefault(),
9328
- style: {
9329
- position: "absolute",
9330
- top: 4,
9331
- right: 4,
9332
- zIndex: 10,
9333
- background: CARD_STYLES.terminology.keyColor,
9334
- color: "#fff",
9335
- border: "none",
9336
- borderRadius: 4,
9337
- padding: "2px 8px",
9338
- fontSize: 12,
9339
- cursor: "pointer",
9340
- opacity: 0,
9341
- transition: "opacity 0.15s"
9342
- },
9343
- className: "html-block-edit-btn",
9344
- children: "Edit Terminology"
9345
- }
9346
- ),
9347
- isEditing ? /* @__PURE__ */ jsxs18("div", { style: { border: "1px solid #ccc", borderRadius: 4, padding: 8, background: "#f9f9f9" }, children: [
9348
- /* @__PURE__ */ jsxs18("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }, children: [
9349
- /* @__PURE__ */ jsx28("span", { style: { fontSize: 13, fontWeight: 600, color: CARD_STYLES.terminology.keyColor }, children: "Edit Terminology" }),
9350
- /* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: 4 }, children: [
9351
- /* @__PURE__ */ jsx28(
9352
- "button",
9353
- {
9354
- type: "button",
9355
- onClick: cancelEdit,
9356
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" },
9357
- children: "Cancel"
9358
- }
9359
- ),
9360
- /* @__PURE__ */ jsx28(
9361
- "button",
9362
- {
9363
- type: "button",
9364
- onClick: saveChanges,
9365
- disabled: !preview,
9366
- style: { padding: "2px 10px", fontSize: 12, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 },
9367
- children: "Save"
9368
- }
9369
- )
9370
- ] })
9371
- ] }),
9372
- items.map((item, index) => /* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: 4, marginBottom: 4, alignItems: "center" }, children: [
9321
+ return /* @__PURE__ */ jsxs18(BlockWithAlignableContents6, { className, format, nodeKey, children: [
9322
+ /* @__PURE__ */ jsxs18("div", { style: { position: "relative" }, children: [
9323
+ isEditable && /* @__PURE__ */ jsx28(
9324
+ "button",
9325
+ {
9326
+ type: "button",
9327
+ onClick: openEditor,
9328
+ onMouseDown: (e) => e.preventDefault(),
9329
+ style: {
9330
+ position: "absolute",
9331
+ top: 4,
9332
+ right: 4,
9333
+ zIndex: 10,
9334
+ background: CARD_STYLES.terminology.keyColor,
9335
+ color: "#fff",
9336
+ border: "none",
9337
+ borderRadius: 4,
9338
+ padding: "2px 8px",
9339
+ fontSize: 12,
9340
+ cursor: "pointer",
9341
+ opacity: 0,
9342
+ transition: "opacity 0.15s"
9343
+ },
9344
+ className: "html-block-edit-btn",
9345
+ children: "Edit Terminology"
9346
+ }
9347
+ ),
9348
+ /* @__PURE__ */ jsx28("div", { dangerouslySetInnerHTML: { __html: html } })
9349
+ ] }),
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: [
9373
9352
  /* @__PURE__ */ jsx28(
9374
9353
  "input",
9375
9354
  {
@@ -9377,7 +9356,6 @@ function TerminologyComponent({
9377
9356
  placeholder: "Term",
9378
9357
  value: item.term,
9379
9358
  onChange: (e) => updateItem(index, "term", e.target.value),
9380
- onMouseDown: (e) => e.stopPropagation(),
9381
9359
  style: { width: "30%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4 }
9382
9360
  }
9383
9361
  ),
@@ -9388,7 +9366,6 @@ function TerminologyComponent({
9388
9366
  placeholder: "Definition",
9389
9367
  value: item.definition,
9390
9368
  onChange: (e) => updateItem(index, "definition", e.target.value),
9391
- onMouseDown: (e) => e.stopPropagation(),
9392
9369
  style: { flex: 1, padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4 }
9393
9370
  }
9394
9371
  ),
@@ -9401,22 +9378,45 @@ function TerminologyComponent({
9401
9378
  children: "\xD7"
9402
9379
  }
9403
9380
  )
9404
- ] }, index)),
9405
- /* @__PURE__ */ jsx28(
9406
- "button",
9407
- {
9408
- type: "button",
9409
- onClick: addItem,
9410
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginTop: 4 },
9411
- children: "+ Add Term"
9412
- }
9413
- ),
9414
- preview && /* @__PURE__ */ jsxs18("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff" }, children: [
9415
- /* @__PURE__ */ jsx28("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9416
- /* @__PURE__ */ jsx28("div", { dangerouslySetInnerHTML: { __html: preview } })
9381
+ ] }, index)) }),
9382
+ /* @__PURE__ */ jsxs18("div", { style: { flexShrink: 0, paddingTop: 8 }, children: [
9383
+ /* @__PURE__ */ jsx28(
9384
+ "button",
9385
+ {
9386
+ type: "button",
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"
9390
+ }
9391
+ ),
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
+ ] })
9417
9417
  ] })
9418
- ] }) : /* @__PURE__ */ jsx28("div", { dangerouslySetInnerHTML: { __html: html } })
9419
- ] }) });
9418
+ ] }) })
9419
+ ] });
9420
9420
  }
9421
9421
  var DATA_ATTR3 = "data-lexical-terminology";
9422
9422
  var TerminologyNode = class _TerminologyNode extends DecoratorBlockNode6 {
@@ -9520,7 +9520,7 @@ function InsertTerminologyDialog({
9520
9520
  onClose
9521
9521
  }) {
9522
9522
  const [input, setInput] = useState23("");
9523
- const preview = useMemo12(() => {
9523
+ const preview = useMemo11(() => {
9524
9524
  if (!input.trim()) return "";
9525
9525
  return convertTerminology(input);
9526
9526
  }, [input]);
@@ -9581,7 +9581,7 @@ function InsertTerminologyDialog({
9581
9581
  import { useLexicalComposerContext as useLexicalComposerContext28 } from "@lexical/react/LexicalComposerContext";
9582
9582
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot10 } from "@lexical/utils";
9583
9583
  import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR17, createCommand as createCommand17 } from "lexical";
9584
- 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";
9585
9585
 
9586
9586
  // src/nodes/TextCardsNode.tsx
9587
9587
  import { $getNodeByKey as $getNodeByKey7 } from "lexical";
@@ -9591,7 +9591,7 @@ import {
9591
9591
  } from "@lexical/react/LexicalDecoratorBlockNode";
9592
9592
  import { useLexicalComposerContext as useLexicalComposerContext27 } from "@lexical/react/LexicalComposerContext";
9593
9593
  import { useLexicalEditable as useLexicalEditable4 } from "@lexical/react/useLexicalEditable";
9594
- 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";
9595
9595
  import { jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
9596
9596
  var SECTION_KEYS = [
9597
9597
  "criticalThinking",
@@ -9629,7 +9629,7 @@ function TextCardsComponent({
9629
9629
  setConcepts(parsed);
9630
9630
  setIsEditing(true);
9631
9631
  }, [html]);
9632
- const preview = useMemo13(() => {
9632
+ const preview = useMemo12(() => {
9633
9633
  if (!isEditing) return "";
9634
9634
  const lines = [];
9635
9635
  concepts.forEach((concept, i) => {
@@ -9690,7 +9690,7 @@ function TextCardsComponent({
9690
9690
  }, []);
9691
9691
  const styles = CARD_STYLES.textCards;
9692
9692
  return /* @__PURE__ */ jsx30(BlockWithAlignableContents7, { className, format, nodeKey, children: /* @__PURE__ */ jsxs20("div", { style: { position: "relative" }, children: [
9693
- isEditable && !isEditing && /* @__PURE__ */ jsx30(
9693
+ isEditable && /* @__PURE__ */ jsx30(
9694
9694
  "button",
9695
9695
  {
9696
9696
  type: "button",
@@ -9715,38 +9715,15 @@ function TextCardsComponent({
9715
9715
  children: "Edit Text Cards"
9716
9716
  }
9717
9717
  ),
9718
- isEditing ? /* @__PURE__ */ jsxs20("div", { style: { border: "1px solid #ccc", borderRadius: 4, padding: 8, background: "#f9f9f9" }, children: [
9719
- /* @__PURE__ */ jsxs20("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }, children: [
9720
- /* @__PURE__ */ jsx30("span", { style: { fontSize: 13, fontWeight: 600, color: "rgba(76, 175, 80, 0.8)" }, children: "Edit Text Cards" }),
9721
- /* @__PURE__ */ jsxs20("div", { style: { display: "flex", gap: 4 }, children: [
9722
- /* @__PURE__ */ jsx30(
9723
- "button",
9724
- {
9725
- type: "button",
9726
- onClick: cancelEdit,
9727
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" },
9728
- children: "Cancel"
9729
- }
9730
- ),
9731
- /* @__PURE__ */ jsx30(
9732
- "button",
9733
- {
9734
- type: "button",
9735
- onClick: saveChanges,
9736
- disabled: !preview,
9737
- style: { padding: "2px 10px", fontSize: 12, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 },
9738
- children: "Save"
9739
- }
9740
- )
9741
- ] })
9742
- ] }),
9743
- concepts.map((concept, cIdx) => /* @__PURE__ */ jsxs20("div", { style: { border: "1px solid #e5e7eb", borderRadius: 6, padding: 8, marginBottom: 8, background: "#fff" }, children: [
9744
- /* @__PURE__ */ jsxs20("div", { style: { display: "flex", gap: 4, marginBottom: 6, alignItems: "center" }, children: [
9745
- /* @__PURE__ */ jsxs20("span", { style: { fontSize: 12, fontWeight: 600, color: "#4caf50", minWidth: 80 }, children: [
9746
- "Concept ",
9747
- cIdx + 1,
9748
- ":"
9749
- ] }),
9718
+ /* @__PURE__ */ jsx30("div", { dangerouslySetInnerHTML: { __html: html } }),
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: [
9721
+ /* @__PURE__ */ jsxs20("div", { style: { display: "flex", gap: 4, marginBottom: 6, alignItems: "center" }, children: [
9722
+ /* @__PURE__ */ jsxs20("span", { style: { fontSize: 12, fontWeight: 600, color: "#4caf50", minWidth: 80 }, children: [
9723
+ "Concept ",
9724
+ cIdx + 1,
9725
+ ":"
9726
+ ] }),
9750
9727
  /* @__PURE__ */ jsx30(
9751
9728
  "input",
9752
9729
  {
@@ -9754,7 +9731,6 @@ function TextCardsComponent({
9754
9731
  placeholder: "Concept title",
9755
9732
  value: concept.conceptTitle,
9756
9733
  onChange: (e) => updateConceptTitle(cIdx, e.target.value),
9757
- onMouseDown: (e) => e.stopPropagation(),
9758
9734
  style: { flex: 1, padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4 }
9759
9735
  }
9760
9736
  ),
@@ -9779,27 +9755,32 @@ function TextCardsComponent({
9779
9755
  placeholder: `${label} content...`,
9780
9756
  value: section.content,
9781
9757
  onChange: (e) => updateSection(cIdx, sIdx, e.target.value),
9782
- onMouseDown: (e) => e.stopPropagation(),
9783
9758
  style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 40, resize: "vertical" }
9784
9759
  }
9785
9760
  )
9786
9761
  ] }, sIdx);
9787
9762
  })
9788
- ] }, cIdx)),
9789
- /* @__PURE__ */ jsx30(
9790
- "button",
9791
- {
9792
- type: "button",
9793
- onClick: addConcept,
9794
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginTop: 4 },
9795
- children: "+ Add Concept"
9796
- }
9797
- ),
9798
- preview && /* @__PURE__ */ jsxs20("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff" }, children: [
9799
- /* @__PURE__ */ jsx30("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
9800
- /* @__PURE__ */ jsx30("div", { dangerouslySetInnerHTML: { __html: preview } })
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
+ ] })
9801
9782
  ] })
9802
- ] }) : /* @__PURE__ */ jsx30("div", { dangerouslySetInnerHTML: { __html: html } })
9783
+ ] }) })
9803
9784
  ] }) });
9804
9785
  }
9805
9786
  var DATA_ATTR4 = "data-lexical-text-cards";
@@ -10005,7 +9986,7 @@ function useRichPaste(onText, baasixClient, folder) {
10005
9986
  }
10006
9987
 
10007
9988
  // src/plugins/TextCardsPlugin/index.tsx
10008
- 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";
10009
9990
  var INSERT_TEXT_CARDS_COMMAND = createCommand17(
10010
9991
  "INSERT_TEXT_CARDS_COMMAND"
10011
9992
  );
@@ -10032,17 +10013,25 @@ function InsertTextCardsDialog({
10032
10013
  onClose
10033
10014
  }) {
10034
10015
  const [input, setInput] = useState26("");
10016
+ const [hasPasted, setHasPasted] = useState26(false);
10035
10017
  let editorConfig = null;
10036
10018
  try {
10037
10019
  editorConfig = useEditorConfig();
10038
10020
  } catch {
10039
10021
  }
10040
10022
  const richPaste = useRichPaste(
10041
- (text) => setInput((prev) => prev ? prev + "\n" + text : text),
10023
+ (text) => {
10024
+ setInput((prev) => prev ? prev + "\n" + text : text);
10025
+ setHasPasted(true);
10026
+ },
10042
10027
  editorConfig?.baasixClient,
10043
10028
  editorConfig?.folder
10044
10029
  );
10045
- const finalHtml = useMemo14(() => {
10030
+ const handleClear = useCallback19(() => {
10031
+ setInput("");
10032
+ setHasPasted(false);
10033
+ }, []);
10034
+ const finalHtml = useMemo13(() => {
10046
10035
  if (!input.trim()) return "";
10047
10036
  const html = convertTextCards(input);
10048
10037
  return richPaste.replaceImagePlaceholders(html);
@@ -10053,70 +10042,60 @@ function InsertTextCardsDialog({
10053
10042
  onClose();
10054
10043
  }, [activeEditor, finalHtml, onClose]);
10055
10044
  return /* @__PURE__ */ jsxs21("div", { style: { minWidth: 500 }, children: [
10056
- /* @__PURE__ */ jsx31(
10057
- "textarea",
10058
- {
10059
- value: input,
10060
- onChange: (e) => setInput(e.target.value),
10061
- placeholder: `Paste concept content here...
10062
- Example:
10063
- CONCEPT 1: DIAGNOSTIC REASONING
10064
-
10065
- Critical Thinking Element
10066
- Pathologists must synthesize clinical history...
10067
-
10068
- Clinical Application
10069
- When examining a tissue specimen...
10070
-
10071
- Example
10072
- A 45-year-old presents with hemoptysis...
10073
-
10074
- Rationalization
10075
- Differential diagnosis prevents anchoring bias...
10076
-
10077
- Critical Insight
10078
- Pathology bridges clinical suspicion with molecular certainty...`,
10079
- style: {
10080
- width: "100%",
10081
- minHeight: 150,
10082
- fontFamily: "monospace",
10083
- fontSize: 13,
10084
- padding: 8,
10085
- border: "1px solid #ddd",
10086
- borderRadius: 4,
10087
- resize: "vertical",
10088
- marginBottom: 8
10089
- }
10090
- }
10091
- ),
10092
- /* @__PURE__ */ jsx31(
10045
+ !hasPasted && /* @__PURE__ */ jsx31(
10093
10046
  "div",
10094
10047
  {
10095
10048
  ref: richPaste.pasteAreaRef,
10096
10049
  contentEditable: true,
10097
10050
  onPaste: richPaste.handlePaste,
10098
10051
  onMouseDown: (e) => e.stopPropagation(),
10052
+ "data-placeholder": richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support",
10099
10053
  style: {
10100
10054
  width: "100%",
10101
- minHeight: 40,
10102
- padding: 8,
10055
+ minHeight: 160,
10056
+ padding: 12,
10103
10057
  border: "2px dashed #93c5fd",
10104
10058
  borderRadius: 4,
10105
- fontSize: 12,
10059
+ fontSize: 13,
10106
10060
  color: "#6b7280",
10107
10061
  marginBottom: 8,
10108
10062
  outline: "none",
10109
10063
  background: "#f0f7ff"
10110
10064
  },
10111
- suppressContentEditableWarning: true,
10112
- children: /* @__PURE__ */ jsx31("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support" })
10065
+ suppressContentEditableWarning: true
10113
10066
  }
10114
10067
  ),
10115
- richPaste.images.length > 0 && /* @__PURE__ */ jsxs21("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: [
10116
- richPaste.images.length,
10117
- " image",
10118
- richPaste.images.length > 1 ? "s" : "",
10119
- " captured"
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
+ )
10120
10099
  ] }),
10121
10100
  finalHtml && /* @__PURE__ */ jsxs21("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 250, overflow: "auto" }, children: [
10122
10101
  /* @__PURE__ */ jsx31("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
@@ -10150,7 +10129,7 @@ Pathology bridges clinical suspicion with molecular certainty...`,
10150
10129
  import { useLexicalComposerContext as useLexicalComposerContext30 } from "@lexical/react/LexicalComposerContext";
10151
10130
  import { $insertNodeToNearestRoot as $insertNodeToNearestRoot11 } from "@lexical/utils";
10152
10131
  import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR18, createCommand as createCommand18 } from "lexical";
10153
- 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";
10154
10133
 
10155
10134
  // src/nodes/QuestionsCardsNode.tsx
10156
10135
  import { $getNodeByKey as $getNodeByKey8 } from "lexical";
@@ -10160,8 +10139,53 @@ import {
10160
10139
  } from "@lexical/react/LexicalDecoratorBlockNode";
10161
10140
  import { useLexicalComposerContext as useLexicalComposerContext29 } from "@lexical/react/LexicalComposerContext";
10162
10141
  import { useLexicalEditable as useLexicalEditable5 } from "@lexical/react/useLexicalEditable";
10163
- 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";
10164
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
+ }
10165
10189
  var GRID_SECTION_KEYS = [
10166
10190
  "rubric",
10167
10191
  "mnemonics",
@@ -10184,9 +10208,9 @@ function QuestionsCardsComponent({
10184
10208
  const [isEditing, setIsEditing] = useState27(false);
10185
10209
  const [qaPairs, setQaPairs] = useState27([]);
10186
10210
  const makeEmptyQA = () => ({
10187
- question: "",
10188
- answer: "",
10189
- sections: GRID_SECTION_KEYS.map((k) => ({ key: k, content: "" }))
10211
+ questionHtml: "",
10212
+ answerHtml: "",
10213
+ sections: GRID_SECTION_KEYS.map((k) => ({ key: k, contentHtml: "" }))
10190
10214
  });
10191
10215
  const openEditor = useCallback20(() => {
10192
10216
  const parsed = parseQuestionsCardsHtml(html);
@@ -10194,30 +10218,22 @@ function QuestionsCardsComponent({
10194
10218
  const existing = qa.sections || [];
10195
10219
  const all = GRID_SECTION_KEYS.map((k) => {
10196
10220
  const found = existing.find((s) => s.key === k);
10197
- return found || { key: k, content: "" };
10221
+ return { key: k, contentHtml: found ? found.content : "" };
10198
10222
  });
10199
- return { question: qa.question, answer: qa.answer, sections: all };
10223
+ return { questionHtml: qa.question, answerHtml: qa.answer, sections: all };
10200
10224
  });
10201
10225
  setQaPairs(pairs.length > 0 ? pairs : [makeEmptyQA()]);
10202
10226
  setIsEditing(true);
10203
10227
  }, [html]);
10204
- const preview = useMemo15(() => {
10228
+ const preview = useMemo14(() => {
10205
10229
  if (!isEditing) return "";
10206
- const cStyles = CARD_STYLES.questionsCards;
10207
- const lines = [];
10208
- qaPairs.forEach((qa, idx) => {
10209
- if (qa.question) lines.push(`${idx + 1}. Question: ${qa.question}`);
10210
- if (qa.answer) lines.push(`Answer: ${qa.answer}`);
10211
- qa.sections.forEach((s) => {
10212
- const sStyle = cStyles[s.key];
10213
- if (sStyle && "title" in sStyle && s.content) {
10214
- lines.push(sStyle.title);
10215
- lines.push(s.content);
10216
- }
10217
- });
10218
- });
10219
- const text = lines.join("\n");
10220
- 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
+ })));
10221
10237
  }, [isEditing, qaPairs]);
10222
10238
  const saveChanges = useCallback20(() => {
10223
10239
  if (!preview) return;
@@ -10232,7 +10248,7 @@ function QuestionsCardsComponent({
10232
10248
  const cancelEdit = useCallback20(() => {
10233
10249
  setIsEditing(false);
10234
10250
  }, []);
10235
- const updateQA = useCallback20((idx, field, value) => {
10251
+ const updateQAHtml = useCallback20((idx, field, value) => {
10236
10252
  setQaPairs((prev) => prev.map((qa, i) => i === idx ? { ...qa, [field]: value } : qa));
10237
10253
  }, []);
10238
10254
  const addQAPair = useCallback20(() => {
@@ -10241,15 +10257,15 @@ function QuestionsCardsComponent({
10241
10257
  const removeQAPair = useCallback20((idx) => {
10242
10258
  setQaPairs((prev) => prev.filter((_, i) => i !== idx));
10243
10259
  }, []);
10244
- const updateSection = useCallback20((qIdx, sIdx, value) => {
10260
+ const updateSectionHtml = useCallback20((qIdx, sIdx, value) => {
10245
10261
  setQaPairs((prev) => prev.map((qa, i) => {
10246
10262
  if (i !== qIdx) return qa;
10247
- 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) };
10248
10264
  }));
10249
10265
  }, []);
10250
10266
  const styles = CARD_STYLES.questionsCards;
10251
10267
  return /* @__PURE__ */ jsx32(BlockWithAlignableContents8, { className, format, nodeKey, children: /* @__PURE__ */ jsxs22("div", { style: { position: "relative" }, children: [
10252
- isEditable && !isEditing && /* @__PURE__ */ jsx32(
10268
+ isEditable && /* @__PURE__ */ jsx32(
10253
10269
  "button",
10254
10270
  {
10255
10271
  type: "button",
@@ -10274,32 +10290,9 @@ function QuestionsCardsComponent({
10274
10290
  children: "Edit Questions Card"
10275
10291
  }
10276
10292
  ),
10277
- isEditing ? /* @__PURE__ */ jsxs22("div", { style: { border: "1px solid #ccc", borderRadius: 4, padding: 8, background: "#f9f9f9" }, children: [
10278
- /* @__PURE__ */ jsxs22("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }, children: [
10279
- /* @__PURE__ */ jsx32("span", { style: { fontSize: 13, fontWeight: 600, color: "rgba(25, 118, 210, 0.8)" }, children: "Edit Questions Card" }),
10280
- /* @__PURE__ */ jsxs22("div", { style: { display: "flex", gap: 4 }, children: [
10281
- /* @__PURE__ */ jsx32(
10282
- "button",
10283
- {
10284
- type: "button",
10285
- onClick: cancelEdit,
10286
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" },
10287
- children: "Cancel"
10288
- }
10289
- ),
10290
- /* @__PURE__ */ jsx32(
10291
- "button",
10292
- {
10293
- type: "button",
10294
- onClick: saveChanges,
10295
- disabled: !preview,
10296
- style: { padding: "2px 10px", fontSize: 12, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer", opacity: preview ? 1 : 0.5 },
10297
- children: "Save"
10298
- }
10299
- )
10300
- ] })
10301
- ] }),
10302
- qaPairs.map((qa, qIdx) => /* @__PURE__ */ jsxs22("div", { style: { border: "1px solid #e5e7eb", borderRadius: 6, padding: 8, marginBottom: 8, background: "#fff" }, children: [
10293
+ /* @__PURE__ */ jsx32("div", { dangerouslySetInnerHTML: { __html: html } }),
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: [
10303
10296
  /* @__PURE__ */ jsxs22("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }, children: [
10304
10297
  /* @__PURE__ */ jsxs22("span", { style: { fontSize: 12, fontWeight: 600, color: "#1976d2" }, children: [
10305
10298
  "Q",
@@ -10318,27 +10311,25 @@ function QuestionsCardsComponent({
10318
10311
  /* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
10319
10312
  /* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#1976d2", fontWeight: 600, display: "block", marginBottom: 2 }, children: "Question" }),
10320
10313
  /* @__PURE__ */ jsx32(
10321
- "textarea",
10314
+ HtmlEditableField,
10322
10315
  {
10323
- placeholder: "Enter question text...",
10324
- value: qa.question,
10325
- onChange: (e) => updateQA(qIdx, "question", e.target.value),
10326
- onMouseDown: (e) => e.stopPropagation(),
10327
- style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 40, resize: "vertical" }
10328
- }
10316
+ initialHtml: qa.questionHtml,
10317
+ onCommit: (v) => updateQAHtml(qIdx, "questionHtml", v),
10318
+ minHeight: 40
10319
+ },
10320
+ `q-${qIdx}-question`
10329
10321
  )
10330
10322
  ] }),
10331
10323
  /* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
10332
10324
  /* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#666", fontWeight: 600, display: "block", marginBottom: 2 }, children: "Answer" }),
10333
10325
  /* @__PURE__ */ jsx32(
10334
- "textarea",
10326
+ HtmlEditableField,
10335
10327
  {
10336
- placeholder: "Enter answer text...",
10337
- value: qa.answer,
10338
- onChange: (e) => updateQA(qIdx, "answer", e.target.value),
10339
- onMouseDown: (e) => e.stopPropagation(),
10340
- style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 60, resize: "vertical" }
10341
- }
10328
+ initialHtml: qa.answerHtml,
10329
+ onCommit: (v) => updateQAHtml(qIdx, "answerHtml", v),
10330
+ minHeight: 60
10331
+ },
10332
+ `q-${qIdx}-answer`
10342
10333
  )
10343
10334
  ] }),
10344
10335
  /* @__PURE__ */ jsxs22("details", { style: { marginTop: 4 }, children: [
@@ -10349,33 +10340,38 @@ function QuestionsCardsComponent({
10349
10340
  return /* @__PURE__ */ jsxs22("div", { style: { marginBottom: 4 }, children: [
10350
10341
  /* @__PURE__ */ jsx32("label", { style: { fontSize: 11, color: "#666", display: "block", marginBottom: 2 }, children: label }),
10351
10342
  /* @__PURE__ */ jsx32(
10352
- "textarea",
10343
+ HtmlEditableField,
10353
10344
  {
10354
- placeholder: `${label} content...`,
10355
- value: section.content,
10356
- onChange: (e) => updateSection(qIdx, sIdx, e.target.value),
10357
- onMouseDown: (e) => e.stopPropagation(),
10358
- style: { width: "100%", padding: "4px 6px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, minHeight: 40, resize: "vertical" }
10359
- }
10345
+ initialHtml: section.contentHtml,
10346
+ onCommit: (v) => updateSectionHtml(qIdx, sIdx, v),
10347
+ minHeight: 40
10348
+ },
10349
+ `q-${qIdx}-s-${sIdx}`
10360
10350
  )
10361
10351
  ] }, sIdx);
10362
10352
  }) })
10363
10353
  ] })
10364
- ] }, qIdx)),
10365
- /* @__PURE__ */ jsx32(
10366
- "button",
10367
- {
10368
- type: "button",
10369
- onClick: addQAPair,
10370
- style: { padding: "2px 10px", fontSize: 12, border: "1px solid #ddd", borderRadius: 4, background: "#fff", cursor: "pointer", marginBottom: 8 },
10371
- children: "+ Add Question"
10372
- }
10373
- ),
10374
- preview && /* @__PURE__ */ jsxs22("div", { style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff" }, children: [
10375
- /* @__PURE__ */ jsx32("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
10376
- /* @__PURE__ */ jsx32("div", { dangerouslySetInnerHTML: { __html: preview } })
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
+ ] })
10377
10373
  ] })
10378
- ] }) : /* @__PURE__ */ jsx32("div", { dangerouslySetInnerHTML: { __html: html } })
10374
+ ] }) })
10379
10375
  ] }) });
10380
10376
  }
10381
10377
  var DATA_ATTR5 = "data-lexical-questions-cards";
@@ -10453,13 +10449,13 @@ function $isQuestionsCardsNode(node) {
10453
10449
  }
10454
10450
 
10455
10451
  // src/plugins/QuestionsCardsPlugin/index.tsx
10456
- 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";
10457
10453
  var INSERT_QUESTIONS_CARDS_COMMAND = createCommand18(
10458
10454
  "INSERT_QUESTIONS_CARDS_COMMAND"
10459
10455
  );
10460
10456
  function QuestionsCardsPlugin() {
10461
10457
  const [editor] = useLexicalComposerContext30();
10462
- useEffect28(() => {
10458
+ useEffect29(() => {
10463
10459
  if (!editor.hasNodes([QuestionsCardsNode])) {
10464
10460
  throw new Error("QuestionsCardsPlugin: QuestionsCardsNode not registered on editor");
10465
10461
  }
@@ -10480,17 +10476,25 @@ function InsertQuestionsCardsDialog({
10480
10476
  onClose
10481
10477
  }) {
10482
10478
  const [input, setInput] = useState28("");
10479
+ const [hasPasted, setHasPasted] = useState28(false);
10483
10480
  let editorConfig = null;
10484
10481
  try {
10485
10482
  editorConfig = useEditorConfig();
10486
10483
  } catch {
10487
10484
  }
10488
10485
  const richPaste = useRichPaste(
10489
- (text) => setInput((prev) => prev ? prev + "\n" + text : text),
10486
+ (text) => {
10487
+ setInput((prev) => prev ? prev + "\n" + text : text);
10488
+ setHasPasted(true);
10489
+ },
10490
10490
  editorConfig?.baasixClient,
10491
10491
  editorConfig?.folder
10492
10492
  );
10493
- const finalHtml = useMemo16(() => {
10493
+ const handleClear = useCallback21(() => {
10494
+ setInput("");
10495
+ setHasPasted(false);
10496
+ }, []);
10497
+ const finalHtml = useMemo15(() => {
10494
10498
  if (!input.trim()) return "";
10495
10499
  const html = convertQuestionsCards(input);
10496
10500
  return richPaste.replaceImagePlaceholders(html);
@@ -10501,36 +10505,7 @@ function InsertQuestionsCardsDialog({
10501
10505
  onClose();
10502
10506
  }, [activeEditor, finalHtml, onClose]);
10503
10507
  return /* @__PURE__ */ jsxs23("div", { style: { minWidth: 500 }, children: [
10504
- /* @__PURE__ */ jsx33(
10505
- "textarea",
10506
- {
10507
- value: input,
10508
- onChange: (e) => setInput(e.target.value),
10509
- placeholder: `Paste question content here...
10510
- Example:
10511
- Q1 : Describe the pathogenesis of tuberculosis.
10512
-
10513
- Answer: Tuberculosis is caused by Mycobacterium tuberculosis...
10514
-
10515
- 1. MARKING RUBRIC
10516
- Definition: 2 marks, Pathogenesis: 5 marks...
10517
-
10518
- 2. MNEMONICS
10519
- Remember TB pathogenesis with "IGRA"...`,
10520
- style: {
10521
- width: "100%",
10522
- minHeight: 150,
10523
- fontFamily: "monospace",
10524
- fontSize: 13,
10525
- padding: 8,
10526
- border: "1px solid #ddd",
10527
- borderRadius: 4,
10528
- resize: "vertical",
10529
- marginBottom: 8
10530
- }
10531
- }
10532
- ),
10533
- /* @__PURE__ */ jsx33(
10508
+ !hasPasted && /* @__PURE__ */ jsx33(
10534
10509
  "div",
10535
10510
  {
10536
10511
  ref: richPaste.pasteAreaRef,
@@ -10539,25 +10514,51 @@ Remember TB pathogenesis with "IGRA"...`,
10539
10514
  onMouseDown: (e) => e.stopPropagation(),
10540
10515
  style: {
10541
10516
  width: "100%",
10542
- minHeight: 40,
10543
- padding: 8,
10517
+ minHeight: 160,
10518
+ padding: 12,
10544
10519
  border: "2px dashed #93c5fd",
10545
10520
  borderRadius: 4,
10546
- fontSize: 12,
10521
+ fontSize: 13,
10547
10522
  color: "#6b7280",
10548
10523
  marginBottom: 8,
10549
10524
  outline: "none",
10550
10525
  background: "#f0f7ff"
10551
10526
  },
10552
- suppressContentEditableWarning: true,
10553
- children: /* @__PURE__ */ jsx33("span", { style: { color: "#9ca3af", pointerEvents: "none", userSelect: "none" }, children: richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support" })
10527
+ "data-placeholder": richPaste.isUploading ? "Uploading images..." : "Paste from Word/Docs here for image support",
10528
+ suppressContentEditableWarning: true
10554
10529
  }
10555
10530
  ),
10556
- richPaste.images.length > 0 && /* @__PURE__ */ jsxs23("div", { style: { marginBottom: 8, fontSize: 11, color: "#16a34a" }, children: [
10557
- richPaste.images.length,
10558
- " image",
10559
- richPaste.images.length > 1 ? "s" : "",
10560
- " captured"
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
+ )
10561
10562
  ] }),
10562
10563
  finalHtml && /* @__PURE__ */ jsxs23("div", { style: { marginBottom: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fafafa", maxHeight: 250, overflow: "auto" }, children: [
10563
10564
  /* @__PURE__ */ jsx33("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
@@ -10595,8 +10596,8 @@ import {
10595
10596
  TableNode as TableNode2,
10596
10597
  TableRowNode as TableRowNode2
10597
10598
  } from "@lexical/table";
10598
- import { createContext as createContext4, useContext as useContext4, useEffect as useEffect29, useMemo as useMemo17, useState as useState29 } from "react";
10599
- 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";
10600
10601
  var CellContext = createContext4({
10601
10602
  cellEditorConfig: null,
10602
10603
  cellEditorPlugins: null,
@@ -10610,7 +10611,7 @@ function InsertTableDialog({
10610
10611
  const [rows, setRows] = useState29("5");
10611
10612
  const [columns, setColumns] = useState29("5");
10612
10613
  const [isDisabled, setIsDisabled] = useState29(true);
10613
- useEffect29(() => {
10614
+ useEffect30(() => {
10614
10615
  const row = Number(rows);
10615
10616
  const column = Number(columns);
10616
10617
  if (row && row > 0 && row <= 500 && column && column > 0 && column <= 50) {
@@ -10626,7 +10627,7 @@ function InsertTableDialog({
10626
10627
  });
10627
10628
  onClose();
10628
10629
  };
10629
- return /* @__PURE__ */ jsxs24(Fragment10, { children: [
10630
+ return /* @__PURE__ */ jsxs24(Fragment13, { children: [
10630
10631
  /* @__PURE__ */ jsx34(
10631
10632
  TextInput,
10632
10633
  {
@@ -10661,7 +10662,7 @@ import {
10661
10662
  } from "@lexical/react/LexicalDecoratorBlockNode";
10662
10663
  import { useLexicalComposerContext as useLexicalComposerContext32 } from "@lexical/react/LexicalComposerContext";
10663
10664
  import { useLexicalEditable as useLexicalEditable6 } from "@lexical/react/useLexicalEditable";
10664
- 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";
10665
10666
  import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
10666
10667
  function HtmlBlockComponent({
10667
10668
  className,
@@ -10673,7 +10674,7 @@ function HtmlBlockComponent({
10673
10674
  const isEditable = useLexicalEditable6();
10674
10675
  const [isEditing, setIsEditing] = useState30(false);
10675
10676
  const [editValue, setEditValue] = useState30("");
10676
- const textareaRef = useRef11(null);
10677
+ const textareaRef = useRef12(null);
10677
10678
  const openEditor = useCallback22(() => {
10678
10679
  setEditValue(html);
10679
10680
  setIsEditing(true);
@@ -10698,7 +10699,7 @@ function HtmlBlockComponent({
10698
10699
  format,
10699
10700
  nodeKey,
10700
10701
  children: /* @__PURE__ */ jsxs25("div", { style: { position: "relative" }, children: [
10701
- isEditable && !isEditing && /* @__PURE__ */ jsx35(
10702
+ isEditable && /* @__PURE__ */ jsx35(
10702
10703
  "button",
10703
10704
  {
10704
10705
  type: "button",
@@ -10723,52 +10724,14 @@ function HtmlBlockComponent({
10723
10724
  children: "Edit HTML"
10724
10725
  }
10725
10726
  ),
10726
- isEditing ? /* @__PURE__ */ jsxs25("div", { style: { border: "1px solid #ccc", borderRadius: 4, padding: 8, background: "#f9f9f9" }, children: [
10727
- /* @__PURE__ */ jsxs25("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }, children: [
10728
- /* @__PURE__ */ jsx35("span", { style: { fontSize: 12, fontWeight: 600, color: "#333" }, children: "Edit HTML Source" }),
10729
- /* @__PURE__ */ jsxs25("div", { style: { display: "flex", gap: 4 }, children: [
10730
- /* @__PURE__ */ jsx35(
10731
- "button",
10732
- {
10733
- type: "button",
10734
- onClick: cancelEdit,
10735
- style: {
10736
- padding: "2px 10px",
10737
- fontSize: 12,
10738
- border: "1px solid #ccc",
10739
- borderRadius: 4,
10740
- background: "#fff",
10741
- cursor: "pointer"
10742
- },
10743
- children: "Cancel"
10744
- }
10745
- ),
10746
- /* @__PURE__ */ jsx35(
10747
- "button",
10748
- {
10749
- type: "button",
10750
- onClick: saveHtml,
10751
- style: {
10752
- padding: "2px 10px",
10753
- fontSize: 12,
10754
- border: "none",
10755
- borderRadius: 4,
10756
- background: "#2563eb",
10757
- color: "#fff",
10758
- cursor: "pointer"
10759
- },
10760
- children: "Save"
10761
- }
10762
- )
10763
- ] })
10764
- ] }),
10727
+ /* @__PURE__ */ jsx35("div", { dangerouslySetInnerHTML: { __html: html } }),
10728
+ isEditing && /* @__PURE__ */ jsx35(Modal, { onClose: cancelEdit, title: "Edit HTML Source", children: /* @__PURE__ */ jsxs25("div", { style: { minWidth: 500 }, children: [
10765
10729
  /* @__PURE__ */ jsx35(
10766
10730
  "textarea",
10767
10731
  {
10768
10732
  ref: textareaRef,
10769
10733
  value: editValue,
10770
10734
  onChange: (e) => setEditValue(e.target.value),
10771
- onMouseDown: (e) => e.stopPropagation(),
10772
10735
  style: {
10773
10736
  width: "100%",
10774
10737
  minHeight: 150,
@@ -10777,21 +10740,36 @@ function HtmlBlockComponent({
10777
10740
  padding: 8,
10778
10741
  border: "1px solid #ddd",
10779
10742
  borderRadius: 4,
10780
- resize: "vertical"
10743
+ resize: "vertical",
10744
+ marginBottom: 8
10781
10745
  }
10782
10746
  }
10783
10747
  ),
10784
- /* @__PURE__ */ jsxs25(
10785
- "div",
10786
- {
10787
- style: { marginTop: 8, padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff" },
10788
- children: [
10789
- /* @__PURE__ */ jsx35("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
10790
- /* @__PURE__ */ jsx35("div", { dangerouslySetInnerHTML: { __html: editValue } })
10791
- ]
10792
- }
10793
- )
10794
- ] }) : /* @__PURE__ */ jsx35("div", { dangerouslySetInnerHTML: { __html: html } })
10748
+ /* @__PURE__ */ jsxs25("div", { style: { padding: 8, border: "1px solid #e5e7eb", borderRadius: 4, background: "#fff", maxHeight: 200, overflow: "auto", marginBottom: 8 }, children: [
10749
+ /* @__PURE__ */ jsx35("span", { style: { fontSize: 11, color: "#888", display: "block", marginBottom: 4 }, children: "Preview:" }),
10750
+ /* @__PURE__ */ jsx35("div", { dangerouslySetInnerHTML: { __html: editValue } })
10751
+ ] }),
10752
+ /* @__PURE__ */ jsxs25("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
10753
+ /* @__PURE__ */ jsx35(
10754
+ "button",
10755
+ {
10756
+ type: "button",
10757
+ onClick: cancelEdit,
10758
+ style: { padding: "6px 16px", fontSize: 13, border: "1px solid #ccc", borderRadius: 4, background: "#fff", cursor: "pointer" },
10759
+ children: "Cancel"
10760
+ }
10761
+ ),
10762
+ /* @__PURE__ */ jsx35(
10763
+ "button",
10764
+ {
10765
+ type: "button",
10766
+ onClick: saveHtml,
10767
+ style: { padding: "6px 16px", fontSize: 13, border: "none", borderRadius: 4, background: "#2563eb", color: "#fff", cursor: "pointer" },
10768
+ children: "Save"
10769
+ }
10770
+ )
10771
+ ] })
10772
+ ] }) })
10795
10773
  ] })
10796
10774
  }
10797
10775
  );
@@ -10886,7 +10864,7 @@ function $isHtmlBlockNode(node) {
10886
10864
  }
10887
10865
 
10888
10866
  // src/plugins/ComponentPickerPlugin/index.tsx
10889
- 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";
10890
10868
  var ComponentPickerOption = class extends MenuOption {
10891
10869
  // What shows up in the editor
10892
10870
  title;
@@ -11172,7 +11150,7 @@ function ComponentPickerMenuPlugin() {
11172
11150
  allowWhitespace: true,
11173
11151
  minLength: 0
11174
11152
  });
11175
- const options = useMemo18(() => {
11153
+ const options = useMemo17(() => {
11176
11154
  const baseOptions = getBaseOptions(editor, showModal);
11177
11155
  if (!queryString) {
11178
11156
  return baseOptions;
@@ -11195,7 +11173,7 @@ function ComponentPickerMenuPlugin() {
11195
11173
  },
11196
11174
  [editor]
11197
11175
  );
11198
- return /* @__PURE__ */ jsxs26(Fragment11, { children: [
11176
+ return /* @__PURE__ */ jsxs26(Fragment14, { children: [
11199
11177
  modal,
11200
11178
  /* @__PURE__ */ jsx36(
11201
11179
  LexicalTypeaheadMenuPlugin,
@@ -11245,11 +11223,11 @@ import {
11245
11223
  CUT_COMMAND,
11246
11224
  PASTE_COMMAND
11247
11225
  } from "lexical";
11248
- import { useMemo as useMemo19 } from "react";
11226
+ import { useMemo as useMemo18 } from "react";
11249
11227
  import { jsx as jsx37 } from "react/jsx-runtime";
11250
11228
  function ContextMenuPlugin() {
11251
11229
  const [editor] = useLexicalComposerContext34();
11252
- const items = useMemo19(() => {
11230
+ const items = useMemo18(() => {
11253
11231
  return [
11254
11232
  new NodeContextMenuOption(`Remove Link`, {
11255
11233
  $onSelect: () => {
@@ -11364,7 +11342,7 @@ import { useLexicalComposerContext as useLexicalComposerContext35 } from "@lexic
11364
11342
  import { DRAG_DROP_PASTE } from "@lexical/rich-text";
11365
11343
  import { isMimeType, mediaFileReader } from "@lexical/utils";
11366
11344
  import { COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW7 } from "lexical";
11367
- import { useEffect as useEffect30 } from "react";
11345
+ import { useEffect as useEffect31 } from "react";
11368
11346
  var ACCEPTABLE_IMAGE_TYPES = [
11369
11347
  "image/",
11370
11348
  "image/heic",
@@ -11375,7 +11353,7 @@ var ACCEPTABLE_IMAGE_TYPES = [
11375
11353
  function DragDropPaste() {
11376
11354
  const [editor] = useLexicalComposerContext35();
11377
11355
  const { baasixClient, folder } = useEditorConfig();
11378
- useEffect30(() => {
11356
+ useEffect31(() => {
11379
11357
  return editor.registerCommand(
11380
11358
  DRAG_DROP_PASTE,
11381
11359
  (files) => {
@@ -11418,9 +11396,9 @@ import {
11418
11396
  $isParagraphNode as $isParagraphNode4,
11419
11397
  $isTextNode as $isTextNode4
11420
11398
  } from "lexical";
11421
- 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";
11422
11400
  import * as ReactDOM3 from "react-dom";
11423
- 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";
11424
11402
  var DRAGGABLE_BLOCK_MENU_CLASSNAME = "draggable-block-menu";
11425
11403
  function isOnMenu(element) {
11426
11404
  return !!element.closest(`.${DRAGGABLE_BLOCK_MENU_CLASSNAME}`);
@@ -11430,10 +11408,10 @@ function DraggableBlockPlugin({
11430
11408
  }) {
11431
11409
  const [editor] = useLexicalComposerContext36();
11432
11410
  const [modal, showModal] = useModal();
11433
- const menuRef = useRef12(null);
11434
- const pickerRef = useRef12(null);
11435
- const searchInputRef = useRef12(null);
11436
- const targetLineRef = useRef12(null);
11411
+ const menuRef = useRef13(null);
11412
+ const pickerRef = useRef13(null);
11413
+ const searchInputRef = useRef13(null);
11414
+ const targetLineRef = useRef13(null);
11437
11415
  const [draggableElement, setDraggableElement] = useState32(
11438
11416
  null
11439
11417
  );
@@ -11442,7 +11420,7 @@ function DraggableBlockPlugin({
11442
11420
  const [queryString, setQueryString] = useState32("");
11443
11421
  const [highlightedIndex, setHighlightedIndex] = useState32(0);
11444
11422
  const [pickerPosition, setPickerPosition] = useState32(null);
11445
- const options = useMemo20(() => {
11423
+ const options = useMemo19(() => {
11446
11424
  const baseOptions = getBaseOptions(editor, showModal);
11447
11425
  if (!queryString) {
11448
11426
  return baseOptions;
@@ -11455,12 +11433,12 @@ function DraggableBlockPlugin({
11455
11433
  )
11456
11434
  ];
11457
11435
  }, [editor, queryString, showModal]);
11458
- useEffect31(() => {
11436
+ useEffect32(() => {
11459
11437
  if (isPickerOpen && searchInputRef.current) {
11460
11438
  searchInputRef.current.focus({ preventScroll: true });
11461
11439
  }
11462
11440
  }, [isPickerOpen]);
11463
- useEffect31(() => {
11441
+ useEffect32(() => {
11464
11442
  if (!isPickerOpen || !options.length) {
11465
11443
  return;
11466
11444
  }
@@ -11468,7 +11446,7 @@ function DraggableBlockPlugin({
11468
11446
  (current) => Math.min(current, Math.max(options.length - 1, 0))
11469
11447
  );
11470
11448
  }, [isPickerOpen, options.length]);
11471
- useEffect31(() => {
11449
+ useEffect32(() => {
11472
11450
  if (!isPickerOpen) {
11473
11451
  return;
11474
11452
  }
@@ -11518,7 +11496,7 @@ function DraggableBlockPlugin({
11518
11496
  },
11519
11497
  [editor, pickerState, queryString]
11520
11498
  );
11521
- useEffect31(() => {
11499
+ useEffect32(() => {
11522
11500
  if (!isPickerOpen) {
11523
11501
  return;
11524
11502
  }
@@ -11580,7 +11558,7 @@ function DraggableBlockPlugin({
11580
11558
  setHighlightedIndex(0);
11581
11559
  setIsPickerOpen(true);
11582
11560
  }
11583
- return /* @__PURE__ */ jsxs27(Fragment12, { children: [
11561
+ return /* @__PURE__ */ jsxs27(Fragment15, { children: [
11584
11562
  modal,
11585
11563
  isPickerOpen && pickerPosition ? ReactDOM3.createPortal(
11586
11564
  /* @__PURE__ */ jsxs27(
@@ -11662,7 +11640,7 @@ import {
11662
11640
  $getSelection as $getSelection11,
11663
11641
  $isRangeSelection as $isRangeSelection9
11664
11642
  } from "lexical";
11665
- 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";
11666
11644
  import * as ReactDOM4 from "react-dom";
11667
11645
  import { jsx as jsx39, jsxs as jsxs28 } from "react/jsx-runtime";
11668
11646
  var EmojiOption = class extends MenuOption2 {
@@ -11712,10 +11690,10 @@ function EmojiPickerPlugin() {
11712
11690
  const [editor] = useLexicalComposerContext37();
11713
11691
  const [queryString, setQueryString] = useState33(null);
11714
11692
  const [emojis, setEmojis] = useState33([]);
11715
- useEffect32(() => {
11693
+ useEffect33(() => {
11716
11694
  import("./emoji-list-MUV74SND.js").then((file) => setEmojis(file.default));
11717
11695
  }, []);
11718
- const emojiOptions = useMemo21(
11696
+ const emojiOptions = useMemo20(
11719
11697
  () => emojis != null ? emojis.map(
11720
11698
  ({ emoji, aliases, tags }) => new EmojiOption(aliases[0], emoji, {
11721
11699
  keywords: [...aliases, ...tags]
@@ -11728,7 +11706,7 @@ function EmojiPickerPlugin() {
11728
11706
  punctuation: `\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\[\\]\\\\/!%'"~=<>:;`
11729
11707
  // allow _ and -
11730
11708
  });
11731
- const options = useMemo21(() => {
11709
+ const options = useMemo20(() => {
11732
11710
  return emojiOptions.filter((option) => {
11733
11711
  return queryString != null ? new RegExp(queryString, "gi").exec(option.title) || option.keywords != null ? option.keywords.some(
11734
11712
  (keyword) => new RegExp(queryString, "gi").exec(keyword)
@@ -11808,7 +11786,7 @@ import {
11808
11786
  KEY_ESCAPE_COMMAND as KEY_ESCAPE_COMMAND2,
11809
11787
  SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND2
11810
11788
  } from "lexical";
11811
- 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";
11812
11790
  import { createPortal as createPortal8 } from "react-dom";
11813
11791
 
11814
11792
  // src/utils/getSelectedNode.ts
@@ -11857,7 +11835,7 @@ function setFloatingElemPositionForLinkEditor(targetRect, floatingElem, anchorEl
11857
11835
  }
11858
11836
 
11859
11837
  // src/plugins/FloatingLinkEditorPlugin/index.tsx
11860
- 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";
11861
11839
  function preventDefault(event) {
11862
11840
  event.preventDefault();
11863
11841
  }
@@ -11869,8 +11847,8 @@ function FloatingLinkEditor({
11869
11847
  isLinkEditMode,
11870
11848
  setIsLinkEditMode
11871
11849
  }) {
11872
- const editorRef = useRef13(null);
11873
- const inputRef = useRef13(null);
11850
+ const editorRef = useRef14(null);
11851
+ const inputRef = useRef14(null);
11874
11852
  const [linkUrl, setLinkUrl] = useState34("");
11875
11853
  const [editedLinkUrl, setEditedLinkUrl] = useState34("https://");
11876
11854
  const [lastSelection, setLastSelection] = useState34(
@@ -11943,7 +11921,7 @@ function FloatingLinkEditor({
11943
11921
  }
11944
11922
  return true;
11945
11923
  }, [anchorElem, editor, setIsLinkEditMode, isLinkEditMode, linkUrl]);
11946
- useEffect33(() => {
11924
+ useEffect34(() => {
11947
11925
  const scrollerElem = anchorElem.parentElement;
11948
11926
  const update = () => {
11949
11927
  editor.getEditorState().read(() => {
@@ -11961,7 +11939,7 @@ function FloatingLinkEditor({
11961
11939
  }
11962
11940
  };
11963
11941
  }, [anchorElem.parentElement, editor, $updateLinkEditor]);
11964
- useEffect33(() => {
11942
+ useEffect34(() => {
11965
11943
  return mergeRegister10(
11966
11944
  editor.registerUpdateListener(({ editorState }) => {
11967
11945
  editorState.read(() => {
@@ -11989,17 +11967,17 @@ function FloatingLinkEditor({
11989
11967
  )
11990
11968
  );
11991
11969
  }, [editor, $updateLinkEditor, setIsLink, isLink]);
11992
- useEffect33(() => {
11970
+ useEffect34(() => {
11993
11971
  editor.getEditorState().read(() => {
11994
11972
  $updateLinkEditor();
11995
11973
  });
11996
11974
  }, [editor, $updateLinkEditor]);
11997
- useEffect33(() => {
11975
+ useEffect34(() => {
11998
11976
  if (isLinkEditMode && inputRef.current) {
11999
11977
  inputRef.current.focus();
12000
11978
  }
12001
11979
  }, [isLinkEditMode, isLink]);
12002
- useEffect33(() => {
11980
+ useEffect34(() => {
12003
11981
  const editorElement = editorRef.current;
12004
11982
  if (editorElement === null) {
12005
11983
  return;
@@ -12050,7 +12028,7 @@ function FloatingLinkEditor({
12050
12028
  setIsLinkEditMode(false);
12051
12029
  }
12052
12030
  };
12053
- 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: [
12054
12032
  /* @__PURE__ */ jsx40(
12055
12033
  "input",
12056
12034
  {
@@ -12130,7 +12108,7 @@ function FloatingLinkEditor({
12130
12108
  function useFloatingLinkEditorToolbar(editor, anchorElem, isLinkEditMode, setIsLinkEditMode) {
12131
12109
  const [activeEditor, setActiveEditor] = useState34(editor);
12132
12110
  const [isLink, setIsLink] = useState34(false);
12133
- useEffect33(() => {
12111
+ useEffect34(() => {
12134
12112
  function $updateToolbar() {
12135
12113
  const selection = $getSelection12();
12136
12114
  if ($isRangeSelection10(selection)) {
@@ -12246,7 +12224,7 @@ import {
12246
12224
  getDOMSelection as getDOMSelection3,
12247
12225
  SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND3
12248
12226
  } from "lexical";
12249
- 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";
12250
12228
  import { createPortal as createPortal9 } from "react-dom";
12251
12229
 
12252
12230
  // src/utils/getDOMRangeRect.ts
@@ -12308,7 +12286,7 @@ function setFloatingElemPosition(targetRect, floatingElem, anchorElem, isLink =
12308
12286
  }
12309
12287
 
12310
12288
  // src/plugins/FloatingTextFormatToolbarPlugin/index.tsx
12311
- 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";
12312
12290
  function TextFormatFloatingToolbar({
12313
12291
  editor,
12314
12292
  anchorElem,
@@ -12325,7 +12303,7 @@ function TextFormatFloatingToolbar({
12325
12303
  isSuperscript: isSuperscript2,
12326
12304
  setIsLinkEditMode
12327
12305
  }) {
12328
- const popupCharStylesEditorRef = useRef14(null);
12306
+ const popupCharStylesEditorRef = useRef15(null);
12329
12307
  const insertLink = useCallback27(() => {
12330
12308
  if (!isLink) {
12331
12309
  setIsLinkEditMode(true);
@@ -12357,7 +12335,7 @@ function TextFormatFloatingToolbar({
12357
12335
  }
12358
12336
  }
12359
12337
  }
12360
- useEffect34(() => {
12338
+ useEffect35(() => {
12361
12339
  if (popupCharStylesEditorRef?.current) {
12362
12340
  document.addEventListener("mousemove", mouseMoveListener);
12363
12341
  document.addEventListener("mouseup", mouseUpListener);
@@ -12385,7 +12363,7 @@ function TextFormatFloatingToolbar({
12385
12363
  );
12386
12364
  }
12387
12365
  }, [editor, anchorElem, isLink]);
12388
- useEffect34(() => {
12366
+ useEffect35(() => {
12389
12367
  const scrollerElem = anchorElem.parentElement;
12390
12368
  const update = () => {
12391
12369
  editor.getEditorState().read(() => {
@@ -12403,7 +12381,7 @@ function TextFormatFloatingToolbar({
12403
12381
  }
12404
12382
  };
12405
12383
  }, [editor, $updateTextFormatFloatingToolbar, anchorElem]);
12406
- useEffect34(() => {
12384
+ useEffect35(() => {
12407
12385
  editor.getEditorState().read(() => {
12408
12386
  $updateTextFormatFloatingToolbar();
12409
12387
  });
@@ -12424,7 +12402,7 @@ function TextFormatFloatingToolbar({
12424
12402
  );
12425
12403
  }, [editor, $updateTextFormatFloatingToolbar]);
12426
12404
  return /* @__PURE__ */ jsxs30("div", { ref: popupCharStylesEditorRef, className: "floating-text-format-popup", children: [
12427
- editor.isEditable() && /* @__PURE__ */ jsxs30(Fragment14, { children: [
12405
+ editor.isEditable() && /* @__PURE__ */ jsxs30(Fragment17, { children: [
12428
12406
  /* @__PURE__ */ jsx41(
12429
12407
  "button",
12430
12408
  {
@@ -12637,13 +12615,13 @@ function useFloatingTextFormatToolbar(editor, anchorElem, setIsLinkEditMode) {
12637
12615
  }
12638
12616
  });
12639
12617
  }, [editor]);
12640
- useEffect34(() => {
12618
+ useEffect35(() => {
12641
12619
  document.addEventListener("selectionchange", updatePopup);
12642
12620
  return () => {
12643
12621
  document.removeEventListener("selectionchange", updatePopup);
12644
12622
  };
12645
12623
  }, [updatePopup]);
12646
- useEffect34(() => {
12624
+ useEffect35(() => {
12647
12625
  return mergeRegister11(
12648
12626
  editor.registerUpdateListener(() => {
12649
12627
  updatePopup();
@@ -12701,10 +12679,10 @@ import { useLexicalComposerContext as useLexicalComposerContext40 } from "@lexic
12701
12679
  import { $trimTextContentFromAnchor } from "@lexical/selection";
12702
12680
  import { $restoreEditorState } from "@lexical/utils";
12703
12681
  import { $getSelection as $getSelection14, $isRangeSelection as $isRangeSelection12, RootNode } from "lexical";
12704
- import { useEffect as useEffect35 } from "react";
12682
+ import { useEffect as useEffect36 } from "react";
12705
12683
  function MaxLengthPlugin({ maxLength }) {
12706
12684
  const [editor] = useLexicalComposerContext40();
12707
- useEffect35(() => {
12685
+ useEffect36(() => {
12708
12686
  let lastRestoredEditorState = null;
12709
12687
  return editor.registerNodeTransform(RootNode, (rootNode) => {
12710
12688
  const selection = $getSelection14();
@@ -12744,7 +12722,7 @@ import {
12744
12722
  KEY_DOWN_COMMAND,
12745
12723
  OUTDENT_CONTENT_COMMAND
12746
12724
  } from "lexical";
12747
- import { useEffect as useEffect36 } from "react";
12725
+ import { useEffect as useEffect37 } from "react";
12748
12726
 
12749
12727
  // src/plugins/ToolbarPlugin/utils.ts
12750
12728
  import { $createCodeNode as $createCodeNode3 } from "@lexical/code";
@@ -13211,7 +13189,7 @@ function ShortcutsPlugin({
13211
13189
  setIsLinkEditMode
13212
13190
  }) {
13213
13191
  const { toolbarState } = useToolbarState();
13214
- useEffect36(() => {
13192
+ useEffect37(() => {
13215
13193
  const keyboardShortcutsHandler = (event) => {
13216
13194
  if (isModifierMatch2(event, {})) {
13217
13195
  return false;
@@ -13301,7 +13279,7 @@ function ShortcutsPlugin({
13301
13279
  // src/plugins/SpecialTextPlugin/index.ts
13302
13280
  import { useLexicalComposerContext as useLexicalComposerContext41 } from "@lexical/react/LexicalComposerContext";
13303
13281
  import { TextNode as TextNode5 } from "lexical";
13304
- import { useEffect as useEffect37 } from "react";
13282
+ import { useEffect as useEffect38 } from "react";
13305
13283
 
13306
13284
  // src/nodes/SpecialTextNode.tsx
13307
13285
  import { addClassNamesToElement as addClassNamesToElement3 } from "@lexical/utils";
@@ -13371,7 +13349,7 @@ function $textNodeTransform(node) {
13371
13349
  }
13372
13350
  }
13373
13351
  function useTextTransformation(editor) {
13374
- useEffect37(() => {
13352
+ useEffect38(() => {
13375
13353
  if (!editor.hasNodes([SpecialTextNode])) {
13376
13354
  throw new Error(
13377
13355
  "SpecialTextPlugin: SpecialTextNode not registered on editor"
@@ -13395,7 +13373,7 @@ import {
13395
13373
  COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW10,
13396
13374
  FOCUS_COMMAND
13397
13375
  } from "lexical";
13398
- import { useEffect as useEffect38 } from "react";
13376
+ import { useEffect as useEffect39 } from "react";
13399
13377
  var TAB_TO_FOCUS_INTERVAL = 100;
13400
13378
  var lastTabKeyDownTimestamp = 0;
13401
13379
  var hasRegisteredKeyDownListener = false;
@@ -13412,7 +13390,7 @@ function registerKeyTimeStampTracker() {
13412
13390
  }
13413
13391
  function TabFocusPlugin() {
13414
13392
  const [editor] = useLexicalComposerContext42();
13415
- useEffect38(() => {
13393
+ useEffect39(() => {
13416
13394
  if (!hasRegisteredKeyDownListener) {
13417
13395
  registerKeyTimeStampTracker();
13418
13396
  hasRegisteredKeyDownListener = true;
@@ -13469,12 +13447,12 @@ import {
13469
13447
  isDOMNode as isDOMNode2,
13470
13448
  SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND4
13471
13449
  } from "lexical";
13472
- 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";
13473
13451
  import { createPortal as createPortal10 } from "react-dom";
13474
13452
 
13475
13453
  // src/ui/ColorPicker.tsx
13476
13454
  import { calculateZoomLevel as calculateZoomLevel2 } from "@lexical/utils";
13477
- 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";
13478
13456
  import { jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
13479
13457
  var skipAddingToHistoryStack = false;
13480
13458
  var basicColors = [
@@ -13504,15 +13482,15 @@ function ColorPicker({
13504
13482
  const [inputColor, setInputColor] = useState36(
13505
13483
  transformColor("hex", color).hex
13506
13484
  );
13507
- const innerDivRef = useRef15(null);
13508
- const saturationPosition = useMemo22(
13485
+ const innerDivRef = useRef16(null);
13486
+ const saturationPosition = useMemo21(
13509
13487
  () => ({
13510
13488
  x: selfColor.hsv.s / 100 * WIDTH,
13511
13489
  y: (100 - selfColor.hsv.v) / 100 * HEIGHT
13512
13490
  }),
13513
13491
  [selfColor.hsv.s, selfColor.hsv.v]
13514
13492
  );
13515
- const huePosition = useMemo22(
13493
+ const huePosition = useMemo21(
13516
13494
  () => ({
13517
13495
  x: selfColor.hsv.h / 360 * WIDTH
13518
13496
  }),
@@ -13614,8 +13592,8 @@ function ColorPicker({
13614
13592
  );
13615
13593
  }
13616
13594
  function MoveWrapper({ className, style, onChange, children }) {
13617
- const divRef = useRef15(null);
13618
- const draggedRef = useRef15(false);
13595
+ const divRef = useRef16(null);
13596
+ const draggedRef = useRef16(false);
13619
13597
  const move = (e) => {
13620
13598
  if (divRef.current) {
13621
13599
  const { current: div } = divRef;
@@ -13741,7 +13719,7 @@ function transformColor(format, color) {
13741
13719
  }
13742
13720
 
13743
13721
  // src/plugins/TableActionMenuPlugin/index.tsx
13744
- 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";
13745
13723
  function computeSelectionCount(selection) {
13746
13724
  const selectionShape = selection.getShape();
13747
13725
  return {
@@ -13788,7 +13766,7 @@ function TableActionMenu({
13788
13766
  showColorPickerModal
13789
13767
  }) {
13790
13768
  const [editor] = useLexicalComposerContext43();
13791
- const dropDownRef = useRef16(null);
13769
+ const dropDownRef = useRef17(null);
13792
13770
  const [tableCellNode, updateTableCellNode] = useState37(_tableCellNode);
13793
13771
  const [selectionCounts, updateSelectionCounts] = useState37({
13794
13772
  columns: 1,
@@ -13799,7 +13777,7 @@ function TableActionMenu({
13799
13777
  const [backgroundColor, setBackgroundColor] = useState37(
13800
13778
  () => currentCellBackgroundColor(editor) || ""
13801
13779
  );
13802
- useEffect39(() => {
13780
+ useEffect40(() => {
13803
13781
  return editor.registerMutationListener(
13804
13782
  TableCellNode3,
13805
13783
  (nodeMutations) => {
@@ -13814,7 +13792,7 @@ function TableActionMenu({
13814
13792
  { skipInitialization: true }
13815
13793
  );
13816
13794
  }, [editor, tableCellNode]);
13817
- useEffect39(() => {
13795
+ useEffect40(() => {
13818
13796
  editor.getEditorState().read(() => {
13819
13797
  const selection = $getSelection17();
13820
13798
  if ($isTableSelection2(selection)) {
@@ -13827,7 +13805,7 @@ function TableActionMenu({
13827
13805
  setCanUnmergeCell($canUnmerge());
13828
13806
  });
13829
13807
  }, [editor]);
13830
- useEffect39(() => {
13808
+ useEffect40(() => {
13831
13809
  const menuButtonElement = contextRef.current;
13832
13810
  const dropDownElement = dropDownRef.current;
13833
13811
  const rootElement = editor.getRootElement();
@@ -13851,7 +13829,7 @@ function TableActionMenu({
13851
13829
  dropDownElement.style.top = `${topPosition}px`;
13852
13830
  }
13853
13831
  }, [contextRef, dropDownRef, editor]);
13854
- useEffect39(() => {
13832
+ useEffect40(() => {
13855
13833
  function handleClickOutside(event) {
13856
13834
  if (dropDownRef.current != null && contextRef.current != null && isDOMNode2(event.target) && !dropDownRef.current.contains(event.target) && !contextRef.current.contains(event.target)) {
13857
13835
  setIsMenuOpen(false);
@@ -14338,8 +14316,8 @@ function TableCellActionMenuContainer({
14338
14316
  cellMerge
14339
14317
  }) {
14340
14318
  const [editor] = useLexicalComposerContext43();
14341
- const menuButtonRef = useRef16(null);
14342
- const menuRootRef = useRef16(null);
14319
+ const menuButtonRef = useRef17(null);
14320
+ const menuRootRef = useRef17(null);
14343
14321
  const [isMenuOpen, setIsMenuOpen] = useState37(false);
14344
14322
  const [tableCellNode, setTableMenuCellNode] = useState37(
14345
14323
  null
@@ -14459,7 +14437,7 @@ function TableCellActionMenuContainer({
14459
14437
  menu.style.transform = `translate(${left}px, ${top}px)`;
14460
14438
  }
14461
14439
  }, [editor, anchorElem, checkTableCellOverflow]);
14462
- useEffect39(() => {
14440
+ useEffect40(() => {
14463
14441
  let timeoutId = void 0;
14464
14442
  const callback = () => {
14465
14443
  timeoutId = void 0;
@@ -14490,14 +14468,14 @@ function TableCellActionMenuContainer({
14490
14468
  () => clearTimeout(timeoutId)
14491
14469
  );
14492
14470
  });
14493
- const prevTableCellDOM = useRef16(tableCellNode);
14494
- useEffect39(() => {
14471
+ const prevTableCellDOM = useRef17(tableCellNode);
14472
+ useEffect40(() => {
14495
14473
  if (prevTableCellDOM.current !== tableCellNode) {
14496
14474
  setIsMenuOpen(false);
14497
14475
  }
14498
14476
  prevTableCellDOM.current = tableCellNode;
14499
14477
  }, [prevTableCellDOM, tableCellNode]);
14500
- 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: [
14501
14479
  /* @__PURE__ */ jsx44(
14502
14480
  "button",
14503
14481
  {
@@ -14563,22 +14541,22 @@ import {
14563
14541
  } from "lexical";
14564
14542
  import {
14565
14543
  useCallback as useCallback29,
14566
- useEffect as useEffect40,
14567
- useMemo as useMemo23,
14568
- useRef as useRef17,
14544
+ useEffect as useEffect41,
14545
+ useMemo as useMemo22,
14546
+ useRef as useRef18,
14569
14547
  useState as useState38
14570
14548
  } from "react";
14571
14549
  import { createPortal as createPortal11 } from "react-dom";
14572
- 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";
14573
14551
  var MIN_ROW_HEIGHT = 33;
14574
14552
  var MIN_COLUMN_WIDTH = 92;
14575
14553
  var ACTIVE_RESIZER_COLOR = "#76b6ff";
14576
14554
  function TableCellResizer({ editor }) {
14577
- const targetRef = useRef17(null);
14578
- const resizerRef = useRef17(null);
14579
- const tableRectRef = useRef17(null);
14555
+ const targetRef = useRef18(null);
14556
+ const resizerRef = useRef18(null);
14557
+ const tableRectRef = useRef18(null);
14580
14558
  const [hasTable, setHasTable] = useState38(false);
14581
- const pointerStartPosRef = useRef17(null);
14559
+ const pointerStartPosRef = useRef18(null);
14582
14560
  const [pointerCurrentPos, updatePointerCurrentPos] = useState38(null);
14583
14561
  const [activeCell, updateActiveCell] = useState38(null);
14584
14562
  const [draggingDirection, updateDraggingDirection] = useState38(null);
@@ -14591,7 +14569,7 @@ function TableCellResizer({ editor }) {
14591
14569
  pointerStartPosRef.current = null;
14592
14570
  tableRectRef.current = null;
14593
14571
  }, []);
14594
- useEffect40(() => {
14572
+ useEffect41(() => {
14595
14573
  const tableKeys = /* @__PURE__ */ new Set();
14596
14574
  return mergeRegister13(
14597
14575
  editor.registerMutationListener(TableNode3, (nodeMutations) => {
@@ -14615,7 +14593,7 @@ function TableCellResizer({ editor }) {
14615
14593
  })
14616
14594
  );
14617
14595
  }, [editor]);
14618
- useEffect40(() => {
14596
+ useEffect41(() => {
14619
14597
  if (!hasTable) {
14620
14598
  return;
14621
14599
  }
@@ -14904,7 +14882,7 @@ function TableCellResizer({ editor }) {
14904
14882
  }
14905
14883
  }, [draggingDirection]);
14906
14884
  const resizerStyles = getResizers();
14907
- 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: [
14908
14886
  /* @__PURE__ */ jsx45(
14909
14887
  "div",
14910
14888
  {
@@ -14928,7 +14906,7 @@ function TableCellResizer({ editor }) {
14928
14906
  function TableCellResizerPlugin() {
14929
14907
  const [editor] = useLexicalComposerContext44();
14930
14908
  const isEditable = useLexicalEditable8();
14931
- return useMemo23(
14909
+ return useMemo22(
14932
14910
  () => isEditable ? createPortal11(/* @__PURE__ */ jsx45(TableCellResizer, { editor }), document.body) : null,
14933
14911
  [editor, isEditable]
14934
14912
  );
@@ -14964,7 +14942,7 @@ import {
14964
14942
  $getSiblingCaret as $getSiblingCaret2,
14965
14943
  isHTMLElement as isHTMLElement5
14966
14944
  } from "lexical";
14967
- 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";
14968
14946
  import { createPortal as createPortal12 } from "react-dom";
14969
14947
 
14970
14948
  // src/utils/getThemeSelector.ts
@@ -14979,7 +14957,7 @@ function getThemeSelector(getTheme, name) {
14979
14957
  }
14980
14958
 
14981
14959
  // src/plugins/TableHoverActionsV2Plugin/index.tsx
14982
- 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";
14983
14961
  var INDICATOR_SIZE_PX = 18;
14984
14962
  var SIDE_INDICATOR_SIZE_PX = 18;
14985
14963
  var TOP_BUTTON_OVERHANG = INDICATOR_SIZE_PX / 2;
@@ -15070,21 +15048,21 @@ function TableHoverActionsV2({
15070
15048
  const isEditable = useLexicalEditable9();
15071
15049
  const [isVisible, setIsVisible] = useState39(false);
15072
15050
  const [isLeftVisible, setIsLeftVisible] = useState39(false);
15073
- const virtualRef = useRef18({
15051
+ const virtualRef = useRef19({
15074
15052
  getBoundingClientRect: () => new DOMRect()
15075
15053
  });
15076
- const leftVirtualRef = useRef18({
15054
+ const leftVirtualRef = useRef19({
15077
15055
  getBoundingClientRect: () => new DOMRect()
15078
15056
  });
15079
- const floatingElemRef = useRef18(null);
15080
- const leftFloatingElemRef = useRef18(null);
15081
- const dragHandleRef = useRef18(null);
15082
- const hoveredLeftCellRef = useRef18(null);
15083
- const hoveredTopCellRef = useRef18(null);
15084
- const handleMouseLeaveRef = useRef18(
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(
15085
15063
  null
15086
15064
  );
15087
- const dropIndicatorCleanupRef = useRef18([]);
15065
+ const dropIndicatorCleanupRef = useRef19([]);
15088
15066
  const [hoveredTable, setHoveredTable] = useState39(
15089
15067
  null
15090
15068
  );
@@ -15119,7 +15097,7 @@ function TableHoverActionsV2({
15119
15097
  strategy: "fixed",
15120
15098
  whileElementsMounted: autoUpdate
15121
15099
  });
15122
- useEffect41(() => {
15100
+ useEffect42(() => {
15123
15101
  if (!isEditable) {
15124
15102
  return;
15125
15103
  }
@@ -15186,7 +15164,7 @@ function TableHoverActionsV2({
15186
15164
  setIsLeftVisible(false);
15187
15165
  };
15188
15166
  }, [anchorElem, getTheme, isEditable, leftRefs, refs, update, updateLeft]);
15189
- useEffect41(() => {
15167
+ useEffect42(() => {
15190
15168
  const handleMouseLeave = (event) => {
15191
15169
  const nextTarget = event.relatedTarget;
15192
15170
  if (nextTarget && floatingElemRef.current && floatingElemRef.current.contains(nextTarget)) {
@@ -15211,7 +15189,7 @@ function TableHoverActionsV2({
15211
15189
  }
15212
15190
  });
15213
15191
  }, [editor]);
15214
- useEffect41(() => {
15192
+ useEffect42(() => {
15215
15193
  if (!hoveredTable) {
15216
15194
  setCanReorder(false);
15217
15195
  return;
@@ -15228,7 +15206,7 @@ function TableHoverActionsV2({
15228
15206
  { editor }
15229
15207
  );
15230
15208
  }, [editor, hoveredTable]);
15231
- useEffect41(() => {
15209
+ useEffect42(() => {
15232
15210
  const handle = dragHandleRef.current;
15233
15211
  const tableElement = hoveredTable;
15234
15212
  const columnIndex = hoveredColumnIndex;
@@ -15247,7 +15225,7 @@ function TableHoverActionsV2({
15247
15225
  });
15248
15226
  return cleanup;
15249
15227
  }, [canReorder, hoveredColumnIndex, hoveredTable]);
15250
- useEffect41(() => {
15228
+ useEffect42(() => {
15251
15229
  dropIndicatorCleanupRef.current.forEach((cleanup) => cleanup());
15252
15230
  dropIndicatorCleanupRef.current = [];
15253
15231
  if (!hoveredTable || !canReorder) {
@@ -15412,7 +15390,7 @@ function TableHoverActionsV2({
15412
15390
  insertionCaret?.splice(0, sortableRows);
15413
15391
  });
15414
15392
  };
15415
- return /* @__PURE__ */ jsxs34(Fragment17, { children: [
15393
+ return /* @__PURE__ */ jsxs34(Fragment20, { children: [
15416
15394
  /* @__PURE__ */ jsxs34(
15417
15395
  "div",
15418
15396
  {
@@ -15517,7 +15495,7 @@ function TableHoverActionsV2Plugin({
15517
15495
  // src/plugins/TableOfContentsPlugin/index.tsx
15518
15496
  import { useLexicalComposerContext as useLexicalComposerContext46 } from "@lexical/react/LexicalComposerContext";
15519
15497
  import { TableOfContentsPlugin as LexicalTableOfContentsPlugin } from "@lexical/react/LexicalTableOfContentsPlugin";
15520
- 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";
15521
15499
  import { jsx as jsx47, jsxs as jsxs35 } from "react/jsx-runtime";
15522
15500
  var MARGIN_ABOVE_EDITOR = 624;
15523
15501
  var HEADING_WIDTH = 9;
@@ -15544,7 +15522,7 @@ function TableOfContentsList({
15544
15522
  tableOfContents
15545
15523
  }) {
15546
15524
  const [selectedKey, setSelectedKey] = useState40("");
15547
- const selectedIndex = useRef19(0);
15525
+ const selectedIndex = useRef20(0);
15548
15526
  const [editor] = useLexicalComposerContext46();
15549
15527
  function scrollToNode(key, currIndex) {
15550
15528
  editor.getEditorState().read(() => {
@@ -15556,7 +15534,7 @@ function TableOfContentsList({
15556
15534
  }
15557
15535
  });
15558
15536
  }
15559
- useEffect42(() => {
15537
+ useEffect43(() => {
15560
15538
  function scrollCallback() {
15561
15539
  if (tableOfContents.length !== 0 && selectedIndex.current < tableOfContents.length - 1) {
15562
15540
  let currentHeading = editor.getElementByKey(
@@ -15655,7 +15633,7 @@ function TableOfContentsPlugin() {
15655
15633
 
15656
15634
  // src/plugins/TableScrollShadowPlugin/index.tsx
15657
15635
  import { useLexicalComposerContext as useLexicalComposerContext47 } from "@lexical/react/LexicalComposerContext";
15658
- import { useEffect as useEffect43 } from "react";
15636
+ import { useEffect as useEffect44 } from "react";
15659
15637
  var SCROLLABLE_WRAPPER_CLASS = "PlaygroundEditorTheme__tableScrollableWrapper";
15660
15638
  var HAS_SCROLL_RIGHT_CLASS = "PlaygroundEditorTheme__tableScrollRight";
15661
15639
  var HAS_SCROLL_LEFT_CLASS = "PlaygroundEditorTheme__tableScrollLeft";
@@ -15679,7 +15657,7 @@ function updateTableScrollState(element) {
15679
15657
  }
15680
15658
  function TableScrollShadowPlugin() {
15681
15659
  const [editor] = useLexicalComposerContext47();
15682
- useEffect43(() => {
15660
+ useEffect44(() => {
15683
15661
  const editorElement = editor.getRootElement();
15684
15662
  if (!editorElement) {
15685
15663
  return;
@@ -15809,7 +15787,7 @@ import {
15809
15787
  SKIP_SELECTION_FOCUS_TAG as SKIP_SELECTION_FOCUS_TAG2,
15810
15788
  UNDO_COMMAND as UNDO_COMMAND2
15811
15789
  } from "lexical";
15812
- 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";
15813
15791
 
15814
15792
  // src/ui/DropdownColorPicker.tsx
15815
15793
  import { jsx as jsx48 } from "react/jsx-runtime";
@@ -15833,7 +15811,7 @@ function DropdownColorPicker({
15833
15811
 
15834
15812
  // src/plugins/ToolbarPlugin/fontSize.tsx
15835
15813
  import * as React3 from "react";
15836
- 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";
15837
15815
  function parseFontSize(input) {
15838
15816
  const match = input.match(/^(\d+(?:\.\d+)?)(px|pt)$/);
15839
15817
  return match ? [Number(match[1]), match[2]] : null;
@@ -15903,7 +15881,7 @@ function FontSize({
15903
15881
  React3.useEffect(() => {
15904
15882
  setInputValue(selectionFontSize);
15905
15883
  }, [selectionFontSize]);
15906
- return /* @__PURE__ */ jsxs36(Fragment18, { children: [
15884
+ return /* @__PURE__ */ jsxs36(Fragment21, { children: [
15907
15885
  /* @__PURE__ */ jsx49(
15908
15886
  "button",
15909
15887
  {
@@ -15962,7 +15940,7 @@ function FontSize({
15962
15940
  }
15963
15941
 
15964
15942
  // src/plugins/ToolbarPlugin/index.tsx
15965
- 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";
15966
15944
  var CODE_LANGUAGE_OPTIONS_PRISM = getCodeLanguageOptionsPrism().filter(
15967
15945
  (option) => [
15968
15946
  "c",
@@ -16618,7 +16596,7 @@ function ToolbarPlugin({
16618
16596
  $handleHeadingNode,
16619
16597
  $handleCodeNode
16620
16598
  ]);
16621
- useEffect45(() => {
16599
+ useEffect46(() => {
16622
16600
  return editor.registerCommand(
16623
16601
  SELECTION_CHANGE_COMMAND5,
16624
16602
  (_payload, newEditor) => {
@@ -16629,7 +16607,7 @@ function ToolbarPlugin({
16629
16607
  COMMAND_PRIORITY_CRITICAL3
16630
16608
  );
16631
16609
  }, [editor, $updateToolbar, setActiveEditor]);
16632
- useEffect45(() => {
16610
+ useEffect46(() => {
16633
16611
  activeEditor.getEditorState().read(
16634
16612
  () => {
16635
16613
  $updateToolbar();
@@ -16637,7 +16615,7 @@ function ToolbarPlugin({
16637
16615
  { editor: activeEditor }
16638
16616
  );
16639
16617
  }, [activeEditor, $updateToolbar]);
16640
- useEffect45(() => {
16618
+ useEffect46(() => {
16641
16619
  return mergeRegister14(
16642
16620
  editor.registerEditableListener((editable) => {
16643
16621
  setIsEditable(editable);
@@ -16768,7 +16746,7 @@ function ToolbarPlugin({
16768
16746
  }
16769
16747
  ),
16770
16748
  /* @__PURE__ */ jsx50(Divider, {}),
16771
- toolbarState.blockType in blockTypeToBlockName && activeEditor === editor && /* @__PURE__ */ jsxs37(Fragment19, { children: [
16749
+ toolbarState.blockType in blockTypeToBlockName && activeEditor === editor && /* @__PURE__ */ jsxs37(Fragment22, { children: [
16772
16750
  /* @__PURE__ */ jsx50(
16773
16751
  BlockFormatDropDown,
16774
16752
  {
@@ -16780,7 +16758,7 @@ function ToolbarPlugin({
16780
16758
  ),
16781
16759
  /* @__PURE__ */ jsx50(Divider, {})
16782
16760
  ] }),
16783
- toolbarState.blockType === "code" && isCodeHighlighted ? /* @__PURE__ */ jsxs37(Fragment19, { children: [
16761
+ toolbarState.blockType === "code" && isCodeHighlighted ? /* @__PURE__ */ jsxs37(Fragment22, { children: [
16784
16762
  !isCodeShiki && /* @__PURE__ */ jsx50(
16785
16763
  DropDown,
16786
16764
  {
@@ -16805,7 +16783,7 @@ function ToolbarPlugin({
16805
16783
  })
16806
16784
  }
16807
16785
  ),
16808
- isCodeShiki && /* @__PURE__ */ jsxs37(Fragment19, { children: [
16786
+ isCodeShiki && /* @__PURE__ */ jsxs37(Fragment22, { children: [
16809
16787
  /* @__PURE__ */ jsx50(
16810
16788
  DropDown,
16811
16789
  {
@@ -16855,7 +16833,7 @@ function ToolbarPlugin({
16855
16833
  }
16856
16834
  )
16857
16835
  ] })
16858
- ] }) : /* @__PURE__ */ jsxs37(Fragment19, { children: [
16836
+ ] }) : /* @__PURE__ */ jsxs37(Fragment22, { children: [
16859
16837
  /* @__PURE__ */ jsx50(
16860
16838
  FontDropDown,
16861
16839
  {
@@ -17098,7 +17076,7 @@ function ToolbarPlugin({
17098
17076
  ]
17099
17077
  }
17100
17078
  ),
17101
- canViewerSeeInsertDropdown && /* @__PURE__ */ jsxs37(Fragment19, { children: [
17079
+ canViewerSeeInsertDropdown && /* @__PURE__ */ jsxs37(Fragment22, { children: [
17102
17080
  /* @__PURE__ */ jsx50(Divider, {}),
17103
17081
  /* @__PURE__ */ jsxs37(
17104
17082
  DropDown,
@@ -17420,10 +17398,10 @@ function ToolbarPlugin({
17420
17398
 
17421
17399
  // src/plugins/StickyPlugin/index.ts
17422
17400
  import { useLexicalComposerContext as useLexicalComposerContext48 } from "@lexical/react/LexicalComposerContext";
17423
- import { useEffect as useEffect46 } from "react";
17401
+ import { useEffect as useEffect47 } from "react";
17424
17402
  function StickyPlugin() {
17425
17403
  const [editor] = useLexicalComposerContext48();
17426
- useEffect46(() => {
17404
+ useEffect47(() => {
17427
17405
  if (!editor.hasNodes([StickyNode])) {
17428
17406
  throw new Error("StickyPlugin: StickyNode not registered on editor");
17429
17407
  }
@@ -17432,7 +17410,7 @@ function StickyPlugin() {
17432
17410
  }
17433
17411
 
17434
17412
  // src/Editor.tsx
17435
- 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";
17436
17414
  function Editor({ placeholder: placeholderProp, maxLength }) {
17437
17415
  const { historyState } = useSharedHistoryContext();
17438
17416
  const {
@@ -17471,7 +17449,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17471
17449
  setFloatingAnchorElem(_floatingAnchorElem);
17472
17450
  }
17473
17451
  };
17474
- useEffect47(() => {
17452
+ useEffect48(() => {
17475
17453
  const updateViewPortWidth = () => {
17476
17454
  const isNextSmallWidthViewport = CAN_USE_DOM && window.matchMedia("(max-width: 1025px)").matches;
17477
17455
  if (isNextSmallWidthViewport !== isSmallWidthViewport) {
@@ -17484,7 +17462,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17484
17462
  window.removeEventListener("resize", updateViewPortWidth);
17485
17463
  };
17486
17464
  }, [isSmallWidthViewport]);
17487
- return /* @__PURE__ */ jsxs38(Fragment20, { children: [
17465
+ return /* @__PURE__ */ jsxs38(Fragment23, { children: [
17488
17466
  isRichText && /* @__PURE__ */ jsx51(
17489
17467
  ToolbarPlugin,
17490
17468
  {
@@ -17521,7 +17499,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17521
17499
  /* @__PURE__ */ jsx51(LexicalAutoLinkPlugin, {}),
17522
17500
  /* @__PURE__ */ jsx51(DateTimePlugin, {}),
17523
17501
  /* @__PURE__ */ jsx51(CommentPlugin, {}),
17524
- isRichText ? /* @__PURE__ */ jsxs38(Fragment20, { children: [
17502
+ isRichText ? /* @__PURE__ */ jsxs38(Fragment23, { children: [
17525
17503
  /* @__PURE__ */ jsx51(HistoryPlugin2, { externalHistoryState: historyState }),
17526
17504
  /* @__PURE__ */ jsx51(
17527
17505
  RichTextPlugin,
@@ -17578,7 +17556,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17578
17556
  /* @__PURE__ */ jsx51(RevisionPlugin, {}),
17579
17557
  /* @__PURE__ */ jsx51(TextCardsPlugin, {}),
17580
17558
  /* @__PURE__ */ jsx51(QuestionsCardsPlugin, {}),
17581
- floatingAnchorElem && /* @__PURE__ */ jsxs38(Fragment20, { children: [
17559
+ floatingAnchorElem && /* @__PURE__ */ jsxs38(Fragment23, { children: [
17582
17560
  /* @__PURE__ */ jsx51(
17583
17561
  FloatingLinkEditorPlugin,
17584
17562
  {
@@ -17595,7 +17573,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17595
17573
  }
17596
17574
  )
17597
17575
  ] }),
17598
- floatingAnchorElem && !isSmallWidthViewport && /* @__PURE__ */ jsxs38(Fragment20, { children: [
17576
+ floatingAnchorElem && !isSmallWidthViewport && /* @__PURE__ */ jsxs38(Fragment23, { children: [
17599
17577
  /* @__PURE__ */ jsx51(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }),
17600
17578
  /* @__PURE__ */ jsx51(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }),
17601
17579
  /* @__PURE__ */ jsx51(TableHoverActionsV2Plugin, { anchorElem: floatingAnchorElem }),
@@ -17607,7 +17585,7 @@ function Editor({ placeholder: placeholderProp, maxLength }) {
17607
17585
  }
17608
17586
  )
17609
17587
  ] })
17610
- ] }) : /* @__PURE__ */ jsxs38(Fragment20, { children: [
17588
+ ] }) : /* @__PURE__ */ jsxs38(Fragment23, { children: [
17611
17589
  /* @__PURE__ */ jsx51(
17612
17590
  PlainTextPlugin2,
17613
17591
  {
@@ -17747,6 +17725,14 @@ function hasComplexStyles(el) {
17747
17725
  return COMPLEX_STYLE_PATTERNS.some((re) => re.test(style));
17748
17726
  }
17749
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
+ ];
17750
17736
  function preprocessHtmlForImport(doc) {
17751
17737
  processChildren(doc.body);
17752
17738
  }
@@ -17754,6 +17740,7 @@ function processChildren(parent) {
17754
17740
  const children = Array.from(parent.children);
17755
17741
  for (const child of children) {
17756
17742
  if (child.hasAttribute(DATA_ATTR7)) continue;
17743
+ if (LEXICAL_NODE_ATTRS.some((attr) => child.hasAttribute(attr))) continue;
17757
17744
  const tag = child.tagName;
17758
17745
  if (tag === "DIV") {
17759
17746
  if (hasComplexStyles(child)) {
@@ -17795,10 +17782,10 @@ function HtmlPlugin({
17795
17782
  debounceMs = 300
17796
17783
  }) {
17797
17784
  const [editor] = useLexicalComposerContext50();
17798
- const lastSyncedValue = useRef20(null);
17799
- const hasUserEdited = useRef20(false);
17800
- const debounceTimer = useRef20(null);
17801
- useEffect48(() => {
17785
+ const lastSyncedValue = useRef21(null);
17786
+ const hasUserEdited = useRef21(false);
17787
+ const debounceTimer = useRef21(null);
17788
+ useEffect49(() => {
17802
17789
  return editor.registerCommand(
17803
17790
  FOCUS_COMMAND2,
17804
17791
  () => {
@@ -17820,7 +17807,7 @@ function HtmlPlugin({
17820
17807
  COMMAND_PRIORITY_LOW11
17821
17808
  );
17822
17809
  }, [editor]);
17823
- useEffect48(() => {
17810
+ useEffect49(() => {
17824
17811
  if (value === lastSyncedValue.current) {
17825
17812
  return;
17826
17813
  }
@@ -17839,9 +17826,9 @@ function HtmlPlugin({
17839
17826
  const parser = new DOMParser();
17840
17827
  const dom = parser.parseFromString(value, "text/html");
17841
17828
  preprocessHtmlForImport(dom);
17842
- const nodes = $generateNodesFromDOM(editor, dom);
17829
+ const nodes = $generateNodesFromDOM2(editor, dom);
17843
17830
  root.clear();
17844
- $insertNodes6(nodes);
17831
+ $insertNodes7(nodes);
17845
17832
  },
17846
17833
  // Prevent scroll-to-top when loading content inside a Sheet
17847
17834
  { tag: "historic" }
@@ -17871,7 +17858,7 @@ function HtmlPlugin({
17871
17858
  },
17872
17859
  [editor, onChange, debounceMs]
17873
17860
  );
17874
- useEffect48(() => {
17861
+ useEffect49(() => {
17875
17862
  return () => {
17876
17863
  if (debounceTimer.current) {
17877
17864
  clearTimeout(debounceTimer.current);
@@ -17882,7 +17869,7 @@ function HtmlPlugin({
17882
17869
  }
17883
17870
  function ReadOnlyController({ readOnly }) {
17884
17871
  const [editor] = useLexicalComposerContext50();
17885
- useEffect48(() => {
17872
+ useEffect49(() => {
17886
17873
  editor.setEditable(!readOnly);
17887
17874
  }, [editor, readOnly]);
17888
17875
  return null;
@@ -17905,6 +17892,51 @@ function LexicalEditor20({
17905
17892
  theme: PlaygroundEditorTheme_default,
17906
17893
  onError: (error) => {
17907
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
+ }, {})
17908
17940
  }
17909
17941
  };
17910
17942
  const style = isFullscreen ? {
@@ -17919,7 +17951,7 @@ function LexicalEditor20({
17919
17951
  position: "relative",
17920
17952
  overflow: "auto"
17921
17953
  };
17922
- useEffect48(() => {
17954
+ useEffect49(() => {
17923
17955
  if (!isFullscreen) return;
17924
17956
  const handleEsc = (e) => {
17925
17957
  if (e.key === "Escape") setIsFullscreen(false);
@@ -17931,11 +17963,11 @@ function LexicalEditor20({
17931
17963
  () => setIsFullscreen((f) => !f),
17932
17964
  []
17933
17965
  );
17934
- const fullscreenValue = useMemo24(
17966
+ const fullscreenValue = useMemo23(
17935
17967
  () => ({ isFullscreen, toggleFullscreen }),
17936
17968
  [isFullscreen, toggleFullscreen]
17937
17969
  );
17938
- const collabContextValue = useMemo24(
17970
+ const collabContextValue = useMemo23(
17939
17971
  () => ({
17940
17972
  color: "#000",
17941
17973
  isCollabActive: false,