Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 5s
Build & Deploy / 🏗️ Build (push) Failing after 14s
Build & Deploy / 🧪 QA (push) Failing after 1m48s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import React from "react";
|
|
|
|
interface HeadingProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
id?: string;
|
|
}
|
|
|
|
const getTextContent = (node: React.ReactNode): string => {
|
|
if (typeof node === "string") return node;
|
|
if (typeof node === "number") return String(node);
|
|
if (React.isValidElement(node)) return getTextContent((node.props as any).children);
|
|
if (Array.isArray(node)) return node.map(getTextContent).join("");
|
|
return "";
|
|
};
|
|
|
|
const charMap: Record<string, string> = { "ä": "ae", "ö": "oe", "ü": "ue" };
|
|
|
|
const generateId = (children: React.ReactNode): string => {
|
|
const text = getTextContent(children);
|
|
return text
|
|
.toLowerCase()
|
|
.replace(/[äöü]/g, (c) => charMap[c] ?? c)
|
|
.replace(/[^a-z0-9]+/g, "-")
|
|
.replace(/^-|-$/g, "");
|
|
};
|
|
|
|
export const H1: React.FC<HeadingProps> = ({ children, className = "", id }) => (
|
|
<h1
|
|
id={id || generateId(children)}
|
|
className={`not-prose text-3xl md:text-5xl font-bold text-slate-900 mb-8 mt-12 leading-[1.1] tracking-tight font-sans ${className}`}
|
|
>
|
|
{children}
|
|
</h1>
|
|
);
|
|
|
|
export const H2: React.FC<HeadingProps> = ({ children, className = "", id }) => {
|
|
const generatedId = id || generateId(children);
|
|
return (
|
|
<h2
|
|
id={generatedId}
|
|
className={`not-prose text-2xl md:text-4xl font-bold text-slate-900 mb-6 mt-10 leading-tight tracking-tight font-sans ${className}`}
|
|
>
|
|
{children}
|
|
</h2>
|
|
);
|
|
};
|
|
|
|
export const H3: React.FC<HeadingProps> = ({ children, className = "", id }) => (
|
|
<h3
|
|
id={id || generateId(children)}
|
|
className={`not-prose text-xl md:text-2xl font-bold text-slate-900 mb-4 mt-8 leading-snug tracking-tight font-sans ${className}`}
|
|
>
|
|
{children}
|
|
</h3>
|
|
);
|