'use client'; import * as React from 'react'; import { useEffect, useState } from 'react'; import { cn } from '@/lib/utils'; import { X } from 'lucide-react'; import { Button } from '@/components/ui/button'; export interface AutoCompleteInputProps extends React.InputHTMLAttributes { items: { label: string, value: any }[]; next?: React.RefObject; } const AutoCompleteInput = React.forwardRef( ({className, type, ...props}, ref) => { const [value, setValue] = useState(getNameOfPropValue()); const [open, setOpen] = useState(false); const [lastKey, setLastKey] = useState(''); const [filteredItems, setFilteredItems] = useState(props.items); function getNameOfPropValue() { if (!props.items) { return ''; } const item = props.items?.find(item => item.value === props.value); return item?.label || ''; } function handleChange(e: React.ChangeEvent) { props.onChange?.(undefined as any); const value = e.target.value; setFilteredItems(props?.items?.filter((item) => { return item.label.toLowerCase().includes(value.toLowerCase()); })); setValue(value); setOpen(value.length > 0); } useEffect(() => { if (filteredItems.length === 1 && /^[a-zA-Z0-9]$/.test(lastKey)) { setValue(filteredItems[0].label); setOpen(false); props.onChange?.({target: {value: filteredItems[0].value}} as any); props.next && props.next.current?.focus(); } }, [filteredItems]); useEffect(() => { console.log('Prop value changed', value, props.value); if (props.value) { setValue(getNameOfPropValue()); } else { setValue(''); } }, [props.value]); return (
{ if (e.metaKey || e.ctrlKey || e.altKey) { props.onKeyDown?.(e); return; } setLastKey(e.key); props.onKeyDown?.(e); }} /> { value.length > 0 && ( ) } { open && (
{filteredItems?.map((item) =>
{ props.onChange?.({target: {value: item.value}} as any); props.next && props.next.current?.focus(); setValue(item.label); setOpen(false); }} key={item.value}> {item.label}
, )}
) }
); }, ); AutoCompleteInput.displayName = 'Input'; export { AutoCompleteInput };