1 |
"use client"; |
2 |
|
3 |
import useIsDesktop from "@/hooks/useIsDesktop"; |
4 |
import usePlatform from "@/hooks/usePlatform"; |
5 |
import { Button } from "@mui/material"; |
6 |
import { useEffect, useRef, useState } from "react"; |
7 |
import { MdSearch } from "react-icons/md"; |
8 |
import SearchInput from "./SearchInput"; |
9 |
import SearchResults from "./SearchResults"; |
10 |
|
11 |
export default function Search() { |
12 |
const platform = usePlatform(); |
13 |
const isDesktop = useIsDesktop(); |
14 |
const ref = useRef<HTMLInputElement>(null); |
15 |
const [query, setQuery] = useState<string | null>(null); |
16 |
const [toggled, setToggled] = useState(false); |
17 |
|
18 |
useEffect(() => { |
19 |
const callback = (event: KeyboardEvent) => { |
20 |
if ( |
21 |
event.code === "Slash" || |
22 |
((platform === "darwin" ? event.metaKey : event.ctrlKey) && |
23 |
event.code === "KeyK") |
24 |
) { |
25 |
event.preventDefault(); |
26 |
ref.current?.focus(); |
27 |
} |
28 |
}; |
29 |
|
30 |
window.addEventListener("keydown", callback); |
31 |
|
32 |
return () => window.removeEventListener("keydown", callback); |
33 |
}, [platform]); |
34 |
|
35 |
return ( |
36 |
<> |
37 |
<div className="relative"> |
38 |
{isDesktop && <SearchInput ref={ref} setQuery={setQuery} />} |
39 |
|
40 |
{query && isDesktop && ( |
41 |
<SearchResults |
42 |
query={query} |
43 |
onClose={() => setQuery(null)} |
44 |
/> |
45 |
)} |
46 |
|
47 |
{!isDesktop && ( |
48 |
<Button |
49 |
style={{ minWidth: 0, color: "white" }} |
50 |
onClick={() => { |
51 |
setToggled(true); |
52 |
}} |
53 |
> |
54 |
<MdSearch size={23} /> |
55 |
</Button> |
56 |
)} |
57 |
|
58 |
{!isDesktop && toggled && ( |
59 |
<div |
60 |
className="fixed top-0 left-0 w-screen h-screen bg-black/30 z-[100000005]" |
61 |
onClick={() => setToggled(false)} |
62 |
> |
63 |
<div |
64 |
className="overflow-y-scroll bg-neutral-900 w-[calc(100vw-2rem)] h-[calc(80vh-4rem)] mx-[1rem] rounded-lg p-[1rem] absolute bottom-4" |
65 |
onClickCapture={event => event.stopPropagation()} |
66 |
> |
67 |
<SearchInput ref={ref} setQuery={setQuery} /> |
68 |
|
69 |
{query && ( |
70 |
<SearchResults |
71 |
query={query} |
72 |
onClose={() => setQuery(null)} |
73 |
/> |
74 |
)} |
75 |
</div> |
76 |
</div> |
77 |
)} |
78 |
</div> |
79 |
</> |
80 |
); |
81 |
} |