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

Import

component.ts
import { NeuCalendarComponent } from '@neural-ui/native/calendar';

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

Select a day to read its agenda. Add, edit or delete events in this local example; changes last only while the page is open.

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 { NeuCalendarComponent } from '@neural-ui/native/calendar';
import { NeuConfirmDialogComponent } from '@neural-ui/native/confirm-dialog';
import { NeuDateInputComponent } from '@neural-ui/native/date-input';
import { NeuModalComponent } from '@neural-ui/native/modal';
import { View, Text, ScrollView } from '@ng-native/components';
import type { NeuCalendarEvent } from '@neural-ui/native/calendar';

@Component({
  selector: 'app-example',
  imports: [NeuButtonComponent, NeuInputComponent, NeuCalendarComponent, NeuConfirmDialogComponent, NeuDateInputComponent, NeuModalComponent, View, Text, ScrollView],
  template: `
    <scroll-view class="calendar-scroll" keyboardShouldPersistTaps="handled"><view class="calendar-content"><neu-calendar
      label="Team calendar" locale="en"
      [(month)]="month" [(value)]="date" [events]="events()" [editable]="true"
      (eventCreateRequested)="createEvent($event)"
      (eventEditRequested)="editEvent($event)"
      (eventDeleteRequested)="requestDelete($event)"
    /></view></scroll-view>
    <neu-modal [(open)]="editorOpen" [title]="editingId() ? 'Edit event' : 'Add event'">
      <neu-input label="Event title" [(value)]="draftTitle" placeholder="Team planning" />
      <neu-date-input label="Event date" locale="en" [(value)]="draftDate" />
      <neu-input label="Details" [(value)]="draftDescription" placeholder="Optional details" />
      @if (formError()) { <text accessibilityRole="alert">{{ formError() }}</text> }
      <view class="actions">
        <neu-button label="Save event" size="sm" (pressed)="saveEvent()" />
        <neu-button label="Cancel" size="sm" variant="text" (pressed)="editorOpen.set(false)" />
      </view>
    </neu-modal>
    <neu-confirm-dialog
      [(open)]="deleteOpen" title="Delete event?"
      [message]="'Remove ' + (deleting()?.label ?? 'this event') + ' from the calendar?'"
      confirmLabel="Delete event" intent="danger" (confirmed)="deleteEvent()"
    />
  `,
  styles: `
.actions { gap: 12px; align-items: flex-start; } text { color: var(--neu-text, #172033); font-size: 16px; }
:host { flex: 1; min-height: 0; } .calendar-scroll { flex: 1; min-height: 0; } .calendar-content { padding-bottom: 20px; } .actions { flex-direction: row; flex-wrap: wrap; gap: 8px; }
  `,
})
export class ExampleComponent {
  readonly month = signal('2026-10');
  readonly date = signal('2026-10-16');
  readonly events = signal<readonly NeuCalendarEvent[]>([
    { id: 'review', label: 'Release review', description: 'Review the mobile release with the team', date: '2026-10-16' },
    { id: 'research', label: 'Customer interview', description: 'Discuss the next mobile experience', date: '2026-10-16' },
    { id: 'planning', label: 'Sprint planning', description: 'Plan the next iteration', date: '2026-10-20' },
  ]);
  readonly editorOpen = signal(false);
  readonly deleteOpen = signal(false);
  readonly editingId = signal<string | null>(null);
  readonly deleting = signal<NeuCalendarEvent | null>(null);
  readonly draftTitle = signal('');
  readonly draftDate = signal('');
  readonly draftDescription = signal('');
  readonly formError = signal('');
  private nextEventId = 0;
  createEvent(date: string): void {
    this.editingId.set(null);
    this.draftTitle.set('');
    this.draftDate.set(date);
    this.draftDescription.set('');
    this.formError.set('');
    this.editorOpen.set(true);
  }
  editEvent(event: NeuCalendarEvent): void {
    this.editingId.set(event.id);
    this.draftTitle.set(event.label);
    this.draftDate.set(event.date);
    this.draftDescription.set(event.description ?? '');
    this.formError.set('');
    this.editorOpen.set(true);
  }
  saveEvent(): void {
    const label = this.draftTitle().trim();
    const date = this.draftDate().trim();
    const parsed = new Date(date + 'T00:00:00.000Z');
    if (!label || !/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(date) || Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== date) {
      this.formError.set('Enter an event title and a valid date (YYYY-MM-DD).');
      return;
    }
    const id = this.editingId();
    const event: NeuCalendarEvent = { id: id ?? 'event-' + ++this.nextEventId, label, date, description: this.draftDescription().trim() };
    this.events.update(events => id ? events.map(item => item.id === id ? event : item) : [...events, event]);
    this.date.set(date);
    this.editorOpen.set(false);
  }
  requestDelete(event: NeuCalendarEvent): void {
    this.deleting.set(event);
    this.deleteOpen.set(true);
  }
  deleteEvent(): void {
    const id = this.deleting()?.id;
    if (id) this.events.update(events => events.filter(event => event.id !== id));
    this.deleteOpen.set(false);
    this.deleting.set(null);
  }
}
Interactive playground

Change the settings and try the result.

Device captures shown in English.

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

API reference

Inputs

NameTypeDefaultBindingDescription
labelstring'Calendar'InputHuman-readable name for the control, action or group.
localestring'en'InputLocale used for calendar or date formatting, such as en or es.
firstDaynumber1InputFirst day of the calendar week: 0 is Sunday and 1 is Monday.
minstring''InputEarliest allowed date as YYYY-MM-DD. An empty string leaves this boundary unset.
maxstring''InputLatest allowed date as YYYY-MM-DD. An empty string leaves this boundary unset.
disabledbooleanfalseInputDisables user interaction. Values can still be supplied by the application.
readonlybooleanfalseInputPrevents user editing or selection while retaining the current value.
previousLabelstring'Previous month'InputText or accessible name used for previous. It does not perform the action by itself.
nextLabelstring'Next month'InputText or accessible name used for next. It does not perform the action by itself.
previousYearLabelstring'Previous year'InputAccessible name for moving back one year in the month picker.
nextYearLabelstring'Next year'InputAccessible name for advancing one year in the month picker.
previousYearsLabelstring'Previous 12 years'InputAccessible name for the previous group of twelve years.
nextYearsLabelstring'Next 12 years'InputAccessible name for the next group of twelve years.
eventsreadonly NeuCalendarEvent[][]InputApp-owned calendar entries. The date field uses YYYY-MM-DD. Dates containing events are marked; the selected date shows its agenda. The component never persists or deletes entries itself.
showAgendabooleantrueInputShow the agenda below the calendar for a selected valid date. DateInput disables it for date-only picking.
editablebooleanfalseInputShow Add, Edit and Delete actions in the agenda. They emit requests; your application implements the form, confirmation and persistence. The disabled and readonly states prevent these actions.
agendaLabelstring'Agenda'InputHeading for the selected date agenda.
emptyAgendaLabelstring'No events on this day'InputMessage displayed when the selected date contains no events.
hasEventsLabelstring'Day with events'InputAccessible hint for dates containing events; the visible dot is decorative.
addEventLabelstring'Add event'InputLabel for requesting a new event on the selected date.
editEventLabelstring'Edit'InputVisible action label and accessible prefix for editing an agenda event.
deleteEventLabelstring'Delete'InputVisible action label and accessible prefix for requesting deletion of an agenda event.

Models

NameTypeDefaultBindingDescription
valuestring''Model · two-wayCurrent edited value or selected ID(s), using the declared type. Bind a writable signal with [(value)].
monthstringtodayISO().slice(0, 7)Model · two-wayCurrent calendar month as YYYY-MM. Bind a writable signal with [(month)].

Outputs

NamePayloadWhen it emits
valueChangestringEmits the updated value value. [(value)] binds this output together with its model input.
monthChangestringEmits the updated month value. [(month)] binds this output together with its model input.
eventCreateRequestedstringRequests a new event for the selected YYYY-MM-DD date. The app opens its editor and updates events after saving.
eventEditRequestedNeuCalendarEventEmits the selected agenda entry to edit. No event data is changed by Calendar.
eventDeleteRequestedNeuCalendarEventEmits the agenda entry requested for deletion. Your application confirms and removes it; Calendar does not delete it.
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>('');
readonly month = signal<string>(new Date().toISOString().slice(0, 7));

Types and data interfaces

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

NeuCalendarEvent

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

// Public definition for reference only. Import this type; do not redeclare it.
export interface NeuCalendarEvent extends NeuOption {
    readonly date: string;
}
FieldTypeRequirementMeaning
datestringRequiredDate associated with the item; Calendar expects YYYY-MM-DD.
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.

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.