mirror of
https://github.com/zhigang1992/redux-form.git
synced 2026-04-29 12:55:34 +08:00
killed the "adapter" API. it was dumb.
This commit is contained in:
@@ -26,15 +26,6 @@ or passed in as props to your component at runtime.**
|
||||
|
||||
### Optional
|
||||
|
||||
#### -`adapter : (component:String, props:Object) => ReactElement` [optional]
|
||||
|
||||
> An adapter function that will render a component based on a string component type and the props
|
||||
given to a `Field`. **Remember that all you really need to hook up to your custom component is
|
||||
`value` and `onChange`.** An example can be found in the
|
||||
[`redux-form-material-ui`](https://github.com/erikras/redux-form-material-ui) library.
|
||||
|
||||
Defaults to `[]`.
|
||||
|
||||
> See [Asynchronous Blur Validation Example](../../examples/asyncValidation) for more
|
||||
details.
|
||||
|
||||
|
||||
@@ -64,11 +64,6 @@ open [`localhost:3030`](http://localhost:3030) in your browser.
|
||||
|
||||
---
|
||||
|
||||
### [Adapter](adapter)
|
||||
|
||||
> How to use the built-in "adapter" API.
|
||||
|
||||
---
|
||||
### [Material-UI Examples](material-ui)
|
||||
|
||||
> Contains multiple Material-UI examples
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"presets": ["react", "es2015", "stage-2"]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
# Simple Material UI Form Example
|
||||
|
||||
## To run locally
|
||||
|
||||
```
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Then open [`http://localhost:3030/`](http://localhost:3030/).
|
||||
@@ -1,27 +0,0 @@
|
||||
var path = require('path');
|
||||
var express = require('express');
|
||||
var webpack = require('webpack');
|
||||
var config = require('./webpack.config.dev');
|
||||
|
||||
var app = express();
|
||||
var compiler = webpack(config);
|
||||
|
||||
app.use(require('webpack-dev-middleware')(compiler, {
|
||||
noInfo: true,
|
||||
publicPath: config.output.publicPath
|
||||
}));
|
||||
|
||||
app.use(require('webpack-hot-middleware')(compiler));
|
||||
|
||||
app.get('*', function(req, res) {
|
||||
res.sendFile(path.join(__dirname, 'index.html'));
|
||||
});
|
||||
|
||||
app.listen(3030, 'localhost', function(err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Listening at http://localhost:3030');
|
||||
});
|
||||
@@ -1,90 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charSet="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
||||
<title>Redux Form</title>
|
||||
<link href="http://redux-form.com/6.0.0-alpha.14/bundle.css"
|
||||
media="screen, projection"
|
||||
rel="stylesheet" type="text/css"/>
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css"
|
||||
media="screen, projection" rel="stylesheet" type="text/css"/>
|
||||
<style type="text/css">
|
||||
/*This CSS has been tweaked from root site
|
||||
to match with material-ui*/
|
||||
form > div > div > div {
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
<meta itemprop="name" content="Redux Form"/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:title" content="Redux Form"/>
|
||||
<meta property="og:site_name" content="Redux Form"/>
|
||||
<meta property="og:description"
|
||||
content="The best way to manage your form state in Redux."/>
|
||||
<meta property="og:image" content="logo.png"/>
|
||||
<meta property="twitter:site" content="@erikras"/>
|
||||
<meta property="twitter:creator" content="@erikras"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<style type="text/css" scoped>
|
||||
.loader {
|
||||
margin: 10% auto;
|
||||
font-size: 10px;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
border-top: 1.1em solid rgba(100, 100, 100, 0.2);
|
||||
border-right: 1.1em solid rgba(100, 100, 100, 0.2);
|
||||
border-bottom: 1.1em solid rgba(100, 100, 100, 0.2);
|
||||
border-left: 1.1em solid grey;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
-webkit-animation: load8 1.1s infinite linear;
|
||||
animation: load8 1.1s infinite linear;
|
||||
}
|
||||
|
||||
.loader,
|
||||
.loader:after {
|
||||
border-radius: 50%;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
}
|
||||
|
||||
@-webkit-keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="loader">Loading...</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="dist/bundle.js"></script>
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-69298417-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build:webpack": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
|
||||
"build": "npm run clean && npm run build:webpack",
|
||||
"lint": "eslint src",
|
||||
"start": "node devServer.js",
|
||||
"prepublish": "npm run lint && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.6.1",
|
||||
"html-loader": "^0.4.3",
|
||||
"json-loader": "^0.5.4",
|
||||
"markdown-loader": "^0.1.7",
|
||||
"material-ui": "^0.15.0",
|
||||
"raw-loader": "^0.5.1",
|
||||
"react": "^15.0.0-rc.2",
|
||||
"react-dom": "^15.0.0-rc.2",
|
||||
"react-redux": "^4.4.1",
|
||||
"react-tap-event-plugin": "^1.0.0",
|
||||
"redux": "^3.3.1",
|
||||
"redux-form": "file:../../",
|
||||
"redux-form-material-ui": "^1.0.0",
|
||||
"redux-form-website-template": "0.0.30"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.3.15",
|
||||
"babel-eslint": "^5.0.0-beta4",
|
||||
"babel-loader": "^6.2.0",
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-preset-react": "^6.3.13",
|
||||
"babel-preset-stage-2": "^6.1.18",
|
||||
"cross-env": "^1.0.7",
|
||||
"eslint": "^1.6.0",
|
||||
"eslint-config-rackt": "^1.1.1",
|
||||
"eslint-loader": "^1.3.0",
|
||||
"eslint-plugin-babel": "^3.0.0",
|
||||
"eslint-plugin-react": "^3.11.3",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
"express": "^4.13.3",
|
||||
"extract-text-webpack-plugin": "^1.0.1",
|
||||
"redbox-react": "^1.2.2",
|
||||
"rimraf": "^2.4.3",
|
||||
"webpack": "^1.12.9",
|
||||
"webpack-dev-middleware": "^1.4.0",
|
||||
"webpack-hot-middleware": "^2.6.0"
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
# Adapter Example
|
||||
|
||||
The "adapter" API in `redux-form` provides an easy way to provide shortcuts to certain commonly
|
||||
used ways of rendering inputs. An "adapter" function, in `redux-form`, takes a string that
|
||||
corresponds to the `component` prop on the `Field` component, and the props that `redux-form`
|
||||
would normally give to the `component`, and gives back a React element. To write that more
|
||||
succinctly in code:
|
||||
|
||||
```js
|
||||
const adapter = (componentName, props) => <MyCustomComponent {...props}/>
|
||||
```
|
||||
|
||||
The adapter API is provided for convenience only, as you could always pass predefined components
|
||||
or stateless function components to your `component` prop. The primary motivation for the adapter
|
||||
interface is to allow third party input libraries to provide easy ways to adapt popular third
|
||||
party input widgets to `redux-form`. e.g.
|
||||
[`redux-form-material-ui`](https://github.com/erikras/redux-form-material-ui).
|
||||
|
||||
The example below is fairly contrived, and is meant only to demonstrate how it works and the kind
|
||||
of flexibility the adapter API provides. It should not necessarily be copied.
|
||||
@@ -1,39 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Field, reduxForm } from 'redux-form'
|
||||
import adapter from './adapter'
|
||||
|
||||
const validate = values => {
|
||||
const errors = {}
|
||||
const requiredFields = [ 'username', 'password', 'email', 'age' ]
|
||||
requiredFields.forEach(field => {
|
||||
if (!values[ field ]) {
|
||||
errors[ field ] = 'Required'
|
||||
}
|
||||
})
|
||||
if (values.email && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
|
||||
errors.email = 'Invalid email address'
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
const AdapterForm = props => {
|
||||
const { handleSubmit, pristine, reset, submitting } = props
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Field name="username" label="Username" component="myCustomText"/>
|
||||
<Field name="password" label="Password" component="myCustomPassword"/>
|
||||
<Field name="email" label="Email" component="myCustomEmail"/>
|
||||
<Field name="age" label="Age" component="myCustomNumber"/>
|
||||
<div>
|
||||
<button type="submit" disabled={pristine || submitting}>Submit</button>
|
||||
<button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
export default reduxForm({
|
||||
form: 'adapterExample', // a unique identifier for this form
|
||||
adapter,
|
||||
validate
|
||||
})(AdapterForm)
|
||||
@@ -1,43 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
const FieldWrapper = ({ touched, error, children, label }) =>
|
||||
<div>
|
||||
<label>{label}</label>
|
||||
<div>
|
||||
{children}
|
||||
{touched && error && <span>{error}</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
const components = {
|
||||
|
||||
myCustomText: props =>
|
||||
<FieldWrapper {...props}>
|
||||
<input type="text" {...props} placeholder={props.label}/>
|
||||
</FieldWrapper>,
|
||||
|
||||
myCustomEmail: props =>
|
||||
<FieldWrapper {...props}>
|
||||
<input type="email" {...props} placeholder={props.label}/>
|
||||
</FieldWrapper>,
|
||||
|
||||
myCustomPassword: props =>
|
||||
<FieldWrapper {...props}>
|
||||
<input type="password" {...props} placeholder={props.label}/>
|
||||
</FieldWrapper>,
|
||||
|
||||
myCustomNumber: props =>
|
||||
<FieldWrapper {...props}>
|
||||
<input type="number" {...props} placeholder={props.label}/>
|
||||
</FieldWrapper>
|
||||
|
||||
}
|
||||
|
||||
const adapter = (key, props) => {
|
||||
const component = components[ key ]
|
||||
if (component) {
|
||||
return component(props)
|
||||
}
|
||||
}
|
||||
|
||||
export default adapter
|
||||
@@ -1,95 +0,0 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { Provider } from 'react-redux'
|
||||
import { createStore, combineReducers } from 'redux'
|
||||
import { reducer as reduxFormReducer } from 'redux-form'
|
||||
import {
|
||||
App,
|
||||
Code,
|
||||
Markdown,
|
||||
Values,
|
||||
generateExampleBreadcrumbs
|
||||
} from 'redux-form-website-template'
|
||||
const dest = document.getElementById('content')
|
||||
const reducer = combineReducers({
|
||||
form: reduxFormReducer // mounted under "form"
|
||||
})
|
||||
const store =
|
||||
(window.devToolsExtension ? window.devToolsExtension()(createStore) : createStore)(reducer)
|
||||
|
||||
const showResults = values =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => { // simulate server latency
|
||||
window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`)
|
||||
resolve()
|
||||
}, 500)
|
||||
})
|
||||
|
||||
let render = () => {
|
||||
const AdapterForm = require('./AdapterForm').default
|
||||
const readme = require('./Adapter.md')
|
||||
const raw = require('!!raw!./AdapterForm')
|
||||
const adapterRaw = require('!!raw!./adapter')
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<App
|
||||
/**
|
||||
* This <App/> component only provides the site wrapper.
|
||||
* Remove it on your dev server if you wish. It will not affect the functionality.
|
||||
*/
|
||||
version="6.0.0-alpha.14"
|
||||
path="/examples/adapter/"
|
||||
breadcrumbs={generateExampleBreadcrumbs('adapter', 'Adapter Example', '6.0.0-alpha.14')}>
|
||||
|
||||
<Markdown content={readme}/>
|
||||
|
||||
<h2>Form</h2>
|
||||
|
||||
<AdapterForm onSubmit={showResults}/>
|
||||
|
||||
<Values form="adapterExample"/>
|
||||
|
||||
<h2>Code</h2>
|
||||
|
||||
<h4>adapter.js</h4>
|
||||
|
||||
<Code source={adapterRaw}/>
|
||||
|
||||
<h4>AdapterForm.js</h4>
|
||||
|
||||
<Code source={raw}/>
|
||||
|
||||
</App>
|
||||
</Provider>,
|
||||
dest
|
||||
)
|
||||
}
|
||||
|
||||
if (module.hot) {
|
||||
// Support hot reloading of components
|
||||
// and display an overlay for runtime errors
|
||||
const renderApp = render
|
||||
const renderError = (error) => {
|
||||
const RedBox = require('redbox-react')
|
||||
ReactDOM.render(
|
||||
<RedBox error={error} className="redbox"/>,
|
||||
dest
|
||||
)
|
||||
}
|
||||
render = () => {
|
||||
try {
|
||||
renderApp()
|
||||
} catch (error) {
|
||||
renderError(error)
|
||||
}
|
||||
}
|
||||
const rerender = () => {
|
||||
setTimeout(render)
|
||||
}
|
||||
module.hot.accept('./AdapterForm', rerender)
|
||||
module.hot.accept('./Adapter.md', rerender)
|
||||
module.hot.accept('!!raw!./AdapterForm', rerender)
|
||||
module.hot.accept('!!raw!./adapter', rerender)
|
||||
}
|
||||
|
||||
render()
|
||||
@@ -1,45 +0,0 @@
|
||||
var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
devtool: 'eval',
|
||||
entry: [
|
||||
'babel-polyfill',
|
||||
'eventsource-polyfill', // necessary for hot reloading with IE
|
||||
'webpack-hot-middleware/client',
|
||||
'./src/index'
|
||||
],
|
||||
output: {
|
||||
path: path.join(__dirname, 'dist'),
|
||||
filename: 'bundle.js',
|
||||
publicPath: '/dist/'
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin()
|
||||
],
|
||||
resolve: {
|
||||
modulesDirectories: [
|
||||
'src',
|
||||
'node_modules'
|
||||
],
|
||||
extensions: [ '', '.json', '.js' ]
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.jsx?/,
|
||||
loaders: [ 'babel', 'eslint' ],
|
||||
include: path.join(__dirname, 'src')
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
loader: 'json-loader'
|
||||
},
|
||||
{
|
||||
test: /\.md/,
|
||||
loaders: [ "html-loader", "markdown-loader" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
devtool: 'source-map',
|
||||
entry: [
|
||||
'babel-polyfill',
|
||||
'./src/index'
|
||||
],
|
||||
output: {
|
||||
path: path.join(__dirname, 'dist'),
|
||||
filename: 'bundle.js',
|
||||
publicPath: '/dist/'
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify('production')
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compressor: {
|
||||
warnings: false
|
||||
}
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
modulesDirectories: [
|
||||
'src',
|
||||
'node_modules'
|
||||
],
|
||||
extensions: [ '', '.json', '.js' ]
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
loaders: [ 'babel' ],
|
||||
include: path.join(__dirname, 'src')
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
loader: 'json-loader'
|
||||
},
|
||||
{
|
||||
test: /\.md/,
|
||||
loaders: [ "html-loader", "markdown-loader" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -19,8 +19,8 @@ Notice that we define simple functions, like `renderTextField`, `renderCheckbox`
|
||||
`renderSelectField` to form a bridge between `redux-form` and the Material UI input components.
|
||||
You would only need to define these in one place in your application and reuse them in each form.
|
||||
|
||||
In fact, we recommend using an adapter. For Material UI, an adapter has already been made for
|
||||
you: [`redux-form-material-ui`](https://github.com/erikras/redux-form-material-ui).
|
||||
For Material UI, `@erikras` has published a set of wrapper components to use Material UI:
|
||||
[`redux-form-material-ui`](https://github.com/erikras/redux-form-material-ui).
|
||||
|
||||
### How to use async validation in form:
|
||||
|
||||
|
||||
@@ -274,7 +274,6 @@ const createReduxForm =
|
||||
_reduxForm: PropTypes.object.isRequired
|
||||
}
|
||||
Form.propTypes = {
|
||||
adapter: PropTypes.func,
|
||||
destroyOnUnmount: PropTypes.bool,
|
||||
form: PropTypes.string.isRequired,
|
||||
initialValues: PropTypes.object,
|
||||
|
||||
Reference in New Issue
Block a user