spaCy/website/src/templates/index.js

208 lines
5.8 KiB
JavaScript
Raw Normal View History

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 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'
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,
}
const AlertSpace = () => {
const isOnline = useOnlineStatus()
return (
<>
{!isOnline && (
<Alert title="Looks like you're offline." icon="offline" variant="warning">
But don't worry, your visited pages should be saved for you.
</Alert>
)}
</>
)
}
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,
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 { title, section, sectionTitle, teaser, theme = 'blue' } = pageContext
const bodyClass = `theme-${theme}`
const meta = site.siteMetadata || {}
const isDocs = ['usage', 'models', 'api', 'styleguide'].includes(section)
const content = !mdx ? null : (
<MDXProvider components={mdxComponents}>
<MDXRenderer scope={this.state.scope}>{mdx.code.body}</MDXRenderer>
</MDXProvider>
)
return (
<>
<SEO
title={title}
description={teaser || meta.description}
section={section}
sectionTitle={sectionTitle}
bodyClass={bodyClass}
/>
<AlertSpace />
<Navigation
title={meta.title}
items={meta.navigation}
section={section}
search={<Search settings={meta.docSearch} />}
>
<Progress key={location.href} />
</Navigation>
{isDocs ? (
<Docs pageContext={pageContext}>{content}</Docs>
) : section === 'universe' ? (
<Universe
pageContext={pageContext}
location={location}
mdxComponents={mdxComponents}
/>
) : (
<>
{children}
{content}
<Footer wide />
</>
)}
</>
)
}
}
export default withMDXScope(Layout)
export const pageQuery = graphql`
query($slug: String!) {
site {
siteMetadata {
title
description
navigation {
text
url
}
docSearch {
apiKey
indexName
2019-03-15 16:48:38 +03:00
appId
}
}
}
file(fields: { slug: { eq: $slug } }) {
childMdx {
code {
scope
body
}
}
}
}
`