import React, { useState, useRef, useEffect, KeyboardEvent, ReactNode, RefObject, Ref, forwardRef, useImperativeHandle } from "react"; import clsx from "clsx"; import HintTooltip from "../tooltips/HintTooltip"; import EntityIcon from "../../layouts/icons/EntityIcon"; //import { RowValueMultipleDto } from "~/application/dtos/entities/RowValueMultipleDto"; import { SeparatorFormatType } from "../../../utils/shared/SeparatorUtils"; import { useApp } from "../../../hooks"; type RowValueMultipleDto = any; export interface RefInputMultiText { input: RefObject; } interface Props { name?: string; title?: string; withLabel?: boolean; value?: RowValueMultipleDto[]; className?: string; classNameBg?: string; minLength?: number; maxLength?: number; readOnly?: boolean; disabled?: boolean; required?: boolean; autoComplete?: string; translationParams?: string[]; placeholder?: string; pattern?: string; rows?: number; button?: ReactNode; lowercase?: boolean; uppercase?: boolean; darkMode?: boolean; hint?: ReactNode; help?: string; icon?: string; onBlur?: () => void; borderless?: boolean; autoFocus?: boolean; separator?: SeparatorFormatType; } const InputMultiText = ( { name, title, withLabel = true, value, className, classNameBg, help, disabled = false, readOnly = false, required = false, minLength, maxLength, autoComplete, placeholder, pattern, hint, rows, button, lowercase, uppercase, darkMode, icon, onBlur, borderless, autoFocus, separator = ",", }: Props, ref: Ref ) => { const { t } = useApp(); useImperativeHandle(ref, () => ({ input })); const input = useRef(null); const [inputValue, setInputValue] = useState(""); const [actualValue, setActualValue] = useState<(string | number)[]>([]); useEffect(() => { const selection = value?.map((f) => f.value) ?? []; if (selection.sort().join(",") !== actualValue.sort().join(",")) { setActualValue(selection); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [value]); const handleKeyDown = (e: KeyboardEvent) => { if (separator === e.key) { e.preventDefault(); if (inputValue.trim() !== "") { setActualValue?.((prevTags) => [...prevTags, inputValue.trim()]); setInputValue(""); } } if (e.key === "Backspace" && inputValue === "") { setActualValue?.((prevTags) => prevTags.slice(0, prevTags.length - 1)); } }; const removeTag = (index: number) => { setActualValue?.((prevTags) => prevTags.filter((_, i) => i !== index)); }; return (
{withLabel && ( )} {actualValue.map((item, idx) => { return ( ); })}
{icon && (
)}
{actualValue?.map((tag, index) => (
{tag} {!disabled && !readOnly && ( )}
))} {!disabled && !readOnly && ( { if (lowercase) { setInputValue(e.target.value.toLowerCase()); } else if (uppercase) { setInputValue(e.target.value.toUpperCase()); } else { setInputValue(e.target.value); } }} onKeyDown={handleKeyDown} //@ts-ignore placeholder={placeholder ?? t("shared.typeAndPressTo", [separator, t("shared.add").toLowerCase()])} id={name} autoComplete={autoComplete} // required={required} minLength={minLength} maxLength={maxLength} // defaultValue={value} onBlur={() => { if (inputValue.trim() !== "") { setActualValue?.((prevTags) => [...prevTags, inputValue.trim()]); setInputValue(""); } if (onBlur) { onBlur(); } }} disabled={disabled} readOnly={readOnly} pattern={pattern !== "" && pattern !== undefined ? pattern : undefined} autoFocus={autoFocus} className={clsx( "block w-full min-w-0 flex-1 rounded-md border-gray-300 focus:border-accent-500 focus:ring-accent-500 sm:text-sm", className, classNameBg, disabled || readOnly ? "cursor-not-allowed bg-gray-100" : "hover:bg-gray-50 focus:bg-gray-50", icon && "pl-10", borderless && "border-transparent" )} /> )}
{button}
); }; export default forwardRef(InputMultiText);