|
|
@ -11,110 +11,28 @@ 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>; |
|
|
|
toc: Array<{ |
|
|
|
url: string; |
|
|
|
text: React.ReactNode; |
|
|
|
depth: number; |
|
|
|
}>; |
|
|
|
} |
|
|
|
|
|
|
|
export function MarkdownPage< |
|
|
|
T extends {title: string; status?: string} = {title: string; status?: string} |
|
|
|
>({children, meta}: MarkdownProps<T>) { |
|
|
|
>({children, meta, toc}: 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', |
|
|
|
'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 ( |
|
|
|
<> |
|
|
|
<div className="lg:pt-0 pt-20 pl-0 lg:pl-80 2xl:px-80 "> |
|
|
@ -129,7 +47,7 @@ export function MarkdownPage< |
|
|
|
<div className="px-5 sm:px-12"> |
|
|
|
<div className="max-w-7xl mx-auto"> |
|
|
|
<MDXContext.Provider value={MDXComponents}> |
|
|
|
{finalChildren} |
|
|
|
{children} |
|
|
|
</MDXContext.Provider> |
|
|
|
</div> |
|
|
|
<DocsPageFooter |
|
|
@ -140,7 +58,7 @@ export function MarkdownPage< |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div className="w-full lg:max-w-xs hidden 2xl:block"> |
|
|
|
{!isHomePage && anchors.length > 0 && <Toc headings={anchors} />} |
|
|
|
{!isHomePage && toc.length > 0 && <Toc headings={toc} />} |
|
|
|
</div> |
|
|
|
</> |
|
|
|
); |
|
|
|