CallCard

Voice-call overlay for ringing, connecting, connected, and ended states.

Quick Preview

Tunde Bakare

In call · 04:32

Composition

CallCard is the in-product surface shown while a voice call is ringing, connecting, connected, or just ended. It owns shape, elevation, and per-size layout, and exposes size/state through context so its parts size and colour themselves. Wiring — mute, hang up, accept — is yours; pass handlers to the action parts.

CallCardOverlay (only for size="full")
└── CallCard (size, state)
    ├── CallCardAvatar
    ├── CallCardIdentity › CallCardName · CallCardStatus
    └── CallCardActions
        ├── CallCardWindowControl
        ├── CallCardMuteButton | CallCardIgnoreButton
        └── CallCardEndCallButton | CallCardAcceptButton

Wrap the full window in CallCardOverlay for its dimmed, blurred scrim; the minimized bar docks inline and needs none. state is the sole driver of the status-dot colour and of whether End Call retires to a neutral tone.

Usage

<CallCardOverlay>
  <CallCard size="full" state="in-call">
    <CallCardAvatar src={contact.photo} alt={contact.name} />
    <CallCardIdentity>
      <CallCardName>{contact.name}</CallCardName>
      <CallCardStatus>In call · 04:32</CallCardStatus>
    </CallCardIdentity>
    <CallCardActions>
      <CallCardWindowControl onClick={dock} />
      <CallCardMuteButton muted={isMuted} onClick={toggleMute} />
      <CallCardEndCallButton onClick={hangUp} />
    </CallCardActions>
  </CallCard>
</CallCardOverlay>

Examples

In call

The full window for an active outbound call. The status dot turns success-green once connected; CallCardMuteButton is a reversible toggle that stays neutral, so it never competes with the destructive End Call.

Tunde Bakare

In call · 04:32

Incoming

Set state="incoming" to swap the action row to Ignore + Accept. The card takes role="alert" and aria-live="assertive" in this state so an arriving call is announced.

Minimize and expand

size="minimized" docks the call as a horizontal bar. Drive size from state and toggle it from CallCardWindowControl to move between the full window and the docked bar. One structure serves both sizes: the window control self-positions (pinned top-right when full, leading the bar when minimized) and swaps its glyph and label on size, so a single control transforms the card.

Tunde Bakare

In call · 04:32

Props

Prop/APITypeDefaultDescription
size on CallCard"full" | "minimized""full"Full window vs docked bar.
state on CallCard"ringing" | "calling" | "in-call" | "call-ended" | "incoming"-Required. Drives the status-dot colour and End Call tone.
src / alt / fallback on CallCardAvatarstring / string / ReactNode-Contact photo; the glyph is a fallback.
muted on CallCardMuteButtonbooleanfalseSwaps the glyph and the accessible label.
tone on CallCardAction"tertiary" | "danger" | "primary""tertiary"Surface emphasis for a custom action.
classNamestring-Local layout or spacing overrides.
native/root propsReact component props-Passed through to the underlying element.

Accessibility

  • state carries the call's status through the dot's colour and the copy in CallCardStatus — never encode it in colour alone.
  • The incoming state announces itself via role="alert" / aria-live="assertive"; other states use a polite status live region.
  • Every action is a real button with a sensible default aria-label; CallCardMuteButton also toggles aria-pressed.
  • Never leave CallCardActions empty — an overlay with no controls traps the user in a live call.
  • Preserve the documented composition so the card's size/state context reaches the avatar, identity, and action parts.

On this page