Skip to main content
Neural Nativev0.1.0-beta.1Documentation

Import

component.ts
import { NeuInputOtpComponent } from '@neural-ui/native/input-otp';

Examples

Import ExampleComponent into its parent and place <app-example /> inside your application’s root neu-theme. The preview supplies the device frame and safe areas; use the root setup from Installation in your app.

One last step

Type, paste, replace or delete code digits and check the complete value locally. This demonstration sends no SMS and does not authenticate an account.

View and copy the complete example
basic.component.ts
import { Component, signal } from '@angular/core';
import { NeuButtonComponent } from '@neural-ui/native/button';
import { NeuInputOtpComponent } from '@neural-ui/native/input-otp';
import { View, Text, ScrollView } from '@ng-native/components';

@Component({
  selector: 'app-example',
  imports: [NeuButtonComponent, NeuInputOtpComponent, View, Text, ScrollView],
  template: `
    <scroll-view class="product-scroll" keyboardShouldPersistTaps="handled" [showsVerticalScrollIndicator]="true"><view class="product-stack"><view class="product-section"><text class="product-title" accessibilityRole="header">One last step</text><text class="product-caption">Keep your account in your hands</text></view>
    <view class="product-surface"><neu-input-otp label="Verification code" [length]="6" hint="Enter any six digits to try this local example" [(value)]="code" />
    <view class="product-actions"><neu-button label="Check code" size="sm" [disabled]="code().length !== 6" (pressed)="checked.set(code())" /><neu-button label="Start over" size="sm" variant="text" (pressed)="reset()" /></view>
    @if (checked()) { <text class="product-caption" accessibilityLiveRegion="polite">Six digits received. A real app verifies them on its server.</text> }</view></view></scroll-view>
  `,
  styles: `
.actions { gap: 12px; align-items: flex-start; } text { color: var(--neu-text, #172033); font-size: 16px; }

:host { flex: 1; flex-shrink: 1; min-height: 0; }
.product-scroll { flex: 1; flex-shrink: 1; height: 0px; min-height: 0; }
.product-stack { gap: 24px; padding-bottom: 20px; }
.product-section { gap: 12px; }
.product-row { flex-direction: row; align-items: center; gap: 12px; }
.product-copy { flex: 1; min-width: 0; gap: 4px; }
.product-title { color: var(--neu-text, #172033); font-size: 24px; line-height: 30px; font-weight: 600; }
.product-heading { color: var(--neu-text, #172033); font-size: 17px; line-height: 23px; font-weight: 600; }
.product-caption { color: var(--neu-muted, #596477); font-size: 14px; line-height: 20px; }
.product-actions { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px; }
.product-surface { gap: 16px; padding: 16px; border-radius: 16px; background-color: var(--neu-surface, #ffffff); border-width: 1px; border-color: var(--neu-border, #a5afbf); }

  `,
})
export class ExampleComponent {
  readonly code = signal('');
  readonly checked = signal('');
  reset() { this.code.set(''); this.checked.set(''); }
}

Read-only code

Display a previously verified four-digit code.

View and copy the complete example
read-only-code.component.ts
import { Component, signal } from '@angular/core';
import { NeuInputOtpComponent } from '@neural-ui/native/input-otp';
import { View, ScrollView } from '@ng-native/components';

@Component({
  selector: 'app-example',
  imports: [NeuInputOtpComponent, View, ScrollView],
  template: `
    <scroll-view class="usage-scroll" keyboardShouldPersistTaps="handled"><view class="usage-stack">
    <neu-input-otp label="Verified code" value="1234" [length]="4" [readonly]="true" hint="A previously verified four-digit code." />
    </view></scroll-view>
  `,
  styles: `
.actions { gap: 12px; align-items: flex-start; } text { color: var(--neu-text, #172033); font-size: 16px; }

.usage-scroll { flex: 1; }
.usage-stack { gap: 20px; padding-bottom: 20px; }
.usage-section { gap: 12px; }
.usage-heading { color: var(--neu-text, #172033); font-size: 16px; font-weight: 600; }
.usage-caption { color: var(--neu-muted, #64748b); font-size: 14px; }
.usage-row { flex-direction: row; flex-wrap: wrap; gap: 12px; align-items: center; }
.usage-actions { flex-direction: row; flex-wrap: wrap; gap: 8px; align-items: center; }


  `,
})
export class ExampleComponent {
  readonly code = signal('');
}
Interactive playground

Change the settings and try the result.

Device captures shown in English.

Input Otp · android · native capture
AndroidNative screenshot
Input Otp · ios · native capture
iOSNative screenshot

API reference

Inputs

NameTypeDefaultBindingDescription
lengthnumber6InputNumber of positions in the one-time-code input.
labelstringRequiredInputHuman-readable name for the control, action or group.
disabledbooleanfalseInputDisables user interaction. Values can still be supplied by the application.
readonlybooleanfalseInputPrevents user editing or selection while retaining the current value.
invalidbooleanfalseInputMarks the control invalid. Your form or application supplies the validation rule.
touchedbooleanfalseInputField interaction state, supplied manually or through Signal Forms.
hintstring''InputField guidance shown when no error message is being displayed.
requiredbooleanfalseInputRequired-field presentation. Define the actual validation rule in your application form.
requiredLabelstring'Required'InputLocalized requirement announced with the field hint when required is true. Defaults to Required; it does not validate the value.
errorstring''InputApplication-provided error message; combine it with the control’s invalid state.

Models

NameTypeDefaultBindingDescription
valuestring''Model · two-wayCurrent edited value or selected ID(s), using the declared type. Bind a writable signal with [(value)].

Outputs

NamePayloadWhen it emits
completedstringEmits the numeric code when an edit fills all positions. Repeating the same complete value does not emit it again. Your application performs verification.
valueChangestringEmits the updated value value. [(value)] binds this output together with its model input.
touchvoidReports user interaction to the surrounding form or application.

Model state

Bind the signal with [(modelName)] without calling it. Use modelName() to read its value.

model-fields.ts
import { signal } from '@angular/core';

// Fields inside your component class
readonly value = signal<string>('');