Build / Molecules
IntegrationRow
One external service and where you stand with it.
The same row does CRM connections, SSO providers, and calendars, because from the person's side they are one question asked repeatedly: is this connected, as whom, and what can I do about it. Three states rather than a boolean — a connection whose permissions have lapsed is neither on nor off, and that is exactly the row someone came to this screen to fix.
The state is a Badge with words in it, never a colored dot, so it survives
being read aloud or printed.
import { IntegrationRow } from '@meetcard/deck'Example
<IntegrationRow name="HubSpot" logo={<HubSpotMark />} status="connected" account="acme.hubspot.com" description="Sync connections and their notes as contacts." actions={<Button variant="secondary" size="sm">Disconnect</Button>} />Stories
Connected, with the account it is connected to and what you can do about it.
Source
const Connected = () => <Card style={{ maxWidth: 620 }}>
<IntegrationRow
name="HubSpot"
logo={<Database aria-hidden="true" />}
description="Sync connections and their notes as contacts and activities."
status="connected"
account="acme.hubspot.com"
actions={(<>
<Button size="sm" variant="secondary">
Manage
</Button>
<Button size="sm" variant="ghost">
Disconnect
</Button>
</>)} />
</Card>;Not connected — the row is an offer, and the one action is to connect.
Source
const NotConnected = () => <Card style={{ maxWidth: 620 }}>
<IntegrationRow
name="Salesforce"
logo={<Cloud aria-hidden="true" />}
description="Push new connections as Leads and log card exchanges as tasks."
actions={<Button size="sm">Connect</Button>} />
</Card>;The state this row exists for. A connection whose permissions lapsed is neither on nor off, and it is the one someone opened this screen to fix.
Source
const NeedsPermission = () => <Card style={{ maxWidth: 620 }}>
<IntegrationRow
name="Outlook Calendar"
logo={<CalendarDays aria-hidden="true" />}
description="Book with can only show real availability once this is enabled."
status="attention"
account="ben.ackles@meetcard.io"
actions={<Button size="sm">Enable calendar</Button>} />
</Card>;The states share a shape, not a vocabulary — a calendar is "enabled".
Source
const CustomStatusLabel = () => <Card style={{ maxWidth: 620 }}>
<IntegrationRow
name="Google Calendar"
logo={<CalendarDays aria-hidden="true" />}
description={undefined}
status="connected"
statusLabel="Calendar enabled"
account="ben@meetcard.io"
actions={(<Button size="sm" variant="ghost">Disconnect
</Button>)} />
</Card>;A read-only roster: who is connected, with nothing to act on here.
Source
const Roster = () => (
<Card style={{ maxWidth: 620 }}>
<IntegrationRow
name="Ben Ackles"
status="connected"
statusLabel="Calendar enabled"
description="Google Calendar"
/>
<IntegrationRow
name="Dana Whitfield"
status="connected"
statusLabel="Calendar enabled"
description="Outlook Calendar"
/>
<IntegrationRow
name="Priya Raman"
status="disconnected"
statusLabel="Not enabled"
description="No calendar connected"
/>
</Card>
);Props
| Prop | Type | Default | Description |
|---|---|---|---|
namerequired | ReactNode | — | The service, as its own users call it — "HubSpot", "Google Calendar". |
account | ReactNode | — | Which identity the connection runs as — ben@meetcard.io, benackles.
The question people actually have about a connected account is which
account, so it sits on the row rather than behind "Manage". |
actions | ReactNode | — | Connect, Manage, Disconnect — whatever this row can do. |
description | ReactNode | — | What connecting it buys you. |
logo | ReactNode | — | The service's mark. Decorative: name is what gets announced. |
status | 'connected' | 'disconnected' | 'attention' | 'disconnected' | — |
statusLabel | ReactNode | — | Overrides the pill's words. The states are shared but their vocabulary is not: a calendar is "Calendar enabled", a CRM is "Connected". |
Also accepts everything from Omit, so id, data-* and event handlers pass straight through.