Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Pin a Quote Testimonials Block for Svelte

Four quote rows in a ruled list with Pin toggles: the pinned quote moves up into a large featured card, a raised panel in a tinted shell with + marks, split from the list by a solid divider, under a compact header with a Shine Button.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

A testimonials section where the visitor, or you, picks the featured quote, for Svelte with Ark UI. A compact header names the section and carries one Shine Button. Below it the page column splits at lg with a solid divider: on one side the featured stage, a raised card inside a tinted shell with + marks on its corners; on the other four short quotes in a ruled list, each with a Pin toggle. The pinned one is shown large in the stage under a "Pinned" badge; pinning another quote swaps them, and unpinning shows a calm empty slot. The first quote is pinned on load, so the section opens complete, and on a phone the stage comes first with the list below. One piece of state drives everything: the pinned id. The stage holds every card in one grid cell, so it's as tall as the tallest and nothing around it moves. The fictional product is Plover, a team workspace. It's built from Toggle, Badge, Avatar, Guides and Shine Button, with CSS transitions only and your theme's tokens; the lit toggle is in the text colour, never the primary. For landing pages with a few strong quotes where you'd like to preview which one leads.

FAQ

How does pinning work?

The component keeps one pinned id. Each row's toggle is pressed when its id is the pinned one; pressing it sets the id, and pressing the pinned one again clears it. The stage shows the card whose id matches, or the empty slot when nothing is pinned. To pin more than one quote, keep a list of ids and render a card for each.

Why doesn't the page jump when I pin another quote?

Every featured card, and the empty slot, is stacked in one grid cell, so the stage always takes the height of the tallest. The cards that aren't pinned are invisible and inert, and the new one fades in with an opacity transition. Quotes of very different lengths just make the stage as tall as the longest one.

How do keyboards and screen readers use it?

Each Pin is a real toggle button reading "Pin Bao Tran's quote, toggle button, pressed" when it's lit. Tab moves through the four; Space and Enter pin and unpin. The cards that aren't showing are hidden from assistive technology and can't take focus. A polite status line announces "Pinned Lena Albrecht's quote as the featured one" after each press, and says nothing on load.

What are the Pinned badge and the shell around the card?

The badge is an outline Badge with a pin icon, decoration for the state the toggle already announces. The shell is a tinted box with a hairline border and + marks on its corners, holding a raised bg-card panel with a soft shadow and a ring: emphasis comes from that structure, and no part of the card is filled with the primary colour.

Does the pin persist or change the real page?

No. It's local state in the preview, so a reload goes back to the first quote. To keep a choice, send it to your CMS or settings from pin, or read the pinned id from your data instead of state and drop the toggles.

How does it fit on a phone?

Below lg the divider becomes a rule: the stage first, then the list. The featured quote's type steps down to text-xl, and in the list each Pin sits at the end of the author line. Nothing has a fixed width or height, and the block fits within about two and a half screens at 375 px.

How is the Shine Button built on each library?

The header's button is the block's only primary control, a link to your customer wall. The button's asChild receives its props: spread them onto your router's link.