mirror of
https://github.com/reactjs/react.dev.git
synced 2026-02-26 18:58:17 +00:00
* Dry version * Here we go again * Recreation lol * Some tweaks (#4285) * tweaks * edit Co-authored-by: Sophie Alpert <git@sophiebits.com>
149 lines
4.0 KiB
TypeScript
149 lines
4.0 KiB
TypeScript
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*/
|
|
|
|
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';
|
|
import PageHeading from 'components/PageHeading';
|
|
import {useRouteMeta} from './useRouteMeta';
|
|
import {Toc} from './Toc';
|
|
export interface MarkdownProps<Frontmatter> {
|
|
meta: Frontmatter & {description?: string};
|
|
children?: React.ReactNode;
|
|
}
|
|
|
|
function MaxWidth({children}: {children: any}) {
|
|
return <div className="max-w-4xl ml-0 2xl:mx-auto">{children}</div>;
|
|
}
|
|
|
|
export function MarkdownPage<
|
|
T extends {title: string; status?: string} = {title: string; status?: string}
|
|
>({children, meta}: MarkdownProps<T>) {
|
|
const {route, nextRoute, prevRoute} = useRouteMeta();
|
|
const title = meta.title || route?.title || '';
|
|
const description = meta.description || route?.description || '';
|
|
|
|
let anchors: Array<{
|
|
url: string;
|
|
text: React.ReactNode;
|
|
depth: number;
|
|
}> = React.Children.toArray(children)
|
|
.filter((child: any) => {
|
|
if (child.props?.mdxType) {
|
|
return ['h1', 'h2', 'h3', 'Challenges', 'Recap'].includes(
|
|
child.props.mdxType
|
|
);
|
|
}
|
|
return false;
|
|
})
|
|
.map((child: any) => {
|
|
if (child.props.mdxType === 'Challenges') {
|
|
return {
|
|
url: '#challenges',
|
|
depth: 0,
|
|
text: 'Challenges',
|
|
};
|
|
}
|
|
if (child.props.mdxType === 'Recap') {
|
|
return {
|
|
url: '#recap',
|
|
depth: 0,
|
|
text: 'Recap',
|
|
};
|
|
}
|
|
return {
|
|
url: '#' + child.props.id,
|
|
depth:
|
|
(child.props?.mdxType &&
|
|
parseInt(child.props.mdxType.replace('h', ''), 0)) ??
|
|
0,
|
|
text: child.props.children,
|
|
};
|
|
});
|
|
if (anchors.length > 0) {
|
|
anchors.unshift({
|
|
depth: 1,
|
|
text: 'Overview',
|
|
url: '#',
|
|
});
|
|
}
|
|
|
|
if (!route) {
|
|
console.error('This page was not added to one of the sidebar JSON files.');
|
|
}
|
|
const isHomePage = route?.path === '/';
|
|
|
|
// Auto-wrap everything except a few types into
|
|
// <MaxWidth> wrappers. Keep reusing the same
|
|
// wrapper as long as we can until we meet
|
|
// a full-width section which interrupts it.
|
|
let fullWidthTypes = [
|
|
'Sandpack',
|
|
'APIAnatomy',
|
|
'FullWidth',
|
|
'Illustration',
|
|
'IllustrationBlock',
|
|
'Challenges',
|
|
'Recipes',
|
|
];
|
|
let wrapQueue: React.ReactNode[] = [];
|
|
let finalChildren: React.ReactNode[] = [];
|
|
function flushWrapper(key: string | number) {
|
|
if (wrapQueue.length > 0) {
|
|
finalChildren.push(<MaxWidth key={key}>{wrapQueue}</MaxWidth>);
|
|
wrapQueue = [];
|
|
}
|
|
}
|
|
function handleChild(child: any, key: string | number) {
|
|
if (child == null) {
|
|
return;
|
|
}
|
|
if (typeof child !== 'object') {
|
|
wrapQueue.push(child);
|
|
return;
|
|
}
|
|
if (fullWidthTypes.includes(child.props.mdxType)) {
|
|
flushWrapper(key);
|
|
finalChildren.push(child);
|
|
} else {
|
|
wrapQueue.push(child);
|
|
}
|
|
}
|
|
React.Children.forEach(children, handleChild);
|
|
flushWrapper('last');
|
|
|
|
return (
|
|
<article className="h-full mx-auto relative w-full min-w-0">
|
|
<div className="lg:pt-0 pt-20 pl-0 lg:pl-80 2xl:px-80 ">
|
|
<Seo title={title} />
|
|
{!isHomePage && (
|
|
<PageHeading
|
|
title={title}
|
|
description={description}
|
|
tags={route?.tags}
|
|
/>
|
|
)}
|
|
<div className="px-5 sm:px-12">
|
|
<div className="max-w-7xl mx-auto">
|
|
<MDXContext.Provider value={MDXComponents}>
|
|
{finalChildren}
|
|
</MDXContext.Provider>
|
|
</div>
|
|
<DocsPageFooter
|
|
route={route}
|
|
nextRoute={nextRoute}
|
|
prevRoute={prevRoute}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="w-full lg:max-w-xs hidden 2xl:block">
|
|
{!isHomePage && anchors.length > 0 && <Toc headings={anchors} />}
|
|
</div>
|
|
</article>
|
|
);
|
|
}
|