Billing Per Seat Pricing
A per-seat pricing calculator with a seat count stepper that recalculates the total on every change, tiered volume pricing that drops the per-seat rate as the count grows, and a monthly/yearly toggle with a built-in annual discount. Built for team-focused SaaS pricing pages where letting someone estimate their own cost, before they talk to sales, removes friction from the signup decision.
Docs
Installation
A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its button, label dependencies and any missing npm packages, and installs them straight into your project.
npx shadcn add https://staaarter.com/r/billing-per-seat-pricing.jsonPrefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing93.tsx instead.
Usage
The file also exports billing93Demo, 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 { Billing93, billing93Demo } from "@/components/blocks/billing/billing93"; export default function Page() { return <Billing93 {...billing93Demo} />; }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| heading | string | "Estimate your team's cost" | Heading shown above the toggle. |
| description | string | none | Optional supporting text under the heading. |
| tiers | SeatPricingTier[] | none | Volume pricing tiers. The active tier is the one with the highest minSeats that's still at or below the current seat count. |
| minSeats | number | 1 | Lower bound for the stepper; the minus button disables at this value. |
| maxSeats | number | 100 | Upper bound for the stepper; at this value the CTA is replaced with a "Talk to sales" link. |
| defaultSeats | number | 5 | Seat count on first render, clamped to [minSeats, maxSeats]. |
| annualDiscountPercent | number | 20 | Percentage knocked off the annualized total when the yearly toggle is active. |
| currencySymbol | string | "$" | Symbol prefixed to every formatted amount. |
| enterpriseHref | string | "#" | Link target for the "Talk to sales" link shown once seats hits maxSeats. |
| ctaLabel | string | "Update seats" | Label for the primary button, shown while seats is below maxSeats. |
| className | string | none | Extra classes for the outer card. |
Types
interface SeatPricingTier { /** Seat count at which this tier's price kicks in. The tier list should be sorted ascending. */ minSeats: number; pricePerSeat: number; }
Behavior notes
- Seat count is local state, changeable with the stepper buttons or by typing directly into the number input; every change is clamped to [minSeats, maxSeats] and immediately recalculates the price.
- The active pricing tier is picked by scanning the tiers array for the highest minSeats that's still at or below the current seat count, so tiers don't need to be pre-sorted, though ascending order is clearer to read.
- Switching the monthly/yearly toggle recomputes the displayed total using annualDiscountPercent off the annualized monthly rate; it doesn't change the seat count or the active tier.
- Once seats reaches maxSeats, the primary CTA button is replaced by a "Talk to sales" link instead of staying disabled, since a hard seat ceiling usually means routing to a sales conversation.
- All money values are computed from the numeric pricePerSeat and seats, not passed in as pre-formatted strings, so the component owns its own currency formatting via currencySymbol.
Frequently asked questions
More Billing Blocks
View all →Billing Invoice List
Invoice history table with status badges, formatted amounts, and a per-row download link, built with shadcn/ui and Tailwind CSS.
Billing Failed Payment Alert
High-contrast failed-payment alert with a message, a retry button, and an optional update-payment-method button, built with shadcn/ui and Tailwind CSS.
Billing Credit Balance
Compact credit balance card with a large total, an optional purchased-versus-promotional breakdown, a low-balance notice, and a top-up button.
Billing Payment Methods
A saved payment method list for React and Next.js with brand icons, a default badge, near-expiry warnings, and remove/set-default actions per row.
Billing Add Card
A card entry form for React and Next.js with auto-formatted fields, internal brand detection, and per-field validation feedback built with shadcn/ui and Tailwind CSS.
Billing Coupon Code
An inline promo code input for React and Next.js with a simulated loading state, an applied summary showing the discount amount, and an invalid-code message.