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

Import

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

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.

Made of many skills

Build a team profile with editable skill tags and a live profile preview. Add your own text or choose a suggestion, remove any tag and respect the same four-item limit in both paths.

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

@Component({
  selector: 'app-example',
  imports: [NeuAvatarComponent, NeuChipComponent, NeuInputTagsComponent, View, Text, ScrollView],
  template: `
    <scroll-view class="product-scroll" keyboardShouldPersistTaps="handled" [showsVerticalScrollIndicator]="false"><view class="product-stack"><view class="product-section"><text class="product-title" accessibilityRole="header">Made of many skills</text><text class="product-caption">Help your next collaborator find you</text></view>
    <view class="profile-preview"><text class="profile-kicker">NEURAL PEOPLE</text><view class="product-row"><neu-avatar label="Alex Morgan" size="lg" /><view class="product-copy"><text class="profile-name">Alex Morgan</text><text class="profile-role">Product designer · Neural Studio</text></view></view>
    <view class="profile-skills">@for (skill of skills(); track skill) { <neu-chip [label]="skill" [selectable]="false" tone="brand" /> } @empty { <text class="profile-role">Your skills will appear here.</text> }</view></view>
    <view class="product-surface"><view class="product-row"><view class="product-copy"><text class="product-heading">Your expertise</text></view><text class="product-caption">{{ skills().length }} / 4</text></view><neu-input-tags label="Skills" placeholder="Add a skill" [(value)]="skills" [max]="4" addLabel="Add skill" />
    <view class="product-section"><text class="product-caption">A little inspiration</text><view class="skill-suggestions">@for (skill of suggestions; track skill) { @if (!skills().includes(skill)) { <neu-chip [label]="skill" [disabled]="skills().length >= 4" (selectedChange)="addSkill(skill)" /> } }</view></view>
    <text class="product-caption">Add up to four skills. Your profile preview updates as you go.</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); }
.profile-preview { gap: 18px; padding: 20px; border-radius: 18px; background-color: #e8effb; --neu-surface-secondary: #d6e4fa; --neu-text: #18375c; }
.profile-kicker { color: #45648d; font-size: 10px; line-height: 16px; font-weight: 600; letter-spacing: 1px; }
.profile-name { color: #18375c; font-size: 22px; line-height: 28px; font-weight: 600; }
.profile-role { color: #496486; font-size: 12px; line-height: 18px; }
.profile-skills, .skill-suggestions { flex-direction: row; flex-wrap: wrap; gap: 8px; }
  `,
})
export class ExampleComponent {
  readonly skills = signal<readonly string[]>(['Angular', 'Design']);
  readonly suggestions = ['Prototyping', 'Accessibility', 'Research'];
  addSkill(skill: string) { if (this.skills().length < 4 && !this.skills().includes(skill)) this.skills.update(value => [...value, skill]); }
}

Read-only tags

Show workspace categories without allowing additions or removal.

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

@Component({
  selector: 'app-example',
  imports: [NeuInputTagsComponent, View, ScrollView],
  template: `
    <scroll-view class="usage-scroll" keyboardShouldPersistTaps="handled"><view class="usage-stack">
    <neu-input-tags label="Workspace categories" [value]="categories" [readonly]="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 categories: readonly string[] = ['Product', 'Mobile'];
}
Interactive playground

Change the settings and try the result.

Device captures shown in English.

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

API reference

Inputs

NameTypeDefaultBindingDescription
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.
maxnumber20InputMaximum accepted number of tags.
addLabelstring'Add'InputAccessible name of the add icon action. The same action is available from the keyboard submit key.
placeholderstring''InputExample or prompt displayed while the value is empty; keep a separate label.
removeLabelstring'Remove'InputAccessible prefix for each tag removal action, followed by its text.

Models

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

Outputs

NamePayloadWhen it emits
valueChangereadonly string[]Emits 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<readonly string[]>([]);