Skip to content

Instantly share code, notes, and snippets.

@Ebrahim-Ramadan
Created June 19, 2024 19:16
Show Gist options
  • Save Ebrahim-Ramadan/234cb0c5e4200bdbf38af0f255c80a85 to your computer and use it in GitHub Desktop.
Save Ebrahim-Ramadan/234cb0c5e4200bdbf38af0f255c80a85 to your computer and use it in GitHub Desktop.
floating header react component
'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 />
},
];
'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