Popconfirm
Popover leve e não-modal (`mk-popconfirm`) ancorado ao elemento que dispara a ação, usado para confirmar decisões binárias sem o overhead visual de um modal.
O mk-popconfirm ancora um popover leve e não-modal diretamente ao elemento que dispara a ação, recebido via slot padrão. Pergunta uma confirmação simples com dois botões — cancelar e confirmar — sem escurecer o restante da tela como o mk-dialog faria. É sempre acionado por clique, nunca por hover, e não deve ser usado para ações com mais de duas opções ou conteúdo rico no título/descrição.
Padrão
import { MkButton, MkPopconfirm } from '@db1/makuco-ui-react';
function Example() {
return (
<MkPopconfirm
heading="Excluir este item?"
description="Esta ação não pode ser desfeita."
onMkConfirm={handleDelete}
>
<MkButton variant="outlined" trailingIcon="trash-2">Excluir</MkButton>
</MkPopconfirm>
);
}<mk-popconfirm
heading="Excluir este item?"
description="Esta ação não pode ser desfeita."
(mkConfirm)="handleDelete()"
>
<mk-button variant="outlined" trailing-icon="trash-2">Excluir</mk-button>
</mk-popconfirm>Destrutivo
Use variant="destructive" para ações irreversíveis. Troca o ícone do cabeçalho (info → circle-x, cor info → error) e o botão de confirmação para kind="destructive".
<MkPopconfirm
variant="destructive"
heading="Excluir permanentemente?"
description="O item será removido e não poderá ser recuperado."
onMkConfirm={handleDelete}
>
<MkButton variant="outlined" kind="destructive" trailingIcon="trash-2">Excluir</MkButton>
</MkPopconfirm><mk-popconfirm
variant="destructive"
heading="Excluir permanentemente?"
description="O item será removido e não poderá ser recuperado."
(mkConfirm)="handleDelete()"
>
<mk-button variant="outlined" kind="destructive" trailing-icon="trash-2">Excluir</mk-button>
</mk-popconfirm>Confirmação assíncrona
Para ações que disparam uma requisição assíncrona e devem manter o popover aberto até a conclusão, chame event.preventDefault() de forma síncrona dentro do handler de mkConfirm — o evento é cancelável, e isso é o que suspende o fechamento automático. Em seguida, sete confirmLoading = true para exibir o spinner e suspender o fechamento por Escape e por clique fora. Ao concluir, sete confirmLoading = false e open = false manualmente.
import { useState } from 'react';
import { MkButton, MkPopconfirm } from '@db1/makuco-ui-react';
function Example() {
const [open, setOpen] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
const handleConfirm = (event: CustomEvent<void>) => {
event.preventDefault();
setConfirmLoading(true);
deleteItem().finally(() => {
setConfirmLoading(false);
setOpen(false);
});
};
return (
<MkPopconfirm
variant="destructive"
heading="Excluir permanentemente?"
open={open}
confirmLoading={confirmLoading}
onMkOpenChange={(e) => setOpen(e.detail.open)}
onMkConfirm={handleConfirm}
>
<MkButton variant="outlined" kind="destructive" trailingIcon="trash-2">Excluir</MkButton>
</MkPopconfirm>
);
}<mk-popconfirm
#popconfirm
variant="destructive"
heading="Excluir permanentemente?"
[confirm-loading]="confirmLoading"
(mkConfirm)="handleConfirm($event, popconfirm)"
>
<mk-button variant="outlined" kind="destructive" trailing-icon="trash-2">Excluir</mk-button>
</mk-popconfirm>handleConfirm(event: Event, popconfirm: HTMLMkPopconfirmElement) {
event.preventDefault();
this.confirmLoading = true;
this.deleteItem().finally(() => {
this.confirmLoading = false;
popconfirm.open = false;
});
}Atenção:
confirmLoadingsozinho não é suficiente para suspender o fechamento quando é controlado por estado reativo (useStateno React, property binding no Angular) — a atualização só chega ao elemento depois do ciclo de render/change detection, ou seja, depois que o popover já decidiu se fecha.event.preventDefault()é a única forma confiável de suspender o fechamento automático nesses casos, porque ele altera o próprio objeto do evento de forma síncrona, independente do framework. UseconfirmLoadingapenas para o spinner e para suspender Escape/clique fora enquanto a ação está pendente.
Desabilitado
disabled impede a abertura do popover pelo trigger. Se setado enquanto open já é true, o componente força o fechamento.
<MkPopconfirm heading="Excluir este item?" disabled>
<MkButton variant="outlined" disabled trailingIcon="trash-2">Excluir</MkButton>
</MkPopconfirm><mk-popconfirm heading="Excluir este item?" disabled>
<mk-button variant="outlined" disabled trailing-icon="trash-2">Excluir</mk-button>
</mk-popconfirm>Posicionamento
Use placement para escolher entre os 8 valores padrão do Makuco, o mesmo vocabulário do mk-tooltip: top-left, top-center, top-right, right, left, bottom-left, bottom-center e bottom-right. A posição é resolvida via @floating-ui/dom, com flip/shift mantendo o popover dentro da viewport. Clique em cada botão para abrir o popover na posição correspondente.
<MkPopconfirm heading="Excluir este item?" placement="right">
<MkButton variant="outlined" trailingIcon="trash-2">Excluir</MkButton>
</MkPopconfirm><mk-popconfirm heading="Excluir este item?" placement="right">
<mk-button variant="outlined" trailing-icon="trash-2">Excluir</mk-button>
</mk-popconfirm>Props — mk-popconfirm
| Prop | Tipo | Padrão | Descrição |
|---|---|---|---|
heading | string | — | Pergunta de confirmação exibida no cabeçalho. Obrigatória. |
description | string | — | Texto de apoio abaixo da pergunta, explicando a consequência da ação. |
variant | "confirmative" | "destructive" | "confirmative" | Controla o ícone e a intenção do botão de confirmação. |
placement | 8 valores (mesmo vocabulário do mk-tooltip) | "top-center" | Posição do popover relativa ao trigger. |
open | boolean | false | Controla a visibilidade do popover. Refletido como atributo; sincronizável de fora via mkOpenChange. |
confirmText | string | i18n "Confirmar" | Texto do botão de confirmação. |
cancelText | string | i18n "Cancelar" | Texto do botão de cancelamento. |
confirmLoading | boolean | false | Coloca o botão de confirmação em loading e suspende o fechamento automático, por Escape e por clique fora — para ações assíncronas. |
disabled | boolean | false | Impede a abertura do popover pelo trigger. |
initialFocus | "cancel" | "confirm" | "cancel" | Botão que recebe foco ao abrir. "cancel" é o padrão mais seguro. |
closeOnOutsideClick | boolean | true | Define se clicar fora do popover o fecha. |
locale | string | — | Tag BCP 47 para i18n ("en", "pt-BR"). Recai para o lang do ancestral mais próximo. |
Eventos
| Evento | Payload | Descrição |
|---|---|---|
mkOpenChange | { open: boolean } | Emitido sempre que a visibilidade muda — clique no trigger, Escape, clique fora, clique em Cancelar ou Confirmar. |
mkCancel | void | Emitido ao clicar em Cancelar, antes do popover fechar. |
mkConfirm | void | Emitido ao clicar em Confirmar. Cancelável: fecha o popover automaticamente logo em seguida, exceto se o handler chamar event.preventDefault() de forma síncrona (necessário para fluxos assíncronos) ou já tiver confirmLoading = true no momento do clique. |
Slots
| Slot | Descrição |
|---|---|
| (padrão) | Elemento que dispara a abertura do popover ao ser clicado — mk-button, mk-icon-button, <a>, texto, etc. O componente não estiliza o conteúdo, apenas o envolve para capturar o clique. |
Acessibilidade
- O popover renderiza com
role="alertdialog",aria-labelledbyapontando para o título earia-describedbypara a descrição, quando presente. - O wrapper do trigger reflete
aria-haspopup="dialog",aria-expanded(sincronizado comopen) earia-disabled(quandodisabled). - Ao abrir, o foco move para o botão indicado por
initialFocus—"cancel"por padrão, reduzindo o risco de uma tecla Enter acidental confirmar uma ação destrutiva. Ao fechar por qualquer via, o foco retorna ao elemento trigger. - A cor do botão de confirmação (
destructive) não deve ser a única pista da gravidade da ação — prefira umconfirmTextexplícito (ex. "Excluir") em vez de "Confirmar".
| Tecla | Comportamento |
|---|---|
Tab / Shift + Tab | Alterna somente entre Cancelar e Confirmar (mini focus-trap de 2 elementos). |
Escape | Fecha o popover e devolve o foco ao trigger. Suspenso durante confirmLoading. |