"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 (
{props.iconSrc && (
)}
{props.icon && (
{props.icon}
)}
);
});