Files
wehub-resource-sync cb15c5e0d8
CI / Rust (windows-latest - x86_64-pc-windows-msvc) (push) Waiting to run
CI / Native E2E Tests (push) Blocked by required conditions
CI / Windows Integration Test (push) Blocked by required conditions
CI / Version Sync Check (push) Waiting to run
CI / Rust (push) Waiting to run
CI / Dashboard (push) Waiting to run
CI / Sandbox Package (push) Waiting to run
CI / Rust (macos-latest - aarch64-apple-darwin) (push) Waiting to run
CI / Rust (macos-latest - x86_64-apple-darwin) (push) Waiting to run
CI / Global Install (macos-latest) (push) Blocked by required conditions
CI / Global Install (ubuntu-latest) (push) Blocked by required conditions
CI / Global Install (windows-latest) (push) Blocked by required conditions
Release / Check for new version (push) Waiting to run
Release / Build macOS ARM64 (push) Blocked by required conditions
Release / Build macOS x64 (push) Blocked by required conditions
Release / Build Linux ARM64 (push) Blocked by required conditions
Release / Build Linux musl ARM64 (push) Blocked by required conditions
Release / Build Linux musl x64 (push) Blocked by required conditions
Release / Build Linux x64 (push) Blocked by required conditions
Release / Build Windows x64 (push) Blocked by required conditions
Release / Publish to npm (push) Blocked by required conditions
Release / Publish sandbox package to npm (push) Blocked by required conditions
Release / Create GitHub Release (push) Blocked by required conditions
chore: import upstream snapshot with attribution
2026-07-13 12:35:58 +08:00

103 lines
2.9 KiB
TypeScript

import type { MDXComponents } from "mdx/types";
import Link from "next/link";
import { CodeBlock } from "@/components/code-block";
function slugify(text: string): string {
return text
.toLowerCase()
.replace(/[^\w\s-]/g, "")
.replace(/\s+/g, "-")
.trim();
}
function extractText(children: React.ReactNode): string {
if (typeof children === "string") return children;
if (typeof children === "number") return String(children);
if (Array.isArray(children)) return children.map(extractText).join("");
if (children && typeof children === "object") {
const obj = children as unknown as Record<string, unknown>;
if ("props" in obj) {
const props = obj.props as { children?: React.ReactNode } | undefined;
return extractText(props?.children);
}
}
return "";
}
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
h1: ({ children }: { children?: React.ReactNode }) => {
const id = slugify(extractText(children));
return (
<h1 id={id} className="heading-anchor">
{children}
<a href={`#${id}`} aria-label="Link to this section">#</a>
</h1>
);
},
h2: ({ children }: { children?: React.ReactNode }) => {
const id = slugify(extractText(children));
return (
<h2 id={id} className="heading-anchor">
{children}
<a href={`#${id}`} aria-label="Link to this section">#</a>
</h2>
);
},
h3: ({ children }: { children?: React.ReactNode }) => {
const id = slugify(extractText(children));
return (
<h3 id={id} className="heading-anchor">
{children}
<a href={`#${id}`} aria-label="Link to this section">#</a>
</h3>
);
},
a: ({
href,
children,
}: {
href?: string;
children?: React.ReactNode;
}) => {
if (href?.startsWith("/")) {
return <Link href={href}>{children}</Link>;
}
return (
<a href={href} target="_blank" rel="noopener noreferrer">
{children}
</a>
);
},
code: ({
children,
className,
}: {
children?: React.ReactNode;
className?: string;
}) => {
if (className) {
return <code className={className}>{children}</code>;
}
return <code>{children}</code>;
},
pre: async ({ children }: { children?: React.ReactNode }) => {
const codeElement = children as React.ReactElement<{
className?: string;
children?: string;
}>;
const className = codeElement?.props?.className || "";
const lang = className.replace("language-", "") || "bash";
const code = codeElement?.props?.children || "";
return (
<CodeBlock
code={typeof code === "string" ? code : String(code)}
lang={lang}
/>
);
},
};
}