import * as React from "react" import { IconX } from "@tabler/icons-react" import { Badge } from "@/components/ui/badge" import { Input } from "@/components/ui/input" import { cn } from "@/lib/utils" type MultiValueInputProps = { values: string[] onChange: (values: string[]) => void placeholder?: string disabled?: boolean maxItems?: number addOnBlur?: boolean className?: string inputClassName?: string validate?: (value: string) => string | null format?: (value: string) => string emptyState?: React.ReactNode } export function MultiValueInput({ values, onChange, placeholder, disabled, maxItems, addOnBlur, className, inputClassName, validate, format, emptyState, }: MultiValueInputProps) { const [pending, setPending] = React.useState("") const [error, setError] = React.useState(null) const inputRef = React.useRef(null) const remainingSlots = typeof maxItems === "number" ? Math.max(maxItems - values.length, 0) : undefined const canAdd = remainingSlots === undefined || remainingSlots > 0 const addValue = React.useCallback( (raw: string) => { const trimmed = raw.trim() if (!trimmed) return const formatted = format ? format(trimmed) : trimmed if (values.includes(formatted)) { setPending("") setError(null) return } if (validate) { const validation = validate(formatted) if (validation) { setError(validation) return } } setError(null) onChange([...values, formatted]) setPending("") }, [format, onChange, validate, values] ) const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === "Enter" || event.key === "," || event.key === "Tab") { if (!canAdd) return event.preventDefault() addValue(pending) } if (event.key === "Backspace" && pending.length === 0 && values.length > 0) { onChange(values.slice(0, -1)) setError(null) } } const handleBlur = () => { if (addOnBlur && pending.trim()) { addValue(pending) } } const removeValue = (value: string) => { onChange(values.filter((item) => item !== value)) setError(null) inputRef.current?.focus() } return (
{values.map((value) => ( {value} ))} {canAdd ? ( { setPending(event.target.value) setError(null) }} onKeyDown={handleKeyDown} onBlur={handleBlur} placeholder={values.length === 0 ? placeholder : undefined} disabled={disabled} className={cn( "m-0 h-auto min-w-[8rem] flex-1 border-0 bg-transparent px-0 py-1 text-sm shadow-none focus-visible:ring-0", inputClassName )} /> ) : null}
{error ?

{error}

: null} {!values.length && emptyState ?
{emptyState}
: null} {typeof remainingSlots === "number" ? (
{remainingSlots} item{remainingSlots === 1 ? "" : "s"} restantes
) : null}
) }