Skip to content
caliper ui docs

Pro

Read receipts

Where a sent message has got to: a clock while sending, one tick once sent, two once delivered, and the faces of the people who have read it. A message that failed says so in words and offers Retry.

Pro
pnpm dlx shadcn@latest add @caliper/read-receipts

Maya, Sam, Priya

Group chat · Design review

Pushed the new onboarding flow, can you all take a look before 3?

Read by Maya Chen and 2 others, 14:12
Installs components/ui/read-receipts.tsxDepends on lucide-reactMotion none in component source

When to use

Use it for

  • Direct messages and small group chats where knowing it was seen changes what you do next.
  • Outbound messages to customers, where delivery can fail.

Skip it when

  • Large channels, where "read by 140" is noise; show a count or nothing.
  • Places where being seen should stay private; let people turn receipts off.

Decisions

Why it is built this way, so you know what to keep when you change your copy.

Behaviour

One sentence
The ticks and faces are hidden from screen readers; the line is read as "Read by Maya and Sam, 09:41".

Styling

Ink, not blue
Read is the darkest tick rather than a brand colour, so it works in every theme and never relies on colour alone.

Installation

terminal
pnpm dlx shadcn@latest add @caliper/read-receipts

Adds its 3 files to components/ui/, each with its own stylesheet, and installs their packages. Pro installs with your access token, set up once per project. See Pro access. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage

Import it from your copy of the source. The example behind the preview comes with the source.

example.tsx
import { ReadReceipts } from "@/components/ui/read-receipts"

The worked example comes with Pro

The 41-line example behind the preview opens here, ready to copy.

  • 576 Pro parts, blocks and page templates, all with source
  • $199 once, with a year of updates. What you have stays yours
  • A full refund within 14 days if it is not for you
Checking your licence…

API reference

ReadReceipts

component

Also accepts the native props of its root element and a ref.

PropTypeDefaultDescription
status *ReceiptStatus—
readersreadonly ReceiptReader[][]Who has read it, first reader first. Shown as faces once the status is `read`.
timestring—When it was sent, already formatted ("09:41").
maxnumber3How many faces before "+n".
onRetry(() => void)—Shown as a Retry button when the status is `failed`.

Accessibility

It is built on native elements and keeps aria-live and aria-hidden in step with state. Changes that matter are announced through a live region.

No custom key handling; Tab and the native activation keys do the work.

Motion

It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.

All Threads examples