diff --git a/src/mdx-components.tsx b/src/mdx-components.tsx index 2186c4997..3409981ba 100644 --- a/src/mdx-components.tsx +++ b/src/mdx-components.tsx @@ -1,8 +1,18 @@ import type { MDXComponents } from "mdx/types"; -import React, { ReactNode } from "react"; +import React from "react"; import { CodeExample } from "./components/code-example"; import Link from "next/link"; +declare module "mdx/types" { + // Augment the MDX types to make it understand React. + namespace JSX { + type Element = React.JSX.Element; + type ElementClass = React.JSX.ElementClass; + type ElementType = React.JSX.ElementType; + type IntrinsicElements = React.JSX.IntrinsicElements; + } +} + function getTextContent(node: React.ReactNode): string { if (typeof node === "string" || typeof node === "number") { return String(node); @@ -51,64 +61,70 @@ function createHeading(level: 1 | 2 | 3 | 4 | 5 | 6) { }; } +const components = { + // Allows customizing built-in components, e.g. to add styling. + // h1: ({ children }) =>
{children}
;
+ }
+
+ if (children.startsWith("<")) {
+ return {children}
;
+ }
+
+ return (
+
+ {children
+ .split(/(<[^>]+>)/g)
+ .map((part, i) => (part.startsWith("<") && part.endsWith(">") ? {part} : part))}
+
+ );
+ },
+
+ pre(props) {
+ let child = React.Children.only(props.children) as React.ReactElement;
+ if (!child) return null;
+
+ // @ts-ignore
+ let { className, children: code } = child.props;
+ let lang = className ? className.replace("language-", "") : "";
+ let filename = undefined;
+
+ // Extract `[!code filename:…]` directives from the first line of code
+ let lines = code.split("\n");
+ let filenameRegex = /\[\!code filename\:(.+)\]/;
+ let match = lines[0].match(filenameRegex);
+ if (match) {
+ filename = match[1];
+ code = lines.splice(1).join("\n");
+ }
+
+ return (
+ {children}
;
- }
-
- if (children.startsWith("<")) {
- return {children}
;
- }
-
- return (
-
- {children
- .split(/(<[^>]+>)/g)
- .map((part, i) => (part.startsWith("<") && part.endsWith(">") ? {part} : part))}
-
- );
- },
-
- pre(props) {
- let child = React.Children.only(props.children) as React.ReactElement;
- if (!child) return null;
-
- // @ts-ignore
- let { className, children: code } = child.props;
- let lang = className ? className.replace("language-", "") : "";
- let filename = undefined;
-
- // Extract `[!code filename:…]` directives from the first line of code
- let lines = code.split("\n");
- let filenameRegex = /\[\!code filename\:(.+)\]/;
- let match = lines[0].match(filenameRegex);
- if (match) {
- filename = match[1];
- code = lines.splice(1).join("\n");
- }
-
- return (
-