Skip to content
txbrendan/ui

Code Field

beta

One field for a code typed or pasted: a code sent by email or text, or a workspace's invite code. It drops anything else, and calls onComplete once the code is whole.

Preview

characters

We sent it to riley.shaw@example.com. It works for 15 minutes.

Your admin gives you this. It joins you to the right team.

size

states

Paste “482 913” and it reads 482913.

Wait for the email to arrive.

Install

  1. 1. Add the registry to components.json, once per app. Without it, the shadcn CLI looks up @txbrendan in a public list that txbrendan/ui does not control.

    npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
  2. 2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.

    npx shadcn@latest add @txbrendan/theme
  3. 3. Add the component.

    npx shadcn@latest add @txbrendan/code-field

Use it for

  • A one-time code sent by email or text: characters="digits", six long by default.
  • A join code of letters and digits: characters="text". It shows in capitals.
  • Check the code in onComplete. It runs once the code is whole, so there is no Continue button to press.
  • Say where the code went and how long it works in hint, like "We sent it to riley@example.com. It works for 15 minutes."
  • Put a wrong or expired code in error, like "That code doesn't match".
  • Pass onResend to add a quiet "Send a new code" button after the hint or error. It reads "Sent" for 10 seconds after a press.

Avoid it for

  • A row of one box per digit. One field takes a paste, autofill, and the phone's suggested code in one go.
  • A password or a PIN people choose. Use an input with type="password".
  • Long codes people copy from a page, like a licence key. Use an input.

Props

  • length

    How many characters make the code whole.

    number · default 6

  • characters

    Digits only, or letters and digits in capitals. Anything else is dropped, so a pasted "123 456" reads 123456.

    "digits" | "text" · default "digits"

  • value

    The code. Use it with onValueChange.

    string

  • defaultValue

    The code at first render, when you do not control it.

    string

  • onValueChange

    Called with the cleaned code each time it changes.

    (code: string) => void

  • onComplete

    Called once the code reaches its length. Check it here.

    (code: string) => void

  • label

    Names the field, above it.

    ReactNode

  • hint

    Where the code went and how long it works.

    ReactNode

  • error

    A wrong or expired code. Replaces the hint, in red, and is announced.

    ReactNode

  • onResend

    Adds a "Send a new code" button after the hint or error.

    () => void

  • resendLabel

    The resend button's words.

    string · default "Send a new code"

  • size

    Height, padding, and text size. The same heights as Input.

    "sm" | "md" | "lg" · default "md"

  • disabled

    Blocks typing and the resend button.

    boolean · default false

  • placeholder

    A sample code, like "TEAM26X".

    string

  • id

    The input's id. Defaults to a generated one.

    string

  • className

    Classes for the frame. Other props, like name and aria-*, land on the input.

    string

Accessibility

  • A native input named by its label, so typing, pasting, and autofill work as usual.
  • autocomplete="one-time-code" lets phones offer the code from the message they got.
  • Digits open the number keypad on phones. Text codes turn on capitals.
  • The hint or error describes the input. An error sets aria-invalid and is announced once when it appears.
  • The resend button keeps its width when it reads "Sent", and a polite live region says "Sent a new code".
  • On touch screens the text is 16px, so iOS Safari does not zoom in when the field gets focus.

Examples

A code sent by email

<CodeField
  label="Code"
  hint="We sent it to riley@example.com. It works for 15 minutes."
  onComplete={(code) => console.log("check", code)}
  onResend={() => console.log("resend")}
/>

Letters and digits, seven long

<CodeField
  label="Invite code"
  characters="text"
  length={7}
  placeholder="TEAM26X"
  hint="Your admin gives you this. It joins you to the right team."
/>

A wrong code

<CodeField label="Code" defaultValue="123456" error="That code doesn't match." />