Selección
Calendar
Elige una fecha en una vista mensual con navegación del calendario.
Importación
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
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.


Referencia API
Inputs
| Nombre | Tipo | Predeterminado | Enlace | Descripción |
|---|---|---|---|---|
| label | string | 'Calendar' | Input | Nombre legible del control, acción o grupo. |
| locale | string | 'en' | Input | Locale utilizado para el calendario o formato de fechas, por ejemplo en o es. |
| firstDay | number | 1 | Input | Primer día de la semana del calendario: 0 es domingo y 1 es lunes. |
| min | string | '' | Input | Fecha mínima admitida en formato YYYY-MM-DD. Un string vacío deja este límite sin definir. |
| max | string | '' | Input | Fecha máxima admitida en formato YYYY-MM-DD. Un string vacío deja este límite sin definir. |
| disabled | boolean | false | Input | Desactiva la interacción del usuario. La aplicación puede seguir proporcionando valores. |
| readonly | boolean | false | Input | Impide editar o seleccionar desde el control y conserva el valor actual. |
| previousLabel | string | 'Previous month' | Input | Texto o nombre accesible utilizado para anterior. No ejecuta la acción por sí solo. |
| nextLabel | string | 'Next month' | Input | Texto o nombre accesible utilizado para siguiente. No ejecuta la acción por sí solo. |
| previousYearLabel | string | 'Previous year' | Input | Nombre accesible para retroceder un año en el selector de meses. |
| nextYearLabel | string | 'Next year' | Input | Nombre accesible para avanzar un año en el selector de meses. |
| previousYearsLabel | string | 'Previous 12 years' | Input | Nombre accesible del grupo anterior de doce años. |
| nextYearsLabel | string | 'Next 12 years' | Input | Nombre accesible del grupo siguiente de doce años. |
| events | readonly NeuCalendarEvent[] | [] | Input | Eventos 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. |
| showAgenda | boolean | true | Input | Muestra la agenda debajo del calendario cuando hay una fecha válida seleccionada. DateInput la desactiva para seleccionar sólo fechas. |
| editable | boolean | false | Input | Muestra 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. |
| agendaLabel | string | 'Agenda' | Input | Encabezado de la agenda de la fecha seleccionada. |
| emptyAgendaLabel | string | 'No events on this day' | Input | Mensaje visible cuando la fecha seleccionada no contiene eventos. |
| hasEventsLabel | string | 'Day with events' | Input | Indicación accesible de los días con eventos; el punto visible es decorativo. |
| addEventLabel | string | 'Add event' | Input | Etiqueta para solicitar un evento nuevo en la fecha seleccionada. |
| editEventLabel | string | 'Edit' | Input | Etiqueta visible y prefijo accesible para editar un evento de la agenda. |
| deleteEventLabel | string | 'Delete' | Input | Etiqueta visible y prefijo accesible para solicitar el borrado de un evento de la agenda. |
Models
| Nombre | Tipo | Predeterminado | Enlace | Descripción |
|---|---|---|---|---|
| value | string | '' | Model · bidireccional | Valor editado o ID(s) seleccionado(s), según el tipo declarado. Enlaza una signal escribible mediante [(value)]. |
| month | string | todayISO().slice(0, 7) | Model · bidireccional | Mes actual del calendario en formato YYYY-MM. Enlaza una signal escribible mediante [(month)]. |
Outputs
| Nombre | Payload | Cuándo se emite |
|---|---|---|
| valueChange | string | Emite el valor actualizado de value. [(value)] enlaza este output junto con su input model. |
| monthChange | string | Emite el valor actualizado de month. [(month)] enlaza este output junto con su input model. |
| eventCreateRequested | string | Solicita un evento nuevo para la fecha seleccionada YYYY-MM-DD. La app abre su editor y actualiza events al guardar. |
| eventEditRequested | NeuCalendarEvent | Emite el evento de la agenda que se solicita editar. Calendar no modifica sus datos. |
| eventDeleteRequested | NeuCalendarEvent | Emite el evento cuyo borrado se solicita. La aplicación confirma y lo elimina; Calendar no lo borra. |
| touch | void | Comunica 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.
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
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;
}| Campo | Tipo | Requisito | Significado |
|---|---|---|---|
| date | string | Obligatorio | Fecha asociada al elemento; Calendar espera YYYY-MM-DD. |
| id | string | Obligatorio | Identificador estable y único para seguimiento y selección. |
| label | string | Obligatorio | Nombre legible del elemento. |
| description | string | Opcional | Texto de apoyo opcional; su presentación depende del control. |
| disabled | boolean | Opcional | Impide activar o seleccionar este elemento. |
NeuOption
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;
}| Campo | Tipo | Requisito | Significado |
|---|---|---|---|
| id | string | Obligatorio | Identificador estable y único para seguimiento y selección. |
| label | string | Obligatorio | Nombre legible del elemento. |
| description | string | Opcional | Texto de apoyo opcional; su presentación depende del control. |
| disabled | boolean | Opcional | Impide activar o seleccionar este elemento. |