update prettier
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-02-23 14:23:46 +01:00
parent 33d1425fbb
commit cbabf43584
25 changed files with 1373 additions and 1363 deletions

View File

@@ -4,168 +4,172 @@ type FieldErrors<TValues> = Partial<Record<keyof TValues, string | undefined>>;
type TouchedFields<TValues> = Partial<Record<keyof TValues, boolean>>;
type SetValuesOptions = {
validate?: boolean;
clearErrors?: boolean;
validate?: boolean;
clearErrors?: boolean;
};
type SetFieldValueOptions = {
validate?: boolean;
touch?: boolean;
validate?: boolean;
touch?: boolean;
};
type ValidateAllOptions = {
touchAll?: boolean;
touchAll?: boolean;
};
type UseValidatedFieldsOptions<TValues> = {
initialValues: TValues;
validate: (values: TValues) => FieldErrors<TValues>;
initialValues: TValues;
validate: (values: TValues) => FieldErrors<TValues>;
};
function hasErrors<TValues>(errors: FieldErrors<TValues>): boolean {
return Object.values(errors).some(Boolean);
return Object.values(errors).some(Boolean);
}
function pickTouchedErrors<TValues>(
errors: FieldErrors<TValues>,
touched: TouchedFields<TValues>,
errors: FieldErrors<TValues>,
touched: TouchedFields<TValues>,
): FieldErrors<TValues> {
const next: FieldErrors<TValues> = {};
const next: FieldErrors<TValues> = {};
for (const key of Object.keys(errors) as Array<keyof TValues>) {
if (touched[key]) {
next[key] = errors[key];
for (const key of Object.keys(errors) as Array<keyof TValues>) {
if (touched[key]) {
next[key] = errors[key];
}
}
}
return next;
return next;
}
function touchAll<TValues extends Record<string, string>>(values: TValues): TouchedFields<TValues> {
const touched: TouchedFields<TValues> = {};
const touched: TouchedFields<TValues> = {};
for (const key of Object.keys(values) as Array<keyof TValues>) {
touched[key] = true;
}
for (const key of Object.keys(values) as Array<keyof TValues>) {
touched[key] = true;
}
return touched;
return touched;
}
export function useValidatedFields<TValues extends Record<string, string>>({
initialValues,
validate,
initialValues,
validate,
}: UseValidatedFieldsOptions<TValues>) {
const [values, setValues] = useState<TValues>(initialValues);
const [allErrors, setAllErrors] = useState<FieldErrors<TValues>>(() => validate(initialValues));
const [touched, setTouched] = useState<TouchedFields<TValues>>({});
const [values, setValues] = useState<TValues>(initialValues);
const [allErrors, setAllErrors] = useState<FieldErrors<TValues>>(() => validate(initialValues));
const [touched, setTouched] = useState<TouchedFields<TValues>>({});
const updateValues = useCallback(
(nextValues: TValues, options: SetValuesOptions = {}) => {
const { validate: shouldValidate = false, clearErrors = false } = options;
setValues(nextValues);
const updateValues = useCallback(
(nextValues: TValues, options: SetValuesOptions = {}) => {
const { validate: shouldValidate = false, clearErrors = false } = options;
setValues(nextValues);
if (shouldValidate || clearErrors) {
setAllErrors(validate(nextValues));
}
if (shouldValidate || clearErrors) {
setAllErrors(validate(nextValues));
}
if (clearErrors) {
setTouched({});
}
},
[validate],
);
if (clearErrors) {
setTouched({});
}
},
[validate],
);
const setFieldValue = useCallback(
<K extends keyof TValues>(key: K, value: TValues[K], options: SetFieldValueOptions = {}) => {
const { validate: shouldValidate = true, touch = true } = options;
const setFieldValue = useCallback(
<K extends keyof TValues>(
key: K,
value: TValues[K],
options: SetFieldValueOptions = {},
) => {
const { validate: shouldValidate = true, touch = true } = options;
if (touch) {
if (touch) {
setTouched((current) => ({
...current,
[key]: true,
}));
}
setValues((current) => {
const nextValues = {
...current,
[key]: value,
};
if (shouldValidate) {
setAllErrors(validate(nextValues));
}
return nextValues;
});
},
[validate],
);
const validateAll = useCallback(
(options: ValidateAllOptions = {}) => {
const { touchAll: shouldTouchAll = true } = options;
const nextErrors = validate(values);
setAllErrors(nextErrors);
if (shouldTouchAll) {
setTouched(touchAll(values));
}
return nextErrors;
},
[validate, values],
);
const setFieldError = useCallback(<K extends keyof TValues>(key: K, message?: string) => {
setTouched((current) => ({
...current,
[key]: true,
...current,
[key]: true,
}));
}
setValues((current) => {
const nextValues = {
...current,
[key]: value,
};
setAllErrors((current) => ({
...current,
[key]: message,
}));
}, []);
if (shouldValidate) {
setAllErrors(validate(nextValues));
const updateErrors = useCallback((nextErrors: FieldErrors<TValues>) => {
const nextTouched: TouchedFields<TValues> = {};
for (const key of Object.keys(nextErrors) as Array<keyof TValues>) {
if (nextErrors[key]) {
nextTouched[key] = true;
}
}
return nextValues;
});
},
[validate],
);
setTouched((current) => ({
...current,
...nextTouched,
}));
setAllErrors(nextErrors);
}, []);
const validateAll = useCallback(
(options: ValidateAllOptions = {}) => {
const { touchAll: shouldTouchAll = true } = options;
const nextErrors = validate(values);
const clearErrors = useCallback(() => {
setAllErrors(validate(values));
setTouched({});
}, [validate, values]);
setAllErrors(nextErrors);
const errors = useMemo(() => pickTouchedErrors(allErrors, touched), [allErrors, touched]);
if (shouldTouchAll) {
setTouched(touchAll(values));
}
const isValid = useMemo(() => {
return !hasErrors(validate(values));
}, [validate, values]);
return nextErrors;
},
[validate, values],
);
const setFieldError = useCallback(<K extends keyof TValues>(key: K, message?: string) => {
setTouched((current) => ({
...current,
[key]: true,
}));
setAllErrors((current) => ({
...current,
[key]: message,
}));
}, []);
const updateErrors = useCallback((nextErrors: FieldErrors<TValues>) => {
const nextTouched: TouchedFields<TValues> = {};
for (const key of Object.keys(nextErrors) as Array<keyof TValues>) {
if (nextErrors[key]) {
nextTouched[key] = true;
}
}
setTouched((current) => ({
...current,
...nextTouched,
}));
setAllErrors(nextErrors);
}, []);
const clearErrors = useCallback(() => {
setAllErrors(validate(values));
setTouched({});
}, [validate, values]);
const errors = useMemo(() => pickTouchedErrors(allErrors, touched), [allErrors, touched]);
const isValid = useMemo(() => {
return !hasErrors(validate(values));
}, [validate, values]);
return {
values,
errors,
isValid,
setValues: updateValues,
setFieldValue,
validateAll,
setFieldError,
setErrors: updateErrors,
clearErrors,
};
return {
values,
errors,
isValid,
setValues: updateValues,
setFieldValue,
validateAll,
setFieldError,
setErrors: updateErrors,
clearErrors,
};
}