'use client'; import React, { useRef } from 'react'; import { useResolvedTheme } from '@djangocfg/ui-core/hooks'; import { FloatingToolbar } from '../../../common/FloatingToolbar'; import { CopyAction, FullscreenAction } from '../../../common/FloatingToolbar/actions'; import { MermaidErrorPanel } from './components/MermaidErrorPanel'; import { MermaidFullscreenModal } from './components/MermaidFullscreenModal'; import { useMermaidFullscreen } from './hooks/useMermaidFullscreen'; import { useMermaidRenderer } from './hooks/useMermaidRenderer'; interface MermaidProps { chart: string; className?: string; isCompact?: boolean; /** Enable click-to-fullscreen functionality (default: true) */ fullscreen?: boolean; /** * Enable the FloatingToolbar's "click to scroll" lock overlay. * Defaults to `false` — Mermaid SVGs are short, the diagram itself * doesn't scroll internally, and a lock overlay just steals * wheel events from the page. Standalone callers can opt in if * they have a reason to. */ scrollIsolation?: boolean; /** * Debounce window (ms) before (re)rendering after `chart` changes. * Lower values feel snappier for static charts; higher values * reduce churn while a diagram is streamed in. Default 300. */ debounceMs?: number; } const Mermaid: React.FC = ({ chart, className = '', isCompact = false, fullscreen = true, scrollIsolation = false, debounceMs = 300, }) => { const containerRef = useRef(null); const theme = useResolvedTheme(); // Rendering logic const { mermaidRef, svgContent, isVertical, isRendering, error } = useMermaidRenderer({ chart, theme, isCompact, debounceMs, }); // Fullscreen modal logic (only used if fullscreen prop is true) const { isFullscreen, fullscreenRef, openFullscreen, closeFullscreen, handleBackdropClick, } = useMermaidFullscreen(); // Hoist derived UI state out of JSX (data-before-JSX). const hasError = error !== null; // The spinner needs a box to sit in while the first diagram renders // (empty SVG host has no intrinsic height). const showPlaceholderHeight = isRendering && !svgContent && !hasError; const showToolbar = !!svgContent && !isRendering && !hasError; return ( <>
{hasError && }
{isRendering && !hasError && (
)} {showToolbar && ( {fullscreen && ( )} )}
{fullscreen && ( )} ); }; export default Mermaid;