Files
prowler/ui/components/ui/custom/custom-input.tsx
T

125 lines
3.3 KiB
TypeScript

"use client";
import { Input } from "@heroui/input";
import { Icon } from "@iconify/react";
import { useState } from "react";
import { Control, FieldPath, FieldValues } from "react-hook-form";
import { FormControl, FormField } from "@/components/ui/form";
interface CustomInputProps<T extends FieldValues> {
control: Control<T>;
name: FieldPath<T>;
label?: string;
labelPlacement?: "inside" | "outside";
variant?: "flat" | "bordered" | "underlined" | "faded";
size?: "sm" | "md" | "lg";
type?: string;
placeholder?: string;
password?: boolean;
confirmPassword?: boolean;
defaultValue?: string;
isReadOnly?: boolean;
isRequired?: boolean;
isDisabled?: boolean;
}
export const CustomInput = <T extends FieldValues>({
control,
name,
type = "text",
label = name,
labelPlacement = "inside",
placeholder,
variant = "bordered",
size = "md",
confirmPassword = false,
password = false,
defaultValue,
isReadOnly = false,
isRequired = true,
isDisabled = false,
}: CustomInputProps<T>) => {
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] =
useState(false);
const inputLabel = confirmPassword
? "Confirm Password"
: password
? "Password"
: label;
const inputPlaceholder = confirmPassword
? "Confirm Password"
: password
? "Password"
: placeholder;
const inputType =
password || confirmPassword
? isPasswordVisible || isConfirmPasswordVisible
? "text"
: "password"
: type;
const inputIsRequired = password || confirmPassword ? true : isRequired;
const toggleVisibility = () => {
if (password) {
setIsPasswordVisible(!isPasswordVisible);
} else if (confirmPassword) {
setIsConfirmPasswordVisible(!isConfirmPasswordVisible);
}
};
const endContent = (password || confirmPassword) && (
<button type="button" onClick={toggleVisibility}>
<Icon
className="text-default-400 pointer-events-none text-2xl"
icon={
(password && isPasswordVisible) ||
(confirmPassword && isConfirmPasswordVisible)
? "solar:eye-closed-linear"
: "solar:eye-bold"
}
/>
</button>
);
return (
<FormField
control={control}
name={name}
render={({ field, fieldState }) => (
<>
<FormControl>
<Input
id={name}
classNames={{
label:
"tracking-tight font-light !text-text-neutral-secondary text-xs z-0!",
input: "text-text-neutral-secondary text-small",
}}
isRequired={inputIsRequired}
label={inputLabel}
labelPlacement={labelPlacement}
placeholder={inputPlaceholder}
type={inputType}
variant={variant}
size={size}
defaultValue={defaultValue}
endContent={endContent}
isDisabled={isDisabled}
isReadOnly={isReadOnly}
isInvalid={!!fieldState.error}
errorMessage={fieldState.error?.message}
{...field}
value={field.value ?? ""}
/>
</FormControl>
</>
)}
/>
);
};