Declarative Form components for React, built on top of MobX
Declarative, just like React and HTML
- Support nested objects and arrays
- Easy to create custom Input (or Select, Checkbox, Radio, etc) components
- Easy to push, update or remove array items
- Built-in validations (eg
required
,pattern
,enum
, etc) - Built-in formats (eg
integer
,number
,boolean
, etc) - Support data transformers / filters
- No styles, just the original appearance, but you could add style easily
- No HTTP requests, but you could choose any HTTP request library you like
yarn add react-form-mobx
You may also need to install react
, mobx
and mobx-react
yarn add react mobx mobx-react react-form-mobx
import React, { Component } from 'react';
import { Form, Input, ObjectOf } from 'react-form-mobx';
export default class MyFriend extends Component {
myData = {
name: 'Luke Skywalker',
height: 172,
colors: {
hair: 'blond',
skin: 'fair',
},
},
handleSubmit = (data) => {
console.log('data', data);
};
render() {
return (
<Form value={this.myData} onSubmit={this.handleSubmit}>
<Input name="name" />
<Input name="height" format="number" />
<ObjectOf name="colors">
<Input name="hair" />
<Input name="skin" />
</ObjectOf>
</Form>
);
}
}
import React, { Component } from 'react';
import { Form, Input, ArrayOf } from 'react-form-mobx';
export default class MyFriend extends Component {
myData = {
name: 'Luke Skywalker',
starships: ['X-wing', 'Imperial shuttle'],
},
handleSubmit = (data) => {
console.log('data', data);
};
render() {
return (
<Form value={this.myData} onSubmit={this.handleSubmit}>
<Input name="name" />
<ArrayOf name="starships">
{(starships, { push, removeBy }) =>
<div>
{starships.map((starship) =>
<span key={starship}>
<Input name={starship} />
<button type="button" onClick={removeBy(starship)}>Remove</button>
</span>
)}
<button type="button" onClick={push}>Add Starship</button>
</div>
}
</ArrayOf>
</Form>
);
}
}
MyInput.js
import React, { Component } from "react";
import { Demon } from "react-form-mobx";
export default class MyInput extends Component {
render() {
return (
<Demon forwardedProps={this.props}>
{(props, { isInvalid, errorMessage }) => (
<label>
<input
style={{ borderColor: isInvalid ? "red" : "green" }}
{...props}
/>
{isInvalid && <span style={{ color: "red" }}>{errorMessage}</span>}
</label>
)}
</Demon>
);
}
}
MyApp.js
import React, { Component } from "react";
import { Form } from "react-form-mobx";
import MyInput from "./MyInput";
export default class MyApp extends Component {
render() {
return (
<Form value={this.myData}>
<MyInput name="name" />
{/* ... */}
</Form>
);
}
}
import { Form } from 'react-form-mobx';
Form component, just like HTML form
component.
Property | Description | Type | Default |
---|---|---|---|
value | Form data | Object | {} |
onSubmit | Defines a function will be called when form submit | Function | |
onValid | Defines a function will be called when form is valid | Function | |
onInvalid | Defines a function will be called when form is invalid | Function | |
onValidChange | Defines a function will be called when form valid status changed | Function | |
onChange | Defines a function will be called when form data changed | Function | |
inputFilter | Defines a filter function will be called when providing a new value | Function | |
outputFilter | Defines a filter function will be called when getting output value | Function |
import { Input, Checkbox, Radio, Select, TextArea } from 'react-form-mobx';
These Input Components mean Input
, Checkbox
, Radio
, Select
, TextArea
or other custom input components created by Demon
.
Property | Description | Type | Default |
---|---|---|---|
name | Field name | String Required |
|
defaultValue | Default value when value is empty | Any | |
defaultChecked | Default checked, only work in checkable components (eg: Checkbox , Radio ) |
Boolean | |
format | Data format | "integer", "number", "string", "boolean", "date", "time", "dateTime" | |
required | Indicates whether field is required | Boolean | false |
enum | Validate a value from a list of possible values | Array of String |
[] |
pattern | Validate from a regular expression | RegExp | |
maxLength | Validate a max length of the field | Number | |
minLength | Validate a min length of the field | Number | |
maximum | Validate if the field is less than or exactly equal to "maximum" | Number | |
exclusiveMaximum | Validate if the field is less than (not equal to) "exclusiveMaximum" | Number | |
minimum | Validate if the field is greater than or exactly equal to "minimum" | Number | |
exclusiveMinimum | Validate if the field is greater than or exactly equal to "exclusiveMinimum" | Number | |
validation | Defines a validator function, should throw error if invalid | Function | |
inputFilter | Defines a filter function will be called when providing a new value to form | Function | |
outputFilter | Defines a filter function will be called when getting output value from form | Function | |
withEmpty | Indicates whether submit empty value or not | "auto", true , false |
"auto" |
The rest of the props are exactly the same as the original DOM attributes.
withEmpty
: If value is empty (saying""
,undefined
,null
,{}
or[]
):"auto"
(Default): Will submit empty value only if pristine value is NOT emptytrue
: Will submit empty valuefalse
: Will not submit empty value
import { ObjectOf } from 'react-form-mobx';
ObjectOf
component provides nested fields.
Property | Description | Type | Default |
---|---|---|---|
name | Field name | String Required |
|
children | Nested input nodes | Node Required |
|
onChange | Defines a function will be called when data changed | Function | |
inputFilter | Defines a filter function will be called when providing a new value to form | Function | |
outputFilter | Defines a filter function will be called when getting output value from form | Function |
import { ArrayOf } from 'react-form-mobx';
ArrayOf
component provides array fields, and could be push, update or remove easily.
Property | Description | Type | Default |
---|---|---|---|
name | Field name | String Required |
|
children | Nested input nodes or function child that should return a node | Node or Function Required |
|
onChange | Defines a function will be called when data changed | Function | |
inputFilter | Defines a filter function will be called when providing a new value to form | Function | |
outputFilter | Defines a filter function will be called when getting output value from form | Function |
If children
prop is a callback renderer function, it will provide two arguments:
names
<Array>: An array of unique names that could be used as thekey
andname
props of chidren componentshelper
<Object>: A helper object to manipulate the array:push()
<Function>: To push a new itemremove(name)
<Function>: To remove a item byname
removeBy(name)
<Function>: To create and return aremove(name)
currying function
Please checkout Dynamic Array Items for usage example.
import { Submit, Reset, Clear } from 'react-form-mobx';
Submit
: Just like HTMLbutton
component. Will emitonSubmit()
inForm
when click.Reset
: Just like HTMLbutton
component. Will reset all input values to pristine values inForm
when clickClear
: Just like HTMLbutton
component. Will clear all input values inForm
when click.
Property | Description | Type | Default |
---|---|---|---|
children | children | Node |
The rest of the props are exactly the same as the original DOM attributes.
import { Demon } from 'react-form-mobx';
Demon
component is the core of creating custom input components.
Property | Description | Type | Default |
---|---|---|---|
name | Field name | String Required |
|
children | Function child that should return a node | Function Required |
|
forwardedProps | Forward props, Demon will decide to handle or forward them |
Object | {} |
checkable | Indicates whether the component is checkable | Boolean | false |
getValueFromChangeEvent | Defines a function to get value in onChange arguments |
Function | (ev) => ev.currentTarget.value |
getCheckedFromChangeEvent | Defines a function to get checked in onChange arguments |
Function | (ev) => ev.currentTarget.checked |
getKeyFromKeyPressEvent | Defines a function to get key in onPress arguments |
Function | (ev) => ev.key |
propOnChange | Defines the prop name of change event | String | "onChange" |
propOnKeyPress | Defines the prop name of key press event | String | "onKeyPress" |
propOnBlur | Defines the prop name of blur event | String | "onBlur" |
children
prop provides two arguments:
-
proxyProps
<Object>: Forwarded props object includingvalue
orchecked
, but excludingname
,format
,enum
and other props only work inDemon
component. Can be directly pass to child component (like<input {...proxyProps} />
) -
validState
<Object>: Valid state helper object, including:errorMessage
<String>: Error message. Would be empty if the status is validisValid
<Boolean>: Would be true if the status is validisInvalid
<Boolean>: Would be true if the status is invalidisTouched
<Boolean>: Is touched or not. Useful if you don't want to showerrorMessage
when field is not touched
By default, onChange
, onKeyPress
, onBlur
props will be proxied.
onChange
:Demon
need to get the changedvalue
orchecked
from thechange
event object to update value. You can change the getting function by settinggetValueFromChangeEvent
orgetCheckedFromChangeEvent
prop toDemon
component.onKeyPress
:Demon
need to get thekey
from thekeyPress
event object to decide to submit. You can change the getting function by setttingpropOnKeyPress
prop toDemon
componentonBlur
:Demon
need to listen to theblur
event to setisTouched
totrue
Please checkout Creating Custom Input Component for usage example.
import { DemonButton } from 'react-form-mobx';
DemonButton
component is the core of creating custom button (Submit, Reset or Clear) components.
Property | Description | Type | Default |
---|---|---|---|
children | Function child that should return a node | Function Required |
|
type | Button type | "submit", "reset", "clear" | "submit" |
forwardedProps | Forward props, DemonButton will decide to handle or forward them |
Object | {} |
getKeyFromKeyPressEvent | Defines a function to get key in onPress arguments |
Function | (ev) => ev.key |
propOnKeyPress | Defines the prop name of key press event | String | "onKeyPress" |
children
prop provides one argument:
proxyProps
<Object>: Forwarded props object. Can be directly pass to child component (like<button {...proxyProps} type="button" />
)
MIT