shadcn.io is not affiliated with official shadcn/ui
Contract Length Slider Pricing Block for React
A split pricing section for a VPN with a contract length slider from 1 to 24 months in a card in a card, where the monthly price at display size, the discount, total and savings roll to each term, and a sticky bar on phones.
Installation
Overview
Let visitors explore the savings curve with this contract length pricing section, shown for Meridian VPN. Two columns share the page's hairline rails and meet at a divider, with a + mark where it meets the top rule: the pitch and a ruled list of what's included on one side, and on the other a card in a card. Its raised panel holds the monthly price at display size, rolling to each new term with Sliding Number, a discount badge, and a Slider from one month to twenty-four; the total contract value and the savings roll in the second panel. Anchor buttons under the track jump to the common terms (monthly, half-year, annual, extended, two years), and the call to action, the one primary Shine Button, names the chosen term. On a phone the card comes first, and a bar with the live total and the call to action sticks to the foot of the section, so the button is always in reach as you drag. Built with Frame, Slider, Button, Sliding Number, Data List, Badge, Guides and Shine Button, with CSS transitions only. Made for annual commitment upsells, VPN, security and any subscription where longer terms unlock bigger discounts.
FAQ
How do I change the range, the prices and the discount curve?
The constants at the top of the file set it: MIN_MONTHS and MAX_MONTHS bound the slider, and ONE_MONTH, ONE_YEAR and TWO_YEARS are the monthly prices you actually sell at 1, 12 and 24 months. centsFor draws a straight line between them for every term in between, in whole cents, so the price never falls out of step with your price list. The discount, the total and the savings are all worked out from that price, so they stay in step. Replace centsFor with a table if you sell only fixed terms.
How do the anchor labels line up with the slider?
Each anchor in ANCHORS is placed at its term's position along the track (positionOf), so it sits under the thumb's centre at that term. The thumb stays inside the track's ends, so the row is inset by half the thumb (mx-1.5, for the default style's 12px thumb; match it if your style's thumb is larger). The first and last labels are aligned to the track's ends instead of centred, so they never spill past the card. The row is positioned with logical properties, so in a right-to-left layout the labels follow the slider to the other side. Anchors marked wide only show from the sm breakpoint up, leaving monthly, annual and two years on a phone.
What does a screen reader hear?
The slider is labelled Contract length and reads its value as a term, such as 12 months, rather than a bare number: getAriaValueText receives the formatted value, the number and the thumb's index. Each anchor is a button named by its visible text. The prices keep their full value in visually hidden text, not a live region, so a screen reader reads them when it reaches them and nothing is announced while the thumb moves. The discount badge reads as "58% off" rather than a bare minus sign.
What is the bar at the foot of the section on a phone?
Below lg the card's own button is removed from the layout and a bar takes its place: the total for the chosen term on one side, a Shine Button on the other, stuck to the bottom of the section with sticky bottom-0 so it stays on screen while you drag the slider and leaves with the section when you scroll past it. It sits inside the section's grid, spanning all of its rows, so it needs no JavaScript. Its label is fixed ("Lock in this rate") so the button never changes width as the term changes.
How do I send the chosen term to checkout?
The call to action is a link: point its href at your checkout route with the term in the query (/checkout?months=12), or swap it for a button that posts months to your server. Work out the price again on the server from the term, never from the page, and map each term to a price in your billing provider. Both the card's button and the phone bar are links, so change both.
Related
- %Pro
Committed Spend Discount Pricing
Billing switchesFour 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
Annual Savings Pricing
Billing switchesThree plans that show what yearly billing saves: each plan's head holds two bars, twelve monthly payments against one yearly payment, with the saving printed in the gap, under a monthly and yearly switch.
- Pro
Billing Toggle Pricing
Billing switchesThree plan cards under a monthly and yearly switch that wears its saving in the header row, with prices that roll to their new amount and each plan a card in a card.
- Pro
Team Size Slider With Volume Discounts
Seats and teamsA 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.
- Pro
Usage Slider Pricing
CalculatorsA 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
Milestone Discount Pricing
Discounts and offersA 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.