Created
June 19, 2024 19:16
-
-
Save Ebrahim-Ramadan/234cb0c5e4200bdbf38af0f255c80a85 to your computer and use it in GitHub Desktop.
floating header react component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use client'; | |
import Image from 'next/image'; | |
import React, { useEffect, useState } from 'react'; | |
import { HomeIcon , ProjectsIcon, ExperienceIcon, BehanceIcon, Behance} from './Icons'; | |
import { MagneticBackgroundTab } from './MagneticBackgroundTab'; | |
export const Header = () => { | |
const [isSticky, setIsSticky] = useState(false); | |
useEffect(() => { | |
const handleScroll = () => { | |
setIsSticky(window.scrollY>50) | |
}; | |
window.addEventListener('scroll', handleScroll); | |
return () => { | |
window.removeEventListener('scroll', handleScroll); | |
}; | |
}, [isSticky]); | |
return ( | |
<div className={` flex flex-col-reverse md:flex-row w-full items-center justify-center pb-4 pt-2 z-20 fixed top-0`}> | |
<div | |
className={`px-2 flex flex-row rounded-3xl ${isSticky&&'backdrop-blur-3xl'} [&>*]:flex [&>*]:items-center [&>*]:cursor-pointer`} | |
> | |
{tabs.map((item) => ( | |
<MagneticBackgroundTab key={item.id} item={item} /> | |
))} | |
</div> | |
</div> | |
); | |
}; | |
export default Header; | |
const tabs = [ | |
{ id: 3, text: 'Projects', position: '1450', icon: <ProjectsIcon /> }, | |
{ id: 2, text: 'Experience', position: '0', icon: <ExperienceIcon /> }, | |
{ | |
id: 2, text: <Behance/>, href: 'https://www.behance.net/ARCHUWK/projects', icon: <BehanceIcon /> | |
}, | |
]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use client' | |
import { scrollToPosition } from "@/utils/scrollToPosition"; | |
import { useRouter } from "next/navigation"; | |
import React, { useRef, useState } from "react"; | |
export const MagneticBackgroundTab = ({ | |
item, | |
isSticky | |
}) => { | |
const ref = useRef(null); | |
const router = useRouter() | |
const [hoverPosition, setHoverPosition] = useState({ | |
x: 0, | |
y: 0, | |
opacity: 0, | |
}); | |
const handleMouseMove = (e) => { | |
const { clientX, clientY, currentTarget } = e; | |
const { left, top, width, height } = currentTarget.getBoundingClientRect(); | |
const x = (clientX - left - width / 2) * 0.15; | |
const y = (clientY - top - height / 2) * 0.15; | |
setHoverPosition({ x, y, opacity: 1 }); | |
}; | |
const onMouseOut = () => { | |
setHoverPosition({ x: 0, y: 0, opacity: 0 }); | |
}; | |
const routeToBehance = () => { | |
if (item.href === 'https://www.behance.net/ARCHUWK/projects') { | |
router.push('https://www.behance.net/ARCHUWK/projects') | |
} else { | |
scrollToPosition(item.position) | |
} | |
} | |
return ( | |
<button | |
onClick={routeToBehance} | |
ref={ref} | |
className="group relative h-12" | |
onMouseMove={handleMouseMove} | |
onMouseLeave={onMouseOut} | |
> | |
<span className={`text-zinc-300 group-hover:text-zinc-200 font-medium relative px-1 md:px-4 py-1 md:py-2 text-sm transition-colors items-center z-10 flex flex-row ${isSticky ? 'md:gap-0 gap-2' : ''} gap-2 flex flex-row`}> | |
<span> | |
{item.icon && ( | |
isSticky ? | |
<span > | |
{item.icon} | |
</span> | |
: | |
<span className=" md:block hidden"> | |
{item.icon} | |
</span> | |
)} | |
</span> | |
<span> | |
{!isSticky && | |
item.text | |
} | |
</span> | |
</span> | |
<div | |
className="absolute bottom-0 left-0 -z-0 w-full rounded-3xl hidden md:block h-full bg-primary-700" | |
style={{ | |
transform: `translate(${hoverPosition.x}px, ${hoverPosition.y}px)`, | |
opacity: hoverPosition.opacity, | |
}} | |
/> | |
</button> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment