Presupuestador_web/client/src/components/Forms/FormTextField.tsx
2025-04-14 21:12:16 +02:00

92 lines
2.6 KiB
TypeScript

import { cn } from "@/lib/utils";
import { FormControl, FormDescription, FormField, FormItem, Input, InputProps } from "@/ui";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { FieldPath, FieldValues, UseControllerProps, useFormContext } from "react-hook-form";
import { FormErrorMessage } from "./FormErrorMessage";
import { FormLabel, FormLabelProps } from "./FormLabel";
import { FormInputProps, FormInputWithIconProps } from "./FormProps";
const formTextFieldVariants = cva("", {
variants: {
variant: {
default: "",
ghost:
"border-0 focus-visible:border focus-visible:border-input focus-visible:ring-0 focus-visible:ring-offset-0 ",
},
},
defaultVariants: {
variant: "default",
},
});
export type FormTextFieldProps<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> = {
button?: (props?: React.PropsWithChildren) => React.ReactNode;
} & InputProps &
FormInputProps &
Partial<FormLabelProps> &
FormInputWithIconProps &
UseControllerProps<TFieldValues, TName> &
VariantProps<typeof formTextFieldVariants>;
export const FormTextField = React.forwardRef<HTMLInputElement, FormTextFieldProps>(
(props, ref) => {
const {
name,
label,
hint,
description,
placeholder,
className,
disabled,
defaultValue,
rules,
required,
type,
variant,
} = props;
const { control } = useFormContext();
return (
<FormField
control={control}
name={name}
disabled={disabled}
rules={{
required,
...rules,
}}
render={({ field, fieldState }) => {
const isRequired = Boolean(rules?.required ?? required);
return (
<FormItem className={cn(className, "space-y-3")}>
{label && <FormLabel label={label} hint={hint} required={isRequired} />}
<FormControl className={"block"}>
<Input
type={type}
placeholder={placeholder}
className={cn(
fieldState.error ? "border-destructive focus-visible:ring-destructive" : "",
formTextFieldVariants({ variant, className })
)}
{...field}
/>
</FormControl>
{description && <FormDescription>{description}</FormDescription>}
<FormErrorMessage />
</FormItem>
);
}}
/>
);
}
);