SPB Git

spb/zyquo-cloud-web Public MIT

Zyquo Cloud Web — every cloud model, one beautiful chat, entirely in your browser.

TypeScript 81.9% CSS 8.9% JavaScript 7.5% Shell 1.1% HTML 0.6%
1.7 KB · 63 lines tsx
Raw Blame History
1/*2 *  Mermaid.tsx3 *  Zyquo Cloud Web4 *5 *  Author: Simon-Pierre Boucher6 *  Mail: contact@spboucher.ai7 *8 *  Mermaid diagram rendering — the library (~1 MB) is lazy-loaded only when a9 *  ```mermaid block actually appears, keeping the main bundle slim.10 */1112import { useEffect, useRef, useState } from 'react'1314let mermaidPromise: Promise<typeof import('mermaid')> | null = null15let renderCounter = 01617export default function Mermaid({ code }: { code: string }) {18  const [svg, setSvg] = useState<string | null>(null)19  const [error, setError] = useState<string | null>(null)20  const ref = useRef<HTMLDivElement>(null)2122  useEffect(() => {23    let live = true24    mermaidPromise ??= import('mermaid')25    void mermaidPromise26      .then(async (mod) => {27        const mermaid = mod.default28        mermaid.initialize({ startOnLoad: false, theme: 'neutral', securityLevel: 'strict' })29        const { svg } = await mermaid.render(`zyquo-mermaid-${++renderCounter}`, code)30        if (live) setSvg(svg)31      })32      .catch((err: unknown) => {33        if (live) setError(err instanceof Error ? err.message : 'Diagram failed to render')34      })35    return () => {36      live = false37    }38  }, [code])3940  if (error) {41    return (42      <div className="code-block">43        <div className="code-block-header">44          <span>mermaid (failed)</span>45        </div>46        <pre>47          <code>{code}</code>48        </pre>49      </div>50    )51  }52  if (!svg) {53    return <div style={{ color: 'var(--z-text-tertiary)', fontSize: 12 }}>Rendering diagram…</div>54  }55  return (56    <div57      ref={ref}58      style={{ overflowX: 'auto', background: 'var(--z-surface)', borderRadius: 10, padding: 8 }}59      dangerouslySetInnerHTML={{ __html: svg }}60    />61  )62}63