|
1 | 1 | "use client"; |
2 | 2 |
|
3 | | -import { AnimatePresence, motion } from "framer-motion"; |
| 3 | +import { |
| 4 | + AnimatePresence, |
| 5 | + motion, |
| 6 | + useMotionValueEvent, |
| 7 | + useScroll, |
| 8 | +} from "framer-motion"; |
4 | 9 | import Image from "next/image"; |
5 | 10 | import Link from "next/link"; |
6 | 11 | import { useState } from "react"; |
@@ -34,16 +39,41 @@ function Logo() { |
34 | 39 | ); |
35 | 40 | } |
36 | 41 |
|
| 42 | +const parentVariants = { |
| 43 | + visible: { opacity: 1, y: 0 }, |
| 44 | + hidden: { opacity: 0, y: "-4rem" }, |
| 45 | +}; |
| 46 | + |
37 | 47 | export function Navbar() { |
38 | 48 | const [isMenuOpen, setIsMenuOpen] = useState(false); |
39 | 49 | const { openDialog } = useFeedback(); |
| 50 | + const { scrollY } = useScroll(); |
| 51 | + const [hidden, setHidden] = useState(false); |
| 52 | + const [previousScroll, setPreviousScroll] = useState(0); |
| 53 | + |
| 54 | + function update(latest: number, previous: number): void { |
| 55 | + if (latest < previous) { |
| 56 | + setHidden(false); |
| 57 | + } else if (latest > 100 && latest > previous) { |
| 58 | + setHidden(true); |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + useMotionValueEvent(scrollY, "change", (latest: number) => { |
| 63 | + update(latest, previousScroll); |
| 64 | + setPreviousScroll(latest); |
| 65 | + }); |
40 | 66 |
|
41 | 67 | const toggleMenu = () => { |
42 | 68 | setIsMenuOpen(!isMenuOpen); |
43 | 69 | }; |
44 | 70 |
|
45 | 71 | return ( |
46 | | - <div className="fixed inset-x-0 top-0 z-50 h-20 border-b border-blue-900/20 bg-blue-100/50 backdrop-blur-[12px] dark:bg-blue-100/5"> |
| 72 | + <motion.div |
| 73 | + animate={hidden ? "hidden" : "visible"} |
| 74 | + variants={parentVariants} |
| 75 | + className="fixed inset-x-0 top-0 z-50 h-20 border-b border-blue-900/20 bg-blue-100/50 backdrop-blur-[12px] dark:bg-blue-100/5" |
| 76 | + > |
47 | 77 | <div className="container mx-auto flex items-center justify-between px-6 md:px-20"> |
48 | 78 | <Logo /> |
49 | 79 |
|
@@ -132,6 +162,6 @@ export function Navbar() { |
132 | 162 | ) : null} |
133 | 163 | </AnimatePresence> |
134 | 164 | </div> |
135 | | - </div> |
| 165 | + </motion.div> |
136 | 166 | ); |
137 | 167 | } |
0 commit comments