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

Import

component.ts
import { NeuAccordionComponent } from '@neural-ui/native/accordion';

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.

Good to know before you order

Read delivery answers within a purchase context and compare single-open with multiple-open behavior. Switching to single-open keeps at most one answer expanded.

View and copy the complete example
basic.component.ts
import { Component, signal } from '@angular/core';
import { NeuSwitchComponent } from '@neural-ui/native/switch';
import { NeuBadgeComponent } from '@neural-ui/native/badge';
import { NeuAccordionComponent } from '@neural-ui/native/accordion';
import { View, Text, ScrollView } from '@ng-native/components';
import type { NeuOption } from '@neural-ui/native';

@Component({
  selector: 'app-example',
  imports: [NeuSwitchComponent, NeuBadgeComponent, NeuAccordionComponent, 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">Good to know before you order</text><text class="product-caption">Clear answers, only when you need them</text></view>
    <view class="product-surface"><neu-badge label="Delivery and returns" tone="info" /><neu-accordion [items]="questions" [(expanded)]="expanded" [multiple]="multiple()" /></view>
    <neu-switch label="Keep several answers open" [checked]="multiple()" (checkedChange)="changeMode($event)" /></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 questions: readonly NeuOption[] = [
    {
      "id": "shipping",
      "label": "When will my order arrive?",
      "description": "Orders usually arrive within three working days."
    },
    {
      "id": "returns",
      "label": "Can I return an item?",
      "description": "Contact support within 30 days of delivery."
    }
  ];
  readonly expanded = signal<readonly string[]>(['shipping']);
  readonly multiple = signal(true);
  changeMode(value: boolean) { this.multiple.set(value); if (!value) this.expanded.update(items => items.slice(0, 1)); }
}

One section at a time

Opening one answer closes the previously expanded answer.

View and copy the complete example
one-section-at-a-time.component.ts
import { Component, signal } from '@angular/core';
import { NeuAccordionComponent } from '@neural-ui/native/accordion';
import { View, ScrollView } from '@ng-native/components';
import type { NeuOption } from '@neural-ui/native';

@Component({
  selector: 'app-example',
  imports: [NeuAccordionComponent, View, ScrollView],
  template: `
    <scroll-view class="usage-scroll" keyboardShouldPersistTaps="handled"><view class="usage-stack">
    <neu-accordion [items]="questions" [(expanded)]="singleExpanded" [multiple]="false" />
    </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 questions: readonly NeuOption[] = [
    {
      "id": "shipping",
      "label": "When will my order arrive?",
      "description": "Orders usually arrive within three working days."
    },
    {
      "id": "returns",
      "label": "Can I return an item?",
      "description": "Contact support within 30 days of delivery."
    }
  ];
  readonly expanded = signal<readonly string[]>(['shipping']);
  readonly singleExpanded = signal<readonly string[]>([]);
}
Interactive playground

Change the settings and try the result.

Device captures shown in English.

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

API reference

Inputs

NameTypeDefaultBindingDescription
itemsreadonly NeuOption[][]InputEach item has a stable id, label for its clickable header, and description for its expandable text body. The disabled flag prevents interaction with that item. The header and body share one surface, separated by a divider while expanded.
multiplebooleanfalseInputAllows multiple choices or files where supported; check the declared model type.
disabledbooleanfalseInputDisables user interaction. Values can still be supplied by the application.

Models

NameTypeDefaultBindingDescription
expandedreadonly string[][]Model · two-wayIDs of currently expanded sections or nodes. Bind a writable signal with [(expanded)].

Outputs

NamePayloadWhen it emits
expandedChangereadonly string[]Emits the updated expanded value. [(expanded)] 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 expanded = signal<readonly 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.