Build / Organisms
PersonCard
The professional business card — the artifact you hand over, and the
canonical child of CardPile.
A fixed box, the shape of a physical business card: 1.75:1 lying down and
1:1.75 stood up, portrait on a phone and landscape from sm up. The box
never grows to fit — the name clamps to two lines and anything past the
edge is clipped — because a card is a fixed-size object, and content that
cannot fit on one is content that does not belong on one.
import { PersonCard } from '@meetcard/deck'Example
<PersonCard name="Ben Ackles" title="Builder" company="MeetCard" companyHref="/companies/meetcard" location="Boulder, Colorado" tagline="What a lovable guy" footer={<> <Button iconStart={<CalendarIcon />}>Book with me</Button> <Button variant="secondary" iconStart={<HandshakeIcon />}> Exchange cards </Button> </>} />Stories
The full card, as handed over during an introduction.
Source
const Default = () => <div style={{ maxWidth: 420 }}>
<PersonCard
name="Ben Ackles"
title="Builder"
company="MeetCard"
location="Boulder, Colorado"
tagline="What a lovable guy"
contactActions={(<>
<IconButton label="Email Ben" icon={<EmailIcon />} size="sm" round />
<IconButton
label="Ben on LinkedIn"
icon={<LinkedInIcon />}
size="sm"
round
/>
<IconButton label="Share card" icon={<ShareIcon />} size="sm" round />
</>)}
footer={(<>
<Button iconStart={<CalendarIcon />}>Book with me</Button>
<Button variant="secondary" iconStart={<HandshakeIcon />}>
Exchange cards
</Button>
</>)} />
</div>;Just the essentials — name and eyebrow are the only required fields.
Source
const Minimal = () => <div style={{ maxWidth: 420 }}>
<PersonCard
name="Ben Ackles"
title={undefined}
company={undefined}
location={undefined}
tagline={undefined} />
</div>;The company links to its profile — the tap-through on a card.
Source
const WithCompanyLink = () => <div style={{ maxWidth: 420 }}>
<PersonCard
name="Ben Ackles"
title="Builder"
company="MeetCard"
location="Boulder, Colorado"
tagline="What a lovable guy"
contactActions={(<>
<IconButton label="Email Ben" icon={<EmailIcon />} size="sm" round />
<IconButton
label="Ben on LinkedIn"
icon={<LinkedInIcon />}
size="sm"
round
/>
<IconButton label="Share card" icon={<ShareIcon />} size="sm" round />
</>)}
footer={(<>
<Button iconStart={<CalendarIcon />}>Book with me</Button>
<Button variant="secondary" iconStart={<HandshakeIcon />}>
Exchange cards
</Button>
</>)}
companyHref="/companies/meetcard" />
</div>;With a private note written. The dot on the pill says there is something on the back.
Source
const WithPrivateNote = () => <div style={{ maxWidth: 420 }}>
<PersonCard
name="Ben Ackles"
title="Builder"
company="MeetCard"
location="Boulder, Colorado"
tagline="What a lovable guy"
contactActions={(<>
<IconButton label="Email Ben" icon={<EmailIcon />} size="sm" round />
<IconButton
label="Ben on LinkedIn"
icon={<LinkedInIcon />}
size="sm"
round
/>
<IconButton label="Share card" icon={<ShareIcon />} size="sm" round />
</>)}
footer={(<>
<Button iconStart={<CalendarIcon />}>Book with me</Button>
<Button variant="secondary" iconStart={<HandshakeIcon />}>
Exchange cards
</Button>
</>)}
privateNote={{ hasContent: true }} />
</div>;A long name still fits — it truncates rather than breaking the layout.
Source
const LongName = () => <div style={{ maxWidth: 420 }}>
<PersonCard
name="Augusta Ada King-Noel, Countess of Lovelace"
title="Head of Strategic Partnerships and Developer Relations"
company="MeetCard"
location="Boulder, Colorado"
tagline="What a lovable guy" />
</div>;A card has two sides. Opening the private note turns this one over, because what you write about someone belongs on the back of their card rather than in a panel somewhere else — and the dot on the front tells you there is something written there without showing it.
Source
const NoteOnTheBack = () => <FlipHarness />;On a phone, on its own. A card stands up on a phone whether or not a
CardPile is around it — before, only a pile could turn one, and a lone
card stayed lying down on a screen it was too wide to read on.
Source
const OnItsOwnOnAPhone = () => <div style={{ maxWidth: 420 }}>
<PersonCard
name="Ben Ackles"
title="Builder"
company="MeetCard"
location="Boulder, Colorado"
tagline="What a lovable guy"
contactActions={(<>
<IconButton label="Email Ben" icon={<EmailIcon />} size="sm" round />
<IconButton
label="Ben on LinkedIn"
icon={<LinkedInIcon />}
size="sm"
round
/>
<IconButton label="Share card" icon={<ShareIcon />} size="sm" round />
</>)}
footer={(<>
<Button iconStart={<CalendarIcon />}>Book with me</Button>
<Button variant="secondary" iconStart={<HandshakeIcon />}>
Exchange cards
</Button>
</>)} />
</div>;Pinned. orientation is for a space that has already committed to a
shape — a landscape slot on a phone, say — and it wins over the viewport.
Source
const PinnedLandscape = () => <div style={{ maxWidth: 420 }}>
<PersonCard
name="Ben Ackles"
title="Builder"
company="MeetCard"
location="Boulder, Colorado"
tagline="What a lovable guy"
contactActions={(<>
<IconButton label="Email Ben" icon={<EmailIcon />} size="sm" round />
<IconButton
label="Ben on LinkedIn"
icon={<LinkedInIcon />}
size="sm"
round
/>
<IconButton label="Share card" icon={<ShareIcon />} size="sm" round />
</>)}
footer={(<>
<Button iconStart={<CalendarIcon />}>Book with me</Button>
<Button variant="secondary" iconStart={<HandshakeIcon />}>
Exchange cards
</Button>
</>)}
orientation="landscape" />
</div>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
namerequired | string | — | — |
avatarSrc | string | — | — |
back | ReactNode | — | The card's other face — normally a PrivateNote. Supplying it turns the
private-note control into a flip: a business card has two sides, and the
things you write about someone belong on the back of theirs rather than
in a panel somewhere else.
Without this the card renders exactly as before, unwrapped, and
privateNote.onClick is left to the caller. |
company | string | — | — |
companyHref | string | — | Makes company a link, styled as a dotted-underline reference. |
contactActions | ReactNode | — | Circular icon buttons for contact methods — email, LinkedIn, share. |
eyebrow | string | 'Meet' | Small caps label above the name. Deck renders it upper-cased via CSS,
so pass natural case — defaults to "Meet". |
flipped | boolean | — | Controlled flip state. Omit to let the card manage its own. |
footer | ReactNode | — | Primary/secondary actions along the bottom edge. |
location | string | — | — |
onFlippedChange | (flipped: boolean) => void | — | — |
orientation | ResolvedCardOrientation | 'responsive' | — | Which way up the card sits. Default responsive: the surrounding
CardPile's orientation if there is one, otherwise portrait on a phone
and landscape from sm up. Pin it only when the space around the card
has already committed to a shape. |
privateNote | PersonCardPrivateNote | — | A dismissible, private annotation only the card's owner can see. |
tagline | string | — | Short status line under the identity row, e.g. "What a lovable guy". |
title | string | — | Role or function, e.g. "Builder". |
Also accepts everything from Omit, so id, data-* and event handlers pass straight through.