prebuiltui

Testimonial

Testimonials 15

About

Here is Testimonial component

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Testimonial to your project and fits it to your theme.

Code

How Testimonial is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

import React from "react";

const App = () => {
  const [tooltip, setTooltip] = React.useState({
    visible: false,
    x: 0,
    y: 0,
    text: "",
  });
  const cardRefs = React.useRef<(HTMLDivElement | null)[]>([]);

  const testimonials = [
    {
      name: "John Doe",
      title: "Frontend Developer",
      message:
        "Integrating this component into our project was seamless and saved us countless hours of development and testing. Highly recommended!",
      image:
        "https://cdn.21st.dev/assets/mirror/20/202f28d9108e13136b34315b1c8dac25678f9dc5cb2f004c713d930cf285e62c.jpg",
    },
    {
      name: "Jane Smith",
      title: "Full Stack Engineer",
      message:
        "This solution not only simplified our workflow but also improved our UI consistency across the board. Excellent tool for modern teams.",
      image:
        "https://cdn.21st.dev/assets/mirror/ce/ce1536afd37b7d4e6c9ffbee65b35e6897d4467ab07efc9b6466b6c1744654f9.jpg",
    },
    {
      name: "Bonnie Green",
      title: "UX Designer",
      message:
        "I was impressed with how intuitive and flexible the design was. It allowed us to rapidly prototype and launch features with confidence.",
      image:
        "https://cdn.21st.dev/assets/mirror/a5/a5daca55ac260069e7a61ad9126a5913eec37ca03cb8cbc29cc37f8d13d2d2dd.jpg",
    },
  ];

  const handleMouseMove = (
    e: React.MouseEvent<HTMLDivElement, MouseEvent>,
    index: number
  ) => {
    const bounds = cardRefs.current[index]?.getBoundingClientRect();
    if (!bounds) return;
    setTooltip({
      visible: true,
      x: e.clientX - bounds.left,
      y: e.clientY - bounds.top,
      text: testimonials[index].name,
    });
  };

  const handleMouseLeave = () => {
    setTooltip((prev) => ({ ...prev, visible: false }));
  };

  return (
    <div className="flex flex-col items-center justify-center gap-6 py-16">
      {/* Title and description now inside container */}
      <div className="text-center max-w-2xl">
        <h1 className="text-4xl font-bold text-gray-900">Testimonials</h1>
        <p className="text-gray-500 mt-2">
          We have collected some testimonials from our users. They are real
          people who have used our product.
        </p>
      </div>

      <div className="flex flex-wrap items-center justify-center gap-6 mt-10">
        {testimonials.map((testimonial, index) => (
          <div
            key={index}
            ref={(el) => (cardRefs.current[index] = el)}
            onMouseMove={(e) => handleMouseMove(e, index)}
            onMouseLeave={handleMouseLeave}
            className="relative border border-gray-200 rounded-lg overflow-hidden max-w-sm hover:shadow-lg transition-shadow duration-300"
          >
            {tooltip.visible && tooltip.text === testimonial.name && (
              <span
                className="absolute px-2.5 py-1 text-sm rounded text-nowrap bg-indigo-500 text-white pointer-events-none transition-all duration-300"
                style={{
                  top: tooltip.y + 8,
                  left: tooltip.x + 8,
                  transition: "all 0.3s ease-out",
                  animationDelay: "0.2s",
                }}
              >
                {tooltip.text}
              </span>
            )}

            <div className="flex flex-col items-center justify-center p-8 text-center">
              <div className="mb-4 text-gray-500">
                <h3 className="text-lg font-semibold text-gray-900">
                  Very easy to integrate
                </h3>
                <p className="my-4 text-sm line-clamp-3">
                  {testimonial.message}
                </p>
              </div>
              <div className="flex items-center justify-center">
                <img
                  className="rounded-full w-9 h-9"
                  src={testimonial.image}
                  alt={`${testimonial.name} profile`}
                />
                <div className="space-y-0.5 font-medium text-left ml-3">
                  <p>{testimonial.name}</p>
                  <p className="text-sm text-gray-500">{testimonial.title}</p>
                </div>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

export default App;

More by prebuiltui

View all
  • Image Gallery

    Image Gallery

    1.3K
  • Hero Section

    Hero Section

    412
  • Feature Sections

    Feature Sections

    344
  • Cards

    Cards

    231
  • FAQ Sections

    FAQ Sections

    177
  • Form

    Form

    136
  • Login Form

    Login Form

    125
  • Pricing Cards

    Pricing Cards

    86

More in Testimonials

View all
  • testimonial

    testimonial

    797
  • Staggered Testimonials Grid

    Staggered Testimonials Grid

    143
  • Testimonial 2

    Testimonial 2

    32
  • Voice Testimonial

    Voice Testimonial

    120
  • Testimonial Card

    Testimonial Card

    69
  • Split Sign In Form

    Split Sign In Form

    16
  • Testimonials Marquee

    Testimonials Marquee

    574
  • Card Studio

    Card Studio

    15