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

Import

component.ts
import { NeuFilterBarComponent } from '@neural-ui/native/filter-bar';

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.

Basic

Search for a project and choose one or more statuses. The list and result count update together; Clear restores all projects.

View and copy the complete example
basic.component.ts
import { Component, signal, computed } from '@angular/core';
import { NeuCardComponent } from '@neural-ui/native/card';
import { NeuBadgeComponent } from '@neural-ui/native/badge';
import { NeuEmptyStateComponent } from '@neural-ui/native/empty-state';
import { NeuFilterBarComponent } from '@neural-ui/native/filter-bar';
import { View, Text, ScrollView } from '@ng-native/components';
import type { NeuOption } from '@neural-ui/native';

@Component({
  selector: 'app-example',
  imports: [NeuCardComponent, NeuBadgeComponent, NeuEmptyStateComponent, NeuFilterBarComponent, View, Text, ScrollView],
  template: `
    <scroll-view class="project-scroll" keyboardShouldPersistTaps="handled">
      <view class="project-browser">
        <view class="project-intro">
          <text class="project-title">Projects</text>
          <text class="project-hint">Search by name or team and choose one or more statuses.</text>
        </view>
        <neu-filter-bar label="Project status" [options]="filters"
          [(value)]="selected" [(query)]="query"
          searchLabel="Search projects" clearLabel="Clear" />
        <text class="result-count">Showing {{ filteredProjects().length }} of {{ projects.length }} projects</text>
        <view class="project-list">
          @for (project of filteredProjects(); track project.id) {
            <neu-card [title]="project.title" [description]="project.team" variant="outlined">
              <neu-badge [label]="project.statusLabel" [tone]="project.tone" />
            </neu-card>
          } @empty {
            <neu-empty-state title="No matching projects"
              description="Try another name or clear the status filters."
              actionLabel="Show all projects" (action)="resetFilters()" />
          }
        </view>
      </view>
    </scroll-view>
  `,
  styles: `
.actions { gap: 12px; align-items: flex-start; } text { color: var(--neu-text, #172033); font-size: 16px; }
:host { flex: 1; min-height: 0; }
.project-scroll { flex: 1; min-height: 0; }
.project-browser { gap: 20px; padding-bottom: 20px; }
.project-intro { gap: 6px; }
.project-title { font-size: 24px; line-height: 32px; font-weight: 700; }
.project-hint { font-size: 14px; line-height: 20px; color: var(--neu-muted, #596477); }
.result-count { font-size: 14px; line-height: 20px; font-weight: 600; color: var(--neu-muted, #596477); }
.project-list { gap: 12px; }
  `,
})
export class ExampleComponent {
  readonly filters: readonly NeuOption[] = [
    { id: 'active', label: 'In progress' },
    { id: 'review', label: 'In review' },
    { id: 'done', label: 'Completed' },
  ];
  readonly projects = [
    { id: 'mobile', title: 'Mobile app', team: 'Product team', status: 'active', statusLabel: 'In progress', tone: 'brand' },
    { id: 'website', title: 'Website refresh', team: 'Platform team', status: 'review', statusLabel: 'In review', tone: 'warning' },
    { id: 'research', title: 'Customer research', team: 'Customer team', status: 'active', statusLabel: 'In progress', tone: 'brand' },
    { id: 'brand', title: 'Brand system', team: 'Design team', status: 'review', statusLabel: 'In review', tone: 'warning' },
    { id: 'payments', title: 'Payment integration', team: 'Platform team', status: 'done', statusLabel: 'Completed', tone: 'success' },
  ] as const;
  readonly selected = signal<readonly string[]>(['active']);
  readonly query = signal('');
  readonly filteredProjects = computed(() => {
    const fold = (text: string) => text.normalize('NFD').replace(/\p{M}/gu, '').toLowerCase();
    const query = fold(this.query().trim());
    const statuses = this.selected();
    return this.projects.filter(project =>
      fold(project.title + ' ' + project.team).includes(query) &&
      (!statuses.length || statuses.includes(project.status)));
  });
  resetFilters(): void {
    this.selected.set([]);
    this.query.set('');
  }
}
Interactive playground

Change the settings and try the result.

Device captures shown in English.

Filter Bar · android · native capture
AndroidNative screenshot
Filter Bar · ios · native capture
iOSNative screenshot

API reference

Inputs

NameTypeDefaultBindingDescription
labelstring'Filters'InputHuman-readable name for the control, action or group.
optionsreadonly NeuOption[][]InputAvailable choices. Selected values refer to option IDs, not their displayed labels.
disabledbooleanfalseInputDisables user interaction. Values can still be supplied by the application.
searchLabelstring'Search'InputText or accessible name used for search. It does not perform the action by itself.
clearLabelstring'Clear filters'InputText or accessible name used for clear. It does not perform the action by itself.

Models

NameTypeDefaultBindingDescription
valuereadonly string[][]Model · two-wayCurrent edited value or selected ID(s), using the declared type. Bind a writable signal with [(value)].
querystring''Model · two-wayCurrent search text used by the control. Bind a writable signal with [(query)].

Outputs

NamePayloadWhen it emits
valueChangereadonly string[]Emits the updated value value. [(value)] binds this output together with its model input.
queryChangestringEmits the updated query value. [(query)] 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<readonly string[]>([]);
readonly query = 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.