Staaarter

Tabbed Plan Cards With Checklist

A tab-switched grid of plan cards. Each tab (e.g. Monthly/Annual) reveals its own set of plan cards, each with a title, full-width CTA button, price subtitle, description, and a checklist with check icons.

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 button dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/tabbed-plan-cards-checklist.json

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

Usage

The file also exports feature169Demo, 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 { Feature169, feature169Demo } from "@/components/blocks/feature/feature169";

export default function Page() {
  return <Feature169 {...feature169Demo} />;
}

Props

PropTypeDefaultDescription
eyebrowstringnoneSmall label above the heading.
headingReactNodenoneSection heading.
descriptionstringnoneSupporting copy under the heading.
tabsPlanTab[]noneTabs, each with its own array of plan cards; the first is active on mount.
classNamestringnoneExtra classes for the outer section element.

Types

type PlanCard = {
  title: string;
  subtitle: string; // price, e.g. "$19/mo"
  description: string;
  ctaLabel: string;
  checklist: string[];
};

type PlanTab = {
  label: string;
  plans: PlanCard[];
};

Behavior notes

  • Real client-side state: clicking a tab switches the active `PlanTab`; the first tab (index 0) is active by default on mount. The tab bar only renders when more than one tab is supplied.
  • The active tab's plan-card grid layout is chosen from `plans.length`: 2 or fewer cards center as a flex row, a count that's a multiple of 4 uses a 4-column grid, and any other count uses a 3-column grid.
  • Each card's CTA button is decorative (no `onClick`/submit action), matching the rest of the catalog's inert pricing CTAs.
  • Demo props live in a sibling feature169.demo.tsx (no "use client" directive) per the client-block demo-file-split rule.