Input OTP

August 8, 2025 ยท View on GitHub

A specialized input component for One-Time Password (OTP) entry. Provides an intuitive interface for entering verification codes, PINs, and other sequential numeric or alphanumeric codes.

Features

  • Flexible Length: Support for 4-8 digit codes
  • Auto-Focus: Automatic focus management between input fields
  • Paste Support: Smart paste handling for complete codes
  • Validation: Built-in validation with customizable patterns
  • Accessibility: Full keyboard navigation and screen reader support
  • Customizable: Various styling options and input types
  • Form Integration: Works seamlessly with Angular reactive forms

Installation

The Input OTP component is part of the Angular SuperUI library:

npx ngsui-cli add input-otp

Basic Usage

Simple OTP Input

import { Component } from '@angular/core';
import { InputOTP } from 'angular-superui';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [InputOTP],
  template: `
    <InputOTP
      [length]="6"
      [(value)]="otpCode"
      placeholder="Enter verification code"
      (complete)="onOTPComplete($event)"
    />
  `
})
export class ExampleComponent {
  otpCode: string = '';
  
  onOTPComplete(code: string): void {
    console.log('OTP entered:', code);
    // Handle OTP verification
  }
}

Variants

Different Lengths

<!-- 4-digit PIN -->
<InputOTP [length]="4" [(value)]="pin" />

<!-- 6-digit verification code -->
<InputOTP [length]="6" [(value)]="verificationCode" />

<!-- 8-digit code -->
<InputOTP [length]="8" [(value)]="longCode" />

Input Types

<!-- Numeric only -->
<InputOTP [length]="6" type="number" [(value)]="numericCode" />

<!-- Alphanumeric -->
<InputOTP [length]="6" type="text" [(value)]="alphanumericCode" />

Form Integration

Reactive Forms

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  template: `
    <form [formGroup]="verificationForm" (ngSubmit)="onSubmit()">
      <InputOTP
        formControlName="otpCode"
        [length]="6"
        [required]="true"
      />
      <button type="submit" [disabled]="verificationForm.invalid">
        Verify Code
      </button>
    </form>
  `
})
export class VerificationComponent {
  verificationForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.verificationForm = this.fb.group({
      otpCode: ['', [Validators.required, Validators.pattern(/^\d{6}$/)]]
    });
  }

  onSubmit(): void {
    if (this.verificationForm.valid) {
      const code = this.verificationForm.get('otpCode')?.value;
      console.log('Verification code:', code);
    }
  }
}

API Reference

InputOTP Props

PropTypeDefaultDescription
lengthnumber6Number of input fields (4-8)
valuestring''Current OTP value
type'text' | 'number''number'Input type constraint
placeholderstring'โ—'Placeholder character for empty fields
disabledbooleanfalseWhether the input is disabled
requiredbooleanfalseWhether the input is required
autoFocusbooleantrueAuto-focus first field on mount
classNamestringundefinedAdditional CSS classes

InputOTP Events

EventTypeDescription
valueChangeEventEmitter<string>Emitted when value changes
completeEventEmitter<string>Emitted when all fields are filled
pasteEventEmitter<string>Emitted when content is pasted

Examples

Two-Factor Authentication

@Component({
  template: `
    <div class="max-w-md mx-auto p-6">
      <h2 class="text-2xl font-bold mb-4">Enter Verification Code</h2>
      <p class="text-gray-600 mb-6">
        We've sent a 6-digit code to your phone number ending in ***{{phoneEnding}}
      </p>
      
      <InputOTP
        [length]="6"
        [(value)]="verificationCode"
        [disabled]="isVerifying"
        (complete)="onCodeComplete($event)"
        className="mb-4"
      />
      
      <div *ngIf="error" class="text-red-500 text-sm mb-4">
        {{ error }}
      </div>
      
      <div class="flex space-x-4">
        <button 
          (click)="verifyCode()" 
          [disabled]="!isCodeComplete || isVerifying"
          class="flex-1 px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
        >
          {{ isVerifying ? 'Verifying...' : 'Verify Code' }}
        </button>
        <button 
          (click)="resendCode()" 
          [disabled]="isVerifying"
          class="px-4 py-2 border border-gray-300 rounded"
        >
          Resend
        </button>
      </div>
    </div>
  `
})
export class TwoFactorComponent {
  verificationCode: string = '';
  phoneEnding: string = '1234';
  isVerifying: boolean = false;
  error: string = '';

  get isCodeComplete(): boolean {
    return this.verificationCode.length === 6;
  }

  onCodeComplete(code: string): void {
    this.verifyCode();
  }

  async verifyCode(): Promise<void> {
    if (!this.isCodeComplete) return;
    
    this.isVerifying = true;
    this.error = '';
    
    try {
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 2000));
      console.log('Code verified:', this.verificationCode);
      // Handle successful verification
    } catch (error) {
      this.error = 'Invalid verification code. Please try again.';
    } finally {
      this.isVerifying = false;
    }
  }

  async resendCode(): Promise<void> {
    // Handle code resend
    console.log('Resending verification code...');
  }
}

This Input OTP component provides a secure and user-friendly way to handle one-time password entry in Angular applications.