committed by
GitHub
7 changed files with 281 additions and 306 deletions
@ -1,28 +1,33 @@ |
|||||
const {readdirSync, readFileSync} = require('fs'); |
const crypto = require(`crypto`); |
||||
const {join, resolve} = require('path'); |
|
||||
|
const createContentDigest = obj => |
||||
|
crypto |
||||
|
.createHash(`md5`) |
||||
|
.update(obj) |
||||
|
.digest(`hex`); |
||||
|
|
||||
// Store code snippets in GraphQL for the home page examples.
|
// Store code snippets in GraphQL for the home page examples.
|
||||
// Snippets will be matched with markdown templates of the same name.
|
// Snippets will be matched with markdown templates of the same name.
|
||||
exports.sourceNodes = ({graphql, actions}) => { |
exports.onCreateNode = async ({actions, node, loadNodeContent}) => { |
||||
const {createNode} = actions; |
const {createNode} = actions; |
||||
|
const {absolutePath, ext, name, relativeDirectory, sourceInstanceName} = node; |
||||
|
|
||||
const path = resolve(__dirname, '../../content/home/examples'); |
if ( |
||||
const files = readdirSync(path); |
sourceInstanceName === 'content' && |
||||
|
relativeDirectory === 'home/examples' && |
||||
files.forEach(file => { |
ext === '.js' |
||||
if (file.match(/\.js$/)) { |
) { |
||||
const code = readFileSync(join(path, file), 'utf8'); |
const code = await loadNodeContent(node); |
||||
const id = file.replace(/\.js$/, ''); |
|
||||
|
|
||||
createNode({ |
createNode({ |
||||
id, |
id: name, |
||||
children: [], |
children: [], |
||||
parent: 'EXAMPLES', |
parent: node.id, |
||||
|
code, |
||||
|
mdAbsolutePath: absolutePath.replace(/\.js$/, '.md'), |
||||
internal: { |
internal: { |
||||
type: 'ExampleCode', |
type: 'ExampleCode', |
||||
contentDigest: JSON.stringify(code), |
contentDigest: createContentDigest(JSON.stringify(code)), |
||||
}, |
}, |
||||
}); |
}); |
||||
} |
} |
||||
}); |
|
||||
}; |
}; |
||||
|
@ -0,0 +1,73 @@ |
|||||
|
import React, {Component} from 'react'; |
||||
|
import PropTypes from 'prop-types'; |
||||
|
|
||||
|
import {colors, media} from 'theme'; |
||||
|
import CodeEditor from '../CodeEditor/CodeEditor'; |
||||
|
|
||||
|
class CodeExample extends Component { |
||||
|
render() { |
||||
|
const {children, code, id, loaded} = this.props; |
||||
|
return ( |
||||
|
<div |
||||
|
id={id} |
||||
|
css={{ |
||||
|
marginTop: 40, |
||||
|
|
||||
|
'&:first-child': { |
||||
|
marginTop: 0, |
||||
|
}, |
||||
|
|
||||
|
'& .react-live': { |
||||
|
width: '100%', |
||||
|
}, |
||||
|
|
||||
|
[media.greaterThan('xlarge')]: { |
||||
|
display: 'flex', |
||||
|
flexDirection: 'row', |
||||
|
marginTop: 80, |
||||
|
}, |
||||
|
|
||||
|
[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> |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
CodeExample.propTypes = { |
||||
|
children: PropTypes.node, |
||||
|
code: PropTypes.string.isRequired, |
||||
|
loaded: PropTypes.bool.isRequired, |
||||
|
}; |
||||
|
|
||||
|
export default CodeExample; |
@ -0,0 +1,3 @@ |
|||||
|
import CodeExample from './CodeExample'; |
||||
|
|
||||
|
export default CodeExample; |
@ -1,36 +0,0 @@ |
|||||
/** |
|
||||
* Copyright (c) 2013-present, Facebook, Inc. |
|
||||
* |
|
||||
* @emails react-core |
|
||||
*/ |
|
||||
|
|
||||
import CodeEditor from '../components/CodeEditor'; |
|
||||
import React from 'react'; |
|
||||
import ReactDOM from 'react-dom'; |
|
||||
|
|
||||
// TODO This is a huge hack.
|
|
||||
// Remark transform this template to split code examples and their targets apart.
|
|
||||
const mountCodeExample = (containerId, code) => { |
|
||||
const container = document.getElementById(containerId); |
|
||||
const parent = container.parentElement; |
|
||||
|
|
||||
const children = Array.prototype.filter.call( |
|
||||
parent.children, |
|
||||
child => child !== container, |
|
||||
); |
|
||||
children.forEach(child => parent.removeChild(child)); |
|
||||
|
|
||||
const description = children |
|
||||
.map(child => child.outerHTML) |
|
||||
.join('') |
|
||||
.replace(/`([^`]+)`/g, '<code>$1</code>'); |
|
||||
|
|
||||
ReactDOM.render( |
|
||||
<CodeEditor code={code}> |
|
||||
{<div dangerouslySetInnerHTML={{__html: description}} />} |
|
||||
</CodeEditor>, |
|
||||
container, |
|
||||
); |
|
||||
}; |
|
||||
|
|
||||
export default mountCodeExample; |
|
Loading…
Reference in new issue