"use client" import type { MotionProps } from "motion/react" import type { CSSProperties, ElementType, JSX } from "react" import { cn } from "@/lib/utils" import { motion } from "motion/react" import { memo, useMemo } from "react" type MotionHTMLProps = MotionProps & Record // Cache motion components at module level to avoid creating during render const motionComponentCache = new Map< keyof JSX.IntrinsicElements, React.ComponentType >() const getMotionComponent = (element: keyof JSX.IntrinsicElements) => { let component = motionComponentCache.get(element) if (!component) { component = motion.create(element) motionComponentCache.set(element, component) } return component } export interface TextShimmerProps { children: string as?: ElementType className?: string duration?: number spread?: number } const ShimmerComponent = ({ children, as: Component = "p", className, duration = 2, spread = 2, }: TextShimmerProps) => { const MotionComponent = useMemo( () => getMotionComponent(Component as keyof JSX.IntrinsicElements), [Component] ) const dynamicSpread = useMemo( () => (children?.length ?? 0) * spread, [children, spread] ) return ( // eslint-disable-next-line react-hooks/static-components -- component is cached at module level via motionComponentCache {children} ) } export const Shimmer = memo(ShimmerComponent)