"use client" import { cn } from "@lib/utils" import { AnimatePresence, motion, type Transition, type Variants, } from "motion/react" import { useMemo, useId } from "react" export type TextMorphProps = { children: string as?: React.ElementType className?: string style?: React.CSSProperties variants?: Variants transition?: Transition } export function TextMorph({ children, as: Component = "p", className, style, variants, transition, }: TextMorphProps) { const uniqueId = useId() const characters = useMemo(() => { const charCounts: Record = {} return children.split("").map((char) => { const lowerChar = char.toLowerCase() charCounts[lowerChar] = (charCounts[lowerChar] || 0) + 1 return { id: `${uniqueId}-${lowerChar}${charCounts[lowerChar]}`, label: char === " " ? "\u00A0" : char, } }) }, [children, uniqueId]) const defaultVariants: Variants = { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, } const defaultTransition: Transition = { type: "spring", stiffness: 280, damping: 18, mass: 0.3, } return ( // @ts-expect-error - style is optional {characters.map((character) => ( ))} ) }