Shake Testimonial Card
uselayouts/shake-testimonial-cardFreeComponent
An eye-catching testimonial card with playful animations.
Live preview
live · rendered by the registry
Rendered by uselayouts on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://uselayouts.com/r/shake-testimonial-card.jsonSource
1"use client";23import React, { useState, useEffect, useCallback } from "react";4import { motion, AnimatePresence } from "motion/react";5import { cn } from "@/lib/utils";67interface Testimonial {8 id: number;9 name: string;10 role: string;11 avatar: string;12 content: string;13 color: string;14 textColor: string;15}1617// Change Here18const testimonials: Testimonial[] = [19 {20 id: 1,21 name: "Marcus Thorne",22 role: "Head of Product, EcoStream",23 avatar: "/ui/memoji/1.svg",24 content:25 "The interface is so intuitive that our team was up and running in hours. Highly recommended for fast-moving startups.",26 color: "#E0F2FE",27 textColor: "#1E3A8A",28 },29 {30 id: 2,31 name: "Elena Rodriguez",32 role: "Director of UX, CreativeFlow",33 avatar: "/ui/memoji/6.svg",34 content:35 "We've tried dozens of tools, but this one stands out for its elegant design. It's a game-changer for our workflow.",36 color: "#F3E8FF",37 textColor: "#581C87",38 },39 {40 id: 3,41 name: "Sarah Jenkins",42 role: "CEO, TechNova",43 avatar: "/ui/memoji/4.svg",44 content:45 "Scaling our infrastructure used to be a nightmare until we found this platform. Now we can focus on building features.",46 color: "#DCFCE7",47 textColor: "#064E3B",48 },49 {50 id: 4,51 name: "David Kim",52 role: "CTO, NextGen Solutions",53 avatar: "/ui/memoji/6.svg",54 content:55 "The security features alone are worth every penny. Our clients feel safer knowing their data is protected by encryption.",56 color: "#FEF9C3",57 textColor: "#713F12",58 },59];6061export default function ShakeTestimonial() {62 const [cards, setCards] = useState(testimonials);63 const [isAnimating, setIsAnimating] = useState(false);6465 const handleNext = useCallback(() => {66 if (isAnimating) return;67 setIsAnimating(true);6869 setTimeout(() => {70 setCards((prev) => {71 const [first, ...rest] = prev;72 return [...rest, first];73 });74 setIsAnimating(false);75 }, 600);76 }, [isAnimating]);7778 useEffect(() => {79 const interval = setInterval(() => {80 handleNext();81 }, 1500);82 return () => clearInterval(interval);83 }, [handleNext]);8485 return (86 <div className="flex items-center justify-center w-full bg-transparent p-4 overflow-hidden py-4 min-h-[650px] max-sm:min-h-[500px]">87 <div88 className="relative w-full max-w-[370px] h-[240px] lg:max-w-[440px] lg:h-[310px] md:h-[320px]"89 style={{ perspective: "1200px" }}90// … truncated
What it pulls in
npm packages
Files it writes
More from uselayouts
All 26 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| 3D Book3d-book | uselayouts | Components | Free | 3 deps | |
| Animated Collectionanimated-collection | uselayouts | Components | Free | 5 deps | |
| Bento Cardbento-card | uselayouts | Components | Free | 5 deps | |
| Bottom Menubottom-menu | uselayouts | Components | Free | 6 deps | |
| Bucketbucket | uselayouts | Components | Free | 5 deps · 2 files | |
| Day Pickerday-picker | uselayouts | Components | Free | 5 deps | |
| Delete Buttondelete-button | uselayouts | Components | Free | 5 deps | |
| Discover Buttondiscover-button | uselayouts | Components | Free | 5 deps |
