import { useState, KeyboardEvent, useEffect, HTMLAttributes, ReactElement, } from "react"; import { RegisterOptions, useFormContext } from "react-hook-form"; import { isNullOrWhiteSpace } from "../../../util/stringUtil"; export type InternalInputProps = { inputClassName?: string; inputState: "default" | "active" | "error" | "disabled"; id: string; name: string; label: string; disabled?: boolean; registerWhenDisabled?: boolean; iconLeft?: ReactElement; onClickIcon?: () => void; iconRight?: ReactElement; type: React.HTMLInputTypeAttribute; autoComplete?: string; registerOptions?: RegisterOptions; updateFilteredOptions?: (currentInput: string) => void; setAutocompleteListActive?: (isListActive: boolean) => void; handleKeyPressed?: (event: KeyboardEvent) => void; setHasFocus: React.Dispatch>; isActive: boolean; setIsActive: React.Dispatch>; inputMode?: HTMLAttributes["inputMode"]; readonly?: boolean; selectOnFocus?: boolean; }; export default function InternalInput({ inputClassName, inputState, id, name, label, registerWhenDisabled, iconLeft, onClickIcon, iconRight, type, disabled = false, autoComplete, registerOptions, readonly, selectOnFocus, updateFilteredOptions, handleKeyPressed, setAutocompleteListActive, setHasFocus, isActive, setIsActive, inputMode = "text", }: InternalInputProps) { const { register, getValues } = useFormContext(); const inputBaseClassName = "p-0 border-none w-full focus:ring-0 text-neutral-very-dark font-normal text-base peer placeholder-neutral-medium disabled:placeholder-neutral-medium-light disabled:text-neutral-medium-light"; const [floatingClassName, setFloatingClassName] = useState( inputBaseClassName + (isActive ? " pt-5" : "") ); const activateFloat = (useTransition: boolean) => { if (!floatingClassName.includes("pt-5")) { setFloatingClassName( `${floatingClassName}${useTransition ? " transition-all duration-200 ease-in-out" : ""} pt-5` ); setIsActive(true); } if (setAutocompleteListActive !== undefined && useTransition) { setAutocompleteListActive(true); } }; const deactiveFloat = () => { if ( floatingClassName.includes("pt-5") && isNullOrWhiteSpace(getValues(name)) ) { setFloatingClassName(inputBaseClassName); setIsActive(false); } if (setAutocompleteListActive !== undefined) { setAutocompleteListActive(false); } }; useEffect(() => { if (!isNullOrWhiteSpace(getValues(name))) { activateFloat(false); } }, [getValues(name)]); const shouldRegisterInput = registerWhenDisabled || !disabled; const registerReturn = shouldRegisterInput ? register(name, { ...registerOptions, onBlur: (event) => { if (registerOptions?.onBlur) { registerOptions.onBlur(event); } event.preventDefault(); deactiveFloat(); event.target.placeholder = label; setHasFocus(false); }, onChange: (event) => { if (registerOptions?.onChange) { registerOptions.onChange(event); } activateFloat(true); if (updateFilteredOptions !== undefined) { updateFilteredOptions(event.target.value); } }, setValueAs: (value) => { let newValue = value; if (registerOptions?.setValueAs) { newValue = registerOptions.setValueAs(value); } return newValue?.trim() ?? newValue; }, }) : null; return (
{iconLeft}
{ activateFloat(true); event.target.placeholder = ""; setHasFocus(true); if (selectOnFocus) { event.target.select(); } }} onKeyDown={(event) => { if (handleKeyPressed !== undefined) { handleKeyPressed(event); } }} />
{iconRight}
); }