UNPKG

xlibs-components

Version:

Modern React component library with Aceternity, MagicUI, and ShadCN components for building beautiful web applications

42 lines (41 loc) 2.62 kB
"use client"; import { jsx as _jsx } from "react/jsx-runtime"; import React, { useState, useEffect, useId } from "react"; import { motion } from "framer-motion"; import { cn } from '../../lib/utils.js'; export function ContainerTextFlip({ words = ["better", "modern", "beautiful", "awesome"], interval = 3000, className, textClassName, animationDuration = 700, }) { const id = useId(); const [currentWordIndex, setCurrentWordIndex] = useState(0); const [width, setWidth] = useState(100); const textRef = React.useRef(null); const updateWidthForWord = () => { if (textRef.current) { // Add some padding to the text width (30px on each side) const textWidth = textRef.current.scrollWidth + 30; setWidth(textWidth); } }; useEffect(() => { // Update width whenever the word changes updateWidthForWord(); }, [currentWordIndex]); useEffect(() => { const intervalId = setInterval(() => { setCurrentWordIndex((prevIndex) => (prevIndex + 1) % words.length); // Width will be updated in the effect that depends on currentWordIndex }, interval); return () => clearInterval(intervalId); }, [words, interval]); return (_jsx(motion.p, { layout: true, layoutId: `words-here-${id}`, animate: { width }, transition: { duration: animationDuration / 2000 }, className: cn("relative inline-block rounded-lg pt-2 pb-3 text-center text-4xl font-bold text-black md:text-7xl dark:text-white", "[background:linear-gradient(to_bottom,#f3f4f6,#e5e7eb)]", "shadow-[inset_0_-1px_#d1d5db,inset_0_0_0_1px_#d1d5db,_0_4px_8px_#d1d5db]", "dark:[background:linear-gradient(to_bottom,#374151,#1f2937)]", "dark:shadow-[inset_0_-1px_#10171e,inset_0_0_0_1px_hsla(205,89%,46%,.24),_0_4px_8px_#00000052]", className), children: _jsx(motion.div, { transition: { duration: animationDuration / 1000, ease: "easeInOut", }, className: cn("inline-block", textClassName), ref: textRef, layoutId: `word-div-${words[currentWordIndex]}-${id}`, children: _jsx(motion.div, { className: "inline-block", children: words[currentWordIndex].split("").map((letter, index) => (_jsx(motion.span, { initial: { opacity: 0, filter: "blur(10px)", }, animate: { opacity: 1, filter: "blur(0px)", }, transition: { delay: index * 0.02, }, children: letter }, index))) }) }) }, words[currentWordIndex])); }