Untitled
unknown
plain_text
a year ago
6.4 kB
5
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