Skip to content

OtpInput

OTP (One-Time Password) input component for verification codes. Supports multiple visual variants, configurable grouping, flexible validation, and auto-submit. WCAG compliant with full keyboard and screen reader support.

Usage

Basic

6-digit code

vue
<SuOtpInput :length="6" />

Visual variants

boxes / underline / seamless

Boxes (default)

Underline

Seamless

vue
<SuOtpInput variant="boxes" :length="6" />
<SuOtpInput variant="underline" :length="6" />
<SuOtpInput variant="seamless" :length="6" />

Sizes

sm / md / lg

vue
<SuOtpInput size="sm" :length="6" />
<SuOtpInput size="md" :length="6" />
<SuOtpInput size="lg" :length="6" />

Grouping

Configurable grouping

6 digits as [3, 3]

6 digits as [2, 2, 2]

8 digits as [4, 4]

vue
<SuOtpInput :length="6" :grouping="[3, 3]" separator="-" />
<SuOtpInput :length="6" :grouping="[2, 2, 2]" separator="·" />
<SuOtpInput :length="8" :grouping="[4, 4]" separator="-" />

Input types

Numeric / Alphanumeric / Alphabetic

Numeric (default)

Alphanumeric

Alphabetic

vue
<SuOtpInput inputType="numeric" :length="6" />
<SuOtpInput inputType="alphanumeric" :length="6" />
<SuOtpInput inputType="alphabetic" :length="6" />

Custom validation

Hexadecimal only

vue
<!-- Via regex pattern -->
<SuOtpInput :length="6" pattern="^[0-9a-fA-F]$" inputType="alphanumeric" />

<!-- Via validate function -->
<SuOtpInput :length="6" :validate="(char) => /^[0-9a-fA-F]$/.test(char)" />

Masked

Hidden characters

vue
<SuOtpInput :length="6" :masked="true" />

Validation states

error / success / warning

vue
<SuOtpInput state="error" :length="6" />
<SuOtpInput state="success" :length="6" />
<SuOtpInput state="warning" :length="6" />

Auto-submit

vue
<SuOtpInput :length="6" :autoSubmit="true" @complete="handleComplete" />
vue
<script setup>
const handleComplete = (code) => {
  console.log('Complete code:', code)
  // Verify the code...
}
</script>

With FormField (OtpInputField)

Label, message, and state

vue
<SuOtpInputField
  label="Verification code"
  message="Enter the code sent via SMS"
  :length="6"
  :grouping="[3, 3]"
/>

4 digits (SMS code)

Short code

vue
<SuOtpInput :length="4" placeholder="0" />

API

Props (OtpInput)

PropTypeDefaultDescription
modelValuestring''OTP code value (v-model)
lengthnumber6Number of characters
variant'boxes' | 'underline' | 'seamless''boxes'Visual variant
inputType'numeric' | 'alphanumeric' | 'alphabetic''numeric'Accepted character type
patternstringCustom regex pattern (overrides inputType)
validate(char: string, index: number) => booleanPer-character validation function
size'sm' | 'md' | 'lg''md'Size
stateState'default'Validation state
disabledbooleanfalseDisabled
readonlybooleanfalseRead-only
requiredbooleanfalseRequired
maskedbooleanfalseMask characters
groupingnumber[]Grouping pattern (e.g., [3, 3])
separatorstring'-'Separator character between groups
autoSubmitbooleanfalseEmit complete when all fields are filled
placeholderstring''Placeholder per field
autoFocusbooleanfalseAuto-focus on mount

Props (OtpInputField)

Inherits from FormFieldProps + OtpInputProps. Additional props:

PropTypeDefaultDescription
labelstringField label
messagestringHelp or error message
fieldIdstringCustom ID
requiredTextstring'requis'Required indicator text

Events

EventPayloadDescription
update:modelValuestringv-model update
completestringAll fields are filled (if autoSubmit)
changestringValue changed
focusFocusEvent, numberFocus on a field (with index)
blurFocusEvent, numberBlur from a field (with index)

Slots

SlotDescription
separatorCustom separator content between groups

Exposed methods

MethodDescription
focus()Focus the first field
clear()Clear all fields and focus the first one

Accessibility

  • role="group" with descriptive aria-label on the container
  • Each field has an individual aria-label ("Character X of Y")
  • aria-live="polite" region to announce progress
  • Keyboard navigation: left/right arrows, Home, End, Backspace, Delete
  • autocomplete="one-time-code" for mobile auto-fill
  • inputmode="numeric" to show numeric keyboard on mobile
  • Paste support with automatic character distribution
  • Supports prefers-contrast: high and prefers-reduced-motion: reduce

Publié sous licence MIT.