# Dialog

![Status](https://img.shields.io/badge/status-stable-brightgreen)

Componente de diálogo modal que exibe conteúdo em uma janela sobreposta. Pode ser utilizado de forma declarativa (via `[(visible)]` no template) ou programática (via `DialogService.open()`).

## Quando usar

- Exibir formulários ou conteúdo que requer atenção exclusiva do usuário
- Fluxos de confirmação, edição ou criação em sobreposição à tela atual
- Quando precisa capturar o resultado do diálogo (botão confirmar/cancelar)

## Quando não usar

- Confirmações simples sem formulário — use [`ConfirmDialog`](../confirm-dialog/README.md)
- Mensagens de feedback — use [`Alert`](../alert/README.md) ou notificações inline
- Tooltips ou popovers de ajuda — use [`HelpPopover`](../help-popover/README.md)

## Instalação

```typescript
import { DialogComponent, DialogService } from '@seniorsistemas/angular-components/dialog';

@Component({
  standalone: true,
  imports: [DialogComponent],
  providers: [DialogService],
})
export class MeuComponent {}
```

## Uso básico

```html
<!-- Modo declarativo -->
<s-button label="Abrir" (clicked)="visible = true"></s-button>

<s-dialog header="Título" [(visible)]="visible">
  <p>Conteúdo do diálogo</p>
  <ng-template sTemplate="footer" let-activeDialog="activeDialog">
    <s-button label="Cancelar" priority="secondary" (clicked)="activeDialog.dismiss()"></s-button>
    <s-button label="Confirmar" priority="primary" (clicked)="activeDialog.close('ok')"></s-button>
  </ng-template>
</s-dialog>
```

## API

### Inputs

| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|-------------|------|--------|:-----------:|-----------|
| `header` | `string` | — | — | Texto do cabeçalho. Pode ser substituído por `sTemplate="header"` |
| `visible` | `boolean` | `undefined` | — | Controla a visibilidade. Suporta two-way binding via `[(visible)]`. Não usar com `DialogService` |
| `size` | `DialogSize` | `'md'` | — | Tamanho do diálogo |
| `escapeOnEsc` | `boolean` | `true` | — | Fecha o diálogo ao pressionar Escape |
| `destroyClickOutside` | `boolean` | `true` | — | Fecha o diálogo ao clicar no backdrop |
| `contentClassName` | `string` | `''` | — | Classes CSS adicionais no container de conteúdo |
| `closeAriaLabel` | `string` | `'Fechar'` | — | Aria-label do botão de fechar |

### Tipos

```typescript
type DialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';
// sm = 300px | md = 500px | lg = 800px | xl = 1140px | fullscreen

type DialogOptions = {
  destroyClickOutside?: boolean;
  escapeOnEsc?: boolean;
  size?: DialogSize;
};

type DialogRef<T> = {
  componentInstance: T;
  closed: Observable<any>;    // Emite ao chamar activeDialog.close(result)
  dismissed: Observable<any>; // Emite ao chamar activeDialog.dismiss() ou fechar pelo X/Esc
};
```

## Exemplos

### Modo declarativo

```html
<s-button label="Abrir Dialog" priority="primary" (clicked)="dialogVisible = true"></s-button>

<s-dialog
  header="Editar registro"
  [(visible)]="dialogVisible"
  size="lg"
  [escapeOnEsc]="true"
  [destroyClickOutside]="false"
>
  <ng-template sTemplate="body">
    <p>Conteúdo do formulário aqui.</p>
  </ng-template>
  <ng-template sTemplate="footer" let-activeDialog="activeDialog">
    <div style="display: flex; justify-content: flex-end; gap: 8px; width: 100%;">
      <s-button label="Cancelar" priority="secondary" (clicked)="activeDialog.dismiss()"></s-button>
      <s-button label="Salvar" priority="primary" (clicked)="activeDialog.close('salvo')"></s-button>
    </div>
  </ng-template>
</s-dialog>
```

### Modo programático via DialogService

```typescript
// Componente de conteúdo do diálogo
@Component({
  standalone: true,
  imports: [TemplateModule, ButtonModule],
  template: `
    <ng-template sTemplate="footer" let-activeDialog="activeDialog">
      <s-button label="Cancelar" (clicked)="activeDialog.dismiss()"></s-button>
      <s-button label="Confirmar" priority="primary" (clicked)="activeDialog.close('confirmado')"></s-button>
    </ng-template>
    <p>Conteúdo do diálogo.</p>
  `,
})
class MeuDialogComponent {}

// No componente pai
const ref = this.dialogService.open(MeuDialogComponent, { size: 'lg' });
ref.closed.subscribe(result => console.log('Fechado:', result));
ref.dismissed.subscribe(() => console.log('Dispensado'));
```

### Cabeçalho customizado

```html
<s-dialog [(visible)]="visible">
  <ng-template sTemplate="header">
    <div style="display: flex; align-items: center; gap: 8px;">
      <i class="fas fa-exclamation-triangle" style="color: #f59e0b;"></i>
      <span>Atenção</span>
    </div>
  </ng-template>
  <p>Esta ação requer sua atenção.</p>
</s-dialog>
```

## Acessibilidade

- O diálogo é renderizado como uma janela modal com `role="dialog"` e captura o foco enquanto está aberto
- Pressionar `Escape` fecha o diálogo quando `escapeOnEsc` é `true`
- O botão de fechar possui `aria-label` configurável via `closeAriaLabel`
- O backdrop bloqueia interação com o conteúdo de fundo

## Componentes relacionados

- [`ConfirmDialog`](../confirm-dialog/README.md) — diálogo de confirmação rápido via serviço, sem template customizado
