Replaced cosmos with demo live server.

This commit is contained in:
Nicolas Perriault
2015-12-27 18:02:06 +01:00
parent f92e2bce39
commit ff796417d9
15 changed files with 456 additions and 44 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
npm-debug.log
node_modules
build
lib

View File

@@ -16,7 +16,7 @@ app.use(require("webpack-dev-middleware")(compiler, {
app.use(require("webpack-hot-middleware")(compiler));
app.get("/", function(req, res) {
res.sendFile(path.join(__dirname, "index.html"));
res.sendFile(path.join(__dirname, "playground", "index.html"));
});
app.get("/react-jsonschema-form.css", function(req, res) {

View File

@@ -1,18 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>React Component Playground</title>
<style>
html, body {
margin: 0;
padding: 0;
}
</style>
<link rel="stylesheet" href="react-jsonschema-form.css">
</head>
<body>
<div id="root"></div>
<script src="/static/bundle.js"></script>
</body>
</html>

View File

@@ -6,8 +6,10 @@
"build:css": "cp css/react-jsonschema-form.css dist/",
"build:lib": "rimraf lib && babel -d lib/ src/",
"build:dist": "rimraf dist && webpack --config webpack.config.dist.js --optimize-minimize",
"build:playground": "rimraf build && webpack --config webpack.config.prod.js --optimize-minimize && cp playground/index.prod.html build/index.html",
"dist": "npm run build:lib && npm run build:dist && npm run build:css",
"lint": "eslint src test",
"publish-to-gh-pages": "npm run build:playground && gh-pages --dist build/",
"publish-to-npm": "npm run dist && npm publish",
"start": "node devServer.js",
"tdd": "npm run test -- -w",
@@ -31,20 +33,24 @@
"babel-loader": "^5.3.2",
"babel-plugin-react-transform": "^1.1.1",
"chai": "^3.3.0",
"cosmos-js": "^0.7.1",
"codemirror": "^5.10.0",
"css-loader": "^0.23.1",
"eslint": "^1.8.0",
"eslint-plugin-react": "^3.6.3",
"express": "^4.13.3",
"extract-text-webpack-plugin": "^0.9.1",
"gh-pages": "^0.4.0",
"html": "0.0.10",
"jsdom": "^7.2.1",
"mocha": "^2.3.0",
"react-addons-test-utils": "^0.14.3",
"react-codemirror": "^0.2.2",
"react-transform-catch-errors": "^1.0.0",
"react-transform-hmr": "^1.0.1",
"redbox-react": "^1.2.0",
"rimraf": "^2.4.4",
"sinon": "^1.17.2",
"style-loader": "^0.13.0",
"webpack": "^1.10.5",
"webpack-dev-middleware": "^1.4.0",
"webpack-hot-middleware": "^2.6.0"

154
playground/app.js Normal file
View File

@@ -0,0 +1,154 @@
import React, { Component } from "react";
import { render } from "react-dom";
import Codemirror from "react-codemirror";
import "codemirror/mode/javascript/javascript";
import { samples } from "./samples";
import Form from "../src";
import "codemirror/lib/codemirror.css";
import "./styles.css";
const log = (type) => console.log.bind(console, type);
const fromJson = (json) => JSON.parse(json);
const toJson = (val) => JSON.stringify(val, null, 2);
const cmOptions = {
theme: "default",
height: "auto",
viewportMargin: Infinity,
mode: {
name: "javascript",
json: true,
statementIndent: 2,
},
lineNumbers: true,
lineWrapping: true,
indentWithTabs: false,
tabSize: 2,
};
class Editor extends Component {
constructor(props) {
super(props);
this.state = {valid: true, code: props.code, data: fromJson(props.code)};
}
componentWillReceiveProps(props) {
this.setState({code: props.code, data: fromJson(props.code)});
}
onCodeChange(code) {
try {
this.setState({valid: true, data: fromJson(code), code});
this.props.onChange(this.state.data);
} catch(err) {
this.setState({valid: false, code});
}
}
render() {
const {title} = this.props;
const icon = this.state.valid ? "ok" : "remove";
return (
<fieldset>
<legend>
<span className={`glyphicon glyphicon-${icon}`} />
{" "}
{title}
</legend>
<Codemirror
value={this.state.code}
onChange={this.onCodeChange.bind(this)}
options={cmOptions} />
</fieldset>
);
}
}
class Selector extends Component {
constructor(props) {
super(props);
this.state = {current: "Simple"};
}
onClick(label, sampleData, event) {
event.preventDefault();
this.setState({current: label});
this.props.onSelected(sampleData);
}
render() {
return (
<ul className="nav nav-pills">{
Object.keys(samples).map((label, i) => {
return (
<li key={i} role="presentation"
className={this.state.current === label ? "active" : ""}>
<a href="#"
onClick={this.onClick.bind(this, label, samples[label])}>
{label}
</a>
</li>
);
})
}</ul>
);
}
}
class App extends Component {
constructor(props) {
super(props);
this.state = {form: false, schema: {}, uiSchema: {}, formData: {}};
}
componentDidMount() {
this.setState({...samples.Simple, form: true});
}
load(data) {
// force resetting form component instance
this.setState({form: false},
_ => this.setState({...data, form: true}));
}
render() {
return (
<div className="container-fluid">
<div className="page-header">
<h1>react-jsonschema-form</h1>
<Selector onSelected={this.load.bind(this)} />
</div>
<div className="col-md-6">
<Editor title="JSONSchema"
code={toJson(this.state.schema)}
onChange={schema => this.setState({schema})} />
<div className="row">
<div className="col-md-6">
<Editor title="UISchema"
code={toJson(this.state.uiSchema)}
onChange={uiSchema => this.setState({uiSchema})} />
</div>
<div className="col-md-6">
<Editor title="formData"
code={toJson(this.state.formData)}
onChange={formData => this.setState({formData})} />
</div>
</div>
</div>
<div className="col-md-6">
{!this.state.form ? null :
<Form
schema={this.state.schema}
uiSchema={this.state.uiSchema}
formData={this.state.formData}
onChange={data => this.setState({formData: data.formData})}
onSubmit={data => this.setState({formData: data.formData})}
onError={log("errors")} />}
</div>
</div>
);
}
}
render(<App />, document.getElementById("app"));

14
playground/index.html Normal file
View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>react-jsonschema-form playground</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<div id="app"></div>
<script src="/static/bundle.js"></script>
</body>
</html>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>react-jsonschema-form playground</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div id="app"></div>
<script src="./bundle.js"></script>
</body>
</html>

View File

@@ -0,0 +1,11 @@
module.exports = {
schema: {
type: "array",
items: {
type: "string",
default: "bazinga"
}
},
uiSchema: {},
formData: ["foo", "bar"]
};

View File

@@ -0,0 +1,11 @@
import arrays from "./arrays";
import nested from "./nested";
import simple from "./simple";
import widgets from "./widgets";
export const samples = {
Simple: simple,
Nested: nested,
Arrays: arrays,
Widgets: widgets,
};

View File

@@ -0,0 +1,62 @@
module.exports = {
schema: {
title: "A list of tasks",
type: "object",
required: ["title"],
properties: {
title: {
type: "string",
title: "Task list title"
},
tasks: {
type: "array",
items: {
type: "object",
title: "Task",
required: ["title"],
properties: {
title: {
type: "string",
title: "Title",
description: "A sample title"
},
details: {
type: "string",
title: "Task details",
description: "Enter the task details"
},
done: {
type: "boolean",
title: "Done?",
default: false
}
}
}
}
}
},
uiSchema: {
tasks: {
items: {
details: {
widget: "textarea"
}
}
}
},
formData: {
title: "My current tasks",
tasks: [
{
title: "My first task",
details: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
done: true
},
{
title: "My second task",
details: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur",
done: false
}
]
}
};

View File

@@ -0,0 +1,20 @@
module.exports = {
schema: {
title: "A simple todo entry",
type: "object",
required: ["title"],
properties: {
title: {type: "string", title: "Title", default: "A new task"},
done: {type: "boolean", title: "Done?", default: false}
}
},
uiSchema: {
done: {
widget: "radio"
}
},
formData: {
title: "My task",
done: false
}
};

View File

@@ -0,0 +1,66 @@
module.exports = {
schema: {
title: "Widgets",
type: "object",
properties: {
boolean: {
type: "object",
title: "Boolean field",
properties: {
default: {
type: "boolean",
title: "checkbox (default)"
},
radio: {
type: "boolean",
title: "radio buttons"
},
select: {
type: "boolean",
title: "select box"
}
}
},
string: {
type: "object",
title: "String field",
properties: {
default: {
type: "string",
title: "text input (default)"
},
textarea: {
type: "string",
title: "textarea"
}
}
}
}
},
uiSchema: {
boolean: {
radio: {
widget: "radio"
},
select: {
widget: "select"
}
},
string: {
textarea: {
widget: "textarea"
}
}
},
formData: {
boolean: {
default: true,
radio: true,
select: true
},
string: {
default: "Hello...",
textarea: "... World"
}
}
};

16
playground/styles.css Normal file
View File

@@ -0,0 +1,16 @@
.rjsf label {
width: 200px;
}
.rjsf input[type=text], .rjsf textarea {
font-weight: normal;
width: 350px;
}
.rjsf textarea {
height: 120px;
}
.rjsf input[type=radio] {
margin-right: .4em;
}

View File

@@ -5,14 +5,8 @@ module.exports = {
devtool: "eval",
entry: [
"webpack-hot-middleware/client?reload=true",
"cosmos-js"
"./playground/app"
],
resolve: {
alias: {
COSMOS_COMPONENTS: path.join(__dirname, "src/components"),
COSMOS_FIXTURES: path.join(__dirname, "fixtures")
}
},
output: {
path: path.join(__dirname, "build"),
filename: "bundle.js",
@@ -23,25 +17,40 @@ module.exports = {
new webpack.NoErrorsPlugin()
],
module: {
loaders: [{
test: /\.jsx?$/,
loader: "babel",
include: path.join(__dirname, "src"),
query: {
plugins: ["react-transform"],
extra: {
"react-transform": {
transforms: [{
transform: "react-transform-hmr",
imports: ["react"],
locals: ["module"]
}, {
transform: "react-transform-catch-errors",
imports: ["react", "redbox-react"]
}]
loaders: [
{
test: /\.jsx?$/,
loader: "babel",
include: [
path.join(__dirname, "src"),
path.join(__dirname, "playground"),
path.join(__dirname, "node_modules", "codemirror", "mode", "javascript"),
],
query: {
plugins: ["react-transform"],
extra: {
"react-transform": {
transforms: [{
transform: "react-transform-hmr",
imports: ["react"],
locals: ["module"]
}, {
transform: "react-transform-catch-errors",
imports: ["react", "redbox-react"]
}]
}
}
}
},
{
test: /\.css$/,
loader: "style!css",
include: [
path.join(__dirname, "css"),
path.join(__dirname, "playground"),
path.join(__dirname, "node_modules"),
],
}
}]
]
}
};

45
webpack.config.prod.js Normal file
View File

@@ -0,0 +1,45 @@
var path = require("path");
var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: "./playground/app",
output: {
path: path.join(__dirname, "build"),
filename: "bundle.js",
publicPath: "/static/"
},
plugins: [
new ExtractTextPlugin("styles.css", {allChunks: true}),
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
})
],
resolve: {
extensions: ["", ".js", ".jsx", ".css"]
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: "babel",
include: [
path.join(__dirname, "src"),
path.join(__dirname, "playground"),
path.join(__dirname, "node_modules", "codemirror", "mode", "javascript"),
],
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("css-loader"),
include: [
path.join(__dirname, "css"),
path.join(__dirname, "playground"),
path.join(__dirname, "node_modules"),
],
}
]
}
};