57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
import { DocumentNode } from "graphql";
|
|
import { useState } from "react";
|
|
import { QueryResult } from "react-apollo";
|
|
|
|
import makeQuery, { UseQueryResult } from "./makeQuery";
|
|
import useDebounce from "./useDebounce";
|
|
|
|
export interface SearchVariables {
|
|
after?: string;
|
|
first: number;
|
|
query: string;
|
|
}
|
|
|
|
export interface UseSearchResult<TData, TVariables extends SearchVariables> {
|
|
loadMore: () => void;
|
|
result: QueryResult<TData, TVariables>;
|
|
search: (query: string) => void;
|
|
}
|
|
export type UseSearchOpts<TVariables extends SearchVariables> = Partial<{
|
|
skip: boolean;
|
|
variables: TVariables;
|
|
}>;
|
|
export type UseSearchHook<TData, TVariables extends SearchVariables> = (
|
|
opts: UseSearchOpts<TVariables>
|
|
) => UseSearchResult<TData, TVariables>;
|
|
|
|
function makeSearch<TData, TVariables extends SearchVariables>(
|
|
query: DocumentNode,
|
|
loadMoreFn: (result: UseQueryResult<TData, TVariables>) => void
|
|
): UseSearchHook<TData, TVariables> {
|
|
const useSearchQuery = makeQuery<TData, TVariables>(query);
|
|
|
|
function useSearch(
|
|
opts: UseSearchOpts<TVariables>
|
|
): UseSearchResult<TData, TVariables> {
|
|
const [searchQuery, setSearchQuery] = useState("");
|
|
const debouncedSearch = useDebounce(setSearchQuery);
|
|
const result = useSearchQuery({
|
|
...opts,
|
|
displayLoader: true,
|
|
variables: {
|
|
...opts.variables,
|
|
query: searchQuery
|
|
}
|
|
});
|
|
|
|
return {
|
|
loadMore: () => loadMoreFn(result),
|
|
result,
|
|
search: debouncedSearch
|
|
};
|
|
}
|
|
|
|
return useSearch;
|
|
}
|
|
|
|
export default makeSearch;
|