-
Notifications
You must be signed in to change notification settings - Fork 103
Expand file tree
/
Copy pathuseFormFieldValidators.ts
More file actions
35 lines (30 loc) · 1.25 KB
/
useFormFieldValidators.ts
File metadata and controls
35 lines (30 loc) · 1.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { useMemo, useRef } from 'react';
import useSWRImmutable from 'swr/immutable';
import { getRegisteredValidator } from '../registry/registry';
import { type FormField, type FormFieldValidator } from '../types';
export function useFormFieldValidators(fields: FormField[]) {
const validatorTypesKey = useMemo(() => {
const uniqueTypes = new Set<string>();
fields.forEach((field) => {
field.validators?.forEach((validator) => uniqueTypes.add(validator.type));
});
return Array.from(uniqueTypes).sort().join(',');
}, [fields]);
const validatorsRef = useRef<Record<string, FormFieldValidator>>({});
const { data: validators } = useSWRImmutable(
validatorTypesKey ? ['formFieldValidators', validatorTypesKey] : null,
async ([, key]) => {
const types = key.split(',');
const loadedValidators = await Promise.all(types.map((type) => getRegisteredValidator(type)));
const validatorsByType: Record<string, FormFieldValidator> = {};
types.forEach((type, index) => {
validatorsByType[type] = loadedValidators[index];
});
return validatorsByType;
},
);
if (validators && validators !== validatorsRef.current) {
validatorsRef.current = validators;
}
return validatorsRef.current;
}