KQ-1707 · INBOX/WAIT
Inbox Wait
A magic-link waiting screen where an envelope rests in a slow breathing glow — a mirrored tween whose strength is glowAmount, running only while waiting, in view and in a visible tab — beside the address, a Resend that counts down and a way to change the address. The page notices the link opening through a BroadcastChannel another tab posts to, an onCheck asked when the tab regains focus, or the host's status; then the flap swings open on springs.snap, the letter rises on springs.glide and grows into the signed-in welcome through a shared layout on glide while the welcome's lines arrive in a cascade. Expired links and links opened on another device each explain the next step.
Check your inbox
We sent a sign-in link to ana@waylight.studio
Link expires in 15 min · this page will notice
waiting · ana@waylight.studio
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/inbox-wait
Props
- string
- default "ana@waylight.studio"
- Where the link went.
- status / defaultStatus
- "waiting" | "verified" | "expired" | "other-device"
- default — / "waiting"
- The page's state, controlled or initial.
- onStatusChange
- (status) => void
- default —
- Fires when the page notices the link opened, the link expires, or a new link goes out.
- sentAt
- number
- default 6 s before now
- When the link was sent, in ms.
- now
- number
- default defaultInboxWaitNow
- The moment the page first renders, in ms; its timers count on from it.
- resendAfter
- number
- default 30
- Seconds before Resend becomes available.
- expiresAfter
- number
- default 15
- Minutes a link stays valid; the page turns to expired when it lapses.
- onResend
- () => void | Promise
- default —
- Resend was pressed; a promise holds the button.
- onChangeEmail
- (email) => void
- default —
- A new address was saved; a fresh link is assumed to have gone to it.
- onVerified
- (info: { name?, via }) => void
- default —
- The page noticed the link was opened, and how ("channel", "check" or "host"); fires once per link.
- onContinue
- () => void
- default —
- Continue was pressed on the welcome.
- channel
- string
- default —
- A BroadcastChannel name; another tab posts { type: "verified", name? } (or "expired", "other-device").
- onCheck
- () => boolean | Promise<boolean>
- default —
- Asked when the tab regains focus (and every pollInterval ms while visible); resolve true once the link has been opened.
- pollInterval
- number
- default 0
- Milliseconds between checks while visible and on screen; 0 checks only on focus.
- name
- string
- default "Ana"
- Who the welcome greets.
- product
- string
- default "Waylight"
- The product being signed in to.
- envelopeStyle
- "flap" | "mailer" | "line"
- default "flap"
- The envelope: a classic flap, a mailer with a tear strip, or line art.
- glowAmount
- number
- default 0.6
- How strongly the resting envelope glows, 0 to 1; 0 is unlit and still.
- tone
- "calm" | "warm" | "mono"
- default "calm"
- The glow, the seal and the primary action: cobalt, amber or ink.
- disabled
- boolean
- default false
- Resend and Change email are unavailable.
- className
- string
- default —
- Classes for the surface; it is max-w-sm unless widened here.
| Prop | Type | Default | Description |
|---|---|---|---|
| string | "ana@waylight.studio" | Where the link went. | |
| status / defaultStatus | "waiting" | "verified" | "expired" | "other-device" | — / "waiting" | The page's state, controlled or initial. |
| onStatusChange | (status) => void | — | Fires when the page notices the link opened, the link expires, or a new link goes out. |
| sentAt | number | 6 s before now | When the link was sent, in ms. |
| now | number | defaultInboxWaitNow | The moment the page first renders, in ms; its timers count on from it. |
| resendAfter | number | 30 | Seconds before Resend becomes available. |
| expiresAfter | number | 15 | Minutes a link stays valid; the page turns to expired when it lapses. |
| onResend | () => void | Promise | — | Resend was pressed; a promise holds the button. |
| onChangeEmail | (email) => void | — | A new address was saved; a fresh link is assumed to have gone to it. |
| onVerified | (info: { name?, via }) => void | — | The page noticed the link was opened, and how ("channel", "check" or "host"); fires once per link. |
| onContinue | () => void | — | Continue was pressed on the welcome. |
| channel | string | — | A BroadcastChannel name; another tab posts { type: "verified", name? } (or "expired", "other-device"). |
| onCheck | () => boolean | Promise<boolean> | — | Asked when the tab regains focus (and every pollInterval ms while visible); resolve true once the link has been opened. |
| pollInterval | number | 0 | Milliseconds between checks while visible and on screen; 0 checks only on focus. |
| name | string | "Ana" | Who the welcome greets. |
| product | string | "Waylight" | The product being signed in to. |
| envelopeStyle | "flap" | "mailer" | "line" | "flap" | The envelope: a classic flap, a mailer with a tear strip, or line art. |
| glowAmount | number | 0.6 | How strongly the resting envelope glows, 0 to 1; 0 is unlit and still. |
| tone | "calm" | "warm" | "mono" | "calm" | The glow, the seal and the primary action: cobalt, amber or ink. |
| disabled | boolean | false | Resend and Change email are unavailable. |
| className | string | — | Classes for the surface; it is max-w-sm unless widened here. |