mirror of
https://github.com/zhigang1992/react-jsonschema-form.git
synced 2026-05-19 19:39:49 +08:00
Replaced cosmos with demo live server.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
npm-debug.log
|
||||
node_modules
|
||||
build
|
||||
lib
|
||||
|
||||
@@ -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) {
|
||||
|
||||
18
index.html
18
index.html
@@ -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>
|
||||
@@ -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
154
playground/app.js
Normal 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
14
playground/index.html
Normal 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>
|
||||
15
playground/index.prod.html
Normal file
15
playground/index.prod.html
Normal 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>
|
||||
11
playground/samples/arrays.js
Normal file
11
playground/samples/arrays.js
Normal file
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
schema: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
default: "bazinga"
|
||||
}
|
||||
},
|
||||
uiSchema: {},
|
||||
formData: ["foo", "bar"]
|
||||
};
|
||||
11
playground/samples/index.js
Normal file
11
playground/samples/index.js
Normal 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,
|
||||
};
|
||||
62
playground/samples/nested.js
Normal file
62
playground/samples/nested.js
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
20
playground/samples/simple.js
Normal file
20
playground/samples/simple.js
Normal 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
|
||||
}
|
||||
};
|
||||
66
playground/samples/widgets.js
Normal file
66
playground/samples/widgets.js
Normal 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
16
playground/styles.css
Normal 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;
|
||||
}
|
||||
@@ -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
45
webpack.config.prod.js
Normal 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"),
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user