Presupuestador_web/client/src/components/Forms/FormTextField.tsx

92 lines
2.6 KiB
TypeScript
Raw Normal View History

2024-06-06 11:05:54 +00:00
import { cn } from "@/lib/utils";
2024-07-03 15:15:52 +00:00
import { FormControl, FormDescription, FormField, FormItem, Input, InputProps } from "@/ui";
2024-06-06 11:05:54 +00:00
2024-07-16 18:18:17 +00:00
import { cva, type VariantProps } from "class-variance-authority";
2024-06-06 11:05:54 +00:00
import * as React from "react";
2024-07-03 15:15:52 +00:00
import { FieldPath, FieldValues, UseControllerProps, useFormContext } from "react-hook-form";
import { FormErrorMessage } from "./FormErrorMessage";
2024-06-06 11:05:54 +00:00
import { FormLabel, FormLabelProps } from "./FormLabel";
import { FormInputProps, FormInputWithIconProps } from "./FormProps";
2024-07-16 18:18:17 +00:00
const formTextFieldVariants = cva("", {
2024-07-11 16:40:46 +00:00
variants: {
variant: {
default: "",
2024-08-25 12:14:21 +00:00
ghost:
2024-07-11 16:40:46 +00:00
"border-0 focus-visible:border focus-visible:border-input focus-visible:ring-0 focus-visible:ring-offset-0 ",
},
},
defaultVariants: {
variant: "default",
},
});
2024-06-06 11:05:54 +00:00
export type FormTextFieldProps<
TFieldValues extends FieldValues = FieldValues,
2024-06-17 10:42:44 +00:00
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
2024-06-06 11:05:54 +00:00
> = {
2024-06-17 10:42:44 +00:00
button?: (props?: React.PropsWithChildren) => React.ReactNode;
2024-06-06 11:05:54 +00:00
} & InputProps &
FormInputProps &
Partial<FormLabelProps> &
FormInputWithIconProps &
2024-07-16 18:18:17 +00:00
UseControllerProps<TFieldValues, TName> &
VariantProps<typeof formTextFieldVariants>;
2024-06-06 11:05:54 +00:00
2024-07-11 16:40:46 +00:00
export const FormTextField = React.forwardRef<HTMLInputElement, FormTextFieldProps>(
(props, ref) => {
const {
name,
label,
hint,
description,
placeholder,
className,
disabled,
defaultValue,
rules,
2025-04-14 19:12:16 +00:00
required,
2024-07-11 16:40:46 +00:00
type,
variant,
} = props;
2024-06-06 11:05:54 +00:00
2024-07-11 16:40:46 +00:00
const { control } = useFormContext();
2024-06-29 19:39:25 +00:00
2024-07-11 16:40:46 +00:00
return (
<FormField
control={control}
name={name}
disabled={disabled}
2024-08-25 12:14:21 +00:00
rules={{
required,
...rules,
}}
2024-07-11 16:40:46 +00:00
render={({ field, fieldState }) => {
2025-04-14 19:12:16 +00:00
const isRequired = Boolean(rules?.required ?? required);
2024-07-11 16:40:46 +00:00
2025-04-14 19:12:16 +00:00
return (
<FormItem className={cn(className, "space-y-3")}>
{label && <FormLabel label={label} hint={hint} required={isRequired} />}
2024-07-03 15:15:52 +00:00
2025-04-14 19:12:16 +00:00
<FormControl className={"block"}>
<Input
type={type}
placeholder={placeholder}
className={cn(
fieldState.error ? "border-destructive focus-visible:ring-destructive" : "",
formTextFieldVariants({ variant, className })
2024-07-11 16:40:46 +00:00
)}
2025-04-14 19:12:16 +00:00
{...field}
/>
</FormControl>
2024-07-03 15:15:52 +00:00
2024-07-11 16:40:46 +00:00
{description && <FormDescription>{description}</FormDescription>}
<FormErrorMessage />
</FormItem>
);
}}
/>
);
}
);