Files
agenciapsilmno/blueprints/DialogConfirmation-blueprint.md

5.4 KiB

DialogConfirmation — Padrão de Componente

Stack: Vue 3 + PrimeVue 4 + Tailwind CSS


Regras gerais

Propriedade Valor obrigatório
group sempre "headless" — desacopla o template do trigger
ConfirmDialog declarado uma única vez, no componente pai (página)
Filhos disparam via useConfirm() com group: 'headless' — sem declarar ConfirmDialog próprio
icon passado em confirm.require({ icon }) — classe PrimeIcons sem o prefixo pi (ex: 'pi-trash')
color passado em confirm.require({ color }) — hex; define o fundo do círculo e a cor do botão Confirmar
ConfirmationService obrigatório em main.jsapp.use(ConfirmationService)

Arquitetura pai / filho

Pai (página)
 └── <ConfirmDialog group="headless" />   ← único, renderiza aqui
      ├── Filho A (componente qualquer)   → confirm.require({ group: 'headless', ... })
      └── Filho B (Dialog interno)        → confirm.require({ group: 'headless', ... })

O ConfirmDialog não deve ser colocado dentro de um <Dialog> filho — isso causaria dois popups simultâneos. Sempre no pai.


Setup obrigatório — main.js

import ConfirmationService from 'primevue/confirmationservice'

app.use(ConfirmationService)  // sem isso, useConfirm() não funciona

Template do ConfirmDialog (somente no pai)

<!-- Declarado uma única vez, antes do conteúdo principal -->
<ConfirmDialog group="headless">
  <template #container="{ message, acceptCallback, rejectCallback }">
    <div class="flex flex-col items-center p-8 bg-surface-0 dark:bg-surface-900 rounded-xl shadow-xl">

      <!-- Círculo central: cor e ícone vindos de message -->
      <div
        class="rounded-full inline-flex justify-center items-center h-24 w-24 -mt-20"
        :style="{ background: message.color || 'var(--p-primary-color)', color: '#fff' }"
      >
        <i :class="`pi ${message.icon || 'pi-question'} !text-4xl`"></i>
      </div>

      <span class="font-bold text-2xl block mb-2 mt-6">{{ message.header }}</span>
      <p class="mb-0 text-center text-[var(--text-color-secondary)]">{{ message.message }}</p>

      <div class="flex items-center gap-2 mt-6">
        <!-- Confirmar: cor dinâmica via message.color -->
        <Button
          label="Confirmar"
          class="rounded-full"
          :style="{
            background: message.color || 'var(--p-primary-color)',
            borderColor: message.color || 'var(--p-primary-color)'
          }"
          @click="acceptCallback"
        />
        <!-- Cancelar: sempre outlined, neutro -->
        <Button
          label="Cancelar"
          variant="outlined"
          class="rounded-full"
          @click="rejectCallback"
        />
      </div>

    </div>
  </template>
</ConfirmDialog>

Uso nos componentes (pai ou filhos)

<script setup>
import { useConfirm } from 'primevue/useconfirm'
const confirm = useConfirm()

function confirmDelete(item) {
  confirm.require({
    group: 'headless',
    header: 'Excluir item?',
    message: `"${item.name}" será removido permanentemente. Essa ação não pode ser desfeita.`,
    icon: 'pi-trash',
    color: '#ef4444',
    accept: () => onDelete(item)
  })
}
</script>

Paleta de ícones e cores por ação

Ação icon color Observação
Excluir / Remover pi-trash #ef4444 Vermelho — ação destrutiva
Salvar / Confirmar pi-save var(--p-primary-color) Cor primária do tema
Editar / Atualizar pi-pencil #f97316 Laranja — mudança de estado
Aviso / Atenção pi-exclamation-triangle #eab308 Amarelo — ação reversível
Info / Neutro pi-info-circle #3b82f6 Azul — informativo

Referência completa de confirm.require

confirm.require({
  group:   'headless',          // obrigatório — aponta para o ConfirmDialog correto
  header:  'Título do popup',   // linha em negrito
  message: 'Descrição clara.',  // linha secundária
  icon:    'pi-trash',          // sufixo PrimeIcons sem o "pi " inicial
  color:   '#ef4444',           // hex — fundo do círculo + cor do botão Confirmar
  accept:  () => { /* ação confirmada */ },
  reject:  () => { /* opcional — ação cancelada */ }
})

Checklist antes de usar

  • ConfirmationService registrado no main.js
  • <ConfirmDialog group="headless"> declarado apenas no pai, antes do conteúdo
  • Filhos usam useConfirm() com group: 'headless' — sem ConfirmDialog próprio
  • icon passado como sufixo PrimeIcons: 'pi-trash', não 'pi pi-trash'
  • color em hex para ações com semântica de cor (delete = #ef4444)
  • header curto e direto | message com contexto suficiente para o usuário decidir
  • accept contém a ação real — reject é opcional

Variações de confirmação

Contexto header icon color
Excluir registro 'Excluir <entidade>?' pi-trash #ef4444
Remover item de lista 'Remover campo?' pi-trash #ef4444
Salvar com impacto 'Confirmar alterações?' pi-save primária
Atualizar com risco 'Atualizar <entidade>?' pi-pencil #f97316
Ação irreversível genérica 'Tem certeza?' pi-exclamation-triangle #eab308