| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- 'use client'
- import { cn } from '../../utils'
- import { motion } from 'motion/react'
- import {
- type CSSProperties,
- type ElementType,
- type JSX,
- memo,
- useMemo,
- } from 'react'
- export type 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 = motion.create(
- Component as keyof JSX.IntrinsicElements
- )
- const dynamicSpread = useMemo(
- () => (children?.length ?? 0) * spread,
- [children, spread]
- )
- return (
- <MotionComponent
- animate={{ backgroundPosition: '0% center' }}
- className={cn(
- 'relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent',
- '[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]',
- className
- )}
- initial={{ backgroundPosition: '100% center' }}
- style={
- {
- '--spread': `${dynamicSpread}px`,
- backgroundImage:
- 'var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))',
- } as CSSProperties
- }
- transition={{
- repeat: Number.POSITIVE_INFINITY,
- duration,
- ease: 'linear',
- }}
- >
- {children}
- </MotionComponent>
- )
- }
- export const Shimmer = memo(ShimmerComponent)
|