"use client" import type { DefaultHTMLStyleProps, Style } from "@/core/types/common"; import type { ChangeEvent, FocusEventHandler, ForwardedRef, MouseEvent, MutableRefObject, ReactNode } 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; 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; } 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 {Readonly} ref - reference object. * @return {JSX.Element} - ReactNode element. * @constructor */ function TextInput( props: Readonly, ref: ForwardedRef ): JSX.Element { const inputRef = useRef(null); const [focused, setFocused] = useState(false); const sizes: Record = { default: 32, medium: 40, } const onChange = useCallback((value: string) => props.onChange && props.onChange(value), [props.onChange]); const onInputText = useCallback((e: ChangeEvent) => { let inputValue = e.target.value; onChange(inputValue); }, [onChange]); const focusHandler: FocusEventHandler = useCallback((event) => { setFocused(true); }, []); const blurHandler: FocusEventHandler = useCallback((event) => { setFocused(false); }, []); const clear = useCallback(() => { onChange(""); setFocused(false); props.onClear && props.onClear(); if (inputRef.current) inputRef.current.blur(); }, [onChange]); 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 MutableRefObject).current = inputRef.current } } }, [ref]); return (
{"close"} {props.iconSrc && ( {"close"} )} {props.icon && (
{props.icon}
)}
); })