Getting StartedInstallation and setup guides 5
LayoutWorkflow and structural layout components 7
OverlayModal and floating layer surfaces 3
FeedbackStatus, empty, progress, and loading placeholder patterns 5
FormInput and selection components 17
UtilityGeneral-purpose interface utilities 7
NavigationMenu surfaces and hierarchical actions 7

API reference

<tng-input-otp> is the wrapper surface. It renders the segmented slots, keeps the combined value in sync, and bridges forms through ControlValueAccessor.

<tng-input-otp> wrapper

Wrapper usage

html
<tng-input-otp
  [length]="6"
  [value]="verificationCode()"
  [type]="'numeric'"
  [required]="true"
  [ariaLabel]="'Verification code'"
  (valueChange)="onVerificationCodeChange($event)"
  (complete)="onVerificationCodeComplete($event)"
></tng-input-otp>
InputTypeNotes
lengthnumberTotal slot count. The component normalizes the value to the configured length.
value / defaultValuestringControlled and uncontrolled starting values for the combined OTP string.
type / pattern'numeric' | 'alphanumeric' | 'custom'Choose the accepted character set, or provide a custom regex when needed.
maskbooleanMasks slot values while keeping the underlying string value intact.
disabled, readonly, required, invalidbooleanMaps interaction and validation state into the rendered slots.
autoFocus / selectOnFocusbooleanControls startup focus and whether existing slot content is selected on focus.
placeholderCharstringSingle-character placeholder shown in empty slots.
name, form, autocomplete, inputModestringHidden-input form submission and mobile keyboard hints.
ariaLabel, ariaLabelledby, ariaDescribedbystringAccessible naming and helper-text wiring for the grouped field.

Events

OutputPayloadNotes
valueChangestringEmits on each valid slot update, paste, deletion, or replacement.
completestringEmits when all slots are filled with valid characters.

Angular forms integration

The wrapper implements ControlValueAccessor and works with formControl, formControlName, and ngModel.

Reactive forms wiring

ts
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';

readonly verificationForm = new FormGroup({
  otp: new FormControl('', { nonNullable: true }),
});

<tng-input-otp formControlName="otp"></tng-input-otp>

Angular Signal Forms can also bind the wrapper directly with [formField] when you want the OTP string to live inside a signal-backed form model.

Signal forms wiring

ts
import { Component, signal } from '@angular/core';
import { FormField, form } from '@angular/forms/signals';
import { TngInputOtpComponent } from '@tailng-ui/components';

@Component({
  selector: 'app-verification-code-signal-form',
  standalone: true,
  imports: [FormField, TngInputOtpComponent],
  template: \`
    <tng-input-otp
      [length]="6"
      [formField]="verificationForm.code"
      ariaLabel="Verification code"
    ></tng-input-otp>
  \`,
})
export class VerificationCodeSignalFormComponent {
  readonly verificationModel = signal({ code: '' });
  readonly verificationForm = form(this.verificationModel);
}

Primitive foundation

The wrapper is built on top of the headless [tngInputOtp] primitive. When you need to fully own the slot markup and state selectors, use the dedicated headless Input OTP docs under /headless/form/input-otp.