diff --git a/beta/package.json b/beta/package.json
index 57e9d23d..f38255fc 100644
--- a/beta/package.json
+++ b/beta/package.json
@@ -26,7 +26,6 @@
"@docsearch/css": "3.0.0-alpha.41",
"@docsearch/react": "3.0.0-alpha.41",
"@headlessui/react": "^1.3.0",
- "@mdx-js/react": "^1.6.16",
"body-scroll-lock": "^3.1.3",
"classnames": "^2.2.6",
"date-fns": "^2.16.1",
diff --git a/beta/src/components/Layout/MarkdownPage.tsx b/beta/src/components/Layout/MarkdownPage.tsx
index 937641fa..a02e254d 100644
--- a/beta/src/components/Layout/MarkdownPage.tsx
+++ b/beta/src/components/Layout/MarkdownPage.tsx
@@ -3,8 +3,6 @@
*/
import * as React from 'react';
-// @ts-ignore
-import {MDXContext} from '@mdx-js/react';
import {DocsPageFooter} from 'components/DocsFooter';
import {MDXComponents} from 'components/MDX/MDXComponents';
import {Seo} from 'components/Seo';
@@ -45,11 +43,7 @@ export function MarkdownPage<
/>
)}
-
-
- {children}
-
-
+
{children}
= {};
let content: React.ReactElement[] = [];
React.Children.forEach(children, (child) => {
- const {props} = child;
- switch (props.mdxType) {
+ const {props, type} = child;
+ switch ((type as any).mdxName) {
case 'Solution': {
challenge.solution = child;
challenge.content = content;
diff --git a/beta/src/components/MDX/CodeDiagram.tsx b/beta/src/components/MDX/CodeDiagram.tsx
index d6ad640d..26a44333 100644
--- a/beta/src/components/MDX/CodeDiagram.tsx
+++ b/beta/src/components/MDX/CodeDiagram.tsx
@@ -12,10 +12,10 @@ interface CodeDiagramProps {
export function CodeDiagram({children, flip = false}: CodeDiagramProps) {
const illustration = React.Children.toArray(children).filter((child: any) => {
- return child.props?.mdxType === 'img';
+ return child.type?.mdxName === 'img';
});
const content = React.Children.toArray(children).map((child: any) => {
- if (child.props?.mdxType === 'pre') {
+ if (child.type?.mdxName === 'pre') {
return (
);
- } else if (child.props?.mdxType === 'img') {
+ } else if (child.type?.mdxName === 'img') {
return null;
} else {
return child;
diff --git a/beta/src/components/MDX/Heading.tsx b/beta/src/components/MDX/Heading.tsx
index 6e29bc4e..1a337f88 100644
--- a/beta/src/components/MDX/Heading.tsx
+++ b/beta/src/components/MDX/Heading.tsx
@@ -71,6 +71,7 @@ export const H2 = ({className, ...props}: HeadingProps) => (
{...props}
/>
);
+
export const H3 = ({className, ...props}: HeadingProps) => (
{
- if (child.props?.mdxType && child.props?.mdxType === 'inlineCode') {
+ if (child.type?.mdxName && child.type?.mdxName === 'inlineCode') {
return React.cloneElement(child, {
isLink: true,
});
diff --git a/beta/src/components/MDX/MDXComponents.tsx b/beta/src/components/MDX/MDXComponents.tsx
index cbb758e2..f92fbc4d 100644
--- a/beta/src/components/MDX/MDXComponents.tsx
+++ b/beta/src/components/MDX/MDXComponents.tsx
@@ -325,3 +325,10 @@ export const MDXComponents = {
Solution,
CodeStep,
};
+
+for (let key in MDXComponents) {
+ if (MDXComponents.hasOwnProperty(key)) {
+ const MDXComponent: any = (MDXComponents as any)[key];
+ MDXComponent.mdxName = key;
+ }
+}
diff --git a/beta/src/components/MDX/PackageImport.tsx b/beta/src/components/MDX/PackageImport.tsx
index 83ae74f8..092b319f 100644
--- a/beta/src/components/MDX/PackageImport.tsx
+++ b/beta/src/components/MDX/PackageImport.tsx
@@ -11,10 +11,10 @@ interface PackageImportProps {
export function PackageImport({children}: PackageImportProps) {
const terminal = React.Children.toArray(children).filter((child: any) => {
- return child.props?.mdxType !== 'pre';
+ return child.type?.mdxName !== 'pre';
});
const code = React.Children.toArray(children).map((child: any, i: number) => {
- if (child.props?.mdxType === 'pre') {
+ if (child.type?.mdxName === 'pre') {
return (
{
return codeSnippets.reduce(
(result: Record, codeSnippet: React.ReactElement) => {
- if (codeSnippet.props.mdxType !== 'pre') {
+ if ((codeSnippet.type as any).mdxName !== 'pre') {
return result;
}
const {props} = codeSnippet.props.children;
diff --git a/beta/src/pages/[[...markdownPath]].js b/beta/src/pages/[[...markdownPath]].js
index 659256bc..07eff0dd 100644
--- a/beta/src/pages/[[...markdownPath]].js
+++ b/beta/src/pages/[[...markdownPath]].js
@@ -2,15 +2,17 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
-import {createElement, Children, useMemo} from 'react';
+import {createElement, Children, Fragment, useMemo} from 'react';
import {MDXComponents} from 'components/MDX/MDXComponents';
import {MarkdownPage} from 'components/Layout/MarkdownPage';
import {Page} from 'components/Layout/Page';
-import {mdx} from '@mdx-js/react';
import {prepareMDX} from '../utils/prepareMDX';
export default function Layout({content, meta}) {
- const decoded = useMemo(() => JSON.parse(content, reviveMDX), [content]);
+ const decoded = useMemo(
+ () => JSON.parse(content, reviveNodeOnClient),
+ [content]
+ );
const {toc, children} = useMemo(
() => prepareMDX(decoded.props.children),
[decoded]
@@ -24,20 +26,48 @@ export default function Layout({content, meta}) {
);
}
-// Create a React tree from server JSON.
-function reviveMDX(key, val) {
- if (val && val.$m) {
- // This is an MDX node we need to revive.
- let args = val.$m;
- if (args[0] == null) {
- // First argument to createElement() is a type.
- // If it didn't serialize, this is a custom MDX component.
- args[0] = MDXComponents[args[1].mdxType];
- if (args[0] == null) {
- throw Error('Unknown type: ' + args[1].mdxType);
- }
+// Deserialize a client React tree from JSON.
+function reviveNodeOnClient(key, val) {
+ if (Array.isArray(val) && val[0] == '$r') {
+ // Assume it's a React element.
+ let type = val[1];
+ let key = val[2];
+ let props = val[3];
+ if (type === 'wrapper') {
+ type = Fragment;
+ props = {children: props.children};
+ }
+ if (MDXComponents[type]) {
+ type = MDXComponents[type];
+ }
+ if (!type) {
+ console.error('Unknown type: ' + type);
+ type = Fragment;
}
- return mdx.apply(null, args);
+ return {
+ $$typeof: Symbol.for('react.element'),
+ type: type,
+ key: key,
+ ref: null,
+ props: props,
+ _owner: null,
+ };
+ } else {
+ return val;
+ }
+}
+
+// Serialize a server React tree node to JSON.
+function stringifyNodeOnServer(key, val) {
+ if (val != null && val.$$typeof === Symbol.for('react.element')) {
+ // Remove fake MDX props.
+ const {mdxType, originalType, parentName, ...cleanProps} = val.props;
+ return [
+ '$r',
+ typeof val.type === 'string' ? val.type : mdxType,
+ val.key,
+ cleanProps,
+ ];
} else {
return val;
}
@@ -72,14 +102,11 @@ export async function getStaticProps(context) {
// Run it to get JSON for render output
const run = new Function('exports', 'mdx', js);
let outputExports = {};
- function createJSONNode(...args) {
- return {$m: args}; // Marker to turn this into createElement on the client
- }
- run(outputExports, createJSONNode);
- const json = outputExports.default({});
+ run(outputExports, createElement);
+ const reactTree = outputExports.default({});
return {
props: {
- content: JSON.stringify(json),
+ content: JSON.stringify(reactTree, stringifyNodeOnServer),
meta,
},
};
diff --git a/beta/src/utils/prepareMDX.js b/beta/src/utils/prepareMDX.js
index 93c89372..efe64c9b 100644
--- a/beta/src/utils/prepareMDX.js
+++ b/beta/src/utils/prepareMDX.js
@@ -44,7 +44,7 @@ function wrapChildrenInMaxWidthContainers(children) {
wrapQueue.push(child);
return;
}
- if (fullWidthTypes.includes(child.props.mdxType)) {
+ if (fullWidthTypes.includes(child.type.mdxName)) {
flushWrapper(key);
finalChildren.push(child);
} else {
@@ -59,22 +59,22 @@ function wrapChildrenInMaxWidthContainers(children) {
function getTableOfContents(children) {
const anchors = Children.toArray(children)
.filter((child) => {
- if (child.props?.mdxType) {
+ if (child.type?.mdxName) {
return ['h1', 'h2', 'h3', 'Challenges', 'Recap'].includes(
- child.props.mdxType
+ child.type.mdxName
);
}
return false;
})
.map((child) => {
- if (child.props.mdxType === 'Challenges') {
+ if (child.type.mdxName === 'Challenges') {
return {
url: '#challenges',
depth: 0,
text: 'Challenges',
};
}
- if (child.props.mdxType === 'Recap') {
+ if (child.type.mdxName === 'Recap') {
return {
url: '#recap',
depth: 0,
@@ -84,8 +84,8 @@ function getTableOfContents(children) {
return {
url: '#' + child.props.id,
depth:
- (child.props?.mdxType &&
- parseInt(child.props.mdxType.replace('h', ''), 0)) ??
+ (child.type?.mdxName &&
+ parseInt(child.type.mdxName.replace('h', ''), 0)) ??
0,
text: child.props.children,
};