@zm-editor/react 0.1.0 → 0.1.1

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
@@ -6,8 +6,6 @@ export * from '@zm-editor/core';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import Image from '@tiptap/extension-image';
8
8
  import { Node as Node$1, mergeAttributes } from '@tiptap/core';
9
- import katex from 'katex';
10
- import mermaid from 'mermaid';
11
9
 
12
10
  // src/components/Editor.tsx
13
11
 
@@ -3413,12 +3411,30 @@ var Bookmark = Node$1.create({
3413
3411
  return ReactNodeViewRenderer(BookmarkNode);
3414
3412
  }
3415
3413
  });
3416
- function renderLatex(latex, displayMode) {
3414
+ var katexModule = null;
3415
+ var katexLoadError = null;
3416
+ async function loadKatex() {
3417
+ if (katexModule) return katexModule;
3418
+ if (katexLoadError) return null;
3419
+ try {
3420
+ katexModule = await import('katex');
3421
+ return katexModule;
3422
+ } catch (err) {
3423
+ katexLoadError = "KaTeX library is not installed. Please run: npm install katex";
3424
+ console.warn("[zm-editor] KaTeX not available:", katexLoadError);
3425
+ return null;
3426
+ }
3427
+ }
3428
+ async function renderLatexAsync(latex, displayMode) {
3417
3429
  if (!latex.trim()) {
3418
3430
  return { html: "", error: null };
3419
3431
  }
3432
+ const katex = await loadKatex();
3433
+ if (!katex) {
3434
+ return { html: "", error: katexLoadError || "KaTeX library not available" };
3435
+ }
3420
3436
  try {
3421
- const html = katex.renderToString(latex, {
3437
+ const html = katex.default.renderToString(latex, {
3422
3438
  displayMode,
3423
3439
  throwOnError: true,
3424
3440
  strict: false,
@@ -3436,19 +3452,35 @@ function MathNode({ node, updateAttributes, selected }) {
3436
3452
  const { latex = "", displayMode = true } = node.attrs;
3437
3453
  const [isEditing, setIsEditing] = useState(false);
3438
3454
  const [latexValue, setLatexValue] = useState(latex);
3455
+ const [renderedHtml, setRenderedHtml] = useState("");
3456
+ const [renderError, setRenderError] = useState(null);
3457
+ const [isKatexAvailable, setIsKatexAvailable] = useState(null);
3458
+ const textareaRef = useRef(null);
3459
+ useEffect(() => {
3460
+ loadKatex().then((k) => setIsKatexAvailable(k !== null));
3461
+ }, []);
3439
3462
  useEffect(() => {
3440
3463
  if (!latex) {
3441
3464
  setIsEditing(true);
3442
3465
  }
3443
3466
  }, []);
3444
- const textareaRef = useRef(null);
3445
- const rendered = useMemo(() => renderLatex(latexValue, displayMode), [latexValue, displayMode]);
3446
3467
  useEffect(() => {
3447
3468
  setLatexValue(latex);
3448
3469
  if (latex) {
3449
3470
  setIsEditing(false);
3450
3471
  }
3451
3472
  }, [latex]);
3473
+ useEffect(() => {
3474
+ if (!latexValue.trim()) {
3475
+ setRenderedHtml("");
3476
+ setRenderError(null);
3477
+ return;
3478
+ }
3479
+ renderLatexAsync(latexValue, displayMode).then((result) => {
3480
+ setRenderedHtml(result.html);
3481
+ setRenderError(result.error);
3482
+ });
3483
+ }, [latexValue, displayMode]);
3452
3484
  const handleSave = useCallback(() => {
3453
3485
  const trimmed = latexValue.trim();
3454
3486
  if (!trimmed) {
@@ -3490,6 +3522,14 @@ function MathNode({ node, updateAttributes, selected }) {
3490
3522
  useEffect(() => {
3491
3523
  adjustTextareaHeight();
3492
3524
  }, [latexValue, adjustTextareaHeight]);
3525
+ if (isKatexAvailable === false) {
3526
+ return /* @__PURE__ */ jsx(NodeViewWrapper, { className: "zm-math-node-wrapper", children: /* @__PURE__ */ jsx("div", { className: `zm-math-node zm-math-unavailable ${selected ? "is-selected" : ""}`, children: /* @__PURE__ */ jsxs("div", { className: "zm-math-unavailable-content", children: [
3527
+ /* @__PURE__ */ jsx(MathIcon, {}),
3528
+ /* @__PURE__ */ jsx("div", { className: "zm-math-unavailable-title", children: "Math Equations" }),
3529
+ /* @__PURE__ */ jsx("div", { className: "zm-math-unavailable-message", children: "To use math equations, please install the KaTeX package:" }),
3530
+ /* @__PURE__ */ jsx("code", { className: "zm-math-unavailable-code", children: "npm install katex" })
3531
+ ] }) }) });
3532
+ }
3493
3533
  if (isEditing || !latex) {
3494
3534
  return /* @__PURE__ */ jsx(NodeViewWrapper, { className: "zm-math-node-wrapper", children: /* @__PURE__ */ jsx(
3495
3535
  "div",
@@ -3517,19 +3557,18 @@ function MathNode({ node, updateAttributes, selected }) {
3517
3557
  spellCheck: false
3518
3558
  }
3519
3559
  ),
3520
- latexValue.trim() && /* @__PURE__ */ jsx("div", { className: "zm-math-preview", children: rendered.error ? /* @__PURE__ */ jsx("div", { className: "zm-math-error", children: rendered.error }) : /* @__PURE__ */ jsx(
3560
+ latexValue.trim() && /* @__PURE__ */ jsx("div", { className: "zm-math-preview", children: renderError ? /* @__PURE__ */ jsx("div", { className: "zm-math-error", children: renderError }) : renderedHtml ? /* @__PURE__ */ jsx(
3521
3561
  "div",
3522
3562
  {
3523
3563
  className: "zm-math-rendered",
3524
- dangerouslySetInnerHTML: { __html: rendered.html }
3564
+ dangerouslySetInnerHTML: { __html: renderedHtml }
3525
3565
  }
3526
- ) }),
3566
+ ) : null }),
3527
3567
  /* @__PURE__ */ jsx("div", { className: "zm-math-hint", children: locale.nodes.math.hint })
3528
3568
  ] })
3529
3569
  }
3530
3570
  ) });
3531
3571
  }
3532
- const finalRendered = renderLatex(latex, displayMode);
3533
3572
  return /* @__PURE__ */ jsxs(NodeViewWrapper, { className: "zm-math-node-wrapper", children: [
3534
3573
  /* @__PURE__ */ jsx(
3535
3574
  "div",
@@ -3537,17 +3576,17 @@ function MathNode({ node, updateAttributes, selected }) {
3537
3576
  className: `zm-math-node zm-math-display ${selected ? "is-selected" : ""}`,
3538
3577
  "data-drag-handle": true,
3539
3578
  onClick: handleEdit,
3540
- children: finalRendered.error ? /* @__PURE__ */ jsxs("div", { className: "zm-math-error-display", children: [
3579
+ children: renderError ? /* @__PURE__ */ jsxs("div", { className: "zm-math-error-display", children: [
3541
3580
  /* @__PURE__ */ jsx("div", { className: "zm-math-error-icon", children: /* @__PURE__ */ jsx(ErrorIcon, {}) }),
3542
- /* @__PURE__ */ jsx("div", { className: "zm-math-error-message", children: finalRendered.error }),
3581
+ /* @__PURE__ */ jsx("div", { className: "zm-math-error-message", children: renderError }),
3543
3582
  /* @__PURE__ */ jsx("div", { className: "zm-math-error-source", children: latex })
3544
- ] }) : /* @__PURE__ */ jsx(
3583
+ ] }) : renderedHtml ? /* @__PURE__ */ jsx(
3545
3584
  "div",
3546
3585
  {
3547
3586
  className: "zm-math-rendered",
3548
- dangerouslySetInnerHTML: { __html: finalRendered.html }
3587
+ dangerouslySetInnerHTML: { __html: renderedHtml }
3549
3588
  }
3550
- )
3589
+ ) : /* @__PURE__ */ jsx("div", { className: "zm-math-loading", children: "Loading..." })
3551
3590
  }
3552
3591
  ),
3553
3592
  selected && /* @__PURE__ */ jsx("div", { className: "zm-math-toolbar", children: /* @__PURE__ */ jsx(
@@ -4401,7 +4440,7 @@ function TerminalNode({ node, updateAttributes, selected }) {
4401
4440
  [updateAttributes]
4402
4441
  );
4403
4442
  const handleOutputInput = useCallback((e) => {
4404
- const textarea = e.target;
4443
+ const textarea = e.currentTarget;
4405
4444
  textarea.style.height = "auto";
4406
4445
  textarea.style.height = `${textarea.scrollHeight}px`;
4407
4446
  }, []);
@@ -4879,8 +4918,22 @@ var ApiBlock = Node$1.create({
4879
4918
  return ReactNodeViewRenderer(ApiBlockNode);
4880
4919
  }
4881
4920
  });
4921
+ var mermaidModule = null;
4922
+ var mermaidLoadError = null;
4882
4923
  var mermaidInitialized = false;
4883
- function initializeMermaid() {
4924
+ async function loadMermaid() {
4925
+ if (mermaidModule) return mermaidModule;
4926
+ if (mermaidLoadError) return null;
4927
+ try {
4928
+ mermaidModule = await import('mermaid');
4929
+ return mermaidModule;
4930
+ } catch (err) {
4931
+ mermaidLoadError = "Mermaid library is not installed. Please run: npm install mermaid";
4932
+ console.warn("[zm-editor] Mermaid not available:", mermaidLoadError);
4933
+ return null;
4934
+ }
4935
+ }
4936
+ function initializeMermaid(mermaid) {
4884
4937
  if (mermaidInitialized) return;
4885
4938
  mermaid.initialize({
4886
4939
  startOnLoad: false,
@@ -4894,9 +4947,13 @@ async function renderMermaid(code, id) {
4894
4947
  if (!code.trim()) {
4895
4948
  return { svg: "", error: null };
4896
4949
  }
4897
- initializeMermaid();
4950
+ const mermaid = await loadMermaid();
4951
+ if (!mermaid) {
4952
+ return { svg: "", error: mermaidLoadError || "Mermaid library not available" };
4953
+ }
4954
+ initializeMermaid(mermaid.default);
4898
4955
  try {
4899
- const { svg } = await mermaid.render(id, code);
4956
+ const { svg } = await mermaid.default.render(id, code);
4900
4957
  return { svg, error: null };
4901
4958
  } catch (err) {
4902
4959
  cleanupOrphanMermaidElements(id);
@@ -4927,8 +4984,12 @@ function MermaidNode({ node, updateAttributes, selected }) {
4927
4984
  const [renderedSvg, setRenderedSvg] = useState("");
4928
4985
  const [renderError, setRenderError] = useState(null);
4929
4986
  const [isRendering, setIsRendering] = useState(false);
4987
+ const [isMermaidAvailable, setIsMermaidAvailable] = useState(null);
4930
4988
  const textareaRef = useRef(null);
4931
4989
  const renderIdRef = useRef(0);
4990
+ useEffect(() => {
4991
+ loadMermaid().then((m) => setIsMermaidAvailable(m !== null));
4992
+ }, []);
4932
4993
  useEffect(() => {
4933
4994
  if (!code) {
4934
4995
  setIsEditing(true);
@@ -4996,6 +5057,14 @@ function MermaidNode({ node, updateAttributes, selected }) {
4996
5057
  useEffect(() => {
4997
5058
  adjustTextareaHeight();
4998
5059
  }, [codeValue, adjustTextareaHeight]);
5060
+ if (isMermaidAvailable === false) {
5061
+ return /* @__PURE__ */ jsx(NodeViewWrapper, { className: "zm-mermaid-node-wrapper", children: /* @__PURE__ */ jsx("div", { className: `zm-mermaid-node zm-mermaid-unavailable ${selected ? "is-selected" : ""}`, children: /* @__PURE__ */ jsxs("div", { className: "zm-mermaid-unavailable-content", children: [
5062
+ /* @__PURE__ */ jsx(MermaidIcon, {}),
5063
+ /* @__PURE__ */ jsx("div", { className: "zm-mermaid-unavailable-title", children: "Mermaid Diagrams" }),
5064
+ /* @__PURE__ */ jsx("div", { className: "zm-mermaid-unavailable-message", children: "To use Mermaid diagrams, please install the mermaid package:" }),
5065
+ /* @__PURE__ */ jsx("code", { className: "zm-mermaid-unavailable-code", children: "npm install mermaid" })
5066
+ ] }) }) });
5067
+ }
4999
5068
  if (isEditing || !code) {
5000
5069
  return /* @__PURE__ */ jsx(NodeViewWrapper, { className: "zm-mermaid-node-wrapper", children: /* @__PURE__ */ jsx(
5001
5070
  "div",