MIF_E31221222/sigap-website/app/_components/floating-action-search-bar.tsx

61 lines
1.8 KiB
TypeScript

"use client";
import { useState, useEffect, useRef } from "react";
import { motion, AnimatePresence } from "framer-motion";
import ActionSearchBar from "@/app/_components/action-search-bar";
export default function FloatingActionSearchBar() {
const [isOpen, setIsOpen] = useState(false);
const searchBarRef = useRef<HTMLInputElement>(null);
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if ((event.ctrlKey || event.metaKey) && event.key === "k") {
event.preventDefault();
setIsOpen((prev) => !prev);
} else if (event.key === "Escape") {
setIsOpen(false);
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, []);
useEffect(() => {
if (isOpen && searchBarRef.current) {
searchBarRef.current.focus();
}
}, [isOpen]);
return (
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.2 }}
className="fixed inset-0 z-50 flex items-start justify-center bg-background/80 backdrop-blur-sm p-4 sm:p-6 md:p-8 lg:p-40"
onClick={() => setIsOpen(false)}
>
<motion.div
initial={{ scale: 0.95, y: -20 }}
animate={{ scale: 1, y: 0 }}
exit={{ scale: 0.95, y: -20 }}
transition={{ duration: 0.2 }}
className="w-full max-w-lg sm:max-w-xl md:max-w-2xl"
onClick={(e) => e.stopPropagation()}
>
<ActionSearchBar
ref={searchBarRef}
autoFocus={true}
isFloating={true}
/>
</motion.div>
</motion.div>
)}
</AnimatePresence>
);
}