Link Reveal
aniket-ui/link-revealUnverifiedComponent
Animated link that reveals the website favicon and primary color on hover.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/singhjashanjot/jashan.codes/master/public/r/link-reveal.jsonSource
1"use client";23import { motion, useReducedMotion } from "motion/react";4import { useState } from "react";5import type { ReactNode } from "react";67import { cn } from "@/lib/utils";89import type { LinkRevealData } from "./types";1011export type LinkRevealProps = Omit<12 React.ComponentProps<"a">,13 | "children"14 | "onDrag"15 | "onDragEnd"16 | "onDragStart"17 | "onAnimationStart"18 | "onAnimationEnd"19> &20 Partial<LinkRevealData> & {21 children: ReactNode;22 icon?: ReactNode;23 };2425export const LinkReveal = ({26 favicon,27 primaryColor,28 icon,29 className,30 children,31 ...props32}: LinkRevealProps) => {33 const reducedMotion = useReducedMotion();34 const [hovered, setHovered] = useState(false);35 const animate = reducedMotion ? false : hovered;3637 return (38 <motion.a39 className={cn(40 "group/link relative inline-flex items-center font-medium",41 "underline underline-offset-2 !no-underline",42 primaryColor && "hover:text-[var(--link-reveal-color)]",43 className44 )}45 style={46 {47 "--link-reveal-color": primaryColor ?? undefined,48 } as React.CSSProperties49 }50 onHoverStart={() => setHovered(true)}51 onHoverEnd={() => setHovered(false)}52 animate={animate ? { x: -4 } : { x: 0 }}53 transition={{ damping: 25, stiffness: 400, type: "spring" }}54 {...props}55 >56 <motion.span57 aria-hidden58 className="absolute left-0 top-0 bottom-0 my-auto inline-flex size-[1.2em] items-center overflow-hidden rounded-xs"59 animate={animate ? { opacity: 1, x: 0 } : { opacity: 0, x: 4 }}60 transition={{ duration: 0.3, ease: "easeOut" }}61 >62 {icon ??63 (favicon && (64 // biome-ignore lint/performance/noImgElement: registry component, favicon from external source65 <img66 alt=""67 className="size-full shrink-0 object-contain"68 height={16}69 src={favicon}70 width={16}71 />72 ))}73 </motion.span>74 <motion.span75 className="leading-none"76 animate={animate ? { paddingLeft: "1.4em" } : { paddingLeft: 0 }}77 transition={{ duration: 0.3, ease: "easeOut" }}78 >79 {children}80 </motion.span>81 </motion.a>82 );83};
What it pulls in
npm packages
