Staaarter

Billing Estimate Calculator

A usage-based price calculator for pay-as-you-go or metered SaaS plans. Each resource, such as seats, API calls, or storage, gets its own slider with an included allotment and a per-unit rate above that. The total recalculates on every drag, and a monthly/yearly toggle applies a discount to the annual total. Built for pricing pages where the ideal plan depends on how much someone actually uses.

By Staaarter Team
Billing
Updated June 25, 2026
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/billing-estimate-calculator.json

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

Usage

The file also exports billing56Demo, 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 { Billing56, billing56Demo } from "@/components/blocks/billing/billing56";

export default function Page() {
  return <Billing56 {...billing56Demo} />;
}

Props

PropTypeDefaultDescription
headingstring"Estimate your bill"Heading above the sliders.
descriptionstringnoneSupporting sentence under the heading.
resourcesEstimateResource[]noneOne slider per entry, rendered in the order given.
basePricenumber0Flat monthly platform fee added on top of every resource's cost.
defaultInterval"monthly" | "yearly""monthly"Which billing interval is active on first render.
yearlyDiscountPercentnumber20Percentage discount applied to the total when yearly is selected.
ctaLabelstring"Get this plan"Label on the bottom call-to-action button.
classNamestringnoneExtra classes for the outer card.

Types

interface EstimateResource {
  id: string;
  label: string;
  unit: string;
  min: number;
  max: number;
  step: number;
  defaultValue: number;
  pricePerUnit: number;
  includedUnits?: number;
}

Behavior notes

  • Sliders are native input type=range elements, not a shadcn/ui primitive, since the base UI kit doesn't ship a slider component.
  • Each resource's billable amount is Math.max(0, quantity - includedUnits), multiplied by pricePerUnit. Nothing is billed below the included allotment.
  • The monthly total is basePrice plus every resource's cost; line items are recomputed with useMemo whenever a slider value changes.
  • The yearly toggle multiplies the monthly total by (1 - yearlyDiscountPercent / 100) and shows that as the monthly-equivalent, with the full annual charge underneath.
  • The bottom CTA button doesn't submit or link anywhere on its own; wrap it in a Link render or add an onClick for a real checkout flow.

Frequently asked questions