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

Import

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

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.

Your public profile

Edit a public profile, compare the read-only identifier and confirm the change locally. The action becomes available only after an edit.

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

@Component({
  selector: 'app-example',
  imports: [NeuButtonComponent, NeuInputComponent, NeuAvatarComponent, 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">Your public profile</text><text class="product-caption">Help your team recognize you</text></view>
    <view class="product-surface"><neu-avatar [label]="name() || 'Alex Morgan'" size="lg" />
    <neu-input label="Full name" hint="This is how your team will see you" [(value)]="name" />
    <neu-input label="Account ID" value="member-104" [readonly]="true" />
    <view class="product-actions"><neu-button label="Update profile" size="sm" [disabled]="!name().trim() || name() === saved()" (pressed)="saved.set(name())" /></view>
    <text class="product-caption" accessibilityLiveRegion="polite">{{ name() === saved() ? 'Profile is up to date' : 'You have unsaved changes' }}</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 name = signal('Alex Morgan');
  readonly saved = signal('Alex Morgan');
}

Validation and unavailable fields

Add @ to clear the example email error and compare the disabled field.

View and copy the complete example
validation-and-unavailable-fields.component.ts
import { Component, signal } from '@angular/core';
import { NeuInputComponent } from '@neural-ui/native/input';
import { View, ScrollView } from '@ng-native/components';

@Component({
  selector: 'app-example',
  imports: [NeuInputComponent, View, ScrollView],
  template: `
    <scroll-view class="usage-scroll" keyboardShouldPersistTaps="handled"><view class="usage-stack">
    <neu-input label="Invitation email" keyboardType="email-address" [(value)]="invitationEmail" [invalid]="invitationEmail().length > 0 && !invitationEmail().includes('@')" [touched]="true" error="Enter an email address including @." placeholder="alex@example.com" />
    <neu-input label="Managed by your organization" value="Workspace account" [disabled]="true" />
    </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 invitationEmail = signal('alex');
}
Interactive playground

Change the settings and try the result.

Device captures shown in English.

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

API reference

Inputs

NameTypeDefaultBindingDescription
keyboardType"default" | "email-address" | "numeric" | "phone-pad"'default'InputKeyboard layout requested from the platform. It does not replace a validation rule.
labelstringRequiredInputHuman-readable name for the control, action or group.
placeholderstring''InputExample or prompt displayed while the value is empty; keep a separate label.
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.
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.
maxLengthnumber | undefinedundefinedInputMaximum accepted text length: a nonnegative integer. Zero prevents entering characters; undefined leaves the limit unset. Negative values normalize to zero and decimals are truncated. This control property also works without Angular Forms.

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
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>('');