# Dialog — Padrão de Componente > **Stack**: Vue 3 + PrimeVue 4 + Tailwind CSS > **Tema-aware**: header e footer respeitam dark/light automaticamente via CSS vars --- ## Regras gerais | Propriedade | Valor obrigatório | |---|---| | `modal` | sempre `true` | | `maximizable` | sempre presente — botão nativo do PrimeVue, sem estado manual | | `:draggable` | sempre `false` | | `:closable` | `!saving` — desabilita o X durante operações assíncronas | | `:dismissableMask` | `!saving` — impede fechar clicando fora durante saving | | `pt:mask:class` | `backdrop-blur-xs` | | Largura | `w-[50rem]` (padrão); responsivo via `:breakpoints` | | Breakpoints | `{ '1199px': '90vw', '768px': '94vw' }` | --- ## Sistema de cores (tema-aware) O dialog **nunca** deve usar `bg-gray-100` ou cores hardcoded — isso quebra no dark mode. Usar sempre as CSS vars do projeto: | Var | Light | Dark | Uso | |---|---|---|---| | `--surface-card` | `--p-surface-0` (branco) | `--p-surface-900` (quase preto) | Fundo do **corpo** do dialog (default) | | `--surface-ground` | `--p-surface-100` (cinza claro) | `--p-surface-950` (preto) | Fundo do **header** e **footer** — um shade mais escuro que o card | | `--surface-border` | `--p-content-border-color` | idem | Borda separadora entre header/content/footer | | `--text-color` | preto | branco | Título principal | | `--text-color-secondary` | cinza médio | cinza claro | Subtítulo, hints | > Resumo: `bg-[var(--surface-ground)]` no header/footer fica **sempre um pouco mais escuro que o corpo**, em ambos os temas. Definido em `_light.scss:19` e `_dark.scss:19`. --- ## Estrutura obrigatória ``` ├── #header ← dot de cor (se aplicável), título/subtítulo, btn Excluir ├── Banner ← preview visual (opcional — apenas quando há cor/identidade visual) ├── Corpo ← campos do formulário └── #footer ← Cancelar (flat) | Salvar (primary) ``` --- ## Configuração completa do `` ```vue ``` ### Detalhes do `pt` | Chave | O que faz | |---|---| | `header` | `!p-3` padding uniforme; `!rounded-t-[12px]` borda top arredondada; `border-b` separador; `bg-[var(--surface-ground)]` fundo um shade mais escuro que o card (tema-aware) | | `content` | `!p-3` padding interno do corpo (herda `bg-[var(--surface-card)]` do PrimeVue) | | `footer` | `!p-0` remove padding nativo (controlado pelo wrapper interno); `!rounded-b-[12px]` borda bottom arredondada; `border-t` separador; `bg-[var(--surface-ground)]` mesmo fundo do header | | `pcCloseButton` | `!rounded-md` remove o círculo nativo; `hover:!text-red-500` feedback de danger no hover | | `pcMaximizeButton` | `!rounded-md` remove o círculo nativo; `hover:!text-primary` feedback de cor primária no hover | > O `!` (important) é necessário porque o PrimeVue injeta estilos inline nos botões e no root do Dialog — sem ele o Tailwind perde a disputa de especificidade. > **Migração de dialogs antigos**: trocar `bg-gray-100` por `bg-[var(--surface-ground)]`. O `shadow-[0_1px_0_0_rgba(255,255,255,0.06)]` antigo era um hack pro dark mode; pode ser removido (a borda já dá a separação). --- ## Header — slot `#header` ``` [dot-cor] [título / subtítulo] [btn-excluir] ← Close e Maximize nativos vêm após ``` - O PrimeVue injeta **Maximize** e **Close** automaticamente à direita do slot `#header`. - O botão **Excluir** fica **sempre no header**, nunca no footer. - Excluir desabilitado quando o registro é nativo/padrão: `:disabled="saving || isNativeRecord"`. ```vue ``` > **Cores**: usar `text-[var(--text-color)]` no título e `text-[var(--text-color-secondary)]` no subtítulo. Não usar `opacity-50` — a cor secondary já tem contraste calibrado por tema. --- ## Footer — slot `#footer` ```vue ``` > **Regra**: Cancelar = `severity="secondary" text` + `hover:!text-red-500`. Salvar = primary (sem severity, usa o padrão do tema). Padding controlado pelo `div` interno (`px-3 py-3`), não pelo `pt.footer`. --- ## Maximizar Use a prop nativa `maximizable`. O PrimeVue injeta e gerencia o botão automaticamente — sem `ref`, sem `isMaximized`, sem `