PlanOptionCard
A selectable pricing/plan card, composed inside a RadioGroup, with an optional current-plan indicator and feature list
pnpm add @wandercom/design-system-web
PlanOptionCard is not a standalone group — compose it directly inside an existing RadioGroup, the same way you'd place a bare RadioGroupItem:
import { PlanOptionCard } from '@wandercom/design-system-web/ui/plan-option-card';
import { RadioGroup } from '@wandercom/design-system-web/ui/radio-group';
import { useState } from 'react';
export default function PlanOptionCardExample() {
const [plan, setPlan] = useState('small-business');
return (
<RadioGroup value={plan} onValueChange={setPlan}>
<PlanOptionCard
value="lite"
name="Wander Lite"
label="List on wander.com only"
price="$1/mo"
/>
<PlanOptionCard
value="small-business"
name="Wander Small Business"
highlightLabel="Recommended"
label="For managers with 1-9 properties"
trialLabel="Free trial"
secondaryPriceLabel="then $39/mo"
price="$39/mo"
/>
</RadioGroup>
);
}PlanOptionCard is shared between two surfaces, which differ only in the copy passed to highlightLabel and trialLabel — the component itself doesn't know which surface it's in:
- Onboarding:
highlightLabel="Recommended"on the suggested plan, and every priced plan passestrialLabel="Free trial"with asecondaryPriceLabel(e.g."then $39/mo") so the price line demotes below it. - Dashboard (e.g. the billing "Change plan" screen):
highlightLabel="Current plan"on whichever card matches the account's active plan, and prices render plainly with notrialLabel.
A full "Change plan" list: cards with a feature list that animates open only while that card's radio is checked, and a current plan that's grown past its own limit, with a warning linking to the plan it should upgrade to instead.
The same list on the onboarding paywall: a "Recommended" indicator instead of a current-plan one, and every priced plan shows a free trial.
value:
id?:
name:
price:
label?:
highlightLabel?:
trialLabel?:
secondaryPriceLabel?:
features?:
warning?:
warningIcon?:
warningColor?:
disabled?:
className?:
classNames?:
PlanOptionCard composes the native RadioGroup and RadioGroupItem primitives, which follow the WAI-ARIA radio group pattern.
Keyboard interaction:
Arrow Up/Arrow Left- Move focus to the previous optionArrow Down/Arrow Right- Move focus to the next optionSpace- Select the focused optionTab- Move focus into/out of the radio group
Each card is a <label> element with htmlFor linking to its radio input, ensuring screen readers announce the option name when focused.