feat: unify code-like components with shared CodeWindow, fix blog re-render loop, and stabilize layouts
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 8s
Build & Deploy / 🧪 QA (push) Failing after 1m2s
Build & Deploy / 🏗️ Build (push) Failing after 3m44s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s

This commit is contained in:
2026-02-15 17:34:07 +01:00
parent 7c774f65bc
commit c1295546a6
32 changed files with 3293 additions and 1235 deletions

View File

@@ -1,19 +1,23 @@
'use client';
"use client";
import React, { useEffect, useRef, useState } from 'react';
import mermaid from 'mermaid';
import React, { useEffect, useRef, useState } from "react";
import mermaid from "mermaid";
interface MermaidProps {
graph: string;
id?: string;
}
import { CodeWindow } from "./Effects/CodeWindow";
export const Mermaid: React.FC<MermaidProps> = ({ graph, id: providedId }) => {
const [id, setId] = useState<string | null>(null);
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
setId(providedId || `mermaid-${Math.random().toString(36).substring(2, 11)}`);
setId(
providedId || `mermaid-${Math.random().toString(36).substring(2, 11)}`,
);
}, [providedId]);
const [isRendered, setIsRendered] = useState(false);
const [error, setError] = useState<string | null>(null);
@@ -21,17 +25,17 @@ export const Mermaid: React.FC<MermaidProps> = ({ graph, id: providedId }) => {
useEffect(() => {
mermaid.initialize({
startOnLoad: false,
theme: 'default',
theme: "default",
darkMode: false,
themeVariables: {
fontFamily: 'Inter, system-ui, sans-serif',
fontSize: '16px',
primaryColor: '#ffffff',
nodeBorder: '#e2e8f0',
mainBkg: '#ffffff',
lineColor: '#cbd5e1',
fontFamily: "Inter, system-ui, sans-serif",
fontSize: "16px",
primaryColor: "#ffffff",
nodeBorder: "#e2e8f0",
mainBkg: "#ffffff",
lineColor: "#cbd5e1",
},
securityLevel: 'loose',
securityLevel: "loose",
});
const render = async () => {
@@ -41,8 +45,8 @@ export const Mermaid: React.FC<MermaidProps> = ({ graph, id: providedId }) => {
containerRef.current.innerHTML = svg;
setIsRendered(true);
} catch (err) {
console.error('Mermaid rendering failed:', err);
setError('Failed to render diagram. Please check the syntax.');
console.error("Mermaid rendering failed:", err);
setError("Failed to render diagram. Please check the syntax.");
setIsRendered(true);
}
}
@@ -57,19 +61,11 @@ export const Mermaid: React.FC<MermaidProps> = ({ graph, id: providedId }) => {
return (
<div className="mermaid-wrapper my-8 not-prose">
<div className="bg-white border border-slate-200 rounded-2xl overflow-hidden transition-all duration-500 hover:border-slate-400">
<div className="px-4 py-3 border-b border-slate-100 bg-white flex items-center justify-between">
<div className="flex items-center gap-2">
<svg className="w-3.5 h-3.5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
</svg>
<span className="text-[10px] font-bold text-slate-400 uppercase tracking-[0.2em]">Diagram</span>
</div>
</div>
<div className="mermaid-container p-8 md:p-12 overflow-x-auto flex justify-center bg-white">
<div
<CodeWindow title="Diagram" className="max-w-4xl" minHeight="300px">
<div className="flex justify-center bg-white p-4">
<div
ref={containerRef}
className={`mermaid transition-opacity duration-500 w-full max-w-4xl ${isRendered ? 'opacity-100' : 'opacity-0'}`}
className={`mermaid transition-opacity duration-500 w-full max-w-4xl ${isRendered ? "opacity-100" : "opacity-0"}`}
id={id}
>
{error ? (
@@ -81,7 +77,7 @@ export const Mermaid: React.FC<MermaidProps> = ({ graph, id: providedId }) => {
)}
</div>
</div>
</div>
</CodeWindow>
</div>
);
};