"use client"; import { motion } from "motion/react"; import { useButtonClick } from "@/hooks/useButtonClick"; import { cls } from "@/lib/utils"; import { useState } from "react"; interface ButtonFlipProps { text: string; variant?: "primary" | "secondary"; href?: string; onClick?: () => void; animate?: boolean; animationDelay?: number; className?: string; } const ButtonFlip = ({ text, variant = "primary", href = "#", onClick, animate: shouldAnimate = true, animationDelay = 0, className = "" }: ButtonFlipProps) => { const handleClick = useButtonClick(href, onClick); const [isHovered, setIsHovered] = useState(false); const maxIndex = Math.max(text.length - 1, 1); const getCharValues = (index: number) => { const t = index / maxIndex; const signedIndex = index - maxIndex / 2; const curve = Math.sin(t * 1.5 * (Math.PI / 180)); const rotCurve = Math.sin(t * 30 * (Math.PI / 180)); const rotSign = Math.max(-1, Math.min(1, signedIndex)); const delay = 0.05 + curve * 2.9; const rotateZ = rotSign * rotCurve * 36 * -1; const translateX = signedIndex * 0.125; return { delay, rotateZ, translateX }; }; const button = ( setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} className={cls("group flex items-center justify-center h-10 px-6 text-sm rounded cursor-pointer active:scale-[0.96]", variant === "primary" ? "primary-button text-primary-cta-text" : "secondary-button text-secondary-cta-text", className)} > {[...text].map((char, index) => { const { delay, rotateZ, translateX } = getCharValues(index); return ( {char} ); })} ); if (!shouldAnimate) return button; return ( {button} ); }; export default ButtonFlip;