import React from 'react' import PropTypes from 'prop-types' import { graphql } from 'gatsby' import { MDXProvider } from '@mdx-js/tag' import { withMDXScope } from 'gatsby-mdx/context' import useOnlineStatus from '@rehooks/online-status' import classNames from 'classnames' import MDXRenderer from './mdx-renderer' // Templates import Docs from './docs' import Universe from './universe' // Components import Navigation from '../components/navigation' import Progress from '../components/progress' import Footer from '../components/footer' import SEO from '../components/seo' import Link from '../components/link' import Section, { Hr } from '../components/section' import { Table, Tr, Th, Td } from '../components/table' import { Pre, Code, InlineCode } from '../components/code' import { Ol, Ul, Li } from '../components/list' import { H2, H3, H4, H5, P, Abbr, Help } from '../components/typography' import Accordion from '../components/accordion' import Infobox from '../components/infobox' import Aside from '../components/aside' import Button from '../components/button' import Tag from '../components/tag' import Grid from '../components/grid' import { YouTube, SoundCloud, Iframe, Image } from '../components/embed' import Alert from '../components/alert' import Search from '../components/search' import Project from '../widgets/project' const mdxComponents = { a: Link, p: P, pre: Pre, code: Code, inlineCode: InlineCode, table: Table, img: Image, tr: Tr, th: Th, td: Td, ol: Ol, ul: Ul, li: Li, h2: H2, h3: H3, h4: H4, h5: H5, blockquote: Aside, section: Section, wrapper: ({ children }) => children, hr: Hr, } const scopeComponents = { Infobox, Table, Tr, Th, Td, Help, Button, YouTube, SoundCloud, Iframe, Abbr, Tag, Accordion, Grid, InlineCode, Project, } const AlertSpace = ({ nightly }) => { const isOnline = useOnlineStatus() return ( <> {nightly && ( The page reflects{' '} spacy-nightly , not the latest stable version. )} {!isOnline && ( But don't worry, your visited pages should be saved for you. )} ) } class Layout extends React.Component { static defaultProps = { scope: {}, } static propTypes = { data: PropTypes.shape({ mdx: PropTypes.shape({ code: PropTypes.shape({ body: PropTypes.string.isRequired, }).isRequired, }), }).isRequired, scope: PropTypes.object.isRequired, pageContext: PropTypes.shape({ title: PropTypes.string, section: PropTypes.string, teaser: PropTypes.string, source: PropTypes.string, isIndex: PropTypes.bool.isRequired, theme: PropTypes.string, searchExclude: PropTypes.bool, next: PropTypes.shape({ title: PropTypes.string.isRequired, slug: PropTypes.string.isRequired, }), }), children: PropTypes.node, } constructor(props) { super(props) // NB: Compiling the scope here instead of in render() is super // important! Otherwise, it triggers unnecessary rerenders of ALL // consumers (e.g. mdx elements), even on anchor navigation! this.state = { scope: { ...scopeComponents, ...props.scope } } } render() { const { data, pageContext, location, children } = this.props const { file, site = {} } = data || {} const mdx = file ? file.childMdx : null const meta = site.siteMetadata || {} const { title, section, sectionTitle, teaser, theme = 'blue', searchExclude } = pageContext const uiTheme = meta.nightly ? 'nightly' : theme const bodyClass = classNames(`theme-${uiTheme}`, { 'search-exclude': !!searchExclude }) const isDocs = ['usage', 'models', 'api', 'styleguide'].includes(section) const content = !mdx ? null : ( {mdx.code.body} ) return ( <> } > {isDocs ? ( {content} ) : section === 'universe' ? ( ) : (
{children} {content}
)} ) } } export default withMDXScope(Layout) export const pageQuery = graphql` query($slug: String!) { site { siteMetadata { nightly title description navigation { text url } docSearch { apiKey indexName } } } file(fields: { slug: { eq: $slug } }) { childMdx { code { scope body } } } } `