import { useCallback, useEffect, useState, useRef } from "react"; import clsx from "clsx"; const useInput = ( innerRef: React.RefObject, labelRef?: React.RefObject, value?: string | number | readonly string[], defaultValue?: string | number | readonly string[], onBlur?: (event: React.FocusEvent) => void, onChange?: (event: React.ChangeEvent) => void, counter?: boolean, maxLength?: number, theme?: any, size?: string, className?: string, formWhite?: boolean ) => { const [newValue, setNewValue] = useState(value || defaultValue); const [labelWidth, setLabelWidth] = useState(0); const [active, setActive] = useState(false); const [focus, setFocus] = useState(false); const labelEl = useRef(null); const labelReference = labelRef ? labelRef : labelEl; const inputClasses = clsx( theme.input, active && theme.activeInput, size === "lg" ? theme.inputSizeLg : size === "base" ? theme.inputSizeBase : size === "sm" ? theme.inputSizeSm : theme.inputSizeBase, formWhite ? theme.inputWhite : theme.inputDefault, className ); const labelClasses = clsx( theme.label, active && theme.activeLabel, active && (size === "lg" ? theme.activeLabelSizeLg : size === "base" ? theme.activeLabelSizeBase : size === "sm" ? theme.activeLabelSizeSm : theme.activeLabelSizeBase), size === "lg" ? theme.labelSizeLg : size === "base" ? theme.labelSizeBase : size === "sm" ? theme.labelSizeSm : theme.labelSizeBase, formWhite ? theme.labelWhite : theme.labelDefault ); const notchLeadingClasses = clsx( theme.notchLeading, formWhite ? theme.notchLeadingWhite : theme.notchLeadingDefault, active && theme.activeNotchLeading, focus && theme.focusedNotchLeading, focus && (formWhite ? theme.focusedNotchLeadingWhite : theme.focusedNotchLeadingDefault) ); const notchMiddleClasses = clsx( theme.notchMiddle, formWhite ? theme.notchMiddleWhite : theme.notchMiddleDefault, active && theme.activeNotchMiddle, focus && theme.focusedNotchMiddle, focus && (formWhite ? theme.focusedNotchMiddleWhite : theme.focusedNotchMiddleDefault) ); const notchTrailingClasses = clsx( theme.notchTrailing, formWhite ? theme.notchTrailingWhite : theme.notchTrailingDefault, active && theme.activeNotchTrailing, focus && theme.focusedNotchTrailing, focus && (formWhite ? theme.focusedNotchTrailingWhite : theme.focusedNotchTrailingDefault) ); useEffect(() => { if (!innerRef.current) return; const { value } = innerRef.current; value != "" ? setActive(true) : setActive(false); }, [innerRef.current?.value]); useEffect(() => { if (value === undefined) return; value != "" ? setActive(true) : setActive(false); }, [value]); useEffect(() => { if (defaultValue === undefined) return; defaultValue != "" ? setActive(true) : setActive(false); }, [defaultValue]); const setWidth = useCallback(() => { if (labelReference.current?.clientWidth) { setLabelWidth(labelReference.current.clientWidth * 0.8 + 8); } }, [labelReference]); useEffect(() => { setWidth(); }, [labelReference.current?.clientWidth, setWidth]); const handleChange = (e: any) => { counter ? characterCounter(e) : setNewValue(e.target.value); onChange?.(e); }; const characterCounter = (e: any) => { const inputValue = e.target.value; if (maxLength === undefined || maxLength <= 0) { return; } else if (inputValue.length <= maxLength) { setNewValue(inputValue); } }; const handleBlur = useCallback( (e: any) => { if (!innerRef.current) return; if ( (newValue !== undefined && newValue != "") || (value !== undefined && value != "") || innerRef.current.value != "" ) { setActive(true); } else { setActive(false); } onBlur && onBlur?.(e); }, [newValue, value, onBlur] ); return { labelReference, labelWidth, newValue, setWidth, setFocus, handleChange, handleBlur, inputClasses, labelClasses, notchLeadingClasses, notchMiddleClasses, notchTrailingClasses, }; }; export { useInput };