{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "animated-testimonials",
  "type": "registry:component",
  "title": "Animated Testimonials",
  "description": "Animated testimonials with blur effect.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "components/xcn/animated-testimonials.tsx",
      "content": "import { motion } from \"motion/react\"\r\nimport { useState } from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nexport type Testimonial = {\r\n  content: string\r\n  image?: string\r\n}\r\n\r\ntype AnimatedTestimonialsProps = {\r\n  testimonials: Array<Testimonial>\r\n  className?: string\r\n  itemClassName?: string\r\n  avatarClassName?: string\r\n  initialBlur?: number\r\n  inactiveBlur?: number\r\n  inactiveOpacity?: number\r\n  transitionDuration?: number\r\n  onActiveIndexChange?: (index: number | null) => void\r\n}\r\n\r\nexport function AnimatedTestimonials({\r\n  testimonials,\r\n  className,\r\n  itemClassName,\r\n  avatarClassName,\r\n  initialBlur = 10,\r\n  inactiveBlur = 4,\r\n  inactiveOpacity = 0.5,\r\n  transitionDuration = 0.2,\r\n  onActiveIndexChange,\r\n}: AnimatedTestimonialsProps) {\r\n  const [activeIndex, setActiveIndex] = useState<number | null>(null)\r\n\r\n  const setIndex = (index: number | null) => {\r\n    setActiveIndex(index)\r\n    onActiveIndexChange?.(index)\r\n  }\r\n\r\n  return (\r\n    <div\r\n      className={cn(\r\n        \"p-2 text-lg text-balance sm:text-xl md:text-2xl lg:text-3xl\",\r\n        className\r\n      )}\r\n    >\r\n      {testimonials.map((testimonial, idx) => (\r\n        <motion.span\r\n          key={testimonial.content}\r\n          className={cn(\"inline\", itemClassName)}\r\n          initial={{ filter: `blur(${initialBlur}px)`, opacity: 0 }}\r\n          animate={{\r\n            filter:\r\n              activeIndex === null\r\n                ? \"blur(0px)\"\r\n                : activeIndex === idx\r\n                  ? \"blur(0px)\"\r\n                  : `blur(${inactiveBlur}px)`,\r\n            opacity:\r\n              activeIndex === null ? 1 : activeIndex === idx ? 1 : inactiveOpacity,\r\n          }}\r\n          transition={{ duration: transitionDuration }}\r\n          onMouseEnter={() => setIndex(idx)}\r\n          onMouseLeave={() => setIndex(null)}\r\n        >\r\n          {testimonial.image ? (\r\n            <img\r\n              src={testimonial.image}\r\n              alt={testimonial.content}\r\n              className={cn(\r\n                \"mr-2 inline-block size-9 rounded-full bg-primary align-middle\",\r\n                avatarClassName\r\n              )}\r\n            />\r\n          ) : (\r\n            <span\r\n              className={cn(\r\n                \"mr-2 inline-block size-9 rounded-full bg-primary align-middle\",\r\n                avatarClassName\r\n              )}\r\n            />\r\n          )}\r\n          {testimonial.content}{\" \"}\r\n        </motion.span>\r\n      ))}\r\n    </div>\r\n  )\r\n}\r\n",
      "type": "registry:component",
      "target": "components/xcn/animated-testimonials.tsx"
    }
  ]
}