Animated Testimonials
scrollxui/animated-testimonialsFreeComponent
Minimal testimonials with image and quote for clean, modern design.
Live preview
live · rendered by the registry
Rendered by scrollxui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://scrollxui.dev/registry/animated-testimonials.jsonSource
1import React from 'react';23import { cn } from '@/lib/utils';45interface Testimonial {6 name: string;7 image: string;8 description: string;9 handle: string;10}1112interface AnimatedCanopyProps extends React.HTMLAttributes<HTMLDivElement> {13 vertical?: boolean;14 repeat?: number;15 reverse?: boolean;16 pauseOnHover?: boolean;17 applyMask?: boolean;18}1920const AnimatedCanopy = ({21 children,22 vertical = false,23 repeat = 4,24 pauseOnHover = false,25 reverse = false,26 className,27 applyMask = true,28 ...props29}: AnimatedCanopyProps) => (30 <div31 {...props}32 className={cn(33 'group relative flex h-full w-full overflow-hidden p-2 [--duration:10s] [--gap:12px] gap-(--gap)',34 vertical ? 'flex-col' : 'flex-row',35 className,36 )}37 >38 {Array.from({ length: repeat }).map((_, index) => (39 <div40 key={`item-${index}`}41 className={cn('flex shrink-0 gap-(--gap)', {42 'group-hover:paused': pauseOnHover,43 'direction-reverse': reverse,44 'animate-canopy-horizontal flex-row': !vertical,45 'animate-canopy-vertical flex-col': vertical,46 })}47 >48 {children}49 </div>50 ))}51 {applyMask && (52 <div53 className={cn(54 'pointer-events-none absolute inset-0 z-10 h-full w-full from-white/50 from-5% via-transparent via-50% to-white/50 to-95% dark:from-gray-800/50 dark:via-transparent dark:to-gray-800/50',55 vertical ? 'bg-linear-to-b' : 'bg-linear-to-r',56 )}57 />58 )}59 </div>60);6162const TestimonialCard = ({63 testimonial,64 className,65}: {66 testimonial: Testimonial;67 className?: string;68}) => (69 <div70 className={cn(71 'group mx-2 flex h-32 w-80 shrink-0 cursor-pointer overflow-hidden rounded-xl border border-transparent p-3 transition-all hover:border-blue-400 hover:shadow-[0_0_10px_#60a5fa] dark:hover:border-blue-400',72 className,73 )}74 >75 <div className='flex items-start gap-3'>76 <div className='relative h-12 w-12 shrink-0 overflow-hidden rounded-full border-2 border-gray-200 dark:border-gray-600'>77 <img78 src={testimonial.image}79 alt={testimonial.name}80 className='h-full w-full not-prose object-cover'81 />82 </div>83 <div className='flex-1'>84 <div className='flex items-baseline gap-2'>85 <span className='text-sm font-bold text-foreground'>86 {testimonial.name}87 </span>88 <span className='text-xs text-muted-foreground'>89// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from scrollxui
All 180 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | scrollxui | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | scrollxui | Components | Free | 7 deps | |
| Animated Buttonanimated-button | scrollxui | Components | Free | 4 deps | |
| Animated Tabsanimated-tabs | scrollxui | Components | Free | 1 dep | |
| Animated TextGenerateanimated-textgenerate | scrollxui | Components | Free | 3 deps | |
| Announcementannouncement | scrollxui | Components | Free | 5 deps | |
| Aspect Ratioaspect-ratio | scrollxui | Components | Free | 1 dep | |
| Aurora Dotsaurora-dots | scrollxui | Components | Free | 2 deps |
