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:
commit
90b580c57e
@ -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>
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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} />
|
||||
|
@ -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}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user