KQ-1279 · REVIEW/CARD

Review Card

A product review that arrives as you read it: the first time it comes into view, the visible lines ink in one at a time under a soft left-to-right edge while the stars fill on the same linear clock, a liquid clipped by the star shapes whose front ripples as it travels and sloshes back on springs.recoil when it lands. A long review folds under a fade and Read more unrolls it to its measured height on the spring you choose (snap, glide or drift), ticking per line; Helpful tallies roll on snap and bump on recoil, and the photos fan out of their seeded deck on snap. Read more is a disclosure that moves focus into the text, Escape rolls it back up and returns focus, and votes are aria-pressed toggles.

KQ-1279 · REVIEW/CARD

12 Sep 2026

Carries a whole day, rain and all

Odile M. · Verified buyer

I bought the Daily in Moss for the commute and it has carried a laptop, a lunch tin and a wet umbrella every day since without losing its shape. The waxed canvas shrugs off rain and the straps sit flat on a coat.

Two small gripes: the inside pocket is too shallow for a phone, and the leather patch scuffed in the first week. Neither would stop me buying the Weekender next.

Harbour tote · Moss · Daily

Helpful?

4 of 5 · 24 found this helpful

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/review-card

Props

rating
number
default 4
The reviewer's rating, 0 to 5; a fraction fills part of a star.
title
string
default "Carries a whole day, rain and all"
The review's title: the card's heading.
body
string
default —
The review; a blank line starts a new paragraph.
author
string
default "Odile M."
Who wrote it.
authorDetail
string
default "Verified buyer"
After the author.
date
Date | number
default 12 Sep 2026
When it was written.
timeZone
string
default "UTC"
The zone dates print in, so the server and the browser print the same day.
formatDate
(date: Date, timeZone: string) => string
default "12 Sep 2026"
How the date is printed.
product
string
default "Harbour tote · Moss · Daily"
What was bought, above the vote.
photos
ReviewPhoto[]
default defaultReviewPhotos
The reviewer's photos: id, alt, and a seed for the procedural scene or an image node.
onPhotoOpen
(id: string) => void
default —
A thumbnail was pressed.
helpful
number
default 24
People who found it helpful, not counting this visitor.
unhelpful
number
default 2
People who did not, not counting this visitor.
vote / defaultVote
"up" | "down" | null
default null
This visitor's vote, controlled or initial.
onVoteChange
(vote: "up" | "down" | null) => void
default —
Fires from the vote press, with the new vote or null when undone.
expanded / defaultExpanded
boolean
default false
Whether the long review is unrolled, controlled or initial.
onExpandedChange
(expanded: boolean) => void
default —
Fires from Read more, Show less or Escape.
lines
number
default 4
Lines shown while the review is folded.
pace
number
default 200
How long each line takes to ink in on view, in ms; the stars take the same time in all.
fill
number
default 0.5
How liquid the stars' fill is, 0 to 1: a straight sweep, or a front that ripples and sloshes.
unroll
"snap" | "glide" | "drift"
default "glide"
The spring that unrolls and rolls up the fold.
fan
number
default 0.5
How far the photos fan out on hover, 0 to 1.
starColor
string
default gold pigment from --warn
The stars' liquid; any CSS colour, with the outline mixed from it.
revealOnView
boolean
default true
Ink the review in the first time it comes into view; off, it starts shown.
headingLevel
2 | 3 | 4
default 3
The heading's level.
sound
boolean
default false
A tick per line as the visitor unrolls the review, a pop for a vote.
disabled
boolean
default false
Locks the fold, the votes and the photos.
className
string
default —
Classes for the article.