shadcn.io is not affiliated with official shadcn/ui
Hybrid Seat and Usage Pricing Block for React Aria
One bill for seats plus metered usage: a seat stepper and an events slider move a two-part bar that splits the total into its fixed and variable parts, with line items and a sticky total on phones.
Installation
Overview
Show buyers what a seats-plus-usage plan really costs with this hybrid pricing block for React with React Aria. A compact header states the deal, then two inputs sit beside the bill. A Number Input with steppers sets the seats, and a Slider sets the events a month; the total rolls to its new amount with Sliding Number. The feature is the two-part bar: its solid part is the fixed seat cost, its pale part is the usage on top of it, and each part grows or shrinks as its cost does. Under the bar, two line items say how each part is made (seats times the seat price, and the events past the included million at the per-thousand rate) with each part's share of the bill. The Shine Button starts the trial and is the block's only primary element. On a phone the call to action moves into a sticky bar that keeps the live total in view. The section sits on the page's lines, drawn by Guides, and the two panels share a Frame. Built with Number Input, Slider, Sliding Number, Frame, Shine Button, Guides and CSS transitions only. For analytics, observability, messaging and any product that charges per seat and per event.
FAQ
How do I change the seat price, the included events and the usage rate?
Edit the constants at the top of the file: SEAT_PRICE (dollars a seat a month), INCLUDED_K (events a month included, in thousands), RATE_PER_K (dollars for every 1,000 events past the included ones), MAX_SEATS and MAX_EVENTS_K (the ends of the two inputs) and STEP_K (the slider's step). The line items, the bar and the total are all derived from seatCostOf and usageCostOf, so nothing else needs touching. The copy under the header and in the footnote names the product's own figures: update it with the constants.
How does the two-part bar work?
Each part is a flex child whose flex-grow is its cost in dollars, set through a CSS variable, so the two parts always fill the bar in proportion and ease to their new widths with a CSS transition (none under reduced motion). The bar is decorative: the line items under it carry the same amounts and shares as text. If the usage is within the included events its part is zero wide and the bar is all seats.
Can I add volume tiers or a minimum commitment?
Yes. Both parts are plain functions: make usageCostOf read a tier table, or add a floor with Math.max(MINIMUM, …). If you add a third cost, such as a platform fee, add a third bar part and a third line item. The bar and the total follow whatever the cost functions return.
Where do the calls to action go?
"Start 14-day free trial" and the phone bar's "Start free trial" are real links, one visible at a time. Each is a ShineButton with href, which React Aria renders as a link. Point both at your sign-up route; you can pass the chosen seats and events in the query string.
Is it accessible?
Yes. The seat stepper is a named spin button and the events slider has its own label and a spoken value ("3.5M events a month"). The total isn't a live region, so typing or dragging doesn't interrupt a screen reader; instead, a polite status line announces the new monthly total once a key press or a drag ends. The line items are a real list with each share read out ("37% of the bill"), and the bar itself is hidden from assistive technology.
What happens on a phone?
The inputs come first, then the bar and line items. The panel's own button is hidden below the md breakpoint, and a bar sticks to the foot of the screen with the live monthly total and the call to action, so the price and the button are in reach however far the page has scrolled. It uses position: sticky, so it stays inside the section and scrolls away with it.