Created
January 31, 2020 23:09
-
-
Save mhartington/f60f22c70819867a23a5490592ad3119 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { Router, globalHistory, Location } from '@reach/router'; | |
import { Global } from '@emotion/core'; | |
import { ThemeProvider } from 'theme-ui'; | |
import { Helmet } from 'react-helmet'; | |
import get from 'lodash.get'; | |
import merge from 'lodash.merge'; | |
import useKeyboard from 'gatsby-theme-mdx-deck/src/hooks/use-keyboard'; | |
import useStorage from 'gatsby-theme-mdx-deck/src/hooks/use-storage'; | |
import useDeck from 'gatsby-theme-mdx-deck/src/hooks/use-deck'; | |
import Context from 'gatsby-theme-mdx-deck/src/context'; | |
import Wrapper from 'gatsby-theme-mdx-deck/src/components/wrapper'; | |
import Slide from 'gatsby-theme-mdx-deck/src/components/slide'; | |
import { modes } from 'gatsby-theme-mdx-deck/src/constants'; | |
import Presenter from 'gatsby-theme-mdx-deck/src/components/presenter'; | |
import Overview from 'gatsby-theme-mdx-deck/src/components/overview'; | |
import Grid from 'gatsby-theme-mdx-deck/src/components/grid'; | |
import posed, { PoseGroup } from 'react-pose'; | |
const Keyboard = () => { | |
useKeyboard(); | |
return false; | |
}; | |
const Storage = () => { | |
useStorage(); | |
return false; | |
}; | |
const Print = ({ slides }) => { | |
const outer = useDeck(); | |
const context = { | |
...outer, | |
mode: modes.print | |
}; | |
return ( | |
<Context.Provider value={context}> | |
{slides.map((slide, i) => ( | |
<Slide key={i} slide={slide} preview /> | |
))} | |
</Context.Provider> | |
); | |
}; | |
const getIndex = () => { | |
const { pathname } = globalHistory.location; | |
const paths = pathname.split('/'); | |
const n = Number(paths[paths.length - 1]); | |
const index = isNaN(n) ? 0 : n; | |
return index; | |
}; | |
const GoogleFont = ({ theme }) => { | |
if (!theme.googleFont) return false; | |
return ( | |
<Helmet> | |
<link rel="stylesheet" href={theme.googleFont} /> | |
</Helmet> | |
); | |
}; | |
const mergeThemes = (...themes) => | |
themes.reduce( | |
(acc, theme) => | |
typeof theme === 'function' ? theme(acc) : merge(acc, theme), | |
{} | |
); | |
const DefaultMode = ({ children }) => <React.Fragment children={children} />; | |
const RouteContainer = posed.div({ | |
enter: { opacity: 1, delay: 300 }, | |
exit: { opacity: 0 } | |
}); | |
const PosedRouter = props => { | |
return ( | |
<Location> | |
{({ location }) => ( | |
<PoseGroup> | |
<RouteContainer key={location.key}> | |
<Router location={location} basepath={props.slug}> | |
{props.children} | |
</Router> | |
</RouteContainer> | |
</PoseGroup> | |
)} | |
</Location> | |
); | |
}; | |
export default ({ | |
slides = [], | |
pageContext: { title, slug }, | |
theme = {}, | |
themes = [], | |
...props | |
}) => { | |
const outer = useDeck(); | |
const index = getIndex(); | |
const head = slides.head.children; | |
const { components, ...mergedTheme } = mergeThemes(theme, ...themes); | |
const context = { | |
...outer, | |
slug, | |
length: slides.length, | |
index, | |
steps: get(outer, `metadata.${index}.steps`), | |
notes: get(outer, `metadata.${index}.notes`), | |
theme: mergedTheme | |
}; | |
let Mode = DefaultMode; | |
switch (context.mode) { | |
case modes.presenter: | |
Mode = Presenter; | |
break; | |
case modes.overview: | |
Mode = Overview; | |
break; | |
case modes.grid: | |
Mode = Grid; | |
break; | |
default: | |
break; | |
} | |
return ( | |
<> | |
<Helmet> | |
<title>{title}</title> | |
{head} | |
</Helmet> | |
<GoogleFont theme={mergedTheme} /> | |
<Context.Provider value={context}> | |
<ThemeProvider components={components} theme={mergedTheme}> | |
<Global | |
styles={{ | |
body: { | |
margin: 0, | |
overflow: context.mode === modes.normal ? 'hidden' : null | |
} | |
}} | |
/> | |
<Keyboard /> | |
<Storage /> | |
<Wrapper> | |
<PosedRouter slug={slug} slides={slides}> | |
<Slide index={0} path="/" slide={slides[0]} /> | |
{slides.map((slide, i) => ( | |
<Slide key={i} index={i} path={i + '/*'} slide={slide} /> | |
))} | |
<Print path="/print" slides={slides} /> | |
</PosedRouter> | |
</Wrapper> | |
</ThemeProvider> | |
</Context.Provider> | |
</> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment