Docs
Navigation Icon
Navigation Icon
When hovering over the navigation icon, the text should move upward or downward based on entry direction. Clicking the icon triggers an alert.
JohnJohn John
RobertRobert Robert
JaneJane Jane
EmilyEmily Emily
Install the following dependencies:
pnpm add gsap
Make a file for cn function and match the import afterwards
import clsx, { ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export const cn = (...classes: ClassValue[]) => twMerge(clsx(...classes))
Make a file and copy paste this code in a file with name Navigation Icon
"use client"
import React, { ReactNode, useRef, useState } from "react"
import { gsap } from "gsap"
import { cn } from "@/lib/utils"
interface NavigationIconProps {
children: ReactNode
parentDivClass: string
innerDivClass: string
textClass: string
translateYUp?: number
translateYDown?: number
opposite?: boolean
duration?: number
stagger?: number
borderClass: string
onClick?: () => void
}
const NavigationIcon: React.FC<NavigationIconProps> = ({
children,
innerDivClass,
textClass,
parentDivClass,
translateYUp = 130,
translateYDown = 130,
opposite = false,
duration = 0.5,
stagger = 0.1,
borderClass,
onClick,
}) => {
const containerRef = useRef<HTMLDivElement>(null)
const [clicked, setClick] = useState<boolean>(false)
const handleMouseEnter = (e: React.MouseEvent) => {
if (containerRef.current) {
const container = containerRef.current.getBoundingClientRect()
const isEnteringFromTop = e.clientY < container.top + container.height / 2
const spans = containerRef.current.querySelectorAll("span")
const upward = opposite ? -1 : 1
gsap.to(spans, {
y: isEnteringFromTop
? `${translateYUp * upward}%`
: `${translateYDown * -1 * upward}%`,
duration,
stagger,
})
}
}
const handleMouseLeave = (e: React.MouseEvent) => {
if (containerRef.current) {
const spans = containerRef.current.querySelectorAll("span")
gsap.to(spans, {
y: "0%", // Reset to the original position
duration,
stagger,
})
}
}
return (
<div
className={cn(
` flex min-h-[100px] w-fit items-center justify-center overflow-hidden`,
parentDivClass
)}
>
<div
ref={containerRef}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={() => {
setClick(true)
onClick?.()
}}
className={cn(
`flex flex-col gap-2 h-10 items-center text-center pb-1 justify-center px-2 overflow-y-hidden rounded-full cursor-pointer ${clicked && borderClass}`,
innerDivClass
)}
>
<span className={textClass}>{children}</span>
<span className={textClass}>{children}</span> {/* Middle Text */}
<span className={textClass}>{children}</span>
</div>
</div>
)
}
export { NavigationIcon }
Props
Name | Type | Description |
---|---|---|
parentDivClass | string | Additional class names for the parent div. |
innerDivClass | string | Additional class names for the inner div. |
borderClass | string | CSS class for border styling applied on click. |
textClass | string | Class for styling the text. |
translateYUp | number | Y translation when hovering from the top. Default is 130. |
translateYDown | number | Y translation when hovering from the bottom. Default is 130. |
opposite | boolean | If true, reverses the hover direction logic. Default is false. |
duration | number | Animation duration in seconds. Default is 0.5. |
stagger | number | Delay between animation of elements. Default is 0.1. |
onClick | function | Callback function triggered when the icon is clicked. |