├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── README.md ├── _config.yml ├── package.json ├── pages └── contact-us.md ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── App.css ├── App.test.tsx ├── App.tsx ├── index.css ├── index.tsx ├── logo.svg ├── react-app-env.d.ts ├── reportWebVitals.ts └── setupTests.ts ├── tsconfig.json └── yarn.lock /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Form validation 2 | 3 | Form validation solution for react JS, super easy to use and can handel all the major user cases. 4 | ##### Based on the React hooks and reactive programing. 5 | #### No extra dependencies pure react js code & lightweight. 6 | 7 | ## Features 8 | 1. Easy validations solution for react js pure react js no extra dependency. 9 | 2. Regex validations. 10 | 3. Custom validations. 11 | 4. Email validations. 12 | 5. Many useful form helping methods i.e hasError, hasChanges, isTouched, getValues, getErrors. 13 | 6. Easy to configure. 14 | 7. Nested form fields validations. 15 | 8. Dynamic add/remove fields. 16 | 17 | ## Installation 18 | ```sh 19 | npm install @surinderlohat/react-form-validation 20 | or 21 | yarn add @surinderlohat/react-form-validation 22 | ``` 23 | ## API Documentation 24 | https://surinderlohat.github.io/react-form-validation/ 25 | 26 | ### Form Helping Methods 27 | #### Note: all methods are available like: form.onSubmit() 28 | 29 | | Method | PARAMS| DESCRIPTION | 30 | | ------ | ------ |------ | 31 | | resetToDefault |No | Reset form state to default All fields will be reset to the default state | 32 | | getField | fieldKey i.e name or user.name if nested field | Return the specific field instance | 33 | | getChangedFields | No | Return fields with initial value and changed value | 34 | | clearForm | No | Clear form values and all nested child's | 35 | | onSubmit | No | Return from values and error state | 36 | 37 | 38 | ### Form Getters 39 | | Name | RETURN Type | RETURN VALUE | 40 | | ------ | ------ |------ | 41 | | getValues | object | Return form values in same order we have pass | 42 | | getErrors | object | Display all errors for each nested field | 43 | | hasChanges | boolean | Return true if any field has changes | 44 | 45 | 46 | ### Field Methods 47 | | Method | TYPE | RETURN VALUE | 48 | | ------ | ------ | ------ | 49 | | hasChanges | Getter | Return field state i.e it's changed or not | 50 | | hasError | Getter | Return error state of the specific field | 51 | | isTouched | Getter | if field is touched or not 52 | | errorMessage| Getter| Return error message for current field from | 53 | | setValue | Function | Set value of specific field | 54 | | getValue | Function | Get value of specific field | 55 | | setRules | (newRules: Rules) | Update field rules on the fly | 56 | | setError | Function | Set custom error message on specific field | 57 | | showErrors | Function | Show error without touching the fields | 58 | ### Rules 59 | ``` sh 60 | Rules 61 | /* Used to identify which rule we are going to use for a field*/ 62 | rule: 'min' | 'max' | 'required' | 'same' | 'email' | 'regex' | 'custom' | 'between' | 'range'; 63 | /* Rule value used to provide value in rule i.e for min:2 max:10 rule value ruleValue will be ruleValue:2 or 5 64 | ruleValue?: any; 65 | /* Used to provide custom message for each rule */ 66 | message?: string; 67 | /* For special cases if we need custom validation then this method will help */ 68 | validation?: (field: IField, form?: ReactForm) => string; 69 | ``` 70 | 71 | ## How to use 72 | ```sh 73 | import { IFieldObject, useReactForm } from '@surinderlohat/react-form-validation'; 74 | import FormField from '../FormField/FormField'; 75 | import { Box, Typography, Button, Paper } from '@mui/material'; 76 | import { FC } from 'react'; 77 | 78 | // Fields Rules 79 | const field: IFieldObject = { 80 | name: { 81 | label: 'User Name', 82 | placeholder: 'Enter your Name', 83 | rules: [{ rule: 'required' }], 84 | }, 85 | email: { 86 | label: 'Email', 87 | placeholder: 'Enter your email', 88 | rules: [{ rule: 'email', message: 'Email is not valid' }], 89 | }, 90 | password: { 91 | label: 'Password', 92 | rules: [{ rule: 'required', message: 'This field is required' }], 93 | }, 94 | confirmPassword: { 95 | label: 'Confirm Password', 96 | rules: [{ rule: 'required' }, { rule: 'same', ruleValue: 'password', message: 'Should be same as Password' }], 97 | }, 98 | }; 99 | 100 | const BasicExample: FC = () => { 101 | const form = useReactForm(field); 102 | return ( 103 | 104 | 105 | Basic Signup Validations 106 | {Object.keys(field).map(key => ( 107 | 108 | ))} 109 | 112 | Has Changes: {`${form.hasChanges}`} 113 | Has hasError: {`${form.hasError}`} 114 | 117 | 118 | 119 | ); 120 | }; 121 | 122 | export default BasicExample; 123 | 124 | ``` 125 | 126 | ## Live working Examples 127 | https://codesandbox.io/examples/package/@surinderlohat/react-form-validation 128 | 129 | Like this package ? show some love by start this repo 130 | 131 | For more packages like this please checkout: https://github.com/surinderlohat 132 | 133 | ## License 134 | MIT **Free Software!** 135 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lohat-from-validation", 3 | "version": "0.1.1", 4 | "private": true, 5 | "homepage": "http://surinderlohat.github.io/lohat-from-validation", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.11.4", 8 | "@testing-library/react": "^11.1.0", 9 | "@testing-library/user-event": "^12.1.10", 10 | "@types/jest": "^26.0.15", 11 | "@types/node": "^12.0.0", 12 | "@types/react": "^17.0.0", 13 | "@types/react-dom": "^17.0.0", 14 | "gh-pages": "^3.2.3", 15 | "react": "^17.0.2", 16 | "react-dom": "^17.0.2", 17 | "react-scripts": "4.0.3", 18 | "typescript": "^4.1.2", 19 | "web-vitals": "^1.0.1" 20 | }, 21 | "scripts": { 22 | "start": "react-scripts start", 23 | "build": "react-scripts build", 24 | "test": "react-scripts test", 25 | "eject": "react-scripts eject", 26 | "predeploy": "npm run build", 27 | "deploy": "gh-pages -d build" 28 | }, 29 | "eslintConfig": { 30 | "extends": [ 31 | "react-app", 32 | "react-app/jest" 33 | ] 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.2%", 38 | "not dead", 39 | "not op_mini all" 40 | ], 41 | "development": [ 42 | "last 1 chrome version", 43 | "last 1 firefox version", 44 | "last 1 safari version" 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /pages/contact-us.md: -------------------------------------------------------------------------------- 1 | # Lohat Form validation Contact Us 2 | 3 | Lohat Form validation is a tool for easy form validations based on the react hooks and reactive programing. 4 | 5 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surinderlohat/react-form-validation/a78dad56b6727d51b18dc0fb1ae4caf2458a2619/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surinderlohat/react-form-validation/a78dad56b6727d51b18dc0fb1ae4caf2458a2619/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surinderlohat/react-form-validation/a78dad56b6727d51b18dc0fb1ae4caf2458a2619/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | render(); 7 | const linkElement = screen.getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | 5 | function App() { 6 | return ( 7 |
8 |
9 | logo 10 |

11 | Edit src/App.tsx and save to reload. 12 |

13 | 19 | Learn React 20 | 21 |
22 |
23 | ); 24 | } 25 | 26 | export default App; 27 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | --------------------------------------------------------------------------------