Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

One-Time Code Input Form Block for React

A six-slot confirmation code in two groups of three with its behaviours in view: paste fills all six and checks at once, a wrong code is marked, counted and cleared, and a resend button waits 30 seconds.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show how a code field behaves, with this one-time code input form for React with Base UI. A compact header sits over a hairline frame with a plus mark on each corner and one row. At the start, the label, a Locked or Open Badge, where the code went, how many attempts remain, and a Resend code Countdown Button that waits 30 seconds after each press. At the end, an Input OTP of six slots in two groups of three. Typing fills the slots in order, Backspace steps back, the arrow keys move across and pasting "428 193", spaces and all, fills all six and checks at once; so does the sixth digit. A wrong code marks every slot invalid, says how many attempts remain, clears the slots and puts focus on the first; after three the field locks until a new code is requested. Open Door 4, the only Shine Button, says what is missing when the code is not complete. It's built from Input OTP, Countdown Button, Badge and Guides. For door and device confirmation, sign-in codes and any short code you ask a person to type.

FAQ

How does pasting a code with spaces work?

The block takes the paste before the field sees it: it keeps only the digits of what was on the clipboard, drops any beyond six and fills the slots, then checks. That makes "428 193", "428-193" and a code copied with a trailing newline all work the same on every version, which a field that validates each paste against its own pattern would refuse. The slots are marked autocomplete="one-time-code" and numeric, so a phone can offer the code from a text message too.

What happens on a wrong code, and why clear the slots?

After a short beat, so you see what you typed, every slot is marked aria-invalid, the line under them says "That code does not match. 2 attempts remain.", the slots are emptied and focus goes to the first, so the next try starts from the start of the field. The foot says the same once in its polite status. After three wrong codes the field stops taking digits, the sentence says why and focus goes to the button, which now reads Request a new code.

Which keys work, and is it the same on every version?

Digits fill and advance, Backspace clears the slot and steps back, the arrow keys, Home and End move between slots, and Enter checks or says what is missing. The slots are drawn over one real input, so a screen reader reads a single field and the caret moves across the drawn slots. The slots read left to right even on a right-to-left page, as codes are typed.

How does the Resend code button wait?

Pressing it starts a 30 second count: its label counts down, a fill drains behind it, and it stays focusable but ignores presses until the time is up. It also gives a fresh code: all attempts come back, the slots empty and focus returns to the first one. Nothing is sent in this demo; in your app send the code from the click handler and set the wait from your server's own limit.

What stays local, and how do I connect it for real?

The code is 428193, typed in the file and printed once in the hint, and it is compared in the browser. Nothing is sent, unlocked or stored. In your app post the digits to your server, count attempts there (the page's count is only a courtesy), expire codes after minutes and never reveal the code in the page; keep the status line for the server's answer.

How do I connect it to react-hook-form or TanStack Form?

Hold the six digits as one string in the form. With react-hook-form, wrap the field in Controller, call field.onChange with the digits from the same handler and run the check in handleSubmit, resetting the field with resetField on a wrong code. With TanStack Form, validate the length on change, check the code in onSubmitAsync and call field.setValue("") on a refusal.

  • Pro

    A sign-in for a clinic as an accordion of three sections: finishing one folds it to a one-line summary with a check and opens the next, sections after the open one are locked but reachable, and Edit reopens a finished one.

  • Pro

    A three-step sign-in for a support desk: a vertical Steps rail at the start (Email, Password, Code) with what was given and an Edit button on each finished step, and the one panel of the step in hand at the end.

  • Pro

    An account's two-factor methods as rows with their role, history and a Test that opens a code field in place, Make primary, a guarded Remove, and a Set up that opens a QR code, a key name or a number.

  • Pro

    A national-number field joined to a country menu that formats the digits for the chosen country as you type, checks the count per country and shows how the number would be stored.

  • Pro

    The sign-in pair done well: an email named for password managers, a password with a reveal button and a Caps Lock warning, one generic failure that never says which half was wrong, and a quiet band with the demo account.

  • Pro

    PIN Keypad Dialog

    Account and security

    A mobile wallet's transfer review with its PIN dialog shown open: four masked slots over a keypad of twelve keys, typed digits and keypad presses writing the same value, and a fourth digit that approves.