Browse Source

feat: refactor index page so hot reloading works for code examples

main
Dustin Schau 7 years ago
parent
commit
3ead525cf7
  1. 43
      src/components/CodeEditor/CodeEditor.js
  2. 54
      src/components/CodeExample/CodeExample.js
  3. 3
      src/components/CodeExample/index.js
  4. 84
      src/pages/index.js

43
src/components/CodeEditor/CodeEditor.js

@ -65,47 +65,8 @@ class CodeEditor extends Component {
} }
return ( return (
<div css={{ flex: 1 }}>
<LiveProvider code={showJSX ? code : compiledES6} mountStylesheet={false}> <LiveProvider code={showJSX ? code : compiledES6} mountStylesheet={false}>
<div
css={{
[media.greaterThan('xlarge')]: {
display: 'flex',
flexDirection: 'row',
},
[media.lessThan('large')]: {
display: 'block',
},
}}>
{children && (
<div
css={{
flex: '0 0 33%',
[media.lessThan('xlarge')]: {
marginBottom: 20,
},
'& h3': {
color: colors.dark,
maxWidth: '11em',
paddingTop: 0,
},
'& p': {
marginTop: 15,
marginRight: 40,
lineHeight: 1.7,
[media.greaterThan('xlarge')]: {
marginTop: 25,
},
},
}}>
{children}
</div>
)}
<div <div
css={{ css={{
[media.greaterThan('medium')]: { [media.greaterThan('medium')]: {
@ -273,8 +234,8 @@ class CodeEditor extends Component {
</div> </div>
)} )}
</div> </div>
</div>
</LiveProvider> </LiveProvider>
</div>
); );
} }

54
src/components/CodeExample/CodeExample.js

@ -0,0 +1,54 @@
import React, { Component } from 'react';
import {colors, media} from 'theme';
import CodeEditor from '../CodeEditor/CodeEditor';
class CodeExample extends Component {
render() {
const {children, code, loaded} = this.props;
return (
<div
css={{
[media.greaterThan('xlarge')]: {
display: 'flex',
flexDirection: 'row',
},
[media.lessThan('large')]: {
display: 'block',
},
}}>
{children && (
<div
css={{
flex: '0 0 33%',
[media.lessThan('xlarge')]: {
marginBottom: 20,
},
'& h3': {
color: colors.dark,
maxWidth: '11em',
paddingTop: 0,
},
'& p': {
marginTop: 15,
marginRight: 40,
lineHeight: 1.7,
[media.greaterThan('xlarge')]: {
marginTop: 25,
},
},
}}>
{children}
</div>
)}
{loaded ? <CodeEditor code={code} /> : <h4>Loading code example...</h4>}
</div>
)
}
}
export default CodeExample;

3
src/components/CodeExample/index.js

@ -0,0 +1,3 @@
import CodeExample from './CodeExample';
export default CodeExample;

84
src/pages/index.js

@ -7,72 +7,37 @@
import ButtonLink from 'components/ButtonLink'; import ButtonLink from 'components/ButtonLink';
import Container from 'components/Container'; import Container from 'components/Container';
import Flex from 'components/Flex'; import Flex from 'components/Flex';
import mountCodeExample from 'utils/mountCodeExample'; import CodeExample from 'components/CodeExample';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, {Component} from 'react'; import React, {Component} from 'react';
import {graphql} from 'gatsby'; import {graphql} from 'gatsby';
import TitleAndMetaTags from 'components/TitleAndMetaTags'; import TitleAndMetaTags from 'components/TitleAndMetaTags';
import Layout from 'components/Layout'; import Layout from 'components/Layout';
import loadScript from 'utils/loadScript';
import {colors, media, sharedStyles} from 'theme'; import {colors, media, sharedStyles} from 'theme';
import createOgUrl from 'utils/createOgUrl'; import createOgUrl from 'utils/createOgUrl';
import loadScript from 'utils/loadScript';
import {babelURL} from 'site-constants'; import {babelURL} from 'site-constants';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import logoWhiteSvg from 'icons/logo-white.svg'; import logoWhiteSvg from 'icons/logo-white.svg';
class Home extends Component { class Home extends Component {
constructor(props, context) { state = {
super(props, context); babelLoaded: false
const {data} = props;
const code = data.code.edges.reduce((map, {node}) => {
map[node.id] = JSON.parse(node.internal.contentDigest);
return map;
}, {});
const examples = data.examples.edges.map(({node}) => ({
content: node.html,
id: node.fields.slug.replace(/^.+\//, '').replace('.html', ''),
title: node.frontmatter.title,
}));
const marketing = data.marketing.edges.map(({node}) => ({
title: node.frontmatter.title,
content: node.html,
}));
this.state = {
code,
examples,
marketing,
}; };
}
componentDidMount() { componentDidMount() {
const {code, examples} = this.state; loadScript(babelURL).then(() => {
this.setState({
examples.forEach(({id}) => { babelLoaded: true
renderExamplePlaceholder(id);
});
function mountCodeExamples() {
examples.forEach(({id}) => {
mountCodeExample(id, code[id]);
}); });
} }, error => {
loadScript(babelURL).then(mountCodeExamples, error => {
console.error('Babel failed to load.'); console.error('Babel failed to load.');
mountCodeExamples();
}); });
} }
render() { render() {
const {examples, marketing} = this.state; const {babelLoaded} = this.state;
const {location} = this.props; const {data, location} = this.props;
const {examples, marketing} = data;
return ( return (
<Layout location={location}> <Layout location={location}>
@ -217,7 +182,7 @@ class Home extends Component {
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
}, },
}}> }}>
{marketing.map((column, index) => ( {marketing.edges.map(({ node: column }, index) => (
<div <div
key={index} key={index}
css={{ css={{
@ -266,9 +231,9 @@ class Home extends Component {
}, },
}, },
]}> ]}>
{column.title} {column.frontmatter.title}
</h3> </h3>
<div dangerouslySetInnerHTML={{__html: column.content}} /> <div dangerouslySetInnerHTML={{__html: column.html }} />
</div> </div>
))} ))}
</div> </div>
@ -283,7 +248,7 @@ class Home extends Component {
/> />
<section css={sectionStyles}> <section css={sectionStyles}>
<div id="examples"> <div id="examples">
{examples.map((example, index) => ( {examples.edges.map(({ node }, index) => (
<div <div
key={index} key={index}
css={{ css={{
@ -297,11 +262,12 @@ class Home extends Component {
marginTop: 80, marginTop: 80,
}, },
}}> }}>
<h3 css={headingStyles}>{example.title}</h3> <CodeExample code={node.code} loaded={babelLoaded}>
<h3 css={headingStyles}>{node.frontmatter.title}</h3>
<div <div
dangerouslySetInnerHTML={{__html: example.content}} dangerouslySetInnerHTML={{__html: node.html}}
/> />
<div id={example.id} /> </CodeExample>
</div> </div>
))} ))}
</div> </div>
@ -339,7 +305,6 @@ class Home extends Component {
Home.propTypes = { Home.propTypes = {
data: PropTypes.shape({ data: PropTypes.shape({
code: PropTypes.object.isRequired,
examples: PropTypes.object.isRequired, examples: PropTypes.object.isRequired,
marketing: PropTypes.object.isRequired, marketing: PropTypes.object.isRequired,
}).isRequired, }).isRequired,
@ -382,22 +347,13 @@ const CtaItem = ({children, primary = false}) => (
export const pageQuery = graphql` export const pageQuery = graphql`
query IndexMarkdown { query IndexMarkdown {
code: allExampleCode {
edges {
node {
id
internal {
contentDigest
}
}
}
}
examples: allMarkdownRemark( examples: allMarkdownRemark(
filter: {fileAbsolutePath: {regex: "//home/examples//"}} filter: {fileAbsolutePath: {regex: "//home/examples//"}}
sort: {fields: [frontmatter___order], order: ASC} sort: {fields: [frontmatter___order], order: ASC}
) { ) {
edges { edges {
node { node {
code
fields { fields {
slug slug
} }

Loading…
Cancel
Save