Skip to content

Commit 41511b4

Browse files
committed
Pass field meta as the third argument to validators
1 parent f63142c commit 41511b4

File tree

6 files changed

+11
-110
lines changed

6 files changed

+11
-110
lines changed

packages/form-state-manager/src/files/compose-validators.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import ComposeValidators from '../types/compose-validators';
99
* Synchronous validators are run in synchrounously and sync error is prioritized over async errors.
1010
* @returns {Function} New validation function
1111
*/
12-
const composeValidators: ComposeValidators = (validators = []) => (value, allValues) => {
12+
const composeValidators: ComposeValidators = (validators = []) => (value, allValues, meta) => {
1313
const promises: Promise<any>[] = [];
1414
let index = 0;
1515
let error: any;
1616
while (validators.length > 0 && !error && index < validators.length) {
17-
const result = validators[index](value, allValues);
17+
const result = validators[index](value, allValues, meta);
1818
if (isPromise(result)) {
1919
promises.push(result as Promise<any>);
2020
} else {
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Validator } from './validate';
22
import AnyObject from './any-object';
3+
import { Meta } from './use-field';
34

45
export interface WarningObject<T = string | undefined> {
56
type: 'warning';
@@ -8,6 +9,6 @@ export interface WarningObject<T = string | undefined> {
89

910
export type ComposeValidators<T = WarningObject | string | undefined> = (
1011
validators: Validator[]
11-
) => (value: any, allValues: AnyObject) => Promise<T> | T;
12+
) => (value: any, allValues: AnyObject, meta: Meta) => Promise<T> | T;
1213

1314
export default ComposeValidators;
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import AnyObject from './any-object';
22
import { ManagerApi } from './manager-api';
3+
import { Meta } from './use-field';
34

45
export interface FormLevelError {
56
[key: string]: string;
67
}
78

8-
export type Validator = (value: any, allValues: AnyObject) => undefined | string | Promise<string | undefined>;
9+
export type Validator = (value: any, allValues: AnyObject, meta: Meta) => undefined | string | Promise<string | undefined>;
910

1011
export type FormValidator = (allValues: AnyObject) => FormLevelError | Promise<FormLevelError>;
1112

1213
export type FieldLevelValidator = (
1314
validator: Validator,
1415
value: any,
1516
allValues: AnyObject,
16-
managerApi: ManagerApi
17+
managerApi: ManagerApi,
18+
meta: Meta
1719
) => string | undefined | Promise<string | undefined>;
1820

1921
export type FormLevelValidator = (validator: FormValidator, allValues: AnyObject, managerApi: ManagerApi) => FormLevelError | Promise<FormLevelError>;

packages/form-state-manager/src/utils/manager-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ const createManagerApi: CreateManagerApi = ({
334334
.filter((validator) => validator !== undefined);
335335

336336
if (validators.length > 0) {
337-
const result = composeValidators(validators as Validator[])(value, state.values);
337+
const result = composeValidators(validators as Validator[])(value, state.values, { ...state.fieldListeners[name].state.meta });
338338
if (isPromise(result)) {
339339
handleFieldError(name, true, undefined, true);
340340
(result as Promise<string | undefined>)

packages/form-state-manager/src/utils/validate.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { FieldLevelValidator, FormLevelValidator, FormLevelError } from '../type
44
export const isPromise = (obj: AnyObject | PromiseLike<unknown> | string | undefined): boolean =>
55
!!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
66

7-
export const fieldLevelValidator: FieldLevelValidator = (validator, value, allValues, managerApi) => {
8-
const result = validator(value, allValues);
7+
export const fieldLevelValidator: FieldLevelValidator = (validator, value, allValues, managerApi, meta) => {
8+
const result = validator(value, allValues, meta);
99
if (isPromise(result)) {
1010
const asyncResult = result as Promise<string | undefined>;
1111
managerApi().registerAsyncValidator(asyncResult);

packages/react-form-renderer/src/tests/form-renderer/validator.test.js

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -56,106 +56,4 @@ describe('FormRenderer validator', () => {
5656
wrapper.find('input').simulate('change', { target: { value: VALUE } });
5757
});
5858
});
59-
60-
describe('warning validators', () => {
61-
const TextFieldWarning = (props) => {
62-
const { input, meta, ...rest } = useFieldApi(props);
63-
return (
64-
<div>
65-
<input {...input} {...rest} />
66-
{meta.warning && <div id="warning">{meta.warning}</div>}
67-
</div>
68-
);
69-
};
70-
71-
let wrapper;
72-
73-
it('should not convert object validator to warning when warnings are not used', async () => {
74-
await act(async () => {
75-
wrapper = mount(
76-
<FormRenderer
77-
FormTemplate={FormTemplate}
78-
componentMapper={{
79-
[componentTypes.TEXT_FIELD]: TextFieldWarning
80-
}}
81-
schema={{
82-
fields: [{ component: 'text-field', name: NAME, validate: [{ type: 'required', warning: true }] }]
83-
}}
84-
onSubmit={jest.fn()}
85-
/>
86-
);
87-
});
88-
wrapper.update();
89-
90-
expect(wrapper.find('#warning')).toHaveLength(0);
91-
});
92-
93-
it('should convert object validator to warning', async () => {
94-
await act(async () => {
95-
wrapper = mount(
96-
<FormRenderer
97-
FormTemplate={FormTemplate}
98-
componentMapper={{
99-
[componentTypes.TEXT_FIELD]: TextFieldWarning
100-
}}
101-
schema={{
102-
fields: [{ component: 'text-field', name: NAME, validate: [{ type: 'required', warning: true }] }]
103-
}}
104-
onSubmit={jest.fn()}
105-
/>
106-
);
107-
});
108-
wrapper.update();
109-
110-
expect(wrapper.find('#warning').text()).toEqual('Required');
111-
});
112-
113-
it('should convert function validator to warning', async () => {
114-
const ERROR = 'SOME-ERROR';
115-
116-
const customValidator = () => ({ type: 'warning', error: ERROR });
117-
118-
await act(async () => {
119-
wrapper = mount(
120-
<FormRenderer
121-
FormTemplate={FormTemplate}
122-
componentMapper={{
123-
[componentTypes.TEXT_FIELD]: TextFieldWarning
124-
}}
125-
schema={{
126-
fields: [{ component: 'text-field', name: NAME, validate: [customValidator] }]
127-
}}
128-
onSubmit={jest.fn()}
129-
/>
130-
);
131-
});
132-
wrapper.update();
133-
134-
expect(wrapper.find('#warning').text()).toEqual(ERROR);
135-
});
136-
137-
it('should convert async function validator to warning', async () => {
138-
const ERROR = 'SOME-ERROR';
139-
140-
const customValidator = () => new Promise((res, rej) => setTimeout(() => rej({ type: 'warning', error: ERROR })));
141-
142-
await act(async () => {
143-
wrapper = mount(
144-
<FormRenderer
145-
FormTemplate={FormTemplate}
146-
componentMapper={{
147-
[componentTypes.TEXT_FIELD]: TextFieldWarning
148-
}}
149-
schema={{
150-
fields: [{ component: 'text-field', name: NAME, validate: [customValidator] }]
151-
}}
152-
onSubmit={jest.fn()}
153-
/>
154-
);
155-
});
156-
wrapper.update();
157-
158-
expect(wrapper.find('#warning').text()).toEqual(ERROR);
159-
});
160-
});
16159
});

0 commit comments

Comments
 (0)