react-formr
Advanced tools
Comparing version 1.2.2 to 1.3.0
@@ -1,4 +0,4 @@ | ||
import React from "react"; | ||
import { FormrProps } from "./Types"; | ||
import React from 'react'; | ||
import { FormrProps } from './Types'; | ||
declare const _default: React.NamedExoticComponent<FormrProps>; | ||
export default _default; |
@@ -12,4 +12,4 @@ var __assign = (this && this.__assign) || function () { | ||
}; | ||
import React, { useRef, useState, useCallback, useEffect } from "react"; | ||
import { validator, fieldBools } from "./utils"; | ||
import React, { useRef, useState, useCallback, useEffect } from 'react'; | ||
import { validator, fieldBools } from './utils'; | ||
var Formr = function (_a) { | ||
@@ -42,7 +42,7 @@ var formFields = _a.formFields, children = _a.children, validation = _a.validation, _b = _a.disbaleAutoFocus, disbaleAutoFocus = _b === void 0 ? false : _b, _c = _a.onChange, onChange = _c === void 0 ? function () { } : _c, _d = _a.onFinishFocus, onFinishFocus = _d === void 0 ? function () { } : _d; | ||
// if validation rules is set | ||
var validation_2 = validator("rules", value, validationObj.rules); | ||
var validation_2 = validator('rules', value, validationObj.rules); | ||
setValid(key, validation_2); | ||
} | ||
else if (validationObj.required) { | ||
var validation_3 = value !== ""; | ||
var validation_3 = value !== ''; | ||
setValid(key, validation_3); | ||
@@ -80,7 +80,7 @@ } | ||
var submissionAllowed = !Object.keys(formFields).some(function (key) { | ||
console.log(valid.current[key]); | ||
// console.log(valid.current[key]); | ||
// reurn true if any nonvalid formfields | ||
if (validation && | ||
validation[key] && | ||
validation[key].hasOwnProperty("required") && | ||
validation[key].hasOwnProperty('required') && | ||
validation[key].required) { | ||
@@ -94,3 +94,3 @@ return valid.current[key] === false; | ||
}); | ||
console.log({ submissionAllowed: submissionAllowed }); | ||
// console.log({ submissionAllowed }); | ||
if (submissionAllowed) { | ||
@@ -118,3 +118,5 @@ callback(values); | ||
for (var idx = cField; idx <= tFields; idx++) { | ||
var focusable = refs.current[Object.keys(formFields).indexOf(key) + (idx - cField) + 1]; | ||
var focusable = refs.current[Object.keys(formFields).indexOf(key) + | ||
(idx - cField) + | ||
1]; | ||
if (focusable) { | ||
@@ -139,3 +141,3 @@ focusable.focus(); | ||
ref: function (ref) { return refsHandler(key, ref); }, | ||
onSubmitEditing: function () { return onSubmitEditingHandler(key); }, | ||
onSubmitEditing: function () { return onSubmitEditingHandler(key); } | ||
}; | ||
@@ -157,3 +159,3 @@ }, [onChangeHandler, onBlurHandler, values, touched, valid, formFields]); | ||
touched: touched, | ||
valid: valid.current, | ||
valid: valid.current | ||
}; | ||
@@ -160,0 +162,0 @@ return children(returnItem); |
import Formr from "./formr"; | ||
import useFormr from './useFormr'; | ||
import * as Types from "./Types"; | ||
export default Formr; | ||
export { Types }; | ||
export { Types, useFormr }; |
import Formr from "./formr"; | ||
import useFormr from './useFormr'; | ||
import * as Types from "./Types"; | ||
export default Formr; | ||
export { Types }; | ||
export { Types, useFormr }; |
{ | ||
"name": "react-formr", | ||
"version": "1.2.2", | ||
"version": "1.3.0", | ||
"description": "Form managing component for React & React Native", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
120
README.md
@@ -0,1 +1,4 @@ | ||
![react-formr](https://github.com/ltsharma/react-formr/blob/master/img/formr-banner.png) | ||
# react-formr | ||
@@ -8,2 +11,3 @@ | ||
Centralised Solution for managing values & validation in react native, the options are unlimited | ||
@@ -19,2 +23,5 @@ | ||
## Detailed blog post | ||
[Easy React Native Form management with react-formr](https://dev.to/ltsharma/easy-react-native-form-management-with-react-formr-47n5) | ||
# Installation | ||
@@ -32,3 +39,3 @@ | ||
```javascript | ||
import Formr from "react-formr"; | ||
import Formr from 'react-formr'; | ||
``` | ||
@@ -40,54 +47,55 @@ | ||
export const App = () => { | ||
return ( | ||
<View> | ||
<Formr | ||
formFields={{ email: "", phone: "" }} | ||
validation={{ | ||
email: { required: true, type: "email" }, | ||
phone: { type: "phone" }, | ||
}}> | ||
{({ | ||
onChangeHandler, | ||
onBlurHandler, | ||
onSubmitEditingHandler, | ||
onSubmitHandler, | ||
inputBinder, | ||
refsHandler, | ||
values, | ||
touched, | ||
valid, | ||
}) => { | ||
<> | ||
<TextInput | ||
style={{ | ||
borderBottomColor: "black", | ||
borderWidth: 1, | ||
width: "100%", | ||
}} | ||
onChangeText={(e) => onChangeHandler("email", e)} | ||
onBlur={() => onBlurHandler("email")} | ||
value={values.email} | ||
ref={(ref) => refsHandler("password", ref)} | ||
/> | ||
{touched.email && !valid.email && <Text>Not valid</Text>} | ||
// Using input binder | ||
<TextInput | ||
style={{ | ||
borderBottomColor: "black", | ||
borderWidth: 1, | ||
width: "100%", | ||
}} | ||
{...inputBinder("phone")} | ||
/> | ||
{touched.phone && !valid.phone && <Text>Not valid</Text>} | ||
<Button | ||
onPress={() => onSubmitHandler(console.log)} | ||
title="Submit" | ||
color="#841584" | ||
/> | ||
</>; | ||
}} | ||
</Formr> | ||
</View> | ||
); | ||
return ( | ||
<View> | ||
<Formr | ||
formFields={{ email: '', phone: '' }} | ||
validation={{ | ||
email: { required: true, type: 'email' }, | ||
phone: { type: 'phone' } | ||
}} | ||
> | ||
{({ | ||
onChangeHandler, | ||
onBlurHandler, | ||
onSubmitEditingHandler, | ||
onSubmitHandler, | ||
inputBinder, | ||
refsHandler, | ||
values, | ||
touched, | ||
valid | ||
}) => { | ||
<> | ||
<TextInput | ||
style={{ | ||
borderBottomColor: 'black', | ||
borderWidth: 1, | ||
width: '100%' | ||
}} | ||
onChangeText={(e) => onChangeHandler('email', e)} | ||
onBlur={() => onBlurHandler('email')} | ||
value={values.email} | ||
ref={(ref) => refsHandler('password', ref)} | ||
/> | ||
{touched.email && !valid.email && ( | ||
<Text>Not valid</Text> | ||
)} | ||
// Using input binder | ||
<TextInput | ||
style={{ | ||
borderBottomColor: 'black', | ||
borderWidth: 1, | ||
width: '100%' | ||
}} | ||
{...inputBinder('phone')} | ||
/> | ||
{touched.phone && !valid.phone && ( | ||
<Text>Not valid</Text> | ||
)} | ||
<Button onPress={() => onSubmitHandler(console.log)} title="Submit" color="#841584" /> | ||
</>; | ||
}} | ||
</Formr> | ||
</View> | ||
); | ||
}; | ||
@@ -125,4 +133,4 @@ ``` | ||
- [ ] To add more validation types | ||
- [ ] To remove validator dependancy | ||
- [ ] Other elements & values support | ||
- [ ] To add more validation types | ||
- [ ] To remove validator dependancy | ||
- [ ] Other elements & values support |
344
src/formr.ts
@@ -1,187 +0,193 @@ | ||
import React, { useRef, useState, useCallback, useEffect } from "react"; | ||
import { validator, fieldBools } from "./utils"; | ||
import React, { useRef, useState, useCallback, useEffect } from 'react'; | ||
import { validator, fieldBools } from './utils'; | ||
import { | ||
BoolObject, | ||
FormValidation, | ||
FormrProps, | ||
FormrFunctions, | ||
StringObject, | ||
InputBinderProps, | ||
} from "./Types"; | ||
BoolObject, | ||
FormValidation, | ||
FormrProps, | ||
FormrFunctions, | ||
StringObject, | ||
InputBinderProps | ||
} from './Types'; | ||
const Formr: React.FC<FormrProps> = ({ | ||
formFields, | ||
children, | ||
validation, | ||
disbaleAutoFocus = false, | ||
onChange = () => {}, | ||
onFinishFocus = () => {}, | ||
formFields, | ||
children, | ||
validation, | ||
disbaleAutoFocus = false, | ||
onChange = () => {}, | ||
onFinishFocus = () => {} | ||
}) => { | ||
// States & refs | ||
const [values, setValues] = useState<StringObject>(formFields); | ||
const [touched, setTouched] = useState<BoolObject>(fieldBools(formFields)); | ||
const valid = useRef<BoolObject>(fieldBools(validation || {})); | ||
const refs = useRef<any>([]); | ||
// States & refs | ||
const [values, setValues] = useState<StringObject>(formFields); | ||
const [touched, setTouched] = useState<BoolObject>(fieldBools(formFields)); | ||
const valid = useRef<BoolObject>(fieldBools(validation || {})); | ||
const refs = useRef<any>([]); | ||
// Additional listener for any change in form fields | ||
useEffect(() => { | ||
onChange(values); | ||
}, [values]); | ||
// Additional listener for any change in form fields | ||
useEffect(() => { | ||
onChange(values); | ||
}, [values]); | ||
// Setting valid helper | ||
const setValid = useCallback( | ||
(key: string, validated: boolean) => { | ||
valid.current = { ...valid.current, [key]: validated }; | ||
}, | ||
[valid] | ||
); | ||
// Setting valid helper | ||
const setValid = useCallback( | ||
(key: string, validated: boolean) => { | ||
valid.current = { ...valid.current, [key]: validated }; | ||
}, | ||
[valid] | ||
); | ||
// run validation & set validation | ||
const fieldValidation = (key: string, value: string) => { | ||
if (validation && validation[key]) { | ||
const validationObj: FormValidation = validation[key]; | ||
// if validation type is set | ||
if (validationObj.type) { | ||
const validation = validator(validationObj.type, value); | ||
setValid(key, validation); | ||
} else if (validationObj.rules) { | ||
// if validation rules is set | ||
const validation = validator("rules", value, validationObj.rules); | ||
setValid(key, validation); | ||
} else if (validationObj.required) { | ||
const validation = value !== ""; | ||
setValid(key, validation); | ||
} else { | ||
// no validation | ||
setValid(key, true); | ||
} | ||
} | ||
}; | ||
// run validation & set validation | ||
const fieldValidation = (key: string, value: string) => { | ||
if (validation && validation[key]) { | ||
const validationObj: FormValidation = validation[key]; | ||
// if validation type is set | ||
if (validationObj.type) { | ||
const validation = validator(validationObj.type, value); | ||
setValid(key, validation); | ||
} else if (validationObj.rules) { | ||
// if validation rules is set | ||
const validation = validator( | ||
'rules', | ||
value, | ||
validationObj.rules | ||
); | ||
setValid(key, validation); | ||
} else if (validationObj.required) { | ||
const validation = value !== ''; | ||
setValid(key, validation); | ||
} else { | ||
// no validation | ||
setValid(key, true); | ||
} | ||
} | ||
}; | ||
// Input change listner | ||
const onChangeHandler = useCallback<FormrFunctions["onChangeHandler"]>( | ||
(key, value) => { | ||
// Set form values | ||
setValues((prev) => ({ ...prev, [key]: value })); | ||
fieldValidation(key, value); | ||
}, | ||
[setValues, values] | ||
); | ||
// Input change listner | ||
const onChangeHandler = useCallback<FormrFunctions['onChangeHandler']>( | ||
(key, value) => { | ||
// Set form values | ||
setValues((prev) => ({ ...prev, [key]: value })); | ||
fieldValidation(key, value); | ||
}, | ||
[setValues, values] | ||
); | ||
// Input Blur listner | ||
const onBlurHandler = useCallback<FormrFunctions["onBlurHandler"]>( | ||
(key) => { | ||
setTouched((prev) => ({ ...prev, [key]: true })); | ||
fieldValidation(key, values[key]); | ||
}, | ||
[setTouched, values] | ||
); | ||
// Input Blur listner | ||
const onBlurHandler = useCallback<FormrFunctions['onBlurHandler']>( | ||
(key) => { | ||
setTouched((prev) => ({ ...prev, [key]: true })); | ||
fieldValidation(key, values[key]); | ||
}, | ||
[setTouched, values] | ||
); | ||
// formSubmit listner | ||
const onSubmitHandler = useCallback<FormrFunctions["onSubmitHandler"]>( | ||
(callback) => { | ||
// run validation | ||
Object.keys(values).forEach((key) => { | ||
fieldValidation(key, values[key]); | ||
}); | ||
const submissionAllowed: boolean = !Object.keys(formFields).some( | ||
(key) => { | ||
console.log(valid.current[key]); | ||
// reurn true if any nonvalid formfields | ||
if ( | ||
validation && | ||
validation[key] && | ||
validation[key].hasOwnProperty("required") && | ||
validation[key].required | ||
) { | ||
return valid.current[key] === false; | ||
} else { | ||
// if no validation or no required fields | ||
// formSubmit listner | ||
const onSubmitHandler = useCallback<FormrFunctions['onSubmitHandler']>( | ||
(callback) => { | ||
// run validation | ||
Object.keys(values).forEach((key) => { | ||
fieldValidation(key, values[key]); | ||
}); | ||
const submissionAllowed: boolean = !Object.keys(formFields).some( | ||
(key) => { | ||
// console.log(valid.current[key]); | ||
// reurn true if any nonvalid formfields | ||
if ( | ||
validation && | ||
validation[key] && | ||
validation[key].hasOwnProperty('required') && | ||
validation[key].required | ||
) { | ||
return valid.current[key] === false; | ||
} else { | ||
// if no validation or no required fields | ||
return false; | ||
} | ||
} | ||
); | ||
// console.log({ submissionAllowed }); | ||
if (submissionAllowed) { | ||
callback(values); | ||
return true; | ||
} else { | ||
// blurr all fields to show error if any | ||
Object.keys(touched).forEach(onBlurHandler); | ||
} | ||
return false; | ||
} | ||
} | ||
); | ||
console.log({ submissionAllowed }); | ||
if (submissionAllowed) { | ||
callback(values); | ||
return true; | ||
} else { | ||
// blurr all fields to show error if any | ||
Object.keys(touched).forEach(onBlurHandler); | ||
} | ||
return false; | ||
}, | ||
[values, touched, valid, onBlurHandler] | ||
); | ||
}, | ||
[values, touched, valid, onBlurHandler] | ||
); | ||
// Mapping ref object to formField keys | ||
const refsHandler = useCallback<FormrFunctions["refsHandler"]>( | ||
(key, ref) => { | ||
refs.current[Object.keys(formFields).indexOf(key)] = ref; | ||
}, | ||
[formFields] | ||
); | ||
// Mapping ref object to formField keys | ||
const refsHandler = useCallback<FormrFunctions['refsHandler']>( | ||
(key, ref) => { | ||
refs.current[Object.keys(formFields).indexOf(key)] = ref; | ||
}, | ||
[formFields] | ||
); | ||
const onSubmitEditingHandler = useCallback< | ||
FormrFunctions["onSubmitEditingHandler"] | ||
>( | ||
(key) => { | ||
if (disbaleAutoFocus) { | ||
return; | ||
} | ||
const cField = Object.keys(formFields).indexOf(key); | ||
const tFields = Object.keys(formFields).length; | ||
if (cField + 1 < tFields) { | ||
for (let idx = cField; idx <= tFields; idx++) { | ||
const focusable = | ||
refs.current[ | ||
Object.keys(formFields).indexOf(key) + (idx - cField) + 1 | ||
]; | ||
if (focusable) { | ||
focusable.focus(); | ||
return; | ||
} | ||
} | ||
onFinishFocus(values); | ||
} else { | ||
onFinishFocus(values); | ||
} | ||
}, | ||
[formFields, onFinishFocus, values] | ||
); | ||
const onSubmitEditingHandler = useCallback< | ||
FormrFunctions['onSubmitEditingHandler'] | ||
>( | ||
(key) => { | ||
if (disbaleAutoFocus) { | ||
return; | ||
} | ||
const cField = Object.keys(formFields).indexOf(key); | ||
const tFields = Object.keys(formFields).length; | ||
if (cField + 1 < tFields) { | ||
for (let idx = cField; idx <= tFields; idx++) { | ||
const focusable = | ||
refs.current[ | ||
Object.keys(formFields).indexOf(key) + | ||
(idx - cField) + | ||
1 | ||
]; | ||
if (focusable) { | ||
focusable.focus(); | ||
return; | ||
} | ||
} | ||
onFinishFocus(values); | ||
} else { | ||
onFinishFocus(values); | ||
} | ||
}, | ||
[formFields, onFinishFocus, values] | ||
); | ||
const inputBinder = useCallback<FormrFunctions["inputBinder"]>( | ||
(key) => { | ||
return { | ||
onChangeText: (text: string) => onChangeHandler(key, text), | ||
onBlur: () => onBlurHandler(key), | ||
value: values[key], | ||
touched: touched[key], | ||
valid: valid.current[key], | ||
ref: (ref: any) => refsHandler(key, ref), | ||
onSubmitEditing: () => onSubmitEditingHandler(key), | ||
}; | ||
}, | ||
[onChangeHandler, onBlurHandler, values, touched, valid, formFields] | ||
); | ||
const outputRefs = { ...formFields }; | ||
Object.keys(formFields).map((val, key) => { | ||
outputRefs[val] = refs.current[key]; | ||
}); | ||
const inputBinder = useCallback<FormrFunctions['inputBinder']>( | ||
(key) => { | ||
return { | ||
onChangeText: (text: string) => onChangeHandler(key, text), | ||
onBlur: () => onBlurHandler(key), | ||
value: values[key], | ||
touched: touched[key], | ||
valid: valid.current[key], | ||
ref: (ref: any) => refsHandler(key, ref), | ||
onSubmitEditing: () => onSubmitEditingHandler(key) | ||
}; | ||
}, | ||
[onChangeHandler, onBlurHandler, values, touched, valid, formFields] | ||
); | ||
const outputRefs = { ...formFields }; | ||
Object.keys(formFields).map((val, key) => { | ||
outputRefs[val] = refs.current[key]; | ||
}); | ||
const returnItem: FormrFunctions = { | ||
onChangeHandler, | ||
onBlurHandler, | ||
onSubmitEditingHandler, | ||
onSubmitHandler, | ||
inputBinder, | ||
refsHandler, | ||
refs: outputRefs, | ||
values, | ||
touched, | ||
valid: valid.current, | ||
}; | ||
return children(returnItem); | ||
const returnItem: FormrFunctions = { | ||
onChangeHandler, | ||
onBlurHandler, | ||
onSubmitEditingHandler, | ||
onSubmitHandler, | ||
inputBinder, | ||
refsHandler, | ||
refs: outputRefs, | ||
values, | ||
touched, | ||
valid: valid.current | ||
}; | ||
return children(returnItem); | ||
}; | ||
export default React.memo(Formr); |
import Formr from "./formr"; | ||
import useFormr from './useFormr' | ||
import * as Types from "./Types"; | ||
export default Formr; | ||
export { Types }; | ||
export { Types, useFormr }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
103542
23
1120
132