2019-10-14 14:17:03 +00:00
|
|
|
import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent";
|
2019-12-17 13:38:13 +00:00
|
|
|
import { FetchMoreProps } from "@saleor/types";
|
2020-05-14 09:30:32 +00:00
|
|
|
import React from "react";
|
2019-10-14 14:17:03 +00:00
|
|
|
|
2019-06-19 14:40:52 +00:00
|
|
|
interface ChoiceProviderProps {
|
2019-12-17 13:38:13 +00:00
|
|
|
children: (
|
|
|
|
props: FetchMoreProps & {
|
|
|
|
choices: SingleAutocompleteChoiceType[];
|
|
|
|
fetchChoices: (value: string) => void;
|
|
|
|
}
|
|
|
|
) => React.ReactElement;
|
2019-10-14 14:17:03 +00:00
|
|
|
choices: SingleAutocompleteChoiceType[];
|
2019-06-19 14:40:52 +00:00
|
|
|
}
|
|
|
|
|
2019-10-14 14:17:03 +00:00
|
|
|
const step = 5;
|
2019-12-17 13:38:13 +00:00
|
|
|
const loadingTime = 400;
|
2019-10-14 14:17:03 +00:00
|
|
|
|
2019-12-17 13:38:13 +00:00
|
|
|
export interface UseMockChoiceProviderOpts extends FetchMoreProps {
|
|
|
|
fetchChoices: (value: string) => void;
|
|
|
|
}
|
|
|
|
export type UseMockChoiceProvider = [
|
|
|
|
SingleAutocompleteChoiceType[],
|
|
|
|
UseMockChoiceProviderOpts
|
|
|
|
];
|
|
|
|
export function useMockChoiceProvider(
|
|
|
|
choices: SingleAutocompleteChoiceType[]
|
|
|
|
): UseMockChoiceProvider {
|
|
|
|
const [filteredChoices, setFilteredChoices] = React.useState(
|
|
|
|
choices.slice(0, step)
|
|
|
|
);
|
|
|
|
const [loading, setLoading] = React.useState(false);
|
|
|
|
const [first, setFirst] = React.useState(step);
|
|
|
|
const timeout = React.useRef(null);
|
2019-06-19 14:40:52 +00:00
|
|
|
|
2019-12-17 13:38:13 +00:00
|
|
|
React.useEffect(
|
|
|
|
() => () => {
|
|
|
|
if (timeout.current) {
|
|
|
|
clearTimeout(timeout.current);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[]
|
|
|
|
);
|
2019-06-19 14:40:52 +00:00
|
|
|
|
2019-12-17 13:38:13 +00:00
|
|
|
const handleChange = (value: string) => {
|
|
|
|
if (!!timeout.current) {
|
|
|
|
clearTimeout(timeout.current);
|
2019-10-14 14:17:03 +00:00
|
|
|
}
|
2019-12-17 13:38:13 +00:00
|
|
|
timeout.current = setTimeout(() => fetchChoices(value), loadingTime);
|
2019-10-14 14:17:03 +00:00
|
|
|
};
|
|
|
|
|
2019-12-17 13:38:13 +00:00
|
|
|
const fetchChoices = (value: string) => {
|
|
|
|
const filteredChoices = choices.filter(
|
2019-10-14 14:17:03 +00:00
|
|
|
suggestion =>
|
2019-12-17 13:38:13 +00:00
|
|
|
!value ||
|
|
|
|
suggestion.label.toLowerCase().indexOf(value.toLowerCase()) !== -1
|
2019-10-14 14:17:03 +00:00
|
|
|
);
|
2019-12-17 13:38:13 +00:00
|
|
|
|
|
|
|
setLoading(true);
|
|
|
|
|
|
|
|
timeout.current = setTimeout(() => {
|
|
|
|
setFilteredChoices(filteredChoices);
|
|
|
|
setLoading(false);
|
|
|
|
setFirst(step);
|
|
|
|
}, loadingTime);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleFetchMore = () => {
|
|
|
|
setLoading(true);
|
|
|
|
|
|
|
|
timeout.current = setTimeout(() => {
|
|
|
|
setFilteredChoices(choices.slice(0, first + step));
|
|
|
|
setLoading(false);
|
|
|
|
setFirst(first + step);
|
|
|
|
}, loadingTime);
|
2019-06-19 14:40:52 +00:00
|
|
|
};
|
|
|
|
|
2019-12-17 13:38:13 +00:00
|
|
|
return [
|
|
|
|
filteredChoices,
|
|
|
|
{
|
|
|
|
fetchChoices: handleChange,
|
|
|
|
hasMore: choices.length > filteredChoices.length,
|
|
|
|
loading,
|
|
|
|
onFetchMore: handleFetchMore
|
|
|
|
}
|
|
|
|
];
|
2019-06-19 14:40:52 +00:00
|
|
|
}
|
2019-12-17 13:38:13 +00:00
|
|
|
|
|
|
|
export const ChoiceProvider: React.FC<ChoiceProviderProps> = ({
|
|
|
|
children,
|
|
|
|
choices
|
|
|
|
}) => {
|
|
|
|
const [filteredChoices, opts] = useMockChoiceProvider(choices);
|
|
|
|
|
|
|
|
return children({
|
|
|
|
choices: filteredChoices,
|
|
|
|
...opts
|
|
|
|
});
|
|
|
|
};
|