Underline Comes In Goes Out
fancy/underline-comes-in-goes-outFreeComponent
A ui component.
Install it
npx shadcn@latest add https://www.fancycomponents.dev/r/underline-comes-in-goes-out.jsonSource
1"use client"23import { ElementType, useEffect, useRef, useState, useMemo } from "react"4import cn from "clsx"5import {6 motion,7 useAnimationControls,8 ValueAnimationTransition,9} from "motion/react"1011interface ComesInGoesOutUnderlineProps {12 /**13 * The content to be displayed and animated14 */15 children: React.ReactNode1617 /**18 * HTML Tag to render the component as19 * @default span20 */21 as?: ElementType2223 /**24 * Direction of the animation25 * @default "left"26 */27 direction?: "left" | "right"2829 /**30 * Optional class name for styling31 */32 className?: string3334 /**35 * Height of the underline as a ratio of font size36 * @default 0.137 */38 underlineHeightRatio?: number3940 /**41 * Padding of the underline as a ratio of font size42 * @default 0.0143 */44 underlinePaddingRatio?: number4546 /**47 * Animation transition configuration48 * @default { duration: 0.4, ease: "easeInOut" }49 */50 transition?: ValueAnimationTransition51}5253const ComesInGoesOutUnderline = ({54 children,55 as,56 direction = "left",57 className,58 underlineHeightRatio = 0.1,59 underlinePaddingRatio = 0.01,60 transition = {61 duration: 0.4,62 ease: "easeInOut",63 },64 ...props65}: ComesInGoesOutUnderlineProps) => {66 const controls = useAnimationControls()67 const [blocked, setBlocked] = useState(false)68 const textRef = useRef<HTMLSpanElement>(null)69 const MotionComponent = useMemo(() => motion.create(as ?? "span"), [as])7071 useEffect(() => {72 const updateUnderlineStyles = () => {73 if (textRef.current) {74 const fontSize = parseFloat(getComputedStyle(textRef.current).fontSize)75 const underlineHeight = fontSize * underlineHeightRatio76 const underlinePadding = fontSize * underlinePaddingRatio77 textRef.current.style.setProperty(78 "--underline-height",79 `${underlineHeight}px`80 )81 textRef.current.style.setProperty(82 "--underline-padding",83 `${underlinePadding}px`84 )85 }86 }8788 updateUnderlineStyles()89 window.addEventListener("resize", updateUnderlineStyles)9091 return () => window.removeEventListener("resize", updateUnderlineStyles)92 }, [underlineHeightRatio, underlinePaddingRatio])9394 const animate = async () => {95 if (blocked) return9697 setBlocked(true)9899 await controls.start({100 width: "100%",101 transition,102 transitionEnd: {103 left: direction === "left" ? "auto" : 0,104 right: direction === "left" ? 0 : "auto",105 },106// … truncated
What it pulls in
npm packages
Files it writes
More from fancy
All 158 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Gradient With Svganimated-gradient-with-svg | fancy | Components | Free | no deps | |
| Basic Number Tickerbasic-number-ticker | fancy | Components | Free | 1 dep | |
| Box Carouselbox-carousel | fancy | Components | Free | 1 dep | |
| Breathing Textbreathing-text | fancy | Components | Free | 1 dep | |
| Circling Elementscircling-elements | fancy | Components | Free | 1 dep | |
| Css Boxcss-box | fancy | Components | Free | 1 dep | |
| Cursor Attractor And Gravitycursor-attractor-and-gravity | fancy | Components | Free | 5 deps | |
| Drag Elementsdrag-elements | fancy | Components | Free | 1 dep |
