Build / Organisms
PlanCard
One plan in a row of them: what it costs, what it includes, and the one button that changes anything.
The plan you are on is marked rather than removed, and its action says what it actually does — you do not "choose" the plan you already have. That mark is a badge and a border, never the border alone: which plan you are on is the single most important thing on the screen and it does not get to depend on seeing a colour.
Features are a list of lines with no nesting on purpose. A plan comparison that grows sub-bullets has stopped comparing and started explaining, and the explaining belongs on a pricing page rather than in a settings panel.
import { PlanCard } from '@meetcard/deck'Example
<PlanCard name="Pro" description="For professionals who network seriously." price="$8" period="/mo" features={['Unlimited cards', 'CRM integrations']} action={<Button size="sm">Choose Pro</Button>} />Stories
A plan you could move to.
Source
const Default = () => <div style={{ maxWidth: 320 }}>
<PlanCard
name="Pro"
description="For professionals who network seriously."
price="$8"
period="/mo"
features={[
'Unlimited cards',
'Unlimited connections',
'CRM integrations',
'Custom domain',
'Advanced analytics',
]}
action={<Button size="sm">Choose Pro</Button>} />
</div>;The plan you are on. Marked with a badge as well as a border, and its action says what it does — you do not "choose" the plan you already have.
Source
const Current = () => <div style={{ maxWidth: 320 }}>
<PlanCard
name="Team"
description="For teams networking at events together."
price="$9"
period="/mo per seat"
features={[
'Everything in Pro',
'500 connections per seat',
'10 events per month',
'Team analytics',
'Shared company branding',
]}
action={(<Button size="sm" variant="secondary">Manage plan
</Button>)}
note="Starting at $9/mo per seat, 3-seat minimum."
current />
</div>;The free one. A price of nothing is still a price and still lines up.
Source
const Free = () => <div style={{ maxWidth: 320 }}>
<PlanCard
name="Solo"
description="For getting started with your digital business card."
price="$0"
period="forever"
features={[
'1 card',
'100 connections',
'Unlimited card exchanges',
'Basic analytics',
]}
action={(<Button size="sm" variant="secondary">Choose Solo
</Button>)} />
</div>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
featuresrequired | ReactNode[] | — | What you get. One line each; no sub-lists. |
namerequired | string | — | — |
pricerequired | string | — | The figure alone — "$8", "$0". Kept apart from period so a column of
plans lines its prices up on the same baseline whatever follows them. |
action | ReactNode | — | The action — "Choose Pro", "Manage plan". |
current | boolean | false | Marks the plan you are already on. |
description | ReactNode | — | — |
level | 2 | 3 | 4 | 3 | Heading level for the plan's name. Default 3. |
note | ReactNode | — | The small print under the price — a seat minimum, a trial length. |
period | ReactNode | — | What the figure is per: "/mo", "/mo per seat", "forever". |
Also accepts everything from Omit, so id, data-* and event handlers pass straight through.