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
99 lines
2.8 KiB
TypeScript
99 lines
2.8 KiB
TypeScript
import React from 'react';
|
|
import type { FieldValues, Path } from 'react-hook-form';
|
|
import { useController, useFormContext } from 'react-hook-form';
|
|
|
|
import type { FormFieldPropsBase } from './types';
|
|
|
|
import { Field } from '../../../chakra/field';
|
|
import type { InputProps } from '../../../chakra/input';
|
|
import { Input } from '../../../chakra/input';
|
|
import { InputGroup } from '../../../chakra/input-group';
|
|
import type { TextareaProps } from '../../../chakra/textarea';
|
|
import { Textarea } from '../../../chakra/textarea';
|
|
import { getFormFieldErrorText } from '../utils/getFormFieldErrorText';
|
|
|
|
interface Props<
|
|
FormFields extends FieldValues,
|
|
Name extends Path<FormFields> = Path<FormFields>,
|
|
> extends FormFieldPropsBase<FormFields, Name> {
|
|
asComponent?: 'Input' | 'Textarea';
|
|
}
|
|
|
|
const FormFieldTextContent = <
|
|
FormFields extends FieldValues,
|
|
Name extends Path<FormFields> = Path<FormFields>,
|
|
>({
|
|
name,
|
|
placeholder,
|
|
rules,
|
|
onBlur,
|
|
group,
|
|
inputProps,
|
|
asComponent,
|
|
size: sizeProp,
|
|
disabled,
|
|
floating: floatingProp,
|
|
...restProps
|
|
}: Props<FormFields, Name>) => {
|
|
const defaultSize = asComponent === 'Textarea' ? '2xl' : 'lg';
|
|
const size = sizeProp || defaultSize;
|
|
const floating = floatingProp !== undefined ? floatingProp : size === defaultSize;
|
|
|
|
const { control } = useFormContext<FormFields>();
|
|
const { field, fieldState, formState } = useController<FormFields, typeof name>({
|
|
control,
|
|
name,
|
|
rules: { ...rules, required: restProps.required },
|
|
});
|
|
|
|
const handleBlur = React.useCallback(() => {
|
|
field.onBlur();
|
|
onBlur?.();
|
|
}, [ field, onBlur ]);
|
|
|
|
const input = asComponent === 'Textarea' ? (
|
|
<Textarea
|
|
{ ...field }
|
|
autoComplete="off"
|
|
flexGrow={ 1 }
|
|
{ ...inputProps as TextareaProps }
|
|
onBlur={ handleBlur }
|
|
/>
|
|
) : (
|
|
<Input
|
|
{ ...field }
|
|
autoComplete="off"
|
|
// for non-floating field label, we pass placeholder to the input component
|
|
placeholder={ !floating ? placeholder : undefined }
|
|
{ ...inputProps as InputProps }
|
|
onBlur={ handleBlur }
|
|
/>
|
|
);
|
|
|
|
const content = group ? (
|
|
<InputGroup
|
|
{ ...group }
|
|
endElement={ typeof group.endElement === 'function' ? group.endElement({ field }) : group.endElement }
|
|
>
|
|
{ input }
|
|
</InputGroup>
|
|
) : input;
|
|
|
|
return (
|
|
<Field
|
|
// for floating field label, we pass placeholder value to the label
|
|
label={ floating ? placeholder : undefined }
|
|
errorText={ getFormFieldErrorText(fieldState.error) }
|
|
invalid={ Boolean(fieldState.error) }
|
|
disabled={ formState.isSubmitting || disabled }
|
|
size={ size }
|
|
floating={ floating }
|
|
{ ...restProps }
|
|
>
|
|
{ content }
|
|
</Field>
|
|
);
|
|
};
|
|
|
|
export const FormFieldText = React.memo(FormFieldTextContent) as typeof FormFieldTextContent;
|