{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mermaid",
  "title": "Mermaid",
  "author": "Poyraz Avsever",
  "description": "Poyraz Soft Glass mermaid with semantic states and composable variants.",
  "dependencies": [
    "mermaid@^11.12.3"
  ],
  "registryDependencies": [
    "@poyraz/poyraz-utils",
    "@poyraz/poyraz-theme"
  ],
  "files": [
    {
      "path": "registry/poyraz/ui/phase7/molecules/mermaid.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\n/* ================================================================== */\n/*  MERMAID — Render mermaid diagrams from children code               */\n/* ================================================================== */\n\nexport interface MermaidProps extends React.HTMLAttributes<HTMLDivElement> {\n  /** Mermaid code — pass as children (string) or as this prop */\n  code?: string;\n  /** Chart id prefix */\n  chartId?: string;\n  children?: React.ReactNode;\n  surface?: \"solid\" | \"soft\" | \"glass\";\n  radius?: \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n  diagramStyle?: \"soft\" | \"minimal\" | \"technical\";\n  loadingContent?: React.ReactNode;\n  errorContent?: (error: string) => React.ReactNode;\n}\n\nlet mermaidReady: Promise<typeof import(\"mermaid\")> | null = null;\n\nfunction getMermaid() {\n  if (!mermaidReady) {\n    mermaidReady = import(\"mermaid\");\n  }\n  return mermaidReady;\n}\n\nfunction resolveColor(container: HTMLElement, variable: string, fallback: string) {\n  const probe = document.createElement(\"span\");\n  probe.style.cssText = `position:absolute;visibility:hidden;color:var(${variable},${fallback})`;\n  container.appendChild(probe);\n  const color = getComputedStyle(probe).color || fallback;\n  probe.remove();\n  return color;\n}\n\nfunction resolveMermaidTheme(container: HTMLElement) {\n  return {\n    primaryColor: resolveColor(container, \"--poyraz-primary-muted\", \"rgb(254 226 226)\"),\n    primaryBorderColor: resolveColor(container, \"--poyraz-primary\", \"rgb(220 38 38)\"),\n    primaryTextColor: resolveColor(container, \"--poyraz-foreground\", \"rgb(15 23 42)\"),\n    secondaryColor: resolveColor(container, \"--poyraz-surface-subtle\", \"rgb(241 245 249)\"),\n    secondaryBorderColor: resolveColor(container, \"--poyraz-border-strong\", \"rgb(148 163 184)\"),\n    secondaryTextColor: resolveColor(container, \"--poyraz-foreground\", \"rgb(51 65 85)\"),\n    tertiaryColor: resolveColor(container, \"--poyraz-warning\", \"rgb(254 243 199)\"),\n    tertiaryBorderColor: resolveColor(container, \"--poyraz-warning-border\", \"rgb(217 119 6)\"),\n    tertiaryTextColor: resolveColor(container, \"--poyraz-warning-foreground\", \"rgb(120 53 15)\"),\n    lineColor: resolveColor(container, \"--poyraz-muted-foreground\", \"rgb(100 116 139)\"),\n    textColor: resolveColor(container, \"--poyraz-foreground\", \"rgb(15 23 42)\"),\n    mainBkg: resolveColor(container, \"--poyraz-surface\", \"rgb(255 255 255)\"),\n    nodeBorder: resolveColor(container, \"--poyraz-primary\", \"rgb(220 38 38)\"),\n    clusterBkg: resolveColor(container, \"--poyraz-surface-subtle\", \"rgb(248 250 252)\"),\n    clusterBorder: resolveColor(container, \"--poyraz-border\", \"rgb(203 213 225)\"),\n    titleColor: resolveColor(container, \"--poyraz-foreground\", \"rgb(15 23 42)\"),\n    edgeLabelBackground: resolveColor(container, \"--poyraz-surface\", \"rgb(255 255 255)\"),\n    nodeTextColor: resolveColor(container, \"--poyraz-foreground\", \"rgb(15 23 42)\"),\n    fontFamily: \"var(--poyraz-font-primary), ui-sans-serif, system-ui, sans-serif\",\n    fontSize: \"13px\",\n  };\n}\n\nlet idCounter = 0;\n\nconst Mermaid = React.forwardRef<HTMLDivElement, MermaidProps>(\n  (\n    {\n      className,\n      code,\n      chartId,\n      children,\n      diagramStyle = \"soft\",\n      errorContent,\n      loadingContent,\n      radius = \"lg\",\n      surface = \"solid\",\n      ...props\n    },\n    ref,\n  ) => {\n    const containerRef = React.useRef<HTMLDivElement>(null);\n    const [svg, setSvg] = React.useState<string>(\"\");\n    const [error, setError] = React.useState<string>(\"\");\n    const [loading, setLoading] = React.useState(true);\n    const [themeRevision, setThemeRevision] = React.useState(0);\n\n    // Resolve mermaid code from children or code prop\n    const mermaidCode = React.useMemo(() => {\n      if (code) return code.trim();\n      if (typeof children === \"string\") return children.trim();\n      return \"\";\n    }, [code, children]);\n\n    React.useEffect(() => {\n      const update = () => setThemeRevision((revision) => revision + 1);\n      const observer = new MutationObserver(update);\n      observer.observe(document.documentElement, {\n        attributes: true,\n        attributeFilter: [\"class\", \"data-poyraz-theme\", \"style\"],\n      });\n      const media = window.matchMedia(\"(prefers-color-scheme: dark)\");\n      media.addEventListener(\"change\", update);\n      return () => {\n        observer.disconnect();\n        media.removeEventListener(\"change\", update);\n      };\n    }, []);\n\n    React.useEffect(() => {\n      if (!mermaidCode) {\n        setLoading(false);\n        setError(\"No mermaid code provided.\");\n        return;\n      }\n\n      let cancelled = false;\n      const id = chartId ?? `poyraz-mermaid-${++idCounter}`;\n\n      setLoading(true);\n      setError(\"\");\n\n      getMermaid()\n        .then(async (mod) => {\n          if (cancelled) return;\n          try {\n            const container = containerRef.current;\n            if (!container) return;\n            mod.default.initialize({\n              startOnLoad: false,\n              securityLevel: \"strict\",\n              theme: \"base\",\n              themeVariables: resolveMermaidTheme(container),\n              flowchart: {\n                htmlLabels: true,\n                curve: diagramStyle === \"technical\" ? \"linear\" : \"basis\",\n                padding: 12,\n              },\n              sequence: { actorMargin: 60, boxMargin: 8, noteMargin: 10, messageMargin: 30 },\n            });\n            const { svg: rendered } = await mod.default.render(id, mermaidCode);\n            if (!cancelled) {\n              setSvg(rendered);\n              setLoading(false);\n            }\n          } catch (err) {\n            if (!cancelled) {\n              setError(err instanceof Error ? err.message : \"Failed to render diagram.\");\n              setLoading(false);\n            }\n          }\n        })\n        .catch((err) => {\n          if (!cancelled) {\n            setError(err instanceof Error ? err.message : \"Failed to load mermaid.\");\n            setLoading(false);\n          }\n        });\n\n      return () => {\n        cancelled = true;\n      };\n    }, [mermaidCode, chartId, diagramStyle, themeRevision]);\n\n    // Combine refs\n    const setRefs = React.useCallback(\n      (node: HTMLDivElement | null) => {\n        (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n        if (typeof ref === \"function\") ref(node);\n        else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n      },\n      [ref],\n    );\n\n    return (\n      <div\n        ref={setRefs}\n        className={cn(\n          \"relative overflow-x-auto border p-4 transition-[background-color,border-color] duration-[var(--poyraz-motion-duration-base)]\",\n          surface === \"solid\" && \"border-border bg-surface\",\n          surface === \"soft\" && \"border-transparent bg-surface-subtle\",\n          surface === \"glass\" && \"border-glass-border-outer bg-glass shadow-md backdrop-blur-glass\",\n          radius === \"none\" && \"rounded-none\",\n          radius === \"sm\" && \"rounded-sm\",\n          radius === \"md\" && \"rounded-md\",\n          radius === \"lg\" && \"rounded-lg\",\n          radius === \"xl\" && \"rounded-xl\",\n          className,\n        )}\n        {...props}\n      >\n        {loading && (\n          <div\n            role=\"status\"\n            className=\"flex items-center justify-center py-8 gap-3 text-sm text-muted-foreground animate-poyraz-fade-in\"\n          >\n            {loadingContent ?? (\n              <>\n                <div className=\"size-4 rounded-full border-2 border-primary/25 border-t-primary animate-poyraz-spin\" />\n                Rendering diagram…\n              </>\n            )}\n          </div>\n        )}\n\n        {error && !loading && (\n          <div className=\"py-6 text-center animate-poyraz-fade-in\">\n            <div\n              role=\"alert\"\n              className=\"inline-block rounded-md border border-invalid-border bg-invalid-muted px-3 py-2 text-xs text-destructive-muted-foreground font-mono\"\n            >\n              {errorContent ? errorContent(error) : error}\n            </div>\n          </div>\n        )}\n\n        {svg && !loading && (\n          <div\n            className=\"mermaid-output flex justify-center animate-poyraz-scale-in motion-reduce:animate-none [&_svg]:max-w-full\"\n            dangerouslySetInnerHTML={{ __html: svg }}\n          />\n        )}\n\n        {/* Override some SVG styles to match brutalist theme */}\n        <style\n          dangerouslySetInnerHTML={{\n            __html: `\n${\n  diagramStyle === \"technical\"\n    ? `.mermaid-output .node rect,\n.mermaid-output .node circle,\n.mermaid-output .node ellipse,\n.mermaid-output .node polygon {\n  stroke-dasharray: 6, 3;\n  stroke-width: 2px;\n}`\n    : \"\"\n}\n.mermaid-output .cluster rect {\n  ${diagramStyle === \"technical\" ? \"stroke-dasharray: 8, 4;\" : \"\"}\n  stroke-width: 1.5px;\n  rx: ${diagramStyle === \"minimal\" ? \"2\" : \"10\"};\n  ry: ${diagramStyle === \"minimal\" ? \"2\" : \"10\"};\n}\n.mermaid-output .edgePath .path {\n  stroke-width: 1.5px;\n}\n.mermaid-output text, .mermaid-output .label { font-family: var(--poyraz-font-primary), ui-sans-serif, system-ui, sans-serif !important; }\n`,\n          }}\n        />\n      </div>\n    );\n  },\n);\nMermaid.displayName = \"Mermaid\";\n\nexport { Mermaid };\n",
      "type": "registry:ui",
      "target": "@ui/molecules/mermaid.tsx"
    }
  ],
  "meta": {
    "category": "phase-7-composite",
    "phase": "beta"
  },
  "type": "registry:ui"
}