├── src ├── components │ ├── Nav │ │ ├── index.js │ │ ├── Tab.js │ │ ├── Nav.scss │ │ ├── Nav.js │ │ └── __tests__ │ │ │ ├── Nav.spec.js │ │ │ └── Tab.spec.js │ ├── Result │ │ ├── index.js │ │ ├── Result.scss │ │ ├── generateHTML.js │ │ ├── __tests__ │ │ │ ├── generateHTML.spec.js │ │ │ └── Result.spec.js │ │ └── Result.js │ ├── CodeEditor │ │ ├── index.js │ │ ├── CodeEditor.js │ │ └── __tests__ │ │ │ └── CodeEditor.spec.js │ ├── global.scss │ └── Playground │ │ ├── Playground.scss │ │ ├── index.js │ │ ├── __tests__ │ │ └── Playground.spec.js │ │ └── Playground.js ├── utils │ ├── index.js │ ├── isEmpty.js │ ├── __tests__ │ │ ├── isEmpty.spec.js │ │ └── getCodeMirrorMode.spec.js │ └── getCodeMirrorMode.js ├── __tests__ │ ├── utils │ │ └── beautifyHTML.js │ └── framework.spec.js ├── redux │ ├── rootReducer.js │ ├── store.js │ └── modules │ │ ├── activeTab.js │ │ ├── compiling.js │ │ ├── __tests__ │ │ ├── compiling.spec.js │ │ ├── code.reducer.spec.js │ │ └── code.actions.spec.js │ │ └── code.js ├── index.js └── plugins │ └── parsers │ ├── sass.js │ └── __tests__ │ └── sass.spec.js ├── bin ├── karma.js ├── build.js ├── webpack.js ├── deploy.js ├── concatStyleSheet.js └── develop.js ├── .gitignore ├── .eslintignore ├── tests.webpack.js ├── .eslintrc ├── demo ├── examples │ ├── slack-logo │ │ ├── html.example │ │ └── sass.example │ └── editr.js │ │ ├── html.example │ │ └── css.example ├── develop.html ├── styles.scss ├── gh-pages.html └── app.js ├── CHANGELOG.md ├── .babelrc ├── LICENSE ├── .travis.yml ├── config └── index.js ├── README.md └── package.json /src/components/Nav/index.js: -------------------------------------------------------------------------------- 1 | export default from './Nav' 2 | -------------------------------------------------------------------------------- /src/components/Result/index.js: -------------------------------------------------------------------------------- 1 | export default from './Result' 2 | -------------------------------------------------------------------------------- /bin/karma.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../build/karma.conf').default 2 | -------------------------------------------------------------------------------- /src/components/CodeEditor/index.js: -------------------------------------------------------------------------------- 1 | export default from './CodeEditor' 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | lib 3 | webpack 4 | coverage 5 | 6 | node_modules 7 | *.log 8 | -------------------------------------------------------------------------------- /src/components/Result/Result.scss: -------------------------------------------------------------------------------- 1 | .iframe { 2 | width: 100%; 3 | height: 100%; 4 | border: none; 5 | position: absolute; 6 | } 7 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage/** 2 | node_modules/** 3 | dist/** 4 | lib/** 5 | webpack/** 6 | src/**/*.spec.js 7 | src/index.html 8 | demo/** 9 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | export { default as isEmpty } from './isEmpty' 2 | export { default as getCodeMirrorMode } from './getCodeMirrorMode' 3 | -------------------------------------------------------------------------------- /tests.webpack.js: -------------------------------------------------------------------------------- 1 | // Bundle all file in src into test 2 | const componentsContext = require.context('./src', true, /\.js$/) 3 | componentsContext.keys().forEach(componentsContext) 4 | -------------------------------------------------------------------------------- /src/__tests__/utils/beautifyHTML.js: -------------------------------------------------------------------------------- 1 | import { 2 | html as beautifyHTML, 3 | default_options as defaultOptions 4 | } from 'js-beautify' 5 | 6 | export default (html) => ( 7 | beautifyHTML(html, {...defaultOptions, indent_size: 2}) 8 | ) 9 | -------------------------------------------------------------------------------- /src/components/global.scss: -------------------------------------------------------------------------------- 1 | $color-white: #fff; 2 | 3 | /* 4 | * App colors 5 | */ 6 | $color-primary: #555; 7 | $color-accent: red; 8 | $color-text: #555; 9 | $color-background: #f0f1f4; 10 | $color-divider: rgba($color-primary, .4); 11 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser" : "babel-eslint", 3 | "extends" : [ 4 | "standard", 5 | "standard-react" 6 | ], 7 | "env" : { 8 | "browser" : true 9 | }, 10 | "globals" : { 11 | "__DEV__" : false, 12 | "__PROD__" : false 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /demo/examples/slack-logo/html.example: -------------------------------------------------------------------------------- 1 |
', `${html}`) 10 | } 11 | if (css) { 12 | result = result.replace('', ``) 13 | } 14 | if (javascript) { 15 | result = result.replace('', ``) 16 | } 17 | return result 18 | } 19 | -------------------------------------------------------------------------------- /bin/build.js: -------------------------------------------------------------------------------- 1 | import webpack from './webpack' 2 | import wpConfig from '../build/webpack.config' 3 | import fs from 'fs-extra' 4 | import config from '../config' 5 | 6 | const debug = require('debug')('playground:bin:build') 7 | 8 | const paths = config.utils_paths 9 | 10 | debug('Start build') 11 | fs.emptyDirSync(paths.dist()) 12 | 13 | webpack(wpConfig, () => { 14 | debug('Webpack build success') 15 | debug('Copy static files') 16 | fs.copySync(paths.demo('vendor'), paths.dist('vendor')) 17 | debug('Done') 18 | }) 19 | -------------------------------------------------------------------------------- /src/components/Nav/Tab.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styles from './Nav.scss' 3 | const cx = require('classnames/bind').bind(styles) 4 | 5 | const Tab = ({ 6 | type, 7 | displayName, 8 | activeTab, 9 | onTabClick 10 | }) => { 11 | const className = cx('tab', { 12 | tabActive: activeTab === type 13 | }) 14 | 15 | return ( 16 |
22 | )
23 | }
24 |
25 | export default Tab
26 |
--------------------------------------------------------------------------------
/src/utils/isEmpty.js:
--------------------------------------------------------------------------------
1 | /**
2 | * isEmpty function
3 | * @param {any} t [variable for checking]
4 | * @return {boolean} [is variable empty or not]
5 | */
6 | export default function (t) {
7 | if (t === null) {
8 | return true
9 | }
10 |
11 | if (Array.isArray(t)) {
12 | return (t.length === 0)
13 | }
14 |
15 | if (typeof t === 'object') {
16 | let k = Object.keys(t)
17 | if (k !== undefined) {
18 | return (Object.keys(t).length === 0)
19 | }
20 | }
21 |
22 | return (t !== undefined) ||
23 | (t !== '')
24 | }
25 |
--------------------------------------------------------------------------------
/bin/webpack.js:
--------------------------------------------------------------------------------
1 | import webpack from 'webpack'
2 | const debug = require('debug')('playground:bin:webpack')
3 |
4 | export default (webpackConfig, cb) => {
5 | webpack(webpackConfig, (err, stats) => {
6 | if (err) {
7 | throw err
8 | }
9 |
10 | if (stats.hasErrors()) {
11 | stats.compilation.errors.forEach(
12 | item => {
13 | item.stack.split('\n').forEach(line => debug(line))
14 | }
15 | )
16 |
17 | throw new Error('webpack build failed with errors')
18 | }
19 | cb(stats)
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/bin/deploy.js:
--------------------------------------------------------------------------------
1 | const ghpages = require('gh-pages')
2 | const debug = require('debug')('playground:bin:deploy')
3 | const path = require('path')
4 |
5 | debug('Start deployment process.')
6 |
7 | debug('Clean up temp folder')
8 | ghpages.clean()
9 |
10 | debug('Deploy with github token')
11 | ghpages.publish(path.join(__dirname, '../dist'), {
12 | repo: 'https://' + process.env.GH_TOKEN + '@github.com/thangngoc89/react-code-playground.git',
13 | silent: true
14 | }, callback)
15 |
16 | var callback = function (err) {
17 | if (err) {
18 | debug(err)
19 | return
20 | }
21 | debug('Finish')
22 | }
23 |
--------------------------------------------------------------------------------
/src/utils/__tests__/isEmpty.spec.js:
--------------------------------------------------------------------------------
1 | import { isEmpty } from '../'
2 |
3 | describe('utils', () => {
4 | describe('isEmpty function lists these at true', () => {
5 | it('empty object', () => {
6 | expect(isEmpty({})).to.be.true
7 | })
8 | it('empty array', () => {
9 | expect(isEmpty([])).to.be.true
10 | })
11 | it('empty string', () => {
12 | expect(isEmpty('')).to.be.true
13 | })
14 | it('undefined', () => {
15 | expect(isEmpty(undefined)).to.be.true
16 | })
17 | it('null', () => {
18 | expect(isEmpty(null)).to.be.true
19 | })
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/src/__tests__/framework.spec.js:
--------------------------------------------------------------------------------
1 | import assert from 'assert'
2 |
3 | describe('(Framework) Karma Plugins', function () {
4 | it('Should expose "expect" globally.', function () {
5 | assert.ok(expect)
6 | })
7 |
8 | it('Should expose "should" globally.', function () {
9 | assert.ok(should)
10 | })
11 |
12 | it('Should have chai-as-promised helpers.', function () {
13 | const pass = new Promise(res => res('test'))
14 | const fail = new Promise((res, rej) => rej())
15 |
16 | return Promise.all([
17 | expect(pass).to.be.fulfilled,
18 | expect(fail).to.not.be.fulfilled
19 | ])
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Playground from './components/Playground'
3 | import store from './redux/store'
4 | import { codeRefresh } from './redux/modules/code'
5 |
6 | class CodePlayground extends Component {
7 | /**
8 | * Set isSynced to false when receive new props
9 | */
10 | componentWillReceiveProps (nextProps) {
11 | if (nextProps !== this.props) {
12 | store.dispatch(codeRefresh())
13 | }
14 | }
15 |
16 | render () {
17 | return (
18 |
foo
' 7 | const javascript = `console.log('foo')` 8 | const css = `.foo {border: 0}` 9 | 10 | it('generate expected code', () => { 11 | const result = generateHTML({javascript, css, html}) 12 | const expectedResult = 13 | ` 14 |
15 | 16 | 17 |
21 |