Skip to content
This repository was archived by the owner on Jul 5, 2019. It is now read-only.

Commit 95ccf8c

Browse files
author
deepsweet
committed
🐣
0 parents  commit 95ccf8c

14 files changed

+3737
-0
lines changed

.babelrc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"presets": ["es2015", "react"],
3+
"plugins": ["transform-object-rest-spread"]
4+
}

.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

.eslintrc

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": [
3+
"tough/config/common",
4+
"tough/config/esnext",
5+
"tough/config/browser",
6+
"tough/config/react"
7+
],
8+
"rules": {
9+
"object-curly-newline": 0,
10+
"immutable/no-mutation": 0
11+
}
12+
}

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
.DS_Store
3+
*.log

demo/index.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>NeoForm</title>
6+
</head>
7+
<body>
8+
<div id="app"></div>
9+
</body>
10+
</html>

demo/index.jsx

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react';
2+
import { render } from 'react-dom';
3+
import { compose } from 'recompose';
4+
5+
import { Form, Field, Validate } from '../lib/';
6+
7+
const MyInput = ({ valid, changeValue, ...props }) => {
8+
const style = {
9+
backgroundColor: valid === false ? 'red' : 'white'
10+
};
11+
12+
return (
13+
<input
14+
{...props}
15+
type="text"
16+
style={style}
17+
onChange={(e) => changeValue(e.target.value)}
18+
/>
19+
);
20+
};
21+
22+
const Input = Field(MyInput);
23+
24+
const MyCheckbox = ({ changeValue, value, ...props }) => (
25+
<input
26+
{...props}
27+
type="checkbox"
28+
checked={value}
29+
onChange={(e) => changeValue(e.target.checked)}
30+
/>
31+
);
32+
33+
const Checkbox = Field(MyCheckbox);
34+
35+
const MyForm = (({ value = {}, valid = {} }) => (
36+
<form
37+
onSubmit={(e) => {
38+
console.log('fields', value);
39+
console.log('validation', valid);
40+
e.preventDefault();
41+
}}
42+
>
43+
<h1>hej</h1>
44+
<Input name="input" value="dns" />
45+
<Input name="input2" value="pdr" />
46+
<Checkbox name="checkbox" value={false} />
47+
<button disabled={valid.input === false || !value.checkbox}>submit</button>
48+
</form>
49+
));
50+
51+
const App = compose(
52+
Form(console.log),
53+
Validate({
54+
input: (value) => value !== ''
55+
})
56+
)(MyForm);
57+
58+
render(
59+
<App />,
60+
global.document.getElementById('app'),
61+
);

demo/webpack.config.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const path = require('path');
2+
const webpack = require('webpack');
3+
const HtmlWebpackPlugin = require('html-webpack-plugin');
4+
5+
module.exports = {
6+
entry: [
7+
'webpack-dev-server/client?http://localhost:8080',
8+
'webpack/hot/only-dev-server',
9+
'./demo/index.jsx'
10+
],
11+
output: {
12+
publicPath: '/',
13+
path: path.resolve('./demo'),
14+
pathinfo: true
15+
},
16+
devtool: 'cheap-module-source-map',
17+
resolve: {
18+
extensions: ['', '.js', '.jsx']
19+
},
20+
module: {
21+
loaders: [
22+
{
23+
test: /\.jsx?$/,
24+
exclude: path.resolve('node_modules/'),
25+
loader: 'babel',
26+
query: {
27+
cacheDirectory: true
28+
}
29+
}
30+
]
31+
},
32+
plugins: [
33+
new webpack.HotModuleReplacementPlugin(),
34+
new HtmlWebpackPlugin({
35+
template: './demo/index.html'
36+
}),
37+
new webpack.DefinePlugin({
38+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
39+
})
40+
]
41+
};

lib/components/Field.jsx

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React, { Component, PropTypes } from 'react';
2+
3+
const propName = 'value';
4+
5+
export default (Target) => {
6+
class Field extends Component {
7+
constructor(...args) {
8+
super(...args);
9+
10+
this.onChange = this.onChange.bind(this);
11+
}
12+
13+
componentWillMount() {
14+
this.context.neoform.updateState(propName, this.props.name, this.props.value);
15+
}
16+
17+
onChange(value) {
18+
this.context.neoform.updateState(propName, this.props.name, value);
19+
}
20+
21+
getValue() {
22+
if (this.context.neoform.propName) {
23+
return this.context.neoform[propName][this.props.name];
24+
}
25+
26+
return this.props.value;
27+
}
28+
29+
getState() {
30+
return Object.keys(this.context.neoform).reduce((result, key) => {
31+
const group = this.context.neoform[key];
32+
33+
if (this.props.name in group) {
34+
result[key] = group[this.props.name];
35+
} else if (key === propName) {
36+
result[key] = this.props.value;
37+
}
38+
39+
return result;
40+
}, {});
41+
}
42+
43+
render() {
44+
const state = this.getState();
45+
// console.log(state);
46+
const props = {
47+
...this.props,
48+
...state,
49+
changeValue: this.onChange
50+
};
51+
52+
return (
53+
<Target { ...props } />
54+
);
55+
}
56+
}
57+
58+
Field.contextTypes = {
59+
neoform: PropTypes.object
60+
};
61+
62+
Field.propTypes = {
63+
name: PropTypes.string
64+
};
65+
66+
return Field;
67+
};

lib/components/Form.jsx

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React, { Component, PropTypes } from 'react';
2+
3+
export default (callback) => (Target) => {
4+
class Form extends Component {
5+
constructor(props) {
6+
super(props);
7+
8+
this.state = {};
9+
10+
this.updateState = this.updateState.bind(this);
11+
}
12+
13+
getChildContext() {
14+
return {
15+
neoform: {
16+
updateState: this.updateState,
17+
...this.state
18+
}
19+
};
20+
}
21+
22+
updateState(prop, name, value) {
23+
this.setState((prevState) => ({
24+
[prop]: {
25+
...prevState[prop],
26+
[name]: value
27+
}
28+
}), () => {
29+
if (typeof callback === 'function') {
30+
callback(prop, name, value);
31+
}
32+
});
33+
}
34+
35+
render() {
36+
return (
37+
<Target {...this.props} {...this.state} />
38+
);
39+
}
40+
}
41+
42+
Form.childContextTypes = {
43+
neoform: PropTypes.object
44+
};
45+
46+
return Form;
47+
};

lib/components/Validate.jsx

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React, { Component, PropTypes } from 'react';
2+
3+
const propName = 'valid';
4+
5+
export default (validators) => (Target) => {
6+
class Validate extends Component {
7+
componentWillReceiveProps(nextProps, nextContext) {
8+
Object.keys(validators).forEach((field) => {
9+
const prevState = this.context.neoform;
10+
const nextState = nextContext.neoform;
11+
12+
if (
13+
prevState.value &&
14+
prevState.value[field] !== nextState.value[field] &&
15+
(field in nextState.value)
16+
) {
17+
const result = validators[field](nextState.value[field]);
18+
19+
if (!nextState[propName] || result !== nextState[propName][field]) {
20+
nextState.updateState(propName, field, result);
21+
}
22+
}
23+
});
24+
}
25+
26+
render() {
27+
return (
28+
<Target {...this.props} />
29+
);
30+
}
31+
}
32+
33+
Validate.contextTypes = {
34+
neoform: PropTypes.object
35+
};
36+
37+
return Validate;
38+
};

lib/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Form from './components/Form';
2+
import Field from './components/Field';
3+
import Validate from './components/Validate';
4+
5+
export { Form };
6+
export { Field };
7+
export { Validate };

package.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "neoform",
3+
"version": "0.1.0",
4+
"private": true,
5+
"description": "",
6+
"main": "build/index.js",
7+
"files": [
8+
"build/"
9+
],
10+
"dependencies": {
11+
"react": "^15.4.1"
12+
},
13+
"devDependencies": {
14+
"babel-core": "^6.21.0",
15+
"babel-loader": "^6.2.10",
16+
"babel-plugin-transform-object-rest-spread": "^6.20.2",
17+
"babel-preset-es2015": "^6.18.0",
18+
"babel-preset-react": "^6.16.0",
19+
"eslint": "^3.12.2",
20+
"eslint-config-tough": "^0.3.3",
21+
"html-webpack-plugin": "^2.25.0",
22+
"react-dom": "^15.4.1",
23+
"recompose": "^0.21.2",
24+
"webpack": "^1.14.0",
25+
"webpack-dev-server": "^1.16.2"
26+
},
27+
"scripts": {
28+
"demo": "webpack-dev-server --config demo/webpack.config.js",
29+
"lint": "eslint --cache --ext jsx lib/"
30+
},
31+
"license": "MIT"
32+
}

readme.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# NeoForm
2+
3+
WIP

0 commit comments

Comments
 (0)