66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import useOpenable from "@Front/Hooks/useOpenable";
|
|
import { useState, useEffect, useCallback } from "react";
|
|
import DropdownMenu from "../Dropdown/DropdownMenu";
|
|
import { IOption } from "../Dropdown/DropdownMenu/DropdownOption";
|
|
import SearchBar from "../SearchBar";
|
|
|
|
type IProps = {
|
|
options: IOption[];
|
|
placeholder: string;
|
|
disabled?: boolean;
|
|
};
|
|
|
|
export default function Autocomplete(props: IProps) {
|
|
const { options, placeholder, disabled } = props;
|
|
const [selectedOption, setSelectedOption] = useState<IOption | null>(null);
|
|
const [searchValue, setSearchValue] = useState("");
|
|
const [filteredOptions, setFilteredOptions] = useState<IOption[]>(options);
|
|
const openable = useOpenable({ defaultOpen: false });
|
|
|
|
useEffect(() => {
|
|
if (searchValue) {
|
|
const filteredOptions = options.filter((option) => getLabel(option)?.toLowerCase().includes(searchValue.toLowerCase()));
|
|
console.log(filteredOptions);
|
|
if (filteredOptions.length === 0)
|
|
return setFilteredOptions([{ id: "no-results", label: "Aucun résulats", notSelectable: true }]);
|
|
return setFilteredOptions(filteredOptions);
|
|
}
|
|
return setFilteredOptions(options);
|
|
}, [searchValue, options]);
|
|
|
|
const handleSearchChange = useCallback(
|
|
(value: string) => {
|
|
setSearchValue(value);
|
|
if (value) {
|
|
openable.open();
|
|
} else {
|
|
openable.close();
|
|
}
|
|
},
|
|
[openable],
|
|
);
|
|
|
|
const handleSelectOption = useCallback(
|
|
(option: IOption) => {
|
|
setSelectedOption(option);
|
|
setSearchValue(getLabel(option) || "");
|
|
openable.close();
|
|
},
|
|
[openable],
|
|
);
|
|
|
|
function getLabel(option: IOption | null): string | null {
|
|
if (!option) return null;
|
|
if (typeof option.label === "string") {
|
|
return option.label;
|
|
}
|
|
return `${option.label.text} ${option.label.subtext}`;
|
|
}
|
|
|
|
return (
|
|
<DropdownMenu options={filteredOptions} openable={openable} onSelect={handleSelectOption} selectedOption={selectedOption}>
|
|
<SearchBar placeholder={placeholder} disabled={disabled} onChange={handleSearchChange} value={searchValue} />
|
|
</DropdownMenu>
|
|
);
|
|
}
|