Usage price calculatorPro
Sliders for what a customer will use (tokens, images, voice minutes) and what every plan would cost for it, with the cheapest plan that covers the usage marked.
On this page
Installation
Usage
import { UsagePriceCalculator } from "@/components/ui/chatcn/pro/usage-price-calculator"
<UsagePriceCalculator meters={meters} plans={plans} yearlyDiscount={0.2} onSelectPlan={startCheckout} />A meter is { id, label, unit, min, max, defaultValue, scale?, step?, hint? }; use scale="log" for tokens, which span orders of magnitude, and the slider snaps to readable stops (1, 2, 2.5 and 5 times a power of ten). A plan is a monthly base with included usage, rates per per units beyond it, and optional limits. Prices roll in tabular figures as the sliders move. A plan the usage has outgrown says which meter is over; when even the biggest is outgrown, it points to sales.
The math is exported for your own pricing pages: quotePlan and recommendPlan from @/lib/chatcn-pro-marketing. Pass currency, locale and labels to translate every string.
Every section is full width with a 16 px gutter on phones and 32 px from 768 px, content capped at 1200 px. Layout follows the section's own width through a container query, not the viewport, so a section in a narrow column lays out like a phone.
Examples
Outgrown plans, locales and disabled
Usage past two plan limits, a single slider priced in euros on a German page, and the disabled state.
Props
| Prop | Type | Notes |
|---|---|---|
title | ReactNode | Optional section headline, an h2 |
description | ReactNode | The paragraph beside the headline |
meters | UsageMeter[] | Required. One slider each |
plans | PricePlan[] | Required. Cheapest base first |
usage, defaultUsage, onUsageChange | Record<string, number> | By meter id |
yearlyDiscount | number | 0 to 1. Shows the Monthly and Yearly switch |
period, defaultPeriod, onPeriodChange | "monthly" | "yearly" | |
currency, locale | Default USD and the page locale | |
onSelectPlan | (planId, quote) => void | A plan's action |
recommendedLabel, contactLabel | string | Default "Best fit", "Talk to sales" |
labels | Partial<UsagePriceLabels> | Every other string |
disabled | boolean | For example while prices load |
footnote | ReactNode | Taxes, how overage is billed |
Keyboard
| Key | Action |
|---|---|
ArrowLeft / ArrowRight | Moves a slider one step (mirrored in right to left) |
PageUp / PageDown | Moves a slider by a large step |
Home / End | Minimum and maximum |
Tab | Moves through the period switch, the sliders and the plan actions |
Accessibility
- Each slider is a native range input labelled by its meter, with a value text such as
25M tokensand the hint as its description. - A polite live region says the recommendation when it changes (
Best fit: Team), not on every slider step. - The recommended plan is marked by its ring, a check and the words, never by color alone.
Motion
- Prices roll digit by digit as the sliders move; the thumb grows slightly while dragged.
- Under reduced motion prices change in place and the thumb does not grow.