vwf .

Developer Docs

Quick reference guides with props tables, usage examples, and best practices for rapid development

Components/Docs/OTPInput

OTPInput

One-time password input with auto-focus progression and paste support

OTPInput

A one-time password input component with intelligent navigation and paste support. Creates individual inputs for each digit with automatic focus management, auto-advance, backspace navigation, and clipboard integration.

Live Example

Current value: [object Object]

🔧 Props

PropTypeDefaultDescription
valuevan.Statevan.state('')OTP value state (automatically updated)
lengthnumber6Number of OTP digits (4-8 typical)
autofocusbooleanfalseAuto-focus first input on mount (100ms setTimeout)
onCompleteFunctionundefinedCallback when all digits entered (receives complete code)
disabledboolean | StatefalseWhether inputs are disabled
classstring''Input classes (overrides defaults via filterClassName)
containerClassstring''Container wrapper classes (flex gap-2 justify-center)
idstringautoContainer ID (auto-generated: input-{timestamp})

💻 Basic Usage

Default 6-digit OTP with auto-focus and completion callback.

Value: [object Object]
const otp = van.state('');

OTPInput({
  value: otp,
  autofocus: true,
  onComplete: (code) => {
    console.log('OTP entered:', code);
    verifyOTP(code);
  }
})

📏 Custom Length

4-digit PIN or 8-digit code - any length supported.

4-Digit PIN

Value: [object Object]
const pin = van.state('');

OTPInput({
  length: 4,
  value: pin,
  onComplete: (code) => validatePIN(code)
})

8-Digit Code

OTPInput({
  length: 8,
  value: code,
  class: 'size-8 text-base'  // Smaller inputs for 8 digits
})

🎨 Custom Styling

Override input appearance and container spacing with Tailwind classes.

Large Inputs

OTPInput({
  value: otp,
  class: 'size-12 text-2xl rounded-xl border-4 border-sky',
  containerClass: 'gap-4'  // More spacing between inputs
})

Custom Colors

OTPInput({
  value: otp,
  class: 'size-10 text-xl bg-white border-2 border-sunset focus:border-sunrise focus:ring-2 focus:ring-sunrise/20'
})

🚫 Disabled State

Show OTP inputs in disabled state (e.g., during verification).

const verifying = van.state(false);

OTPInput({
  value: otp,
  disabled: verifying  // Disable during API call
})

⌨️ Smart Navigation

Built-in keyboard navigation for seamless user experience.

✅Auto-advance on digit entry

Automatically moves to next input when a digit is entered

✅Backspace navigation

Pressing backspace on empty input moves to previous input

✅Arrow key navigation

Use left/right arrow keys to move between inputs

✅Auto-select on focus

Clicking an input automatically selects its content for easy replacement

🕐 Paste Support

Intelligent clipboard integration with automatic digit distribution.

✅Numeric filtering

Pasted content is automatically filtered to only include digits (0-9)

✅Auto-distribution

Pasted digits are automatically distributed across inputs from paste position

✅Length limiting

Pasted content is truncated to fit remaining inputs (e.g., paste "123456789" into 6-digit OTP)

✅Focus management

Focus automatically moves to last filled input after paste

// User pastes "123456789" into first input of 6-digit OTP
// Result: Inputs show "1 2 3 4 5 6", extra digits ignored
// Focus moves to 6th input automatically

⚡️ Best Practices

✓ Do This

✓Use autofocus for better UX

- Set autofocus: true so users can immediately start typing without clicking.

✓Provide onComplete callback

- Auto-submit verification when all digits are entered for faster flow.

✓Use appropriate length

- Common lengths: 4 (PIN), 6 (OTP), 8 (security codes). Match your backend requirements.

✓Disable during verification

- Set disabled: true while verifying to prevent re-submission and changes.

✓Clear on error

- Reset value to empty string when verification fails for better UX.

✗ Avoid This

✗Don't use very small inputs

- Minimum size-8 recommended for mobile touch targets (44x44px accessibility guideline).

✗Don't forget to handle paste

- Paste support is built-in, but make sure your onComplete handler can process pasted codes.

✗Don't use extreme lengths

- Stick to 4-8 digits. Longer codes should use a single input field instead.

✨ Key Features

⭑Individual State Per Input

- Dual-state pattern: each input has its own state, plus parent state for the complete value.

⭑Auto-Updated Parent State

- Parent state automatically updates as a concatenated string of all digit values.

⭑Smart Navigation

- Auto-advance on input, backspace to previous, arrow key navigation between inputs.

⭑Paste Support

- Built-in paste handling with numeric filtering - extracts only digits from pasted content.

⭑Auto-Focus

- First input auto-focuses with 100ms setTimeout to ensure DOM readiness.

⭑onComplete Callback

- Fires once when all digits are entered, perfect for auto-submit verification.

⭑Numeric-Only Input

- Enforces numeric input with special key allowances (backspace, delete, arrows, tab).

⭑Auto-Select on Focus

- Existing digit auto-selects on focus for easy replacement without backspace.

⭑Disabled State Support

- All inputs disable together, useful during verification process.

⭑Full Tailwind Override

- filterClassName enables complete styling customization with any Tailwind classes.

⭑Auto-Generated IDs

- Automatic unique ID generation if not provided, preventing console errors.

⭑DOM Leakage Prevention

- Proper cleanup of event listeners and timeouts to prevent memory leaks.

Explore More Components

Browse other component categories