"use client"; // Ürün genelindeki "el çizimi" mermaid şemalarının tek kaynağı: /meraklisina // hunisi de rehber yazılarındaki şemalar da bu bileşenle çizilir, böylece // görünüm (font, renk teması, çizgi titremesi) her yerde birebir aynı kalır. // Mermaid ağır bir paket olduğu için useEffect içinde dinamik import edilir; // sayfa paketine girmez. import { useEffect, useId, useState } from "react"; import localFont from "next/font/local"; // Şemanın "el çizimi" görünümüne uyan el yazısı fontu (Sweet Cucumber // Mocktail, Misti's Fonts). Türkçe glifler doğrulandı (ş, ğ, ı, İ… hepsi // var). DİKKAT: lisans "kişisel kullanım için ücretsiz" — canlıya çıkmadan // mistifonts.com/sweet-cucumber-mocktail adresinden ticari lisans alınmalı. const elYazisi = localFont({ src: "../fonts/SweetCucumberMocktail.woff2", display: "swap", }); export function ElCizimiSema({ tanim, ariaLabel, figcaption, }: { /** Mermaid tanımı (flowchart vb.) */ tanim: string; /** Şemanın tamamını anlatan erişilebilirlik metni */ ariaLabel: string; figcaption?: React.ReactNode; }) { const [svg, setSvg] = useState(null); // mermaid.render'ın istediği DOM id'si: useId'nin ":" karakterleri geçersiz const semaId = `sema-${useId().replace(/[^a-zA-Z0-9-]/g, "")}`; useEffect(() => { let iptal = false; import("mermaid").then(async ({ default: mermaid }) => { mermaid.initialize({ startOnLoad: false, look: "handDrawn", handDrawnSeed: 7, // her render'da aynı çizgi titremesi (deterministik) theme: "base", fontFamily: `${elYazisi.style.fontFamily}, cursive`, themeVariables: { primaryColor: "#ffffff", primaryBorderColor: "#e2e8f0", primaryTextColor: "#0f172a", lineColor: "#94a3b8", edgeLabelBackground: "#ffffff", fontFamily: `${elYazisi.style.fontFamily}, cursive`, fontSize: "17px", // script fontun x-yüksekliği düşük; okunurluk için büyütüldü }, }); const sonuc = await mermaid.render(semaId, tanim); if (!iptal) setSvg(sonuc.svg); }); return () => { iptal = true; }; }, [semaId, tanim]); return (
{svg ? (
) : (
)} {figcaption ? (
{figcaption}
) : null}
); }