Build / Organisms
ContactCard
A saved contact, with their reachable details and follow-up state.
This is the "after the handshake" view: PersonCard helps you find someone,
ContactCard helps you act on the relationship. Details render as a real
<dl> so the label/value pairing survives in a screen reader.
import { ContactCard } from '@meetcard/deck'Example
<ContactCard name="Ada Lovelace" company="MeetCard" metAt="Met at SaaSConf · 12 June" details={[{ label: 'Email', value: 'ada@meetcard.com', href: 'mailto:ada@meetcard.com' }]} status={{ label: 'Follow up', tone: 'warning' }} />Stories
Source
const Default = () => <div style={{ maxWidth: 440 }}>
<ContactCard
name="Ada Lovelace"
title="Head of Partnerships"
company="MeetCard"
details={[
{
label: 'Email',
value: 'ada@meetcard.com',
href: 'mailto:ada@meetcard.com',
},
{ label: 'Phone', value: '+44 20 7946 0958', href: 'tel:+442079460958' },
{ label: 'Location', value: 'London, UK' },
]} />
</div>;Where and when you met — the context that makes a contact useful later.
Source
const WithMetAt = () => <div style={{ maxWidth: 440 }}>
<ContactCard
name="Ada Lovelace"
title="Head of Partnerships"
company="MeetCard"
details={[
{
label: 'Email',
value: 'ada@meetcard.com',
href: 'mailto:ada@meetcard.com',
},
{ label: 'Phone', value: '+44 20 7946 0958', href: 'tel:+442079460958' },
{ label: 'Location', value: 'London, UK' },
]}
metAt="Met at SaaSConf · 12 June" />
</div>;A contact you owe something — the status is the reason to open the card.
Source
const NeedsFollowUp = () => <div style={{ maxWidth: 440 }}>
<ContactCard
name="Ada Lovelace"
title="Head of Partnerships"
company="MeetCard"
details={[
{
label: 'Email',
value: 'ada@meetcard.com',
href: 'mailto:ada@meetcard.com',
},
{ label: 'Phone', value: '+44 20 7946 0958', href: 'tel:+442079460958' },
{ label: 'Location', value: 'London, UK' },
]}
metAt="Met at SaaSConf · 12 June"
status={{ label: 'Follow up', tone: 'warning' }} />
</div>;Email and phone are actionable; plain values stay as text.
Source
const ActionableDetails = () => <div style={{ maxWidth: 440 }}>
<ContactCard
name="Ada Lovelace"
title="Head of Partnerships"
company="MeetCard"
details={[
{
label: 'Email',
value: 'ada@meetcard.com',
href: 'mailto:ada@meetcard.com',
},
{ label: 'Phone', value: '+44 20 7946 0958', href: 'tel:+442079460958' },
{ label: 'Location', value: 'London, UK' },
]} />
</div>;With actions, for acting on the follow-up without leaving the card.
Source
const WithActions = () => <div style={{ maxWidth: 440 }}>
<ContactCard
name="Ada Lovelace"
title="Head of Partnerships"
company="MeetCard"
details={[
{
label: 'Email',
value: 'ada@meetcard.com',
href: 'mailto:ada@meetcard.com',
},
{ label: 'Phone', value: '+44 20 7946 0958', href: 'tel:+442079460958' },
{ label: 'Location', value: 'London, UK' },
]}
status={{ label: 'Follow up', tone: 'warning' }}
actions={(<>
<Button size="sm">Send message</Button>
<Button size="sm" variant="ghost">
Snooze
</Button>
</>)} />
</div>;Details are optional — the identity block stands on its own.
Source
const WithoutDetails = () => <div style={{ maxWidth: 440 }}>
<ContactCard
name="Ada Lovelace"
title="Head of Partnerships"
company="MeetCard"
details={undefined} />
</div>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
namerequired | string | — | — |
actions | ReactNode | — | Footer controls, typically Buttons. |
avatarSrc | string | — | — |
company | string | — | — |
details | ContactDetail[] | — | Reachable details, rendered as a description list. |
metAt | string | — | Where and when you met — the context that makes a contact useful later. |
status | { label: string; tone?: BadgeTone } | — | Follow-up state, e.g. { label: 'Follow up', tone: 'warning' }. |
title | string | — | — |
Also accepts everything from Omit, so id, data-* and event handlers pass straight through.