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. 90
      src/pages/index.js

43
src/components/CodeEditor/CodeEditor.js

@ -65,47 +65,8 @@ class CodeEditor extends Component {
}
return (
<div css={{ flex: 1 }}>
<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
css={{
[media.greaterThan('medium')]: {
@ -273,8 +234,8 @@ class CodeEditor extends Component {
</div>
)}
</div>
</div>
</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;

90
src/pages/index.js

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

Loading…
Cancel
Save