fix: add desktop search dropdown
This commit is contained in:
@@ -285,10 +285,13 @@ export function PublicLayout() {
|
||||
const outlet = useOutlet();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [mobileSearchOpen, setMobileSearchOpen] = useState(false);
|
||||
const [desktopSearchOpen, setDesktopSearchOpen] = useState(false);
|
||||
const [q, setQ] = useState("");
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
const mobileMenuButtonRef = useRef<HTMLButtonElement>(null);
|
||||
const desktopMenuButtonRef = useRef<HTMLButtonElement>(null);
|
||||
const desktopSearchRef = useRef<HTMLDivElement>(null);
|
||||
const desktopSearchPanelRef = useRef<HTMLDivElement>(null);
|
||||
const nav = useNavigate();
|
||||
|
||||
const na = (which: PublicNavWhich) =>
|
||||
@@ -342,6 +345,7 @@ export function PublicLayout() {
|
||||
nav(`/browse?q=${encodeURIComponent(s)}`);
|
||||
setOpen(false);
|
||||
setMobileSearchOpen(false);
|
||||
setDesktopSearchOpen(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -350,6 +354,33 @@ export function PublicLayout() {
|
||||
);
|
||||
}, [open]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!desktopSearchOpen) return;
|
||||
|
||||
const closeOnOutside = (event: MouseEvent | TouchEvent) => {
|
||||
const target = event.target as Node;
|
||||
if (
|
||||
desktopSearchRef.current?.contains(target) ||
|
||||
desktopSearchPanelRef.current?.contains(target)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setDesktopSearchOpen(false);
|
||||
};
|
||||
const closeOnEscape = (event: KeyboardEvent) => {
|
||||
if (event.key === "Escape") setDesktopSearchOpen(false);
|
||||
};
|
||||
|
||||
document.addEventListener("mousedown", closeOnOutside);
|
||||
document.addEventListener("touchstart", closeOnOutside);
|
||||
window.addEventListener("keydown", closeOnEscape);
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", closeOnOutside);
|
||||
document.removeEventListener("touchstart", closeOnOutside);
|
||||
window.removeEventListener("keydown", closeOnEscape);
|
||||
};
|
||||
}, [desktopSearchOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
|
||||
@@ -448,6 +479,7 @@ export function PublicLayout() {
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
setDesktopSearchOpen(false);
|
||||
setMobileSearchOpen((value) => !value);
|
||||
}}
|
||||
className="flex h-[40px] w-[40px] items-center justify-center rounded-full bg-[#191921] outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08070c]"
|
||||
@@ -470,6 +502,7 @@ export function PublicLayout() {
|
||||
ariaLabel={t("langLabel")}
|
||||
onOpen={() => {
|
||||
setOpen(false);
|
||||
setDesktopSearchOpen(false);
|
||||
setMobileSearchOpen(false);
|
||||
}}
|
||||
/>
|
||||
@@ -479,6 +512,7 @@ export function PublicLayout() {
|
||||
className="inline-flex h-[40px] w-[40px] shrink-0 items-center justify-center rounded-full bg-[#191921] text-[#a8a9ae] outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-[#08070c]"
|
||||
onClick={() => {
|
||||
setMobileSearchOpen(false);
|
||||
setDesktopSearchOpen(false);
|
||||
setOpen((v) => !v);
|
||||
}}
|
||||
aria-label="menu"
|
||||
@@ -577,10 +611,16 @@ export function PublicLayout() {
|
||||
</nav>
|
||||
|
||||
<div className="flex min-w-0 flex-1 items-center justify-end gap-2 min-[1200px]:flex-none">
|
||||
<div className="hidden h-10 min-w-0 flex-1 items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] py-2 pl-3 pr-3 shadow-inner md:flex min-[1200px]:w-44 min-[1200px]:flex-none lg:pr-4 xl:w-52">
|
||||
<div
|
||||
ref={desktopSearchRef}
|
||||
className="hidden h-10 min-w-0 flex-1 items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] py-2 pl-3 pr-3 shadow-inner md:flex min-[1200px]:w-44 min-[1200px]:flex-none lg:pr-4 xl:w-52"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={goSearch}
|
||||
onClick={() => {
|
||||
if (q.trim()) goSearch();
|
||||
else setDesktopSearchOpen((value) => !value);
|
||||
}}
|
||||
className="shrink-0 rounded-full p-1 text-[#c6c7cf] transition hover:bg-white/5 hover:text-ark-gold focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/60"
|
||||
aria-label={t("searchNow")}
|
||||
>
|
||||
@@ -588,6 +628,8 @@ export function PublicLayout() {
|
||||
</button>
|
||||
<input
|
||||
value={q}
|
||||
onFocus={() => setDesktopSearchOpen(true)}
|
||||
onClick={() => setDesktopSearchOpen(true)}
|
||||
onChange={(e) => setQ(e.target.value)}
|
||||
onKeyDown={(e) => e.key === "Enter" && goSearch()}
|
||||
placeholder={t("searchPlaceholder")}
|
||||
@@ -604,7 +646,10 @@ export function PublicLayout() {
|
||||
ref={desktopMenuButtonRef}
|
||||
type="button"
|
||||
className="inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-ark-line bg-[#1a1b20] text-neutral-200 outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg min-[1200px]:hidden"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
onClick={() => {
|
||||
setDesktopSearchOpen(false);
|
||||
setOpen((v) => !v);
|
||||
}}
|
||||
aria-label="menu"
|
||||
>
|
||||
{open ? <X size={18} /> : <Menu size={18} />}
|
||||
@@ -680,12 +725,25 @@ export function PublicLayout() {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{desktopSearchOpen ? (
|
||||
<SearchPanel
|
||||
panelRef={desktopSearchPanelRef}
|
||||
lang={lang}
|
||||
t={t}
|
||||
query={q}
|
||||
onQueryChange={setQ}
|
||||
onSearch={goSearch}
|
||||
variant="desktop"
|
||||
showInput={false}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<main
|
||||
className={`mx-auto w-full max-w-[1280px] max-md:pb-[calc(68px+max(env(safe-area-inset-bottom),0px)+1rem)] ${
|
||||
isHome
|
||||
? "flex-1 px-0 pb-6 pt-0 md:px-9 md:pb-10 md:pt-10 xl:px-0"
|
||||
: footerInContentFlow
|
||||
? "flex-1 px-0 pb-0 pt-0 md:px-9 md:pt-10 xl:px-0"
|
||||
? "flex-1 px-0 pb-0 pt-0 md:px-9 xl:px-0"
|
||||
: "flex-1 px-4 pb-6 pt-6 min-[440px]:px-5 sm:px-6 md:px-9 md:pb-10 md:pt-10 xl:px-0"
|
||||
}`}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user