A press-and-hold seat stepper that fills a row of teammate avatars while a dot climbs down a volume staircase chart. Price per seat, savings and the next price break update live, with a jump to the break.
Team pricing
One price per seat, set by the size of your team. Cross a break and every seat drops to the lower rate, not just the new ones.
npx shadcn@latest add https://hyperblur.dev/r/pricing-seat-stepper.jsonWorks in any React project set up with the shadcn CLI. The file lands in components/hyperblur/pricing-seat-stepper.tsx.
import { PricingSeatStepper } from "@/components/hyperblur/pricing-seat-stepper"
<PricingSeatStepper defaultValue={40} onChange={(seats, monthly) => console.log(seats, monthly)} />| Prop | Type | Default | Description |
|---|---|---|---|
| eyebrow | string | "Team pricing" | Small label above the title. Empty hides it. |
| title | string | "Add your whole team. Every seat gets cheaper." | Section heading. |
| subtitle | string | Paragraph under the heading. Empty hides it. | |
| bands | { upTo: number | null; price: number }[] | 16, 14, 12, 10, 8 | Volume bands in ascending order. upTo null marks the last open band. All seats pay the band price. |
| min | number | 1 | Fewest seats. |
| max | number | 500 | Most seats. |
| value | number | Controlled seat count. Pair with onChange. | |
| defaultValue | number | 18 | Initial seats when uncontrolled. |
| onChange | (seats: number, monthly: number) => void | Called with the seat count and the monthly total. | |
| names | string[] | 24 names | Names used for avatar initials. |
| currency | string | "USD" | ISO 4217 currency code passed to Intl.NumberFormat. |
| locale | string | "en-US" | Locale used to format every amount. |
| cta | { label: string; href: string } | { label: "Start your team trial", href: "#" } | Primary button. |
| accent | string | "#2f7bff" | Active band, dot and button color. |
| className | string | "" | Extra classes for the section element. |
| style | CSSProperties | Inline styles merged after the accent variables. |