Saltar al contenido principal
Neural Nativev0.1.0-beta.1Documentación

Importación

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

Ejemplos

Importa ExampleComponent en su padre y coloca <app-example /> dentro del neu-theme raíz de tu aplicación. El preview aporta el marco y las zonas seguras; utiliza la estructura raíz de Instalación en tu app.

Básico

Selecciona un día para consultar su agenda. Puedes añadir, editar o eliminar eventos de este ejemplo; los cambios se conservan solo mientras la página está abierta.

Ver y copiar el ejemplo completo
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 nextYearsLabel="12 años siguientes" previousYearsLabel="12 años anteriores" nextYearLabel="Año siguiente" previousYearLabel="Año anterior" nextLabel="Mes siguiente" previousLabel="Mes anterior" deleteEventLabel="Eliminar" editEventLabel="Editar" addEventLabel="Añadir evento" hasEventsLabel="Día con eventos" emptyAgendaLabel="No hay eventos este día" agendaLabel="Agenda"
      label="Calendario del equipo" locale="es"
      [(month)]="month" [(value)]="date" [events]="events()" [editable]="true"
      (eventCreateRequested)="createEvent($event)"
      (eventEditRequested)="editEvent($event)"
      (eventDeleteRequested)="requestDelete($event)"
    /></view></scroll-view>
    <neu-modal closeLabel="Cerrar diálogo" [(open)]="editorOpen" [title]="editingId() ? 'Editar evento' : 'Añadir evento'">
      <neu-input requiredLabel="Obligatorio" label="Título del evento" [(value)]="draftTitle" placeholder="Planificación del equipo" />
      <neu-date-input nextYearsLabel="12 años siguientes" previousYearsLabel="12 años anteriores" nextYearLabel="Año siguiente" previousYearLabel="Año anterior" nextLabel="Mes siguiente" previousLabel="Mes anterior" closeLabel="Cerrar calendario" label="Fecha del evento" locale="es" [(value)]="draftDate" />
      <neu-input requiredLabel="Obligatorio" label="Detalles" [(value)]="draftDescription" placeholder="Detalles opcionales" />
      @if (formError()) { <text accessibilityRole="alert">{{ formError() }}</text> }
      <view class="actions">
        <neu-button label="Guardar evento" size="sm" (pressed)="saveEvent()" />
        <neu-button label="Cancelar" size="sm" variant="text" (pressed)="editorOpen.set(false)" />
      </view>
    </neu-modal>
    <neu-confirm-dialog closeLabel="Cerrar confirmación" cancelLabel="Cancelar"
      [(open)]="deleteOpen" title="¿Eliminar evento?"
      [message]="'¿Eliminar ' + (deleting()?.label ?? 'este evento') + ' del calendario?'"
      confirmLabel="Eliminar evento" 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: 'Revisión del lanzamiento', description: 'Revisa el lanzamiento móvil con el equipo', date: '2026-10-16' },
    { id: 'research', label: 'Entrevista con un cliente', description: 'Comenta la próxima experiencia móvil', date: '2026-10-16' },
    { id: 'planning', label: 'Planificación del sprint', description: 'Planifica la próxima iteración', 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('Introduce un título y una fecha válida (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);
  }
}
Playground interactivo

Ajusta la configuración y prueba el resultado.

Capturas del dispositivo en inglés.

Calendar · android · native capture
AndroidCaptura nativa
Calendar · ios · native capture
iOSCaptura nativa

Referencia API

Inputs

NombreTipoPredeterminadoEnlaceDescripción
labelstring'Calendar'InputNombre legible del control, acción o grupo.
localestring'en'InputLocale utilizado para el calendario o formato de fechas, por ejemplo en o es.
firstDaynumber1InputPrimer día de la semana del calendario: 0 es domingo y 1 es lunes.
minstring''InputFecha mínima admitida en formato YYYY-MM-DD. Un string vacío deja este límite sin definir.
maxstring''InputFecha máxima admitida en formato YYYY-MM-DD. Un string vacío deja este límite sin definir.
disabledbooleanfalseInputDesactiva la interacción del usuario. La aplicación puede seguir proporcionando valores.
readonlybooleanfalseInputImpide editar o seleccionar desde el control y conserva el valor actual.
previousLabelstring'Previous month'InputTexto o nombre accesible utilizado para anterior. No ejecuta la acción por sí solo.
nextLabelstring'Next month'InputTexto o nombre accesible utilizado para siguiente. No ejecuta la acción por sí solo.
previousYearLabelstring'Previous year'InputNombre accesible para retroceder un año en el selector de meses.
nextYearLabelstring'Next year'InputNombre accesible para avanzar un año en el selector de meses.
previousYearsLabelstring'Previous 12 years'InputNombre accesible del grupo anterior de doce años.
nextYearsLabelstring'Next 12 years'InputNombre accesible del grupo siguiente de doce años.
eventsreadonly NeuCalendarEvent[][]InputEventos propiedad de la aplicación. El campo date utiliza YYYY-MM-DD. Se marcan los días con eventos y se muestra la agenda de la fecha seleccionada. El componente no almacena ni elimina los datos por sí mismo.
showAgendabooleantrueInputMuestra la agenda debajo del calendario cuando hay una fecha válida seleccionada. DateInput la desactiva para seleccionar sólo fechas.
editablebooleanfalseInputMuestra las acciones de añadir, editar y borrar de la agenda. Emiten solicitudes; la aplicación implementa el formulario, la confirmación y el almacenamiento. Los estados disabled y readonly impiden estas acciones.
agendaLabelstring'Agenda'InputEncabezado de la agenda de la fecha seleccionada.
emptyAgendaLabelstring'No events on this day'InputMensaje visible cuando la fecha seleccionada no contiene eventos.
hasEventsLabelstring'Day with events'InputIndicación accesible de los días con eventos; el punto visible es decorativo.
addEventLabelstring'Add event'InputEtiqueta para solicitar un evento nuevo en la fecha seleccionada.
editEventLabelstring'Edit'InputEtiqueta visible y prefijo accesible para editar un evento de la agenda.
deleteEventLabelstring'Delete'InputEtiqueta visible y prefijo accesible para solicitar el borrado de un evento de la agenda.

Models

NombreTipoPredeterminadoEnlaceDescripción
valuestring''Model · bidireccionalValor editado o ID(s) seleccionado(s), según el tipo declarado. Enlaza una signal escribible mediante [(value)].
monthstringtodayISO().slice(0, 7)Model · bidireccionalMes actual del calendario en formato YYYY-MM. Enlaza una signal escribible mediante [(month)].

Outputs

NombrePayloadCuándo se emite
valueChangestringEmite el valor actualizado de value. [(value)] enlaza este output junto con su input model.
monthChangestringEmite el valor actualizado de month. [(month)] enlaza este output junto con su input model.
eventCreateRequestedstringSolicita un evento nuevo para la fecha seleccionada YYYY-MM-DD. La app abre su editor y actualiza events al guardar.
eventEditRequestedNeuCalendarEventEmite el evento de la agenda que se solicita editar. Calendar no modifica sus datos.
eventDeleteRequestedNeuCalendarEventEmite el evento cuyo borrado se solicita. La aplicación confirma y lo elimina; Calendar no lo borra.
touchvoidComunica la interacción del usuario al formulario o aplicación que lo contiene.

Estado de los models

Enlaza la signal con [(nombreModel)] sin llamarla. Utiliza nombreModel() para leer su valor.

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

Tipos e interfaces de datos

Utiliza los imports en tu aplicación. Las definiciones siguientes se muestran como referencia.

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;
}
CampoTipoRequisitoSignificado
datestringObligatorioFecha asociada al elemento; Calendar espera YYYY-MM-DD.
idstringObligatorioIdentificador estable y único para seguimiento y selección.
labelstringObligatorioNombre legible del elemento.
descriptionstringOpcionalTexto de apoyo opcional; su presentación depende del control.
disabledbooleanOpcionalImpide activar o seleccionar este elemento.

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;
}
CampoTipoRequisitoSignificado
idstringObligatorioIdentificador estable y único para seguimiento y selección.
labelstringObligatorioNombre legible del elemento.
descriptionstringOpcionalTexto de apoyo opcional; su presentación depende del control.
disabledbooleanOpcionalImpide activar o seleccionar este elemento.