PlanPicker
Compare plans, see the price difference, and switch.
SourcePackage @kerf-js/veneer
Preview
tsx
import { state } from '@kerf-js/core'import { PlanPicker, Toaster } from '@kerf-js/veneer'import type { BillingPlan } from '@kerf-js/veneer'export function Team() { const current = state('team') const change = async (plan: { id: string }) => { await wait(700) current.value = plan.id } return ( <> <PlanPicker plans={PLANS} current={current.value} seats={8} daysLeft={9} losses={(plan) => plan.id === 'hobby' ? [ 'Preview environments', '7 of your 10 seats', ] : [] } onChange={change} /> <Toaster /> </> )}const PLANS: BillingPlan[] = [ { id: 'hobby', name: 'Hobby', price: 0, description: 'For side projects.', features: [ '3 seats', '100 deploys a month', '1 region', ], }, { id: 'team', name: 'Team', price: 24, description: 'For product teams.', features: [ '10 seats', 'Unlimited deploys', '5 regions', 'Preview environments', ], }, { id: 'scale', name: 'Scale', price: 64, description: 'For many teams.', features: [ '50 seats', 'Unlimited deploys', 'Every region', 'SSO and audit export', ], },]const wait = (ms: number) => new Promise<void>((done) => { setTimeout(done, ms) })Installation
npm install @kerf-js/veneerUsage
tsx
import { PlanPicker } from '@kerf-js/veneer'Accessibility
- This has no shortcuts of its own: controls inside it use Tab, Enter and Space as usual, and veneer's parts keep their roles and labels.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
plans | BillingPlan[] | — | The plans to compare, one card each. |
current | string | — | The id of the plan the workspace is on. |
selected | State<string> | — | The checked card, when something else needs to set it. |
interval | State<BillingInterval> | — | Monthly or yearly, when you want to own it. |
seats | number | — | Seats, for the price. |
daysLeft | number | — | Days left in this period, for the proration. |
periodDays | number | — | The length of a period in days. |
currency | string | — | The ISO 4217 code prices are shown in, such as EUR. |
locale | string | — | The language and region used to format values. |
preview | ((plan: BillingPlan, interval: BillingInterval) => Proration | Promise<P… | — | Your server's proration, to replace the built-in one. |
losses | ((plan: BillingPlan) => string[]) | — | What stops working on a downgrade. |
| Event | Type | Default | Description |
|---|---|---|---|
onChange | (plan: BillingPlan, interval: BillingInterval) => string | void | Promis… | — | Makes the change. Resolve with a message to keep the dialog open and show it. |