alternative tangled frontend (extremely wip)

feat: additional component

serenity ce962e10 98dbdf60

+65
+65
src/components/Animated/UnderlineIconLink.tsx
··· 1 + import { motion, Transition, Variants } from "motion/react"; 2 + import { ReactNode } from "react"; 3 + 4 + export const UnderlineIconRouterLink = ({ 5 + href, 6 + icon, 7 + label, 8 + className, 9 + iconClassName = "text-[#cba6f7]", 10 + labelClassName = "text-[#cba6f7]", 11 + underlineClassName = "bg-[#cba6f7]", 12 + position = "left", 13 + iconVariants = { 14 + hover: { rotate: [0, -10, 10, -10, 10, 0] }, 15 + }, 16 + iconTransitions = { duration: 0.3, ease: "easeInOut" }, 17 + }: { 18 + href: string; 19 + icon: ReactNode; 20 + label: string; 21 + className?: string; 22 + iconClassName?: string; 23 + labelClassName?: string; 24 + underlineClassName?: string; 25 + position?: "right" | "left"; 26 + iconVariants?: Variants; 27 + iconTransitions?: Transition; 28 + }) => { 29 + const iconElement = ( 30 + <motion.div 31 + variants={iconVariants} 32 + transition={iconTransitions} 33 + className={iconClassName} 34 + > 35 + {icon} 36 + </motion.div> 37 + ); 38 + 39 + return ( 40 + <motion.a 41 + href={href} 42 + className={`flex cursor-pointer items-center gap-1 pl-2 ${className}`} 43 + initial="initial" 44 + whileHover="hover" 45 + > 46 + {position === "left" && iconElement} 47 + <motion.div className="relative inline-block"> 48 + <p className={labelClassName}>{label}</p> 49 + <motion.span 50 + className={`absolute bottom-1 left-0 h-0.25 w-full origin-center ${underlineClassName}`} 51 + variants={{ 52 + initial: { scaleX: 0 }, 53 + hover: { scaleX: 1 }, 54 + }} 55 + transition={{ 56 + type: "spring", 57 + duration: 0.2, 58 + bounce: 0.3, 59 + }} 60 + /> 61 + </motion.div> 62 + {position === "right" && iconElement} 63 + </motion.a> 64 + ); 65 + };