"use client" import type { DefaultHTMLStyleProps, Style } from "@/core/types/common"; import type { FocusEventHandler, ForwardedRef, MouseEvent, RefObject, ReactNode, ChangeEventHandler } from "react"; import { forwardRef, useCallback, useEffect, useRef, useState } from "react"; import SearchIcon from "@/core/components/Icons/SearchIcon"; import Image from "next/image"; type TextInputSize = "default" | "medium"; interface TextInputProps extends DefaultHTMLStyleProps, Style { value: string; name?: string; form?: string; placeholder?: string; onChange?: (value: string) => void; onClick?: (event: MouseEvent) => void; onClear?: () => void; search?: boolean; inputClassName?: string; size?: TextInputSize; icon?: ReactNode; iconSize?: { width: number, height: number, }; iconSrc?: string; disabled?: boolean; required?: boolean; } export default forwardRef( /** * Shared `TextInput` component to handling the user's **Input** data.\ * The text input component provides _**extended functionality**_ beside the custom styles.\ * The `ref` props supported as well with `ForwardRef` interface. * @param onClear * @param onChange * @param required * @param {Readonly} ref - reference object. * @return {ReactNode} - ReactNode element. * @constructor */ function TextInput( { onClear, onChange, required, ...props }: Readonly, ref: ForwardedRef ): ReactNode { const inputRef = useRef(null); const [focused, setFocused] = useState(false); const sizes: Record = { default: 32, medium: 40, } const onChangeHandler = useCallback( (value: string) => onChange && onChange(value), [onChange] ); const onInputText: ChangeEventHandler = useCallback( ({ target: { value } }) => onChangeHandler(value), [onChangeHandler] ); const focusHandler: FocusEventHandler = useCallback( (event) => setFocused(true), [] ); const blurHandler: FocusEventHandler = useCallback( (event) => setFocused(false), [] ); const clear = useCallback( () => { onChangeHandler(""); setFocused(false); onClear && onClear(); if (inputRef.current) inputRef.current.blur(); }, [onChangeHandler, onClear] ); useEffect(() => { /** * ForwardRef object initialization by the internal component's Ref object. * This is minor extending the reference functionality by existing internal properties. */ if (ref) { if (typeof ref === "function") { ref(inputRef.current); } else { (ref as RefObject).current = inputRef.current } } }, [ref]); return (
{"close"} {props.iconSrc && ( {"close"} )} {props.icon && (
{props.icon}
)}
); });