@coxy/react-validator 1.3.4 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.eslintignore +1 -1
  2. package/.eslintrc.js +25 -8
  3. package/CHANGELOG.md +6 -0
  4. package/README.md +15 -15
  5. package/babel.config.js +3 -0
  6. package/dist/context.d.ts +5 -0
  7. package/dist/context.js +5 -0
  8. package/dist/index.d.ts +5 -0
  9. package/dist/index.js +13 -0
  10. package/dist/rules.d.ts +38 -0
  11. package/dist/rules.js +43 -0
  12. package/dist/use-validator.d.ts +3 -0
  13. package/dist/use-validator.js +22 -0
  14. package/dist/validator-field.d.ts +25 -0
  15. package/dist/validator-field.js +33 -0
  16. package/dist/validator-wrapper.d.ts +17 -0
  17. package/dist/validator-wrapper.js +42 -0
  18. package/dist/validator.d.ts +28 -0
  19. package/dist/validator.js +72 -0
  20. package/example/example.jsx +29 -26
  21. package/example/index.html +2 -0
  22. package/example/webpack.config.js +15 -7
  23. package/jest.config.ts +10 -0
  24. package/package.json +34 -27
  25. package/src/context.test.ts +7 -0
  26. package/src/context.ts +6 -0
  27. package/src/index.test.ts +7 -0
  28. package/src/index.ts +5 -0
  29. package/src/jest.d.ts +1 -0
  30. package/src/rules.test.ts +127 -0
  31. package/src/{rules.js → rules.ts} +26 -15
  32. package/src/use-validator.test.tsx +58 -0
  33. package/src/use-validator.ts +10 -0
  34. package/src/validator-field.test.tsx +161 -0
  35. package/src/validator-field.tsx +71 -0
  36. package/src/validator-wrapper.test.tsx +138 -0
  37. package/src/validator-wrapper.tsx +58 -0
  38. package/src/validator.test.tsx +30 -0
  39. package/src/validator.ts +105 -0
  40. package/tsconfig.build.json +12 -0
  41. package/tsconfig.json +39 -0
  42. package/.babelrc.js +0 -14
  43. package/build/index.js +0 -1
  44. package/jest.config.js +0 -5
  45. package/src/context.js +0 -3
  46. package/src/context.test.js +0 -13
  47. package/src/index.js +0 -13
  48. package/src/index.test.js +0 -13
  49. package/src/rules.test.js +0 -134
  50. package/src/use-validator.js +0 -8
  51. package/src/use-validator.test.js +0 -56
  52. package/src/validator-field.jsx +0 -72
  53. package/src/validator-field.test.js +0 -190
  54. package/src/validator-wrapper.jsx +0 -63
  55. package/src/validator-wrapper.test.js +0 -177
  56. package/src/validator.js +0 -82
  57. package/src/validator.test.js +0 -40
  58. package/webpack.config.js +0 -32
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@coxy/react-validator",
3
- "version": "1.3.4",
3
+ "version": "2.0.2",
4
4
  "description": "🚀 Simple validation form for React or NodeJS apps. useValidator are included ;)",
5
- "main": "./build/index.js",
5
+ "main": "./dist/index.js",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/dsshard/react-validator.git"
@@ -19,40 +19,47 @@
19
19
  ],
20
20
  "author": "dsshard",
21
21
  "scripts": {
22
- "start": "NODE_ENV=development && webpack-cli --watch --mode development",
23
- "build": "NODE_ENV=production && webpack-cli --mode production",
24
- "example": "webpack -w -d --config example/webpack.config.js",
22
+ "start": "ts-node . --watch",
23
+ "build": "NODE_ENV=production tsc --project tsconfig.build.json",
24
+ "example": "webpack-cli -w --config ./example/webpack.config.js",
25
25
  "coverage": "codecov",
26
26
  "coveralls": "coveralls .",
27
27
  "test": "jest"
28
28
  },
29
29
  "license": "MIT",
30
30
  "peerDependencies": {
31
- "react": ">=16.9.x",
32
- "prop-types": ">=15.5.x"
31
+ "react": ">=18.x.x"
33
32
  },
34
33
  "dependencies": {
35
- "prop-types": ">=15.5.x",
36
- "react": ">=16.9.x"
34
+ "react": ">=18.x.x"
37
35
  },
38
36
  "devDependencies": {
39
- "@babel/core": "7.14.6",
40
- "@babel/preset-env": "7.14.7",
41
- "@babel/preset-react": "7.14.5",
42
- "babel-eslint": "10.1.0",
43
- "babel-loader": "8.2.2",
44
- "babel-plugin-transform-react-remove-prop-types": "0.4.24",
45
- "codecov": "3.8.2",
46
- "coveralls": "3.1.1",
47
- "eslint": "7.30.0",
48
- "eslint-config-airbnb": "18.2.1",
49
- "eslint-plugin-import": "2.23.4",
50
- "eslint-plugin-jsx-a11y": "6.4.1",
51
- "eslint-plugin-react": "7.24.0",
52
- "jest": "27.0.6",
53
- "react-dom": "16.9.0",
54
- "react-test-renderer": "17.0.2",
55
- "webpack": "5.42.0",
56
- "webpack-cli": "4.7.2"
37
+ "@babel/core": "^7.18.6",
38
+ "@babel/preset-env": "^7.18.6",
39
+ "@babel/preset-react": "^7.18.6",
40
+ "@testing-library/react": "^13.3.0",
41
+ "@types/jest": "^28.1.4",
42
+ "@types/react": "^18.0.15",
43
+ "@typescript-eslint/eslint-plugin": "^5.30.6",
44
+ "@typescript-eslint/parser": "^5.30.6",
45
+ "babel-loader": "^8.2.5",
46
+ "codecov": "^3.8.3",
47
+ "coveralls": "^3.1.1",
48
+ "eslint": "7.32.0",
49
+ "eslint-config-standard": "^16.0.3",
50
+ "eslint-plugin-import": "^2.26.0",
51
+ "eslint-plugin-jsx-a11y": "^6.6.0",
52
+ "eslint-plugin-node": "^11.1.0",
53
+ "eslint-plugin-promise": "^6.0.0",
54
+ "eslint-plugin-react": "^7.30.1",
55
+ "jest": "^28.1.2",
56
+ "jest-environment-jsdom": "^28.1.2",
57
+ "react-dom": "^18.2.0",
58
+ "react-test-renderer": "^18.2.0",
59
+ "ts-jest": "^28.0.5",
60
+ "ts-node": "^10.8.2",
61
+ "typescript": "^4.7.4",
62
+ "webpack": "^5.73.0",
63
+ "webpack-cli": "^4.10.0"
57
64
  }
58
65
  }
@@ -0,0 +1,7 @@
1
+ import { Context } from './context'
2
+
3
+ it('renders with or without a name', () => {
4
+ expect(typeof Context).toBe('object')
5
+ expect(typeof Context.Consumer).toBe('object')
6
+ expect(typeof Context.Provider).toBe('object')
7
+ })
package/src/context.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { createContext } from 'react'
2
+
3
+ export const Context = createContext<{
4
+ registerField:(field: string | number) => void,
5
+ unregisterField:(field: string | number) => void
6
+ }>(null)
@@ -0,0 +1,7 @@
1
+ import { ValidatorWrapper, ValidatorField, rules } from './index'
2
+
3
+ it('renders with or without a name', () => {
4
+ expect(typeof ValidatorWrapper).toBe('function')
5
+ expect(typeof ValidatorField).toBe('function')
6
+ expect(typeof rules).toBe('object')
7
+ })
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { rules } from './rules'
2
+ export { ValidatorField } from './validator-field'
3
+ export { ValidatorWrapper } from './validator-wrapper'
4
+ export { Validator } from './validator'
5
+ export { useValidator } from './use-validator'
package/src/jest.d.ts ADDED
@@ -0,0 +1 @@
1
+ declare let shallow: any
@@ -0,0 +1,127 @@
1
+ import { rules } from './rules'
2
+
3
+ it('check rule email', () => {
4
+ expect(rules.email.length).toBe(2)
5
+
6
+ let result
7
+ // email.length > 0
8
+ result = rules.email[0].rule('test')
9
+ expect(result).toBe(true)
10
+
11
+ // email check regexp
12
+ result = rules.email[1].rule('test')
13
+ expect(result).toBe(false)
14
+
15
+ // email check regexp
16
+ result = rules.email[1].rule('test@gmail.com')
17
+ expect(result).toBe(true)
18
+ })
19
+
20
+ it('check rule password', () => {
21
+ expect(rules.password.length).toBe(2)
22
+
23
+ let result
24
+ // password.length > 0
25
+ result = rules.password[0].rule('test')
26
+ expect(result).toBe(true)
27
+
28
+ // password.length > 5
29
+ result = rules.password[1].rule('test')
30
+ expect(result).toBe(false)
31
+ })
32
+
33
+ it('check rule bool', () => {
34
+ expect(rules.bool.length).toBe(1)
35
+
36
+ const result = rules.bool[0].rule(true)
37
+ expect(result).toBe(true)
38
+ })
39
+
40
+ it('check rule notEmpty', () => {
41
+ expect(rules.notEmpty.length).toBe(1)
42
+
43
+ let result
44
+ result = rules.notEmpty[0].rule('')
45
+ expect(result).toBe(false)
46
+
47
+ result = rules.notEmpty[0].rule('test')
48
+ expect(result).toBe(true)
49
+ })
50
+
51
+ it('check rule min', () => {
52
+ expect(rules.min(1).length).toBe(1)
53
+ expect(typeof rules.min).toBe('function')
54
+
55
+ let result
56
+ result = rules.min(10)[0].rule('')
57
+ expect(result).toBe(false)
58
+
59
+ result = rules.min(9)[0].rule('testtesttest')
60
+ expect(result).toBe(false)
61
+
62
+ result = rules.min(9)[0].rule('11')
63
+ expect(result).toBe(true)
64
+
65
+ result = rules.min(9)[0].rule(10)
66
+ expect(result).toBe(true)
67
+
68
+ result = rules.min(9)[0].rule('8')
69
+ expect(result).toBe(false)
70
+
71
+ result = rules.min(9)[0].rule(7)
72
+ expect(result).toBe(false)
73
+
74
+ result = rules.min(-1)[0].rule('')
75
+ expect(result).toBe(false)
76
+ })
77
+
78
+ it('check rule max', () => {
79
+ let result
80
+ result = rules.max(10)[0].rule('')
81
+ expect(result).toBe(false)
82
+
83
+ result = rules.max(9)[0].rule('testtesttest')
84
+ expect(result).toBe(false)
85
+
86
+ result = rules.max(9)[0].rule('11')
87
+ expect(result).toBe(false)
88
+
89
+ result = rules.max(9)[0].rule(10)
90
+ expect(result).toBe(false)
91
+
92
+ result = rules.max(9)[0].rule('5')
93
+ expect(result).toBe(true)
94
+
95
+ result = rules.max(9)[0].rule(5)
96
+ expect(result).toBe(true)
97
+
98
+ result = rules.max(-1)[0].rule('')
99
+ expect(result).toBe(false)
100
+ })
101
+
102
+ it('check rule length', () => {
103
+ let result
104
+ result = rules.length(1)[0].rule('')
105
+ expect(result).toBe(false)
106
+
107
+ result = rules.length(1)[0].rule('1')
108
+ expect(result).toBe(true)
109
+
110
+ result = rules.length(1, 10)[0].rule('testtesttest')
111
+ expect(result).toBe(true)
112
+
113
+ result = rules.length(1, 10)[1].rule('testtesttest')
114
+ expect(result).toBe(false)
115
+
116
+ result = rules.length(1, 10)[0].rule('lol')
117
+ expect(result).toBe(true)
118
+
119
+ result = rules.length(1, 10)[1].rule('lol')
120
+ expect(result).toBe(true)
121
+
122
+ result = rules.length(1)[1].rule('test undefined 2 param')
123
+ expect(result).toBe(true)
124
+
125
+ result = rules.length(10)[0].rule('tes')
126
+ expect(result).toBe(false)
127
+ })
@@ -1,48 +1,59 @@
1
+ import { Value } from './validator-field'
2
+
1
3
  // eslint-disable-next-line
2
- const emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
4
+ const emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
5
+
6
+ type Fn = (value: Value) => string
7
+
8
+ export interface RuleInstance {
9
+ rule: (value: Value) => boolean
10
+ message: string | Fn
11
+ }
3
12
 
4
- export default {
13
+ export type ValidatorRules = RuleInstance[]
14
+
15
+ export const rules = {
5
16
  notEmpty: [{
6
17
  rule: (value) => value !== '' && value.length > 0,
7
- message: 'Value is required',
18
+ message: 'Value is required'
8
19
  }],
9
20
 
10
21
  bool: [{
11
22
  rule: (value) => !!value,
12
- message: 'Value is required',
23
+ message: 'Value is required'
13
24
  }],
14
25
 
15
26
  password: [{
16
27
  rule: (value) => value.length > 0,
17
- message: 'Password field cannot be empty',
28
+ message: 'Password field cannot be empty'
18
29
  }, {
19
30
  rule: (value) => value.length > 5,
20
- message: 'Password field can not be less than 6 characters',
31
+ message: 'Password field can not be less than 6 characters'
21
32
  }],
22
33
 
23
34
  email: [{
24
35
  rule: (value) => !!value && value !== '' && value.length !== 0,
25
- message: 'Email is required',
36
+ message: 'Email is required'
26
37
  }, {
27
38
  rule: (value) => emailReg.test(String(value).toLowerCase()),
28
- message: 'Email is invalid',
39
+ message: 'Email is invalid'
29
40
  }],
30
41
 
31
42
  min: (min) => [{
32
43
  rule: (value) => parseFloat(value) > min,
33
- message: `The value must be greater than ${min}`,
44
+ message: `The value must be greater than ${min}`
34
45
  }],
35
46
 
36
47
  max: (max) => [{
37
48
  rule: (value) => parseFloat(value) < max,
38
- message: `The value must be smaller ${max}`,
49
+ message: `The value must be smaller ${max}`
39
50
  }],
40
51
 
41
- length: (min, max) => [{
52
+ length: (min, max?) => [{
42
53
  rule: (value) => String(value).length >= min,
43
- message: `No less than ${min} symbols`,
54
+ message: `No less than ${min} symbols`
44
55
  }, {
45
56
  rule: (value) => (max !== undefined ? String(value).length <= max : true),
46
- message: `No more than ${max} symbols`,
47
- }],
48
- };
57
+ message: `No more than ${max} symbols`
58
+ }]
59
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { unmountComponentAtNode } from 'react-dom'
6
+ import { render, screen } from '@testing-library/react'
7
+ import { act } from 'react-dom/test-utils'
8
+ import { useEffect, useState } from 'react'
9
+
10
+ import { rules } from './rules'
11
+ import { useValidator } from './use-validator'
12
+
13
+ let container
14
+ beforeEach(() => {
15
+ container = document.createElement('div')
16
+ document.body.appendChild(container)
17
+ })
18
+
19
+ afterEach(() => {
20
+ unmountComponentAtNode(container)
21
+ container.remove()
22
+ container = null
23
+ })
24
+
25
+ jest.useFakeTimers()
26
+
27
+ it('check state change and hide field', () => {
28
+ function Comp () {
29
+ const [value, setValue] = useState(false)
30
+ const [isValid, validateObject] = useValidator(value, rules.bool)
31
+
32
+ useEffect(() => {
33
+ setTimeout(() => {
34
+ act(() => {
35
+ setValue(true)
36
+ })
37
+ }, 100)
38
+ }, [])
39
+
40
+ return (
41
+ <>
42
+ <span data-testid="test1">{isValid ? 'true' : 'false'}</span>
43
+ <span data-testid="test2">{validateObject.message || 'true'}</span>
44
+ </>
45
+ )
46
+ }
47
+ act(() => {
48
+ render(<Comp />)
49
+ })
50
+
51
+ expect(screen.getByTestId('test1').textContent).toContain('false')
52
+ expect(screen.getByTestId('test2').textContent).toContain('Value is required')
53
+
54
+ jest.runAllTimers()
55
+
56
+ expect(screen.getByTestId('test1').textContent).toContain('true')
57
+ expect(screen.getByTestId('test2').textContent).toContain('true')
58
+ })
@@ -0,0 +1,10 @@
1
+ import { Validator } from './validator'
2
+ import { ValidatorRules } from './rules'
3
+ import { Validity, Value } from './validator-field'
4
+
5
+ export function useValidator (value: Value, rules: ValidatorRules): [boolean, Pick<Validity, 'message' | 'errors'>] {
6
+ const validator = new Validator()
7
+ validator.addField({ value, rules })
8
+ const { isValid, ...validateObject } = validator.validate()
9
+ return [isValid, validateObject]
10
+ }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { createRef, useEffect, useState } from 'react'
6
+ import { render, act } from '@testing-library/react'
7
+
8
+ import { ValidatorWrapper } from './validator-wrapper'
9
+ import { ValidatorField } from './validator-field'
10
+ import { rules } from './rules'
11
+
12
+ it('render without wrapper', () => {
13
+ expect(() => shallow(<ValidatorField />)).toThrowError()
14
+ })
15
+
16
+ it('normal render', () => {
17
+ render((
18
+ <ValidatorWrapper>
19
+ <ValidatorField rules={[]} value="" />
20
+ </ValidatorWrapper>
21
+ ))
22
+ })
23
+
24
+ it('check context validator', () => {
25
+ const validator = createRef<ValidatorWrapper>()
26
+ render((
27
+ <ValidatorWrapper ref={validator}>
28
+ <ValidatorField rules={[]} />
29
+ </ValidatorWrapper>
30
+ ))
31
+
32
+ const validateResult = validator.current.validate()
33
+
34
+ expect(validateResult.isValid).toBe(true)
35
+ expect(validateResult.message).toBe('')
36
+ })
37
+
38
+ it('check failed validation', () => {
39
+ const validator1 = createRef<ValidatorWrapper>()
40
+ const validator2 = createRef<ValidatorWrapper>()
41
+
42
+ render((
43
+ <>
44
+ <ValidatorWrapper ref={validator1}>
45
+ <ValidatorField rules={rules.email} value="test" />
46
+ </ValidatorWrapper>
47
+ <ValidatorWrapper ref={validator2}>
48
+ <ValidatorField rules={rules.email} value="" />
49
+ </ValidatorWrapper>
50
+ </>
51
+ ))
52
+
53
+ act(() => {
54
+ const validateResult1 = validator1.current.validate()
55
+
56
+ expect(validateResult1.isValid).toBe(false)
57
+ expect(validateResult1.message).toBe('Email is invalid')
58
+ expect(validateResult1.errors.length).toBe(1)
59
+
60
+ const validateResult2 = validator2.current.validate()
61
+
62
+ expect(validateResult2.isValid).toBe(false)
63
+ expect(validateResult2.message).toBe('Email is required')
64
+ expect(validateResult2.errors.length).toBe(1)
65
+ })
66
+ })
67
+
68
+ jest.useFakeTimers()
69
+
70
+ it('check state change and hide field', () => {
71
+ const validator1 = createRef<ValidatorWrapper>()
72
+
73
+ function Comp () {
74
+ const [st, setSt] = useState(true)
75
+
76
+ useEffect(() => {
77
+ setTimeout(() => {
78
+ act(() => {
79
+ setSt(false)
80
+ })
81
+ }, 100)
82
+ }, [])
83
+
84
+ return (
85
+ <ValidatorWrapper ref={validator1}>
86
+ <ValidatorField rules={rules.email} value="test" />
87
+ {st && (
88
+ <ValidatorField rules={rules.email} value="" />
89
+ )}
90
+ </ValidatorWrapper>
91
+ )
92
+ }
93
+
94
+ render(<Comp />)
95
+
96
+ jest.runAllTimers()
97
+
98
+ const validateResult1 = validator1.current.validate()
99
+
100
+ expect(validateResult1.isValid).toBe(false)
101
+ expect(validateResult1.message).toBe('Email is invalid')
102
+ expect(validateResult1.errors.length).toBe(1)
103
+ })
104
+
105
+ it('check success validation', () => {
106
+ const validator = createRef<ValidatorWrapper>()
107
+ render((
108
+ <ValidatorWrapper ref={validator}>
109
+ <ValidatorField rules={rules.email} value="email@email.com" />
110
+ </ValidatorWrapper>
111
+ ))
112
+
113
+ const validateResult = validator.current.validate()
114
+
115
+ expect(validateResult.isValid).toBe(true)
116
+ expect(validateResult.message).toBe('')
117
+ })
118
+
119
+ it('check success validation fot child function', () => {
120
+ const validator = createRef<ValidatorWrapper>()
121
+ render((
122
+ <ValidatorWrapper ref={validator}>
123
+ <ValidatorField rules={rules.email} value="email@email.com">
124
+ {({ isValid, message }) => (
125
+ <>
126
+ {!isValid && <div>{message}</div>}
127
+ </>
128
+ )}
129
+ </ValidatorField>
130
+ </ValidatorWrapper>
131
+ ))
132
+
133
+ const validateResult = validator.current.validate()
134
+
135
+ expect(validateResult.isValid).toBe(true)
136
+ expect(validateResult.message).toBe('')
137
+ })
138
+
139
+ it('check custom rule message function', () => {
140
+ const validator = createRef<ValidatorWrapper>()
141
+ const rule = [{
142
+ rule: (value) => value !== 'test',
143
+ message: (value) => `test message ${value}`
144
+ }]
145
+ render((
146
+ <ValidatorWrapper ref={validator}>
147
+ <ValidatorField rules={rule} value="test">
148
+ {({ isValid, message }) => (
149
+ <>
150
+ {!isValid && <div>{message}</div>}
151
+ </>
152
+ )}
153
+ </ValidatorField>
154
+ </ValidatorWrapper>
155
+ ))
156
+
157
+ const validateResult = validator.current.validate()
158
+
159
+ expect(validateResult.isValid).toBe(false)
160
+ expect(validateResult.message).toBe('test message test')
161
+ })
@@ -0,0 +1,71 @@
1
+ import { Component, ReactNode } from 'react'
2
+
3
+ import { Context } from './context'
4
+ import { Field } from './validator'
5
+ import { ValidatorRules } from './rules'
6
+
7
+ export type Value = any
8
+
9
+ export interface ErrorMessage {
10
+ message: string
11
+ isValid: boolean
12
+ }
13
+
14
+ export interface Validity {
15
+ message: string
16
+ isValid: boolean
17
+ errors?: ErrorMessage[]
18
+ id?: string | number
19
+ }
20
+
21
+ type Fn = (validity: Validity, value: Value) => ReactNode
22
+
23
+ interface Props {
24
+ rules?: ValidatorRules,
25
+ required?: boolean,
26
+ value?: Value
27
+ id?: string | number
28
+ children?: ReactNode | Fn
29
+ unregisterField: (val: any) => void
30
+ registerField: (val: any) => void
31
+ }
32
+
33
+ class ValidationFieldWrapper extends Component<Props> {
34
+ componentWillUnmount () {
35
+ this.props.unregisterField(this)
36
+ }
37
+
38
+ componentDidMount () {
39
+ this.props.registerField(this)
40
+ }
41
+
42
+ validate (): Validity {
43
+ const field = new Field({
44
+ rules: this.props.rules,
45
+ required: this.props.required,
46
+ value: this.props.value,
47
+ id: this.props.id
48
+ })
49
+ return field.validate()
50
+ }
51
+
52
+ render () {
53
+ const { children, value } = this.props
54
+ const validity = this.validate()
55
+ return (typeof children === 'function' ? children(validity, value) : children)
56
+ }
57
+ }
58
+
59
+ export function ValidatorField (props: Omit<Props, 'registerField' | 'unregisterField'>) {
60
+ return (
61
+ <Context.Consumer>
62
+ {(data) => (
63
+ <ValidationFieldWrapper
64
+ {...props}
65
+ registerField={data.registerField}
66
+ unregisterField={data.unregisterField}
67
+ />
68
+ )}
69
+ </Context.Consumer>
70
+ )
71
+ }