1
1
mirror of https://github.com/jxnblk/mdx-deck.git synced 2024-11-29 13:58:02 +03:00

Merge pull request #329 from jxnblk/google-fonts-fix

Fix for Google fonts & Head
This commit is contained in:
Brent Jackson 2019-04-20 12:16:55 -04:00 committed by GitHub
commit 90b580c57e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 51 deletions

View File

@ -5,7 +5,7 @@ import { Head } from './Head'
const GoogleFonts = withTheme(({ theme }) => {
if (!theme.googleFont) return false
return (
<Head>
<Head portal>
<link rel="stylesheet" href={theme.googleFont} />
</Head>
)

View File

@ -1,6 +1,8 @@
import React from 'react'
import React, { useEffect, useContext } from 'react'
import { createPortal } from 'react-dom'
let didMount = false
export const HeadContext = React.createContext({
tags: [],
push: () => {
@ -16,54 +18,36 @@ export const HeadProvider = ({ tags = [], children }) => {
return <HeadContext.Provider value={context}>{children}</HeadContext.Provider>
}
export class Head extends React.Component {
state = {
didMount: false,
}
rehydrate = () => {
const children = React.Children.toArray(this.props.children)
const nodes = [...document.head.querySelectorAll('[data-head]')]
nodes.forEach(node => {
if (typeof node.remove !== 'function') return
node.remove()
})
children.forEach(child => {
if (child.type === 'title') {
const title = document.head.querySelector('title')
if (title) title.remove()
}
if (child.type === 'meta') {
const { name } = child.props
let meta
if (name) meta = document.head.querySelector(`meta[name="${name}"]`)
if (meta) meta.remove()
}
})
this.setState({ didMount: true })
}
componentDidMount() {
this.rehydrate()
}
render() {
const children = React.Children.toArray(this.props.children).map(child =>
React.cloneElement(child, {
'data-head': true,
})
// get head for all slides
export const UserHead = ({ mdx }) =>
React.createElement(mdx, {
components: {
wrapper: props => {
if (!didMount) return false
const heads = React.Children.toArray(props.children).filter(
child => child.props.originalType === Head
)
if (!this.state.didMount) {
return (
<HeadContext.Consumer
children={({ push }) => {
const head = React.Children.toArray(
heads.reduce((acc, head) => [...acc, ...head.props.children], [])
)
return createPortal(head, document.head)
},
},
})
export const Head = props => {
const { push } = useContext(HeadContext)
const children = React.Children.toArray(props.children)
useEffect(() => {
didMount = true
}, [])
if (!didMount) {
push(children)
return false
}}
/>
)
}
if (!props.portal) return false
return createPortal(children, document.head)
}
}
export default Head

View File

@ -1,7 +1,7 @@
import React from 'react'
import { ThemeProvider } from 'emotion-theming'
import merge from 'lodash.merge'
import { HeadProvider } from './Head'
import { HeadProvider, UserHead } from './Head'
import { MDXProvider } from '@mdx-js/react'
import defaultTheme from '@mdx-deck/themes/base'
import mdxComponents from './mdx-components'
@ -16,7 +16,7 @@ const mergeThemes = themes =>
)
export const Provider = props => {
const { headTags, theme: baseTheme, themes = [] } = props
const { headTags, theme: baseTheme, themes = [], mdx } = props
const theme = mergeThemes([defaultTheme, baseTheme, ...themes])
const {
Provider: UserProvider = DefaultProvider,
@ -30,6 +30,7 @@ export const Provider = props => {
return (
<HeadProvider tags={headTags}>
<UserHead mdx={mdx} />
<ThemeProvider theme={theme}>
<MDXProvider components={allComponents}>
<UserProvider {...props} />

View File

@ -3,12 +3,18 @@ import { render } from 'react-dom'
import { MDXDeck } from '@mdx-deck/components'
const mod = require(FILENAME)
const { slides, theme, themes } = mod
const { default: mdx, slides, theme, themes } = mod
export default class App extends React.Component {
render() {
return (
<MDXDeck {...this.props} slides={slides} theme={theme} themes={themes} />
<MDXDeck
{...this.props}
slides={slides}
theme={theme}
themes={themes}
mdx={mdx}
/>
)
}
}