Staaarter

Billing Feature Comparison Table

A feature-by-feature comparison table for pricing pages with more than one plan. Each feature row can hold a boolean (rendered as a check or a dash) or a plain value like a limit or a duration, one plan can be marked highlighted for a tinted column that runs from the header through the footer, and the whole table scrolls horizontally on narrow screens instead of collapsing.

By Staaarter Team
Billing
Updated July 9, 2026
Docs
Live preview

Docs

Installation

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

npx shadcn add https://staaarter.com/r/billing-feature-comparison-table.json

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

Usage

The file also exports billing58Demo, 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 { Billing58, billing58Demo } from "@/components/blocks/billing/billing58";

export default function Page() {
  return <Billing58 {...billing58Demo} />;
}

Props

PropTypeDefaultDescription
headingstring"Compare plans"Heading above the table.
descriptionstringnoneSupporting sentence under the heading.
plansComparisonPlan[]noneColumns of the table, rendered in the order given.
featuresComparisonFeature[]noneRows of the table, rendered in the order given.
ctaLabelstring"Choose plan"Label on every plan's footer button.
classNamestringnoneExtra classes for the outer wrapper.

Types

interface ComparisonPlan {
  id: string;
  name: string;
  price: string;
  badge?: string;
  highlighted?: boolean;
  ctaHref?: string;
}

interface ComparisonFeature {
  id: string;
  label: string;
  values: Record<string, boolean | string>;
}

Behavior notes

  • Each feature's values map is keyed by plan id; true renders a check icon, false or a missing key renders a dash, any string renders as plain text for numeric or tiered limits.
  • Setting highlighted: true on a plan adds a tinted background and a side border that spans the header cell, every body cell in that column, and the footer cell.
  • The table sits in an overflow-x-auto wrapper with a min-width on the table itself, so it scrolls horizontally on narrow viewports instead of reflowing into cards.
  • Rows get a subtle background tint on hover to help someone visually track a feature across columns on a wide table.
  • Every plan's footer button is a next/link styled as a button, not a real submit, wire ctaHref (or replace it with an onClick) to your actual checkout or plan-switch flow.

Frequently asked questions