Verification code
An OTP flow with a resend cooldown and a failure state that does not clear the entered code.
Live preview
Source
This exact file renders the preview above.
components/blocks/forms/verification.tsx
components/ui/otp-field.tsx
Demo source — adapt to your project. Foundry is not published as a package.
Usage
Wraps the OTP primitive in a real flow. The two things that make verification screens usable are a resend control with a visible cooldown and a failure that preserves what was typed. Demo code: 481902.
- Pasting a full code fills every box — the single most common OTP bug.
- The cooldown is announced politely, so a screen-reader user knows why the button is disabled.
- Validation runs on completion, not on every digit.
Variants and states
Every entry below is a genuine difference in behaviour or layout, and every one of them is visible in the preview above.
- Idle
- Incomplete
- Incorrect code
- Resend cooldown
- Success
Accessibility
- Per-digit labels
- Each box is labelled “Digit n of 6”.
- Cooldown announcement
- The remaining time is in a polite live region.
- Preserved input
- A rejected code stays in the field so it can be corrected rather than retyped.
Foundry implements published ARIA patterns and is tested against them. No WCAG certification is claimed — see the accessibility documentation for what is and is not covered.
Related
All formsOTP field
Segmented one-time-code entry that advances on type, steps back on backspace and fills every box from a single paste.
advanced4 variantsLogin
Email and password with a form-level rejection that does not reveal which half was wrong.
starterFeatured6 variantsMagic link
A one-field sign-in whose success state names the address and offers a correction path.
starter4 variants