Plans
Studio includes
Studio · $20 a month, billed monthly
KQ-1272 · PRICING/PLINTH
A pricing table whose plans stand on plinths along a floor: choosing one lifts it on the glide spring while its plinth grows underneath, a spotlight pans across to it from above on the same spring and pools light on its head, the other plans step back, and the chosen plan's features check in one after another with each tick drawn on the flick spring. The Monthly/Yearly switch slides its thumb on snap and re-rolls every price on an odometer whose wheels each go round once more and settle on their new digits on glide, a beat apart, as a save tag swings in on its string on the recoil spring. Plans and billing are real radiogroups where the arrow keys move and choose and Home and End jump, a polite live region speaks the chosen plan and price once, and under reduced motion nothing rises, pans or spins while the light, ring and prices still change.
Studio includes
Studio · $20 a month, billed monthly
Studio · $20 a month · billed monthly
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/pricing-plinth
| Prop | Type | Default | Description |
|---|---|---|---|
| plans | PricingPlan[] | defaultPricingPlans | The plans, left to right: { id, name, blurb?, monthly, yearly, features }, with monthly and yearly both as prices per month. |
| value / defaultValue | string | null | the second plan | The chosen plan's id, controlled or initial; null chooses none and puts the light out. |
| onValueChange | (id: string) => void | — | Fires from the press or the key that chose a plan. |
| cycle / defaultCycle | "monthly" | "yearly" | "monthly" | The billing cycle, controlled or initial. Changing it re-rolls every price. |
| onCycleChange | (cycle: "monthly" | "yearly") => void | — | Fires from the switch that changed it. |
| onConfirm | (id: string, cycle: "monthly" | "yearly") => void | — | The Continue button, with the chosen plan and cycle. |
| rise | number | 14 | How high the chosen plan rises on its plinth, in px (up to 28); a hovered plan rises 30% of it. |
| spotlight | number | 0.7 | How strong the light on the chosen plan is, 0 to 1: the cone, the pool on its head and the lit plinth. 0 puts the spotlight out. |
| stagger | number | 40 | Delay between the odometer's wheels as prices re-roll, in ms. |
| title | string | "Plans" | The heading, and the plans' accessible name. |
| monthlyLabel | string | "Monthly" | The switch's first option. |
| yearlyLabel | string | "Yearly" | The switch's second option. |
| saveLabel | string | "Save N%" | The tag that swings in for yearly billing, by default the best saving across the plans; an empty string hides it. |
| actionLabel | (plan: PricingPlan) => string | "Continue with {name}" | The Continue button's text for a plan. The button is always as wide as the longest. |
| currency | string | "USD" | ISO 4217 code the prices are in. |
| locale | string | "en-US" | Locale the prices are written in. |
| size | "sm" | "md" | "lg" | "md" | The prices' type scale. |
| accent | string | "var(--accent-bright)" | The light, the chosen ring, the tag and the ticks, any CSS colour. |
| sound | boolean | false | Play a click on the switch, a chime as the saving swings in and a snap as a plan lands on its plinth. |
| disabled | boolean | false | Nothing can be chosen or switched, and the table is drawn at reduced strength. |
| className | string | — | Classes for the table's outer box. |