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

Import

component.ts
import { NeuTabsComponent } from '@neural-ui/native/tabs';

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.

The release desk

Switch between a release overview and a team activity feed. Completing the final review updates the readiness bar and banner status together; the choice survives switching panels.

View and copy the complete example
basic.component.ts
import { Component, signal } from '@angular/core';
import { NeuCheckboxComponent } from '@neural-ui/native/checkbox';
import { NeuDividerComponent } from '@neural-ui/native/divider';
import { NeuAvatarComponent } from '@neural-ui/native/avatar';
import { NeuProgressBarComponent } from '@neural-ui/native/progress-bar';
import { NeuTabsComponent } from '@neural-ui/native/tabs';
import { View, Text, ScrollView } from '@ng-native/components';
import { NeuTabPanelComponent } from '@neural-ui/native/tabs';
import type { NeuOption } from '@neural-ui/native';

@Component({
  selector: 'app-example',
  imports: [NeuCheckboxComponent, NeuDividerComponent, NeuAvatarComponent, NeuProgressBarComponent, NeuTabsComponent, NeuTabPanelComponent, 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">The release desk</text><text class="product-caption">Everything about this milestone in one place</text></view>
    <view class="release-banner"><text class="release-kicker">NEURAL STUDIO / RELEASE 02</text><text class="release-title">A thoughtful welcome.</text><view class="product-row"><view class="product-copy"><text class="release-date">Mobile launch · Friday</text></view><view class="release-stage"><text class="release-stage-text">{{ done() ? 'Ready' : 'In review' }}</text></view></view></view>
    <neu-tabs label="Project details" [tabs]="tabs" [(value)]="selectedTab"><neu-tab-panel id="overview"><view class="release-overview"><neu-progress-bar label="Release readiness" [value]="done() ? 100 : 72" /><text class="product-heading">A welcoming first impression</text><text class="product-caption">Prepare the onboarding flow and final release notes.</text><view class="release-review"><neu-checkbox label="Final review complete" [(checked)]="done" /><text class="product-caption">{{ done() ? 'All set for the next milestone.' : 'One final look before the handoff.' }}</text></view></view></neu-tab-panel>
    <neu-tab-panel id="activity"><view class="product-section"><view class="product-row"><neu-avatar label="Grace Hopper" size="sm" /><view class="product-copy"><text class="product-heading">Grace Hopper</text><text class="product-caption">Updated the release notes · Today</text></view></view><neu-divider /><view class="product-row"><neu-avatar label="Ada Lovelace" size="sm" /><view class="product-copy"><text class="product-heading">Ada Lovelace</text><text class="product-caption">Reviewed onboarding · Yesterday</text></view></view></view></neu-tab-panel></neu-tabs></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); }
.release-banner { gap: 16px; padding: 22px; border-radius: 20px; background-color: #e7edff; }
.release-kicker { color: #3a5693; font-size: 10px; line-height: 16px; font-weight: 600; letter-spacing: 1px; }
.release-title { color: #173f82; font-size: 30px; line-height: 36px; font-weight: 600; }
.release-date { color: #425d8c; font-size: 13px; line-height: 19px; }
.release-stage { padding: 6px 10px; border-radius: 20px; background-color: #ffffff; }
.release-stage-text { color: #234e94; font-size: 11px; line-height: 16px; font-weight: 600; }
.release-overview { gap: 16px; padding-top: 8px; }
.release-review { gap: 8px; padding: 16px; border-radius: 14px; background-color: var(--neu-surface, #ffffff); border-width: 1px; border-color: var(--neu-border, #a5afbf); }
  `,
})
export class ExampleComponent {
  readonly tabs: readonly NeuOption[] = [
    {
      "id": "overview",
      "label": "Overview"
    },
    {
      "id": "activity",
      "label": "Activity"
    }
  ];
  readonly selectedTab = signal('overview');
  readonly done = signal(false);
}
Interactive playground

Change the settings and try the result.

Device captures shown in English.

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

Personalization

Projected content

Project neu-tab-panel children with IDs matching the tabs data. Each active panel renders its own projected content. Import NeuTabPanelComponent from @neural-ui/native/tabs as well as NeuTabsComponent.

Use native elements from @ng-native/components and public Neural Native controls. Angular styles belong to the component that declares this content.

API reference

Inputs

NameTypeDefaultBindingDescription
labelstring'Tabs'InputHuman-readable name for the control, action or group.
tabsreadonly NeuOption[][]InputTab definitions with stable IDs, labels and optional disabled state.
disabledbooleanfalseInputDisables user interaction. Values can still be supplied by the application.

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.

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

Types and data interfaces

Use the imports in your application. The definitions below are provided for reference.

NeuOption

NeuOption.ts
import type { NeuOption } from '@neural-ui/native';

// Public definition for reference only. Import this type; do not redeclare it.
export interface NeuOption {
    readonly id: string;
    readonly label: string;
    readonly description?: string;
    readonly disabled?: boolean;
}
FieldTypeRequirementMeaning
idstringRequiredStable, unique identifier used for tracking and selection.
labelstringRequiredHuman-readable item name.
descriptionstringOptionalOptional supporting text; rendering depends on the control.
disabledbooleanOptionalPrevents activating or selecting this item.

Companion component: NeuTabPanelComponent

companion-import.ts
import { NeuTabPanelComponent } from '@neural-ui/native/tabs';

Import the companion together with the parent component and add both to Component.imports. The example above demonstrates their relationship.

NameTypeDefaultBindingDescription
idstringRequiredInputRequired panel ID. It must match the id of an enabled item in the parent Tabs tabs array.