mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
* first version of the pack * single entry point * add custom components to the package * move form components to toolkit * add more utils and hooks to the package * minor fixes * add CI workflow * update readme and package.json * fix ts * fix build of env-validator * fix docker build * fix icons size * test fixes * more test fixes
96 lines
2.3 KiB
TypeScript
96 lines
2.3 KiB
TypeScript
import React from 'react';
|
|
import type { FieldValues, Path } from 'react-hook-form';
|
|
import { useFormContext, useWatch } from 'react-hook-form';
|
|
|
|
import { urlValidator } from '../../validators/url';
|
|
|
|
interface Params<
|
|
FormFields extends FieldValues,
|
|
Name extends Path<FormFields>,
|
|
> {
|
|
name: Name;
|
|
isRequired?: boolean;
|
|
}
|
|
|
|
interface ReturnType {
|
|
input: {
|
|
rules: {
|
|
required?: boolean;
|
|
validate: {
|
|
preview: () => string | true;
|
|
};
|
|
};
|
|
isRequired?: boolean;
|
|
onBlur: () => void;
|
|
};
|
|
preview: {
|
|
src: string | undefined;
|
|
isInvalid: boolean;
|
|
onLoad: () => void;
|
|
onError: () => void;
|
|
};
|
|
}
|
|
|
|
export function useImageField<
|
|
FormFields extends FieldValues,
|
|
Name extends Path<FormFields>,
|
|
>({
|
|
name,
|
|
isRequired,
|
|
}: Params<FormFields, Name>): ReturnType {
|
|
const { trigger, formState, control } = useFormContext<FormFields>();
|
|
|
|
const imageLoadError = React.useRef(false);
|
|
const fieldValue = useWatch({ name, control, exact: true });
|
|
const fieldError = formState.errors[name];
|
|
|
|
const [ value, setValue ] = React.useState<string | undefined>(fieldValue);
|
|
|
|
const validator = React.useCallback(() => {
|
|
return imageLoadError.current ? 'Unable to load image' : true;
|
|
}, []);
|
|
|
|
const onLoad = React.useCallback(() => {
|
|
imageLoadError.current = false;
|
|
trigger(name);
|
|
}, [ name, trigger ]);
|
|
|
|
const onError = React.useCallback(() => {
|
|
imageLoadError.current = true;
|
|
trigger(name);
|
|
}, [ name, trigger ]);
|
|
|
|
const onBlur = React.useCallback(() => {
|
|
if (!isRequired && !fieldValue) {
|
|
imageLoadError.current = false;
|
|
trigger(name);
|
|
setValue(undefined);
|
|
return;
|
|
}
|
|
|
|
const isValidUrl = urlValidator(fieldValue);
|
|
isValidUrl === true && setValue(fieldValue);
|
|
}, [ fieldValue, isRequired, name, trigger ]);
|
|
|
|
return React.useMemo(() => {
|
|
return {
|
|
input: {
|
|
isRequired,
|
|
rules: {
|
|
required: isRequired,
|
|
validate: {
|
|
preview: validator,
|
|
},
|
|
},
|
|
onBlur,
|
|
},
|
|
preview: {
|
|
src: fieldError?.type === 'url' ? undefined : value,
|
|
isInvalid: fieldError?.type === 'preview',
|
|
onLoad,
|
|
onError,
|
|
},
|
|
};
|
|
}, [ fieldError?.type, isRequired, onBlur, onError, onLoad, validator, value ]);
|
|
}
|