Staaarter

Before/After Comparison Toggle

A comparison section with a pill-style Before/After toggle above a list of feature items. Switching the toggle swaps in the other set of items, and each row fades and slides in on its own staggered delay so the new list animates in item by item rather than popping in all at once.

By Staaarter Team
Feature
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/before-after-comparison-toggle.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/feature/feature102.tsx instead.

Usage

The file also exports feature102Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Feature102, feature102Demo } from "@/components/blocks/feature/feature102";

export default function Page() {
  return <Feature102 {...feature102Demo} />;
}

Props

PropTypeDefaultDescription
eyebrowstringundefinedSmall label above the heading; omitted entirely when unset.
headingReactNodenoneSection heading.
descriptionstringundefinedSupporting copy under the heading.
beforeLabelstring"Before"Label on the toggle's first segment.
afterLabelstring"After"Label on the toggle's second segment.
beforeComparisonItem[]noneItems shown while the toggle is set to "before".
afterComparisonItem[]noneItems shown while the toggle is set to "after".
classNamestringundefinedExtra classes for the outer section element.

Types

type ComparisonItem = {
  title: string;
  description: string;
};

Behavior notes

  • Real client-side state: clicking a toggle segment sets useState<"before" | "after">, which swaps the rendered item list and the toggle's own visual state (aria-pressed and background) between the two segments.
  • "use client" component, so its demo props live in the sibling feature102.demo.tsx file per this repo's client/demo-file-split rule, not in feature102.tsx itself.
  • The staggered fade-in is real: each row is keyed by `${mode}-${item.title}`, so switching modes remounts every row and replays a `tw-animate-css` enter animation (fade + slight slide) with a per-index `animationDelay` set inline (`index * 80ms`), producing a genuine staggered reveal rather than a single simultaneous fade.
  • The pill toggle is a two-segment `role="group"` of native buttons with `aria-pressed` on each segment, not a single checkbox, so both the pressed segment and the underlying state stay in sync for assistive tech.
  • Each row's leading icon (check for "after", x for "before") is purely decorative styling driven by the current mode, not per-item data.