-
Notifications
You must be signed in to change notification settings - Fork 225
Expand file tree
/
Copy pathdiscover-search-context.tsx
More file actions
76 lines (65 loc) · 1.84 KB
/
discover-search-context.tsx
File metadata and controls
76 lines (65 loc) · 1.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
'use client';
import { createContext, useCallback, useContext, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
interface DiscoverSearchContextValue {
input: string;
setInput: (value: string) => void;
query: string;
isSearching: boolean;
isDirty: boolean;
submit: () => void;
clear: () => void;
}
const DiscoverSearchContext = createContext<DiscoverSearchContextValue | null>(
null
);
export const useDiscoverSearch = () => {
const ctx = useContext(DiscoverSearchContext);
if (!ctx)
throw new Error(
'useDiscoverSearch must be used within DiscoverSearchProvider'
);
return ctx;
};
export const DiscoverSearchProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const router = useRouter();
const searchParams = useSearchParams();
const initialQuery = searchParams.get('q') ?? '';
const [input, setInputRaw] = useState(initialQuery);
const [query, setQuery] = useState(initialQuery);
const setInput = useCallback(
(value: string) => {
setInputRaw(value);
if (value.trim().length === 0 && query.length > 0) {
setQuery('');
router.replace('/', { scroll: false });
}
},
[query, router]
);
const submit = useCallback(() => {
const trimmed = input.trim();
if (trimmed.length > 0) {
setQuery(trimmed);
router.replace(`/?q=${encodeURIComponent(trimmed)}`, { scroll: false });
}
}, [input, router]);
const clear = useCallback(() => {
setInputRaw('');
setQuery('');
router.replace('/', { scroll: false });
}, [router]);
const isSearching = query.length > 0;
const isDirty = input.trim() !== query;
return (
<DiscoverSearchContext.Provider
value={{ input, setInput, query, isSearching, isDirty, submit, clear }}
>
{children}
</DiscoverSearchContext.Provider>
);
};