Skip to content

OTP input ​

A segmented one-time-code field. Typing moves forward, Backspace moves back, and a paste fills every box.

Open in demo
Open in demo

Usage ​

v-model is the joined digit string, not an array. Non-digits are ignored on the way in, so a pasted 482-913 becomes 482913.

complete fires the moment every box is filled, whether the last digit was typed or pasted. That is where you submit, rather than asking the reader to press a button they no longer need.

The group is dir="ltr" in every language. A code is read left to right, so the first box stays on the left in a right-to-left layout and ArrowRight still means the next box.

Examples ​

A different length ​

length sets the number of boxes. It defaults to 6.

Disabled ​

API ​

Source: src/shared/components/common/SaOtpInput.vue

Props ​

PropTypeDefaultDescription
modelValuestring''The joined digits. Longer than length is trimmed.
lengthnumber6The number of boxes.
disabledbooleanfalseDims the boxes and blocks them.

Emits ​

EventPayloadDescription
update:modelValuevalue: stringFires on every keystroke and on paste.
completevalue: stringFires when every box is filled.

Slots ​

None.

Accessibility ​

  • Each box is named "Digit 1", "Digit 2" and so on.
  • Every box carries inputmode="numeric" and autocomplete="one-time-code", so a phone shows the number pad and can offer the code from an SMS.
  • ArrowLeft and ArrowRight move between boxes. Backspace in an empty box moves back and clears the box it lands on.
  • Pasting into any box fills from the first, and focus lands on the first box still empty.