Untitled
unknown
plain_text
a year ago
6.4 kB
4
Indexable
function Autocomplete(props: AutocompleteProps) { const [input, setInput] = useState<string>(''); const [isSelected, setIsSelected] = useState<boolean>(false); const [invalid, setInvalid] = useState<boolean>(true); const filteredData = useMemo( () => { const matchedData = props.filterFields?.length > 0 ? props.options?.filter((val: any) => { for (const field of props.filterFields) { if ( val[field] .toLowerCase() .includes( typeof input === 'string' ? input.toLowerCase() : input[field].toLowerCase() ) ) { return true; } } return false; }) : props.options?.filter((val: any) => { return val.toLowerCase().includes(input.toLowerCase()); }); return matchedData; }, props.maps ? [props.options] : [input] ); const [selectedValue, setSelectedValue] = useState<string>(); const handleListSelect = (option: any) => { setSelectedValue( textContent( <div className="flex w-full items-center justify-start gap-3 overflow-hidden text-xs text-black"> <span className="font-light capitalize "> {props.displayFields ? props.displayFields.map((field: string) => `${option[field]} `) : option} </span> </div> ) ); setInput(option); setInvalid(false); }; function textContent(elem: React.JSX.Element): string { if (!elem) { return ''; } if (typeof elem === 'string') { return elem; } const children = elem.props && elem.props.children; if (children instanceof Array) { return children.map(textContent).join(''); } return textContent(children); } const chooseData = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => { setInput(e.currentTarget.textContent || ''); setIsSelected(true); }; const messages = props.validationObjects || []; return ( <div className="flex flex-col"> <LabelText invalid={invalid} isClicked={props.isClicked} required={props.required} label={props.label} > {props.label} </LabelText> <div className={`relative flex size-full flex-col truncate rounded-3xl bg-bgColor shadow-inner duration-200 ${ props.isClicked && invalid ? 'border border-red' : '' }`} > {props.IconOne && ( <span className="absolute left-6 top-3 flex items-center justify-center pb-1"> {props.IconOne} </span> )} <input className={`${props.IconOne ? 'pl-14' : 'pl-6'} flex h-12 w-full justify-center rounded-full bg-transparent px-6 py-2 font-text text-sm font-light outline-none duration-300 ease-in-out md:text-base`} value={selectedValue} defaultValue={props.defaultValue} required={props.required} placeholder={ props.value && Object.keys(props.value).length !== 0 ? '' : props.placeholder } onChange={(e) => { setInput(e.target.value); setIsSelected(false); setInvalid(true); setSelectedValue(undefined); if (props.handleChange) props.handleChange(e.target.value); }} /> <input type="hidden" name={props.name} value={typeof input === 'object' ? JSON.stringify(input) : input} /> {!isSelected && ( <div className={`flex flex-col justify-start duration-300 ${ props.IconOne ? 'px-10' : 'px-2' } divide-y divide-gray-400/30 overflow-auto ${ input?.length > 0 ? 'max-h-52' : 'max-h-0' }`} > {filteredData?.length > 0 ? ( filteredData?.map((option, idx) => ( <div className={`flex w-full items-center justify-start gap-20 px-4 py-5 hover:bg-bgColorHover ${ input?.length === 0 ? 'h-0 p-0 opacity-0' : 'h-8 py-1' } cursor-pointer duration-200`} key={idx} onClick={(e) => { chooseData(e); handleListSelect(option); }} > {props.displayFields ? ( <div className="flex w-full items-center justify-start gap-3 overflow-hidden text-xs text-black"> <span className="font-light capitalize "> {props.displayFields.map((field: string) => `${option[field]} `)} </span> </div> ) : ( <div className="flex w-full items-center justify-start gap-3 overflow-hidden text-xs text-black"> <span className="font-light capitalize">{option}</span> </div> )} </div> )) ) : ( <div className="relative flex flex-col items-center justify-center whitespace-normal py-4"> <span className={`${ props.HandleNoMatch ? '' : 'w-full' } flex items-center justify-start gap-20 px-4 py-5 text-inputLabelAccent ${ input?.length === 0 ? 'h-0 p-0 opacity-0' : 'h-11 py-4' } cursor-pointer duration-200`} > Sorry, there is nothing that matches your search </span> {props.HandleNoMatch && ( <div className="flex w-full justify-center py-4">{props.HandleNoMatch}</div> )} </div> )} </div> )} </div> {messages.map((message, index) => ( <span key={index} className={`mx-4 pt-1 text-sm text-red ${props.isClicked && invalid ? 'block' : 'hidden'}`} > {message} </span> ))} </div> ); }
Editor is loading...
Leave a Comment