Testimonials

Pro

A minimal quote card for social-proof walls. Named parts you assemble: an optional quote mark, the quote, an author row and an optional logo. Stars come from Rating, the headshot from Avatar.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
AR
Alex Rivera
Founder, Lumen
Owning the source is the killer feature. We copy a component in, tweak the recipe, and it still matches.
PN
Priya Nair
Staff Engineer, Cobalt
It looks finished out of the box. The polish on hover and press states is what sold our designers.
DO
Daniel Okafor
Co-founder, Quanta

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add testimonials

Usage#

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Anatomy#

import {  Testimonial, TestimonialMark, TestimonialQuote, TestimonialBody,  TestimonialFooter, TestimonialAuthor, TestimonialName, TestimonialTitle,  TestimonialLogo,} from "@/components/ui/testimonials"<Testimonial>  <TestimonialMark />  <TestimonialQuote>…</TestimonialQuote>  <TestimonialBody>…</TestimonialBody>  <TestimonialFooter>    {/* <Avatar /> */}    <TestimonialAuthor>      <TestimonialName>…</TestimonialName>      <TestimonialTitle>…</TestimonialTitle>    </TestimonialAuthor>    <TestimonialLogo>…</TestimonialLogo>  </TestimonialFooter></Testimonial>

Variants#

The default is plain: a flat, tinted surface with no border line or shadow. outline adds a hairline border, soft trades it for a subtle shadow, and elevated drops the border and lifts the card to feature one quote. There is also a borderless ghost for walls on a tinted section, and bare, which strips the surface and padding entirely so the quote sits flush on the page.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
AR
Alex Rivera
Founder, Lumen
plain
Owning the source is the killer feature. We copy a component in, tweak the recipe, and it still matches.
PN
Priya Nair
Staff Engineer, Cobalt
outline
It looks finished out of the box. The polish on hover and press states is what sold our designers.
DO
Daniel Okafor
Co-founder, Quanta
soft
We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
AR
Alex Rivera
Founder, Lumen
elevated
Owning the source is the killer feature. We copy a component in, tweak the recipe, and it still matches.
PN
Priya Nair
Staff Engineer, Cobalt
ghost
It looks finished out of the box. The polish on hover and press states is what sold our designers.
DO
Daniel Okafor
Co-founder, Quanta
bare

With a rating#

Drop our Rating with readOnly above the quote for star social proof.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
AR
Alex Rivera
Founder, Lumen
Owning the source is the killer feature. We copy a component in, tweak the recipe, and it still matches.
PN
Priya Nair
Staff Engineer, Cobalt
It looks finished out of the box. The polish on hover and press states is what sold our designers.
DO
Daniel Okafor
Co-founder, Quanta

Author on top#

Lead with the byline by rendering the TestimonialFooter first with className="mt-0": a compact, scannable layout for dense walls.

AR
Alex Rivera
Founder, Lumen
We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
PN
Priya Nair
Staff Engineer, Cobalt
Owning the source is the killer feature. We copy a component in, tweak the recipe, and it still matches.
DO
Daniel Okafor
Co-founder, Quanta
It looks finished out of the box. The polish on hover and press states is what sold our designers.

Set divided for a hairline rule above the author row, and drop a TestimonialLogo in the footer for a company wordmark; it sits flush to the trailing edge.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
AR
Alex Rivera
Founder, Lumen
Lumen
Owning the source is the killer feature. We copy a component in, tweak the recipe, and it still matches.
PN
Priya Nair
Staff Engineer, Cobalt
Cobalt

Logo-led#

Lead the card with the company logo instead of trailing it: drop a TestimonialLogo at the top and put a logo lockup inside it (here, a colored mark from the placeholder set). Outside a TestimonialFooter the logo stays on the start edge; it only pushes to the trailing edge inside the footer. Pairs well with variant="bare" for a logo wall.

Lumen
We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
AR
Alex Rivera
Founder, Lumen
Cobalt
Owning the source is the killer feature. We copy a component in, tweak the recipe, and it still matches.
PN
Priya Nair
Staff Engineer, Cobalt
Quanta
It looks finished out of the box. The polish on hover and press states is what sold our designers.
DO
Daniel Okafor
Co-founder, Quanta

Container-less#

The most minimal option: variant="bare" strips the surface entirely (no border, background, padding, or radius) so the quotes sit flush on the page with nothing but whitespace between them.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
AR
Alex Rivera
Founder, Lumen
Owning the source is the killer feature. We copy a component in, tweak the recipe, and it still matches.
PN
Priya Nair
Staff Engineer, Cobalt
It looks finished out of the box. The polish on hover and press states is what sold our designers.
DO
Daniel Okafor
Co-founder, Quanta

Centered pull-quote#

Pair variant="bare" with align="center" for a single standout quote: centers the mark, quote, and byline with no chrome at all.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.
AR
Alex Rivera
Founder, Lumen

Headline and size#

A TestimonialQuote followed by a TestimonialBody becomes the card's headline (semibold, full-strength ink) over the longer quote; drop the body and it reads as a plain pull-quote again. size sets the type scale: md (default) for dense grids and carousels, lg for landing rows and walls (an 18px headline over 16px body and byline), and xl for one quote given room beside a picture (24px over 18px). Pair the bigger steps with an lg Avatar.

size="md"

We shipped the new site in a weekend.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.

AR
Alex Rivera
Founder, Lumen

size="lg"

We shipped the new site in a weekend.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.

AR
Alex Rivera
Founder, Lumen

size="xl"

We shipped the new site in a weekend.

We replaced our half-finished in-house kit in a weekend. Everything felt consistent, down to the focus rings.

AR
Alex Rivera
Founder, Lumen

Drop a TestimonialMark in for a quotation glyph and use variant="elevated" to lift one standout quote.

Radix under the hood means I stopped worrying about keyboard and screen-reader bugs. They are just handled.
ML
Mei Lin
Frontend Lead, Cadence

API reference#

Testimonial

The root card, a <figure> that shares its styles with every part through context. Forwards all native <figure> props; every part accepts className, merged last.

PropTypeDefaultDescription
variant"plain" | "outline" | "soft" | "elevated" | "ghost" | "bare""plain"The surface: a tinted fill, a hairline ring, a soft ring with shadow, a lifted card, no surface (keeps padding), or no surface and no padding.
align"start" | "center""start"center centers the mark, quote and byline, for a single pull-quote.
dividedbooleanfalseAdds a hairline rule above the TestimonialFooter.
size"md" | "lg" | "xl""md"The type scale of the quote, body and byline together. Pair lg and xl with an lg Avatar.
asChildbooleanfalseRenders onto its child element (Radix Slot) instead of a <figure>.
CSS variableDescription
--surfaceSet by the plain and elevated variants to the card's fill, for nested parts that match it.

TestimonialMark

An optional decorative quotation glyph above the quote, aria-hidden. Forwards all native <div> props.

TestimonialQuote

The quote, a <blockquote>. Followed by a TestimonialBody, it styles itself as the headline (semibold, full-strength ink). Forwards all native <blockquote> props.

TestimonialBody

Optional longer quote under a headline TestimonialQuote, quieter and a step smaller. Forwards all native <p> props.

TestimonialFooter

The author row, a <figcaption> pinned to the bottom with mt-auto (pass mt-0 to lead with it). Forwards all native <figcaption> props.

TestimonialAuthor

The name and title stack beside the Avatar. Forwards all native <div> props.

TestimonialName

The author's name. Forwards all native <div> props.

TestimonialTitle

The author's role, muted; truncates at size="md". Forwards all native <div> props.

TestimonialLogo

A company wordmark or logo: trailing edge inside the footer, start edge anywhere else. Forwards all native <div> props.

FAQ#

Testimonial is pure layout, so it does not ship its own stars or avatar. Drop our `Rating` with `readOnly` in for the stars, and our `Avatar` into the `TestimonialFooter` beside the author stack.