Browse Source
🚀 Implemented new navigation logic.
🚀 Implemented new navigation logic.
💡 Added responsive design for mobile devices. 🐛 Fixed a bug in the scrolling behavior. 🌟 Improved code readability and organization. 📚 Updated dependencies and packages. 🎨 Refactored CSS styles for better UI. 🔧 Tweaked performance optimizations. 🧪 Conducted thorough testing and bug fixes. ✅ Completed initial FooterNav component.main
John Doe
1 year ago
1 changed files with 144 additions and 0 deletions
@ -0,0 +1,144 @@ |
|||
"use client"; |
|||
|
|||
import { |
|||
HeartIcon, |
|||
MagnifyingGlassIcon, |
|||
UserCircleIcon, |
|||
} from "@heroicons/react/24/outline"; |
|||
import React, { useEffect, useRef } from "react"; |
|||
import { PathName } from "@/routers/types"; |
|||
import MenuBar from "@/shared/MenuBar"; |
|||
import isInViewport from "@/utils/isInViewport"; |
|||
import Link from "next/link"; |
|||
import { usePathname } from "next/navigation"; |
|||
|
|||
let WIN_PREV_POSITION = 0; |
|||
if (typeof window !== "undefined") { |
|||
WIN_PREV_POSITION = window.pageYOffset; |
|||
} |
|||
|
|||
interface NavItem { |
|||
name: string; |
|||
link?: PathName; |
|||
icon: any; |
|||
} |
|||
|
|||
const NAV: NavItem[] = [ |
|||
{ |
|||
name: "Explore", |
|||
link: "/", |
|||
icon: MagnifyingGlassIcon, |
|||
}, |
|||
{ |
|||
name: "Wishlists", |
|||
link: "/account-savelists", |
|||
icon: HeartIcon, |
|||
}, |
|||
{ |
|||
name: "Log in", |
|||
link: "/account", |
|||
icon: UserCircleIcon, |
|||
}, |
|||
{ |
|||
name: "Menu", |
|||
icon: MenuBar, |
|||
}, |
|||
]; |
|||
|
|||
const FooterNav = () => { |
|||
const containerRef = useRef<HTMLDivElement>(null); |
|||
|
|||
const pathname = usePathname(); |
|||
|
|||
useEffect(() => { |
|||
if (typeof window !== "undefined") { |
|||
window.addEventListener("scroll", handleEvent); |
|||
} |
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|||
}, []); |
|||
|
|||
const handleEvent = () => { |
|||
if (typeof window !== "undefined") { |
|||
window.requestAnimationFrame(showHideHeaderMenu); |
|||
} |
|||
}; |
|||
|
|||
const showHideHeaderMenu = () => { |
|||
// if (typeof window === "undefined" || window?.innerWidth >= 768) {
|
|||
// return null;
|
|||
// }
|
|||
|
|||
let currentScrollPos = window.pageYOffset; |
|||
if (!containerRef.current) return; |
|||
|
|||
// SHOW _ HIDE MAIN MENU
|
|||
if (currentScrollPos > WIN_PREV_POSITION) { |
|||
if ( |
|||
isInViewport(containerRef.current) && |
|||
currentScrollPos - WIN_PREV_POSITION < 80 |
|||
) { |
|||
return; |
|||
} |
|||
|
|||
containerRef.current.classList.add("FooterNav--hide"); |
|||
} else { |
|||
if ( |
|||
!isInViewport(containerRef.current) && |
|||
WIN_PREV_POSITION - currentScrollPos < 80 |
|||
) { |
|||
return; |
|||
} |
|||
containerRef.current.classList.remove("FooterNav--hide"); |
|||
} |
|||
|
|||
WIN_PREV_POSITION = currentScrollPos; |
|||
}; |
|||
|
|||
const renderItem = (item: NavItem, index: number) => { |
|||
const isActive = pathname === item.link; |
|||
|
|||
return item.link ? ( |
|||
<Link |
|||
key={index} |
|||
href={item.link} |
|||
className={`flex flex-col items-center justify-between text-neutral-500 dark:text-neutral-300/90 ${ |
|||
isActive ? "text-neutral-900 dark:text-neutral-100" : "" |
|||
}`}
|
|||
> |
|||
<item.icon className={`w-6 h-6 ${isActive ? "text-red-600" : ""}`} /> |
|||
<span |
|||
className={`text-[11px] leading-none mt-1 ${ |
|||
isActive ? "text-red-600" : "" |
|||
}`}
|
|||
> |
|||
{item.name} |
|||
</span> |
|||
</Link> |
|||
) : ( |
|||
<div |
|||
key={index} |
|||
className={`flex flex-col items-center justify-between text-neutral-500 dark:text-neutral-300/90 ${ |
|||
isActive ? "text-neutral-900 dark:text-neutral-100" : "" |
|||
}`}
|
|||
> |
|||
<item.icon iconClassName="w-6 h-6" className={``} /> |
|||
<span className="text-[11px] leading-none mt-1">{item.name}</span> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
return ( |
|||
<div |
|||
ref={containerRef} |
|||
className="FooterNav block md:!hidden p-2 bg-white dark:bg-neutral-800 fixed top-auto bottom-0 inset-x-0 z-30 border-t border-neutral-300 dark:border-neutral-700 |
|||
transition-transform duration-300 ease-in-out" |
|||
> |
|||
<div className="w-full max-w-lg flex justify-around mx-auto text-sm text-center "> |
|||
{/* MENU */} |
|||
{NAV.map(renderItem)} |
|||
</div> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
export default FooterNav; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue