# Spotlight

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

Sistema de destaque guiado que combina máscara de fundo semitransparente com um popover informativo posicionado ao lado de um elemento alvo. Suporta destaque simples (passo único) e tours guiados com múltiplos passos e navegação sequencial.

## Quando usar

- Onboarding de novos usuários apresentando funcionalidades pela primeira vez
- Destacar um campo ou ação importante em resposta a uma regra de negócio
- Tours guiados para apresentar uma tela complexa em sequência lógica
- Dicas contextuais disparadas por clique ou por lógica da aplicação

## Quando não usar

- Ajuda contextual estática sempre visível — prefira `HelpPopover`
- Dicas simples ao passar o mouse — prefira `Tooltip`
- Mensagens de alerta críticas que exigem uma ação imediata — prefira `Dialog`

## Instalação

```typescript
import {
  SpotlightTourService,
  SpotlightStepDirective,
} from '@seniorsistemas/angular-components/spotlight';

@Component({
  standalone: true,
  imports: [SpotlightStepDirective],
  providers: [SpotlightTourService],
})
export class MeuComponent {
  private readonly tourService = inject(SpotlightTourService);
}
```

## Uso básico

```html
<!-- Marque os elementos alvo com a diretiva -->
<button [sSpotlightStep]="'meu-botao'">Clique aqui</button>
```

```typescript
// Destaque simples em um elemento
this.tourService.spotlight('meu-botao', {
  title: 'Novo recurso',
  message: 'Este botão agora tem uma função adicional.',
  position: 'bottom-center',
});

// Tour guiado com múltiplos passos
this.tourService.start([
  { stepId: 'passo-1', title: 'Início', message: 'Descrição do passo 1' },
  { stepId: 'passo-2', title: 'Configuração', message: 'Descrição do passo 2' },
]);
```

## API

### Diretiva `[sSpotlightStep]`

| Propriedade | Tipo | Obrigatório | Descrição |
|-------------|------|:-----------:|-----------|
| `sSpotlightStep` | `string` | Sim | ID único do passo do tour ao qual este elemento está associado |

### SpotlightComponent (popover isolado)

| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|-------------|------|--------|:-----------:|-----------|
| `title` | `string \| TemplateRef<any>` | `''` | Não | Título exibido no cabeçalho do popover |
| `message` | `string \| TemplateRef<any>` | `undefined` | Não | Mensagem principal do popover |
| `content` | `TemplateRef<any> \| null` | `null` | Não | Template para área de mídia/conteúdo customizado |
| `position` | `SpotlightPosition` | `'bottom-center'` | Não | Posição do popover em relação ao elemento alvo |
| `currentStep` | `number` | `1` | Não | Número do passo atual (1-based) |
| `totalSteps` | `number` | `1` | Não | Total de passos do tour |
| `showDoNotShowAgain` | `boolean` | `true` | Não | Exibe o checkbox "Não mostrar novamente" (apenas em modo simples) |
| `actions` | `SpotlightStepAction[]` | `[]` | Não | Botões adicionais no rodapé do popover |
| `arrowOffsetPx` | `number \| null` | `null` | Não | Deslocamento em pixels para posicionar a seta manualmente |

### Outputs do SpotlightComponent

| Evento | Tipo | Descrição |
|--------|------|-----------|
| `closed` | `OutputEmitterRef<void>` | Emitido ao clicar no botão de fechar (X) |
| `next` | `OutputEmitterRef<void>` | Emitido ao clicar em "Próximo" |
| `previous` | `OutputEmitterRef<void>` | Emitido ao clicar em "Voltar" |
| `understand` | `OutputEmitterRef<void>` | Emitido ao clicar em "Entendido" (modo simples) |

### Tipos

```typescript
type SpotlightPosition =
  | 'top-start' | 'top-center' | 'top-end'
  | 'right-start' | 'right-center' | 'right-end'
  | 'bottom-start' | 'bottom-center' | 'bottom-end'
  | 'left-start' | 'left-center' | 'left-end';

interface SpotlightStep {
  stepId: string;
  title?: string | TemplateRef<any>;
  message?: string | TemplateRef<any>;
  position?: SpotlightPosition;
  showDoNotShowAgain?: boolean;
  dismissible?: boolean;
  actions?: SpotlightStepAction[];
}

interface SpotlightStepAction {
  label: string;
  handler: () => void;
}
```

### SpotlightTourService — API pública

| Método/Propriedade | Descrição |
|---|---|
| `spotlight(stepId, config)` | Exibe destaque simples em um elemento |
| `start(steps)` | Inicia tour guiado com múltiplos passos |
| `next()` | Avança para o próximo passo |
| `previous()` | Retorna ao passo anterior |
| `stop(event?)` | Encerra o tour |
| `isActive` | Signal: indica se o tour está ativo |
| `currentIndex` | Signal: índice (0-based) do passo atual |
| `totalSteps` | Signal computado: total de passos |
| `stopped$` | Observable emitido ao encerrar o tour |
| `stepChanged$` | Observable emitido ao mudar de passo |

## Exemplos

### Destaque simples

```typescript
this.tourService.spotlight('campo-obrigatorio', {
  title: 'Campo obrigatório',
  message: 'Este campo deve ser preenchido antes de continuar.',
  position: 'bottom-center',
  showDoNotShowAgain: true,
  dismissible: true,
});
```

### Tour guiado com 3 passos

```typescript
this.tourService.start([
  {
    stepId: 'btn-novo',
    title: 'Passo 1 — Criar',
    message: 'Use este botão para criar um novo registro.',
    position: 'bottom-center',
  },
  {
    stepId: 'filtro-data',
    title: 'Passo 2 — Filtrar',
    message: 'Filtre por período usando este campo de data.',
    position: 'bottom-start',
  },
  {
    stepId: 'btn-exportar',
    title: 'Passo 3 — Exportar',
    message: 'Exporte os dados filtrados em diferentes formatos.',
    position: 'top-center',
  },
]);

// Reagir ao encerramento
this.tourService.stopped$.subscribe(event => {
  if (event.doNotShowAgain) {
    // salvar preferência do usuário
  }
});
```

### Spotlight bloqueado (não pode ser fechado pelo backdrop)

```typescript
this.tourService.spotlight('elemento-alvo', {
  title: 'Ação obrigatória',
  message: 'Você deve completar esta ação antes de continuar.',
  position: 'bottom-center',
  dismissible: false,
  showDoNotShowAgain: false,
});
```

## Acessibilidade

- O popover utiliza `role="dialog"` com `aria-labelledby` e `aria-describedby` referenciando título e mensagem
- O foco é gerenciado via CDK FocusTrap: ao abrir, o foco vai para o primeiro elemento interativo do popover
- Pressionar `Escape` fecha o spotlight quando `dismissible !== false`
- A posição do popover se ajusta automaticamente quando há pouco espaço na viewport
- Suporte completo à navegação por teclado (Tab, Shift+Tab, Enter, Escape)

## Componentes relacionados

- [`HelpPopover`](../help-popover/README.md) — popover de ajuda contextual fixo em elementos de formulário
- [`Tooltip`](../tooltip/README.md) — dica de conteúdo simples ao passar o mouse
