@henrypap/muiform
v1.1.40
Published
Quick and easy to use form for react, written in JS but hopefully soon converted to TS
Downloads
7
Readme
MuiForm
How it works
It relies heavily on Context to keep the components up to date. This can cause some re-renders unless you take care of that (more about that in "Create-custom-field section").
How to use
You can either use it as it is, or extend and make complex Fields by the HOC (maybe a hook could come later)
Start by importing the Form
, you can also import the Fields you want, for now only Input
and Select
is supported. Include a submit button as well (wrap in div unless you want it streched).
Basic usages
See example below
import Form, { Input, Select } from "muiform";
import MenuItem form "@material-ui/core/MenuItem";
import Button form "@material-ui/core/Button";
export default () => { // form-page
function submit (values) {
console.log('yay', values); // { a: "", b: "" }
}
return (
<Form onSubmit={submit}>
<Input name="a">
<Select name="b">
<MenuItem value="b1">B1</MenuItem>
<MenuItem value="b2">B2</MenuItem>
</Select>
<div>
<Button type="submit">Submit</Button>
</div>
</Form>
);
}
And thats pretty much it
Create custom Field
To create a new custom field you need to wrap it with the HOC "withForm", I like to then wrap it with React.memo and set a equal function to skip unecessary re-renders (there is a isEqual function provided - more about it later).
The props you give to your custom-field will live inside the "prop" of the "props" (sounds more tricky then it is).
withForm takes 2 argument,
- component
- defaultValue // defaults to null (global level defaultValue)
import { withForm, isEqual } from "muiform";
// material-ui imports
import FormHelperText from "@material-ui/core/FormHelperText";
import FormControl from "@material-ui/core/FormControl";
import InputLabel from "@material-ui/core/InputLabel";
// has 2 input fields
const CustomField = withForm(
// note props (these are your props)
React.memo(({ value, error, errorMessage, setValue, props }) => {
const { label, ...rest } = props;
// will have default value
const [customValue, setCustomValue] = React.useState(value);
function handleChange (e) {
const { name, value } = e.target;
const newValue = { ...customValue, [name]: value };
setCustomValue(newValue);
if (newValue.foo && newValue.bar) {
setValue(newValue); // here we actually set the form value
}
}
return (
<FormControl
{...rest}
error={error}
helperText={errorMessage}
>
{label && <InputLabel htmlFor={props.name}>{label}</InputLabel>}
<input type="text" name="foo" value={customValue.foo} onChange={handleChange} />
<input type="text" name="foo" value={customValue.bar} onChange={handleChange} />
{Boolean(errorMessage) && (
<FormHelperText>{errorMessage}</FormHelperText>
)}
</FormControl>
);
}, isEqual) // not the equal method here
, { foo: 'hello', bar: 'world' });
export default CustomField;
Form props
Form props (all other props are passed to html form) | name | value | | onSubmit | function | | onValid | function | | onInvalid | function |
Field Props
The props that we can give the field are the following (and custom props ofc..) | name | value | description | |:-- |:--:|:-- | | value | any | | | hidden | bool | | | required | bool | | | validation | function or RegExp | | | errorMessage | string or ReactNode | | | defaultValue | string or ReactNode or function | overrides the defaultvalue that can be passed to component (when created) |
The props recieved when using HOC
| name | value | description | |:--|:--:| :-- | | value | any | our value | | values | object | we can reference others value thought this object | | setValue | function(value, name) | to set fields value (we can also set another's value if name is provided) | | error | bool | | | errors | object | same as values but with errors | | setError | function(value, name) | works the same as setValue | | errorMessage | string or ReactNode | this is null if no error && isTouched | | isTouched | bool | | | required | bool | | | validation | function or RegExp | in case you want it :shrug: | | defaultValue | any | the default value provided as a second argument for withForm |
isEqual
the isEqual checks if isTouched, error has changed first if not then it checks if value is the same as before (since value could be an array, object or plain) it does shallow checking for the first two
If you have a complex Field that is referencing another field, best would be to make a new equal funciton in order to receive this change.