Skip to content
Template Empire
Browse components

Case Study Selector

A free testimonial selector that keeps every company visible while one case study and outcome takes focus.

Customer evidence

Proof from teams that ship

Select a company to see the result behind the quote.

Case study 01

Northstar

We replaced three hand-offs with one visible decision trail. The team now knows why a release moved.

Maya ChenVP Product

Case study 02

Arc Systems

Evidence sits beside the work instead of disappearing into another dashboard. Reviews are shorter and better.

Theo MartinEngineering Director

Case study 03

Fieldnote

Every launch starts with the same definition of success, so product and go-to-market move together.

Priya ShahChief Operating Officer

Customise

24px

Code

<QuoteCaseStudySelector
  title="Proof from teams that ship"
  description="Select a company to see the result behind the quote."
  items={[
    {
      id: "northstar",
      company: "Northstar",
      quote: "We replaced three hand-offs with one visible decision trail. The team now knows why a release moved.",
      author: "Maya Chen",
      role: "VP Product",
      result: "3.4x",
      resultLabel: "faster release cycles",
    },
    {
      id: "arc",
      company: "Arc Systems",
      quote: "Evidence sits beside the work instead of disappearing into another dashboard. Reviews are shorter and better.",
      author: "Theo Martin",
      role: "Engineering Director",
      result: "41%",
      resultLabel: "less review time",
    },
    {
      id: "fieldnote",
      company: "Fieldnote",
      quote: "Every launch starts with the same definition of success, so product and go-to-market move together.",
      author: "Priya Shah",
      role: "Chief Operating Officer",
      result: "18 days",
      resultLabel: "saved per launch",
    },
  ]}
/>

Case Study Selector is a free testimonial component for Next.js and React that presents customer evidence as manual company tabs with no autoplay. Built with Motion and styled with Tailwind, it pairs each quote with a visible outcome metric so visitors can move directly to the proof that matters to them.

The selector becomes a vertical master-detail layout on desktop and a touch-scrollable horizontal tab list on mobile. Every case study is rendered once in a shared intrinsic grid cell, so the tallest story reserves the panel height, while JavaScript-free pages restore the same articles as a readable stacked list with fragment links.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/quote-case-study-selector

Usage

import {
  QuoteCaseStudySelector,
  type CaseStudyItem,
} from "@/components/quote-case-study-selector";

const caseStudies: CaseStudyItem[] = [
  {
    id: "northstar",
    company: "Northstar",
    quote:
      "We replaced three hand-offs with one visible decision trail. The team now knows why a release moved.",
    author: "Maya Chen",
    role: "VP Product",
    result: "3.4x",
    resultLabel: "faster release cycles",
  },
  {
    id: "arc",
    company: "Arc Systems",
    quote:
      "Evidence sits beside the work instead of disappearing into another dashboard. Reviews are shorter and better.",
    author: "Theo Martin",
    role: "Engineering Director",
    result: "41%",
    resultLabel: "less review time",
  },
];

export function CustomerProof() {
  return (
    <QuoteCaseStudySelector
      title="Proof from teams that ship"
      description="Select a company to see the result behind the quote."
      items={caseStudies}
    />
  );
}

Props

PropTypeDefaultDescription
titlestringrequiredSection heading rendered as an h2.
descriptionstringundefinedOptional section introduction.
itemsCaseStudyItem[]requiredTwo to six case studies with a stable ID, company, quote, author, optional role and logo, result, and result label.
valuestringundefinedControlled active item ID.
defaultValuestringfirst item IDInitial item ID for uncontrolled use. Invalid IDs fall back to the first case study.
onValueChange(id: string) => voidundefinedCalled once after pointer or keyboard selection changes the active item.
panelOffsetnumber24Directional panel travel in pixels, clamped from 0 to 48 and ignored under reduced motion.
classNamestringundefinedAdditional classes merged onto the section root.

Customisation

Case Study Selector exposes four Tier 3 colour tokens. Override --case-study-tab for inactive selector surfaces, --case-study-active for the shared active indicator, --case-study-panel for the quote surface and --case-study-border for the section rules. The panelOffset prop controls real transition geometry from 0 to 48 pixels, while all wording and case-study data stay in your items array.

.customer-proof {
  --case-study-tab: var(--surface);
  --case-study-active: var(--primary);
  --case-study-panel: var(--background);
  --case-study-border: var(--border);
}

<QuoteCaseStudySelector
  className="customer-proof"
  title="Proof from teams that ship"
  items={caseStudies}
  panelOffset={32}
/>

Frequently asked questions

Is Case Study Selector free for commercial use?
Yes. Case Study Selector is MIT licensed, so you can use it in personal and commercial projects without attribution.
How do keyboard navigation and reduced motion work in Case Study Selector?
The company controls follow the WAI-ARIA tabs pattern with roving focus. Up and Down move through the vertical desktop list, Left and Right move through the horizontal mobile list, and Home and End jump to the first or last company. With reduced motion enabled the shared indicator changes instantly and panels use a short opacity-only crossfade with no directional movement.
How can I customise the case-study panel?
Pass panelOffset from 0 to 48 to tune the directional travel, and override the four case-study colour tokens from a wrapper or your theme. Company names, quotes, authors, roles, logos and outcome metrics all come from the items array, so the component structure stays stable while the evidence remains yours.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with customer proof, product storytelling and conversion sections designed as one system.Explore Template Empire templates