Skip to content
Cards

Cards

TestimonialCard

Review card with star rating, quoted text and an initial-letter avatar.

npx bezel-add add testimonial-card

About

A testimonial card for React that shows a star rating, the quoted review in italics and the reviewer's name with an optional role. The avatar is generated from the first letter of the name, so no photo is needed. The stars are exposed to screen readers as one image with a spoken rating, which suits review sections on landing and product pages.

Key props: testimonial (object with rating, text, name and optional role)

packages/ui/src/cards/TestimonialCard.tsx · 51 lines

import { Star } from "lucide-react";

export interface Testimonial {
  rating: number;
  text: string;
  name: string;
  role?: string;
}

type Props = {
  testimonial: Testimonial;
};

export function TestimonialCard({ testimonial }: Props) {
  return (
    <div className="bg-white rounded-2xl p-6 shadow-sm border border-neutral-100">
      {/* The stars are one image with a spoken rating. Gold fill keeps the look;
          the darker gold outline is what clears 3:1 on white. */}
      <div
        role="img"
        aria-label={`Rated ${testimonial.rating} out of 5`}
        className="flex items-center gap-0.5 mb-4"
      >
        {Array.from({ length: testimonial.rating }).map((_, i) => (
          <Star
            key={i}
            size={14}
            aria-hidden
            className="fill-[color:var(--bz-gold-fill,#c9a227)] text-[color:var(--bz-gold,#7a6015)]"
          />
        ))}
      </div>
      <p className="text-neutral-600 text-sm leading-relaxed mb-5 italic">
        &ldquo;{testimonial.text}&rdquo;
      </p>
      <div className="flex items-center gap-3">
        <div className="w-10 h-10 rounded-full bg-neutral-200 flex items-center justify-center">
          <span className="text-neutral-600 font-bold text-sm">
            {testimonial.name.charAt(0)}
          </span>
        </div>
        <div>
          <p className="text-neutral-900 font-semibold text-sm">{testimonial.name}</p>
          {testimonial.role && (
            <p className="text-[color:var(--bz-ink-subtle,#6b6b70)] text-xs">{testimonial.role}</p>
          )}
        </div>
      </div>
    </div>
  );
}