This Gist was generated by Contrived.
Do not modify the metadata file if you want to open in Contrived again. Otherwise, it is safe to delete.
Happy Hacking!
{"user":"5f0c542a4a2ce5e528e01fdf","templateVersion":"1","templateId":"reactjs","resources":["<meta charset=\"UTF-8\" />","<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">"],"dependencies":[{"name":"react","version":"16.13.1","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"},{"name":"react-dom","version":"16.13.1","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"}],"files":[{"id":1,"parentId":0,"name":"public","path":"/public","type":"folder","isRoot":true,"selected":false,"expanded":false,"children":[{"id":2,"name":"index.html"}]},{"id":2,"parentId":1,"name":"index.html","path":"/src/index.html","type":"file","mimeType":"html","isRoot":false,"open":false,"selected":false,"content":""},{"id":3,"parentId":0,"name":"src","path":"/src","type":"folder","isRoot":true,"selected":false,"expanded":true,"children":[{"id":4,"name":"index.js"},{"id":5,"name":"styles.css"}]},{"id":4,"parentId":3,"name":"index.js","path":"/src/index.js","type":"file","mimeType":"es6","isRoot":false,"open":true,"selected":true,"content":""},{"id":5,"parentId":3,"name":"style.css","path":"/src/style.css","type":"file","mimeType":"css","isRoot":false,"open":true,"selected":false,"content":""}],"experimentId":"5f6c3ae9923a2900174e971a"} |
.App { | |
font-family: sans-serif; | |
text-align: center; | |
} | |
.editor-container { | |
margin: 20px 0px; | |
color: cyan; | |
} | |
.editor { | |
background: #141414; | |
color: #ccc; | |
} | |
.playground { | |
position: fixed; | |
top: 0; | |
bottom: 0; | |
left: 0; | |
width: 450px; | |
background-color: #1E1E2C; | |
} | |
.result { | |
position: fixed; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 450px; | |
overflow: hidden; | |
background: #222; | |
} | |
.iframe { | |
width: 100%; | |
height: 100%; | |
border: none; | |
} |
<div id="root"></div> |
const { useEffect, useState, useRef } = React; | |
const Editor = ({ title, value, onChange }) => { | |
return ( | |
<div className="editor-container"> | |
<div>{title}</div> | |
<textarea className="editor" value={value} onChange={onChange} rows="8" cols="50" /> | |
</div> | |
); | |
}; | |
const App = () => { | |
const ref = useRef(); | |
const [html, setHtml] = useState('<h2 id="title">\n Hello Inception\n</h2>'); | |
const [css, setCss] = useState('#title {\n color: magenta\n};'); | |
const [js, setJs] = useState(''); | |
useEffect(() => { | |
runCode(); | |
}, [html, css, js]); | |
const runCode = () => { | |
if (!ref.current) return; | |
const document = ref.current.contentDocument; | |
const documentContents = ` | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Document</title> | |
<style> | |
${css} | |
</style> | |
</head> | |
<body> | |
${html} | |
</body> | |
<script type="text/javascript"> | |
${js} | |
<script> | |
</html> | |
`; | |
document.open(); | |
document.write(documentContents); | |
document.close(); | |
}; | |
return ( | |
<div className='App'> | |
<section className="playground"> | |
<div style={{ margin: '15px', color: 'white' }}>Inception - Code Editor</div> | |
<Editor title="HTML Editor" value={html} onChange={(e) => setHtml(e.target.value)} /> | |
<Editor title="CSS Editor" value={css} onChange={(e) => setCss(e.target.value)} /> | |
<Editor title="JS Editor" value={js} onChange={(e) => setJs(e.target.value)} /> | |
</section> | |
<section className="result"> | |
<iframe title="result" className="iframe" ref={ref} /> | |
</section> | |
</div> | |
); | |
}; | |
ReactDOM.render(<App/>, document.getElementById('root')); |