# TemplateDirective

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

Diretiva estrutural que marca um `<ng-template>` com um alias nomeado, permitindo que o componente pai identifique e projete templates específicos por nome. É a base do mecanismo de slots nomeados usado por Card, Accordion, Panel, Dialog, Fieldset e Insights.

## Quando usar

- Substituir uma seção específica de um componente (header, footer, body etc.) por conteúdo customizado
- Adicionar ícones, badges ou formatação especial em uma região que o componente já define como slot nomeado
- Fornecer templates para estados específicos de um componente (ex: `empty`, `no-permission` no Insights)

## Quando não usar

- Para o conteúdo principal/padrão de um componente que já aceita `ng-content` diretamente — use projeção de conteúdo simples
- Para nomes de slot que o componente pai não declara — a diretiva não valida o `type`; se o nome não for reconhecido pelo componente pai, o template é ignorado silenciosamente. Consulte o README do componente pai para saber quais nomes ele aceita

## Instalação

```typescript
import { TemplateDirective } from '@seniorsistemas/angular-components/template';

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

Para uso via `NgModule`, importe `TemplateModule`:

```typescript
import { TemplateModule } from '@seniorsistemas/angular-components/template';

@NgModule({
  imports: [TemplateModule],
})
export class MeuModule {}
```

## Uso básico

```html
<s-card>
  <ng-template sTemplate="header">
    <h3>Cabeçalho customizado</h3>
  </ng-template>
</s-card>
```

## API

### Inputs

| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|-------------|------|--------|:-----------:|-----------|
| `sTemplate` | `string` | — | Sim | Nome (alias) que identifica o template nomeado. O valor deve corresponder a um dos nomes de slot aceitos pelo componente pai |

### Como o componente pai consome o template

`TemplateDirective` não renderiza nada por si só — ela apenas envolve um `TemplateRef` e expõe o alias (`type`) informado em `sTemplate`. O componente pai coleta todas as instâncias projetadas via `@ContentChildren` e busca a que corresponde ao nome desejado:

```typescript
import { Component, ContentChildren, QueryList, TemplateRef } from '@angular/core';
import { TemplateDirective } from '@seniorsistemas/angular-components/template';

@Component({ /* ... */ })
export class MeuComponent {
  @ContentChildren(TemplateDirective)
  public templates?: QueryList<TemplateDirective>;

  private _getTemplate(type: string): TemplateRef<any> | undefined {
    return this.templates?.find((template) => template.type === type)?.template;
  }
}
```

O template resultante é então renderizado internamente (via `*ngTemplateOutlet` ou equivalente) no lugar do slot padrão do componente.

### Tipos

A diretiva não expõe tipos, enums ou interfaces próprias — apenas a propriedade `type: string`, alimentada pelo input `sTemplate`.

## Exemplos

### Customizando header e footer de um Card

```html
<s-card style="max-width: 500px;">
  <ng-template sTemplate="header">
    <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
      <div style="display: flex; align-items: center; gap: 8px;">
        <i class="fa fa-rocket"></i>
        <strong>Header via sTemplate</strong>
      </div>
    </div>
  </ng-template>

  <p>Conteúdo do card via ng-content padrão.</p>

  <ng-template sTemplate="footer">
    <div style="display: flex; justify-content: flex-end; gap: 8px; width: 100%;">
      <s-button label="Cancelar" priority="secondary"></s-button>
      <s-button label="Confirmar" priority="primary"></s-button>
    </div>
  </ng-template>
</s-card>
```

### Header customizado em um painel do Accordion

```html
<s-accordion style="max-width: 500px;">
  <s-accordion-panel>
    <ng-template sTemplate="header">
      <div style="display: flex; align-items: center; gap: 8px;">
        <i class="fa fa-user"></i>
        <span>Dados Pessoais</span>
        <span style="font-size: 0.7rem; background: #fee2e2; color: #dc2626; padding: 1px 6px; border-radius: 4px;">Pendente</span>
      </div>
    </ng-template>
    <div>
      <p>Conteúdo do painel com header customizado.</p>
    </div>
  </s-accordion-panel>
</s-accordion>
```

### Header, body e footer em um Dialog

```html
<s-dialog [(visible)]="showDialog">
  <ng-template sTemplate="header">
    <strong>Confirmar exclusão</strong>
  </ng-template>
  <ng-template sTemplate="body">Conteúdo</ng-template>
  <ng-template sTemplate="footer" let-activeDialog="activeDialog">
    <button (click)="activeDialog.close()">Fechar</button>
  </ng-template>
</s-dialog>
```

### Estados customizados no Insights

```html
<s-insights [hasPermission]="hasPermission">
  <ng-template sTemplate="intro">Intro Template</ng-template>
  <ng-template sTemplate="empty">Empty Template</ng-template>
  <ng-template sTemplate="no-permission">No Permission Template</ng-template>
</s-insights>
```

### Nomes de slot aceitos por componente

| Componente | Templates aceitos |
|---|---|
| Card | `header`, `body`, `footer` |
| Accordion | `header` (por painel) |
| Panel | `header`, `body`, `footer` |
| Dialog | `header`, `body`, `footer` |
| Fieldset | `header` |
| Insights | `intro`, `empty`, `no-permission` |

Consulte o README de cada componente para a lista definitiva e atualizada de slots aceitos.

## Acessibilidade

- A diretiva em si não introduz nenhum comportamento de acessibilidade — ela apenas identifica um `TemplateRef`
- Atributos ARIA, foco e semântica dependem inteiramente do conteúdo colocado dentro do `<ng-template>` e de como o componente pai renderiza o slot

## Componentes relacionados

- [`CardComponent`](../card/README.md) — usa `sTemplate` para `header`, `body` e `footer`
- [`DialogComponent`](../dialog/README.md) — usa `sTemplate` para `header`, `body` e `footer`
- [`AccordionComponent`](../accordion/README.md) — usa `sTemplate` para `header` de cada painel
- [`PanelComponent`](../panel/README.md) — usa `sTemplate` para `header`, `body` e `footer`
- [`InsightsComponent`](../insights/README.md) — usa `sTemplate` para `intro`, `empty` e `no-permission`
