1. Documentation
  2. Forms
  3. OTP Field
ReadmenpmGitHub
  • Introduction
  • Installation
  • Theming
  • Icons
  • Accordion
  • Card
  • Scroll Area
  • Separator
  • Sidebar
  • Field
  • Label
  • Input
  • Textarea
  • Number Field
  • OTP Field
  • Select
  • Combobox
  • Checkbox
  • Radio
  • Switch
  • Slider
  • Toggle
  • Calendar
  • Date Picker
  • File Upload
  • Button
  • Copy Button
  • Dropdown
  • Command
  • Tabs
  • Breadcrumb
  • Pagination
  • Tree
  • Table
  • Data Table
  • Stat
  • Timeline
  • Avatar
  • Status Bar
  • Badge
  • Meter
  • Empty
  • Skeleton
  • Spinner
  • Toast
  • Dialog
  • Sheet
  • Popover
  • Tooltip
  • Text
  • Kbd
  • Code Block
  • Utilities
  • Design rules

OTP Field

A one-time code field — one square box per character, paste-aware, with the caret moving itself.

Loading documentation…

Number Field< PreviousSelectNext >

Powered by heyo

On this page

UsageGroupingCompletionProperties

We sent a six-digit code to your email.

<OtpFieldlabel="Verification code"description="We sent a six-digit code to your email."length={6}groupAfter={3}/>

OtpField is the two-factor box: one slot per character, the caret moving itself as you type, and a paste anywhere in the field filling every slot at once.

The slots are square, and on the same 8px rhythm as every other control — base is the 32px control height. A taller-than-wide slot reads as a text field that has been squashed; a square one reads as a keycap, which is what it is.

Usage

tsx
import { OtpField } from "@heyo-sh/heyo-ui";<OtpField length={6} groupAfter={3} onValueComplete={verify} />;

Grouping

groupAfter inserts a dash after n slots. It is cosmetic, but it makes a six-digit code readable as two chunks instead of one blur.

<OtpField length={6} aria-label="Code" /><OtpField length={6} groupAfter={3} aria-label="Code" /><OtpField length={8} groupAfter={4} size="sm" aria-label="Backup code" />

Completion

onValueComplete fires the moment the last slot is filled — by typing or by pasting — which is where verification belongs. There is no submit button to wait for.

tsx
<OtpField  label="Verification code"  length={6}  onValueComplete={(code) => verify(code)}  error={failed ? "That code is not valid." : undefined}/>
That code is not valid.
<OtpField label="Verification code" length={6} error="That code is not valid." />

Properties

lengthnumberoptional

How many slots. It defaults to 6.

groupAfternumberoptional

Inserts a dash after this many slots — 3 gives 123-456.

size"sm" | "base" | "lg"optional

28, 32 or 40px square. It defaults to base.

value / defaultValuestringoptional

Controlled and uncontrolled value.

onValueChange(value: string) => voidoptional

Fires on every keystroke.

onValueComplete(value: string) => voidoptional

Fires when every slot is filled.

maskbooleanoptional

Masks the entered characters.

autoSubmitbooleanoptional

Submits the owning form once the code is complete.

validationType"numeric" | "alpha" | "alphanumeric" | "none"optional

What the field accepts. It defaults to numeric, which also sets the on-screen keyboard.

label / description / error / optional / labelAsideFieldOwnPropsoptional

The same field layout every heyo-ui control composes. See Field.

disabled / required / name—optional

Standard form behaviour, passed through to Base UI.