Fundamentos
Overlays y foco
Abre una tarea concreta, separa los borradores y define cada vía de cierre.
Elige la presentación según la tarea
| Componente | Uso |
|---|---|
| Modal | Un editor o tarea concreta con acciones explícitas. |
| BottomSheet | Contenido u opciones móviles contextuales junto a la tarea actual. |
| ConfirmDialog | Una decisión claramente explicada con confirmación y cancelación. |
Son componentes de la biblioteca, no un sustituto de las rutas de la aplicación ni de las APIs de presentación del router del framework. Conserva el estado open en la pantalla y evita abrir varias presentaciones con una misma secuencia de pulsaciones rápidas.
Un editor que permite cancelar sin guardar
Crea src/app/edit-profile.component.ts dentro del tema existente. El editor trabaja sobre un borrador: guardar confirma los cambios; cancelar y los demás cierres los descartan. Al volver a abrir, recupera los datos guardados.
import { Component, signal } from '@angular/core';
import { Text, View } from '@ng-native/components';
import { NeuButtonComponent } from '@neural-ui/native/button';
import { NeuModalComponent } from '@neural-ui/native/modal';
import { NeuInputComponent } from '@neural-ui/native/input';
@Component({
selector: 'app-edit-profile',
imports: [Text, View, NeuButtonComponent, NeuModalComponent, NeuInputComponent],
template: `
<neu-button label="Edit profile" (pressed)="beginEdit()" />
<text class="feedback">{{ savedName() }}</text>
<neu-modal title="Edit profile" [(open)]="editing" closeLabel="Cancel editing">
<view class="content">
<neu-input label="Full name" [(value)]="draft" />
<neu-button label="Save changes" [disabled]="!draft().trim()" (pressed)="save()" />
<neu-button label="Cancel" variant="text" (pressed)="editing.set(false)" />
</view>
</neu-modal>
`,
styles: `
.content { gap: 16px; }
.feedback { color: var(--neu-text); }
`,
})
export class EditProfileComponent {
readonly editing = signal(false);
readonly savedName = signal('Ada Lovelace');
readonly draft = signal('');
beginEdit(): void {
this.draft.set(this.savedName());
this.editing.set(true);
}
save(): void {
const name = this.draft().trim();
if (!name) return;
this.savedName.set(name);
this.editing.set(false);
}
}Estado de apertura, eventos y foco
[(open)] conecta la visibilidad solicitada con una signal escribible. Modal expone opened y dismissed para el ciclo de presentación y closed identifica una solicitud de cierre nativa, de una acción o del fondo. Consulta la API individual antes de compartir handlers: BottomSheet y ConfirmDialog no tienen el mismo contrato de output closed.
Mantén disponible la acción que abrió el overlay después de cerrarlo. Coordina el foco del teclado y de accesibilidad con la presentación y el cierre: elige en tu aplicación el control inicial y el destino al regresar. Verifica la interacción completa con el teclado abierto, Back nativo en Android y tecnología de asistencia.
Con dismissible=false, Modal y BottomSheet restringen los cierres del usuario, pero la app puede cerrarlos mediante open. Proporciona una salida explícita. Para una confirmación asíncrona, utiliza busy en ConfirmDialog y evita solicitudes duplicadas en el handler.