Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Milestone Discount Pricing Block for React

A slider-driven rate card for usage that gets cheaper at milestones: slide to a monthly volume and the label count rides the thumb, four rate zones show the current one, and the estimate and the next milestone update.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show buyers where the price drops with this milestone discount pricing section. A Slider is the track, split into four equal zones, one for each rate of a shipping-label API: 8¢ a label to start, then 5¢ from 10K labels a month, 3.5¢ from 50K and 2.5¢ from 250K. The label count rides the thumb in large type, rolling with Sliding Number. Under the track a row of four cells shows each zone's rate and its saving against the base rate, the current zone marked with a heavier rule, and one line says how many more labels unlock the next rate. Beside it the result: your current rate, an estimate of the month's bill and the block's one primary Shine Button, over a short feature list. The section sits on the page's lines, drawn by Guides: side rails, a rule along its top, and the track band ruled with a + at each corner. Built with Slider, Sliding Number, Shine Button, Guides and Lucide icons, with CSS transitions only. For APIs, metered products and any price that falls as usage grows.

FAQ

How do I change the rates and the milestones?

Edit ZONES at the top of the file: each zone has the monthly volume it from, a short name for its cell and its rate in dollars. MAX_LABELS is the track's right end and ROUNDING is how each zone rounds the count shown (to 100, 500, 1,000 and 5,000 labels), so the readout stays tidy. The number of zones sets the track: each takes an equal share, so it works with three or five zones if you change the cells' grid-cols-4 to match.

How is the estimate worked out?

Each rate applies to the labels past its milestone, not to all of them: 22,000 labels cost 10,000 at 8¢ plus 12,000 at 5¢, which is $1,400. That is why crossing a milestone never makes the bill jump. billFor does the sum from ZONES, so if your pricing is different (every label at the rate of the milestone you reached, say), change that one function. The footnote under the section says which rule applies, so keep it in step with your terms.

Why are the zones the same width when 250K is 25 times 10K?

On a linear track the first zones would be a few pixels wide and impossible to use. Each zone takes a quarter of the track and the thumb moves through that zone's range (0 to 10K, 10K to 50K, 50K to 250K, 250K to 1M), so the milestones sit at even steps and every rate is easy to land on. The slider's own value is a position from 0 to 400; labelsAt turns it into the label count and its rounding.

Where does the call to action go?

"Start shipping labels" is a real link. It's a ShineButton with render set to an a element and nativeButton={false}. Point it at your sign-up route; the slider is an estimator, so nothing it shows is sent anywhere. It's the only primary element: the slider's track and thumb are drawn in your foreground colour.

Is the slider accessible?

Yes. It has a visible label ("Labels a month") and reads its value as text, such as "22,000 labels a month, 5¢ a label", so a screen reader doesn't announce a position out of 400. The arrow keys, Home and End move it. The rate and the next milestone are announced once you stop dragging or release a key, in a polite live region, not at every step. The four zones are a list named "Rates by monthly volume", and the current one is marked with aria-current.

How does it look on a phone?

The track panel comes first and the result below it, so the slider, its readout and the call to action are all within the first two screens. The four zone cells shrink to fit 320 px, each with its rate large and its saving small, and the label count riding the thumb stays inside the panel at both ends of the track. Nothing scrolls sideways.

  • Pro

    Per-seat pricing that falls across four team-size brackets, drawn as a descending bar chart beside compact rows with the saving on each bracket and a call to action per row.

  • Pro

    A usage-based bill calculator for a search API: a slider over monthly search volumes sits in one short band, and a meter of what the plan covers and what is billed as overage rolls the estimated bill beside it.

  • Pro

    Tiered API Pricing

    Comparison tables

    API tiers by request quota, with the quota as the headline: four columns open with 10k, 250k, 2M and 10M+ requests a month at display size, then the price, the overage rate and a call to action, over grouped limits and features.

  • Pro

    Pay As You Go Pricing

    Usage and credits

    Usage pricing for a serverless platform as rate rows: each billable resource with its free allowance, its starting rate at display size and the two volume steps that lower it, with one call to action in the header.

  • Pro

    Four big commitment chips, $500 to $50k a month, and in the same row the discount each earns at display size, over every unit's committed price against its on-demand price, with the call to action beside the result.

  • Pro

    A seat calculator: a slider sets the team size with its count riding the thumb, ticks at the 10, 25 and 50 seat discounts, shortcuts to them, and a panel that rolls the seat price and monthly total.