shadcn.io is not affiliated with official shadcn/ui
Stacked User Quote Banner Block for React
A start-aligned post from a user of a UI kit, drawn like a social post with no network in it: avatar, name and handle, the quote, the post's age and a like button whose count rolls and rolls back.
Installation
Overview
A user's post for React with Base UI, the kind of unprompted praise that deserves a card of its own. A framed card with + marks on its corners sits at the start of the column, not in the middle: a figure opens with its caption, an initials avatar with the name and the @handle, then the quote in normal weight, the way a feed would draw it, with no network name and no logo. A foot row under a solid rule shows how long ago it was posted, "3 hr. ago", and a like button, the catalog's Counter Button: a heart and a count that rolls to the next number when it's pressed, and rolls back on the next press. The markup is a figure with its figcaption first and a blockquote. It's built from Guides, Avatar and Counter Button with a Lucide icon and your theme's tokens for every colour. For social proof pages, changelogs and launch announcements where the voice matters more than the numbers.
FAQ
How do I change the post?
Edit POST at the top of the file: the name, the @handle, the initials, the text and the number of likes the post starts with. Keep the quote to two lines on a desktop; a post that needs more room is a testimonial and wants the other card. Only post what the person published, with their permission.
How does the like button work?
The button shows the starting count, POST.likes. A press adds one and the digits roll to the new number; the next press takes it back and they roll down. It does that by flipping the step between +1 and -1 and keeping the count between the two numbers. The button is a toggle (aria-pressed), the heart fills when it's on, and a polite status inside the button speaks the new count. It lives on the page only; to keep a like, send it to your server in onCountChange.
Why does the age never change?
It's written for the reader's language with Intl.RelativeTimeFormat and a fixed three hours, so it can't go stale or differ between the server and the browser. In a real post, compute it from the post's date after the first render, or show the date. The time element carries a duration, so it stays valid.
Related
- Pro
Stacked Testimonial Banner
Stacked cardsA single customer quote for a block library: a quote mark, the quote in medium weight, an initials avatar with name and role, and a tinted band with the result in numbers and a case-study link.
- 123Pro
Numbered Social Proof Banner
Numbered listsA leaderboard banner for an open-source tool: the top three contributors this week as a framed, ranked list on shared hairlines, each cell one link with an initials avatar and a merged count.
- Pro
Activity Proof Stacked Banner
Stacked cardsA centred social-proof card for a team workspace: a line saying who and how many teams upgraded this week, with the count rolling up, a sentence, a ringed avatar stack and a Shine Button.
- Pro
Testimonials Centre-Mode Carousel
Carousels and decksA centre-mode quote carousel for a support inbox: a centred header with a Shine Button above one hairline band, where the active quote sits in the middle on a raised card with its neighbours peeking in, with previous and next buttons, a dot per quote and arrow-key control.
- Pro
Stacked Partner Logo Banner
Stacked cardsA partnership card for a hosting platform: a lockup band joins two made-up wordmarks across a solid divider with a cross, over a badge, a heading, one sentence and an underlined link.
- Pro
Achievement Ribbon Banner
Stacked cardsA centred milestone card for a running app: a corner ribbon reading Unlocked, a trophy, a heading, one sentence, a track of five pips with three earned, the next milestone named, and a Shine Button.