Skip to content
🌏 Translated with the assistance of DeepSeek and ChatGPT

Popconfirm

A popup with a confirm button.

Popconfirm is similar to Popover in interaction, but focuses on confirmation (confirm/cancel) scenarios for quick confirmation flows.

Basic Usage

Use the content prop to set the message. By default Popconfirm shows an icon, message and footer buttons (confirm/cancel).

<template>
	<px-space>
		<px-popconfirm content="Are you sure you want to delete this item?">
			<px-button theme="danger">Delete</px-button>
		</px-popconfirm>
		<px-popconfirm>
			<template #content>
				<div>
					Shouldn't we make the warning mark bigger?<br />
					It's hard to notice as is.
				</div>
			</template>
			<px-button>Confirm</px-button>
		</px-popconfirm>
	</px-space>
</template>
<template>
	<div class="box">
		<div class="left">
			<px-popconfirm
				v-for="item in ['left-start', 'left', 'left-end']"
				:key="item"
				:placement="item"
				:content="getContent(item)"
			>
				<px-button>{{ getLabel(item) }}</px-button>
			</px-popconfirm>
		</div>
		<div class="center">
			<div class="top">
				<px-popconfirm
					v-for="item in ['top-start', 'top', 'top-end']"
					:key="item"
					:placement="item"
					:content="getContent(item)"
				>
					<px-button>{{ getLabel(item) }}</px-button>
				</px-popconfirm>
			</div>
			<div class="bottom">
				<px-popconfirm
					v-for="item in ['bottom-start', 'bottom', 'bottom-end']"
					:key="item"
					:placement="item"
					:content="getContent(item)"
				>
					<px-button>{{ getLabel(item) }}</px-button>
				</px-popconfirm>
			</div>
		</div>
		<div class="right">
			<px-popconfirm
				v-for="item in ['right-start', 'right', 'right-end']"
				:key="item"
				:placement="item"
				:content="getContent(item)"
			>
				<px-button>{{ getLabel(item) }}</px-button>
			</px-popconfirm>
		</div>
	</div>
</template>

<script setup lang="ts">
const getLabel = (placement: string) => {
	return placement.replace(/-/g, ' ').replace(/\b\w/g, (l) => l.toUpperCase())
}

const getContent = (placement: string) => {
	let contentArr: string[] = []
	if (placement.includes('-')) {
		const [pos, sub] = placement.split('-')
		contentArr = [capitalize(pos), capitalize(sub), 'Popover']
	} else {
		contentArr = [capitalize(placement), 'Popover']
	}

	return placement.startsWith('top') || placement.startsWith('bottom')
		? contentArr.join(' ')
		: contentArr.join('\n')
}

const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
</script>

<style lang="css" scoped>
.box {
	display: flex;
	width: 600px;
	height: 350px;
	margin-left: 100px;
	margin-top: 64px;
	margin-bottom: 64px;
}
.left,
.right {
	flex-shrink: 0;
	display: flex;
	flex-direction: column;
	justify-content: space-around;
}
.left {
	align-items: flex-start;
}
.right {
	align-items: flex-end;
}
.center {
	flex: 1;
	display: flex;
	flex-direction: column;
}
.top,
.bottom {
	display: flex;
	justify-content: space-around;
}
.top {
	flex: 1;
}
</style>

Controlled Mode

Passing visible switches the component to controlled mode. If omitted or set to undefined, the component is uncontrolled and defaultVisible can be used to set the initial state. The component emits update:visible to support v-model.

<template>
	<px-popconfirm content="Controlled confirm" v-model:visible="visible">
		<px-button>Controlled {{ visible }}</px-button>
	</px-popconfirm>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const visible = ref(false)
</script>

Asynchronous Confirmation

When onBeforeOk is provided, the confirmation process will wait for onBeforeOk to complete. If the result is not false, subsequent code will be executed.

<template>
	<px-popconfirm content="This will run an async check" :onBeforeOk="beforeOk">
		<px-button>Async Confirm</px-button>
	</px-popconfirm>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const calls = ref(0)
const beforeOk = async () => {
	calls.value += 1
	if (calls.value % 2 === 1) {
		await new Promise((r) => setTimeout(r, 500))
		return false
	}
	await new Promise((r) => setTimeout(r, 500))
	return true
}
</script>

Customize the entire bottom area via the footer slot. Use the icon slot for custom icons; showIcon controls icon visibility. To modify button text or properties only, use okText, cancelText, okButtonProps, and cancelButtonProps.

<template>
	<px-space>
		<px-popconfirm content="Custom Icon example">
			<template #icon>
				<IconMinds />
			</template>
			<px-button>Custom Icon</px-button>
		</px-popconfirm>
		<px-popconfirm content="No Icon example" :show-icon="false">
			<px-button>No Icon</px-button>
		</px-popconfirm>
		<px-popconfirm
			content="Custom Button example"
			ok-text="Yes, delete"
			cancel-text="No, keep it"
			cancel-button-props="{ theme: 'info' }"
			ok-button-props="{ theme: 'danger' }"
		>
			<px-button>Custom Button</px-button>
		</px-popconfirm>
		<px-popconfirm content="Custom footer example" v-model:visible="visible4CustomFooter">
			<template #footer> Custom Footer Content </template>
			<px-button>Custom Footer</px-button>
		</px-popconfirm>
	</px-space>
</template>

<script setup lang="tsx">
import { ref } from 'vue'
import { IconMinds } from '@pixelium/web-vue/icon-hn/es'

const visible4CustomFooter = ref(false)
</script>

Disabled State

Set disabled to disable the component. Trigger actions will be ignored and the popup will not open.

<template>
	<px-popconfirm content="This popconfirm is disabled" disabled>
		<px-button>Disabled</px-button>
	</px-popconfirm>
</template>

API

PopconfirmProps

AttributeTypeOptionalDefaultDescriptionVersion
contentstringTrueText content of the confirmation popup.0.1.0
visibleboolean | nullTrueWhether to display (controlled mode, supports v-model).0.1.0
defaultVisibleboolean | nullTrueDefault visibility state in uncontrolled mode.0.1.0
loadingbooleanTruefalsePass loading to control the loading state of the confirm button.0.1.0
placement'top' | 'right' | 'bottom' | 'left' | 'top-start' | 'top-end' | 'right-start' | 'right-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end'True'top'Popup placement.0.1.0
okTextstringTrueText for the confirm button.0.1.0
cancelTextstringTrueText for the cancel button.0.1.0
showIconbooleanTruetrueWhether to show the default icon.0.1.0
showCancelbooleanTruetrueWhether to show the cancel button.0.1.0
showFooterbooleanTruetrueWhether to show the footer area.0.1.0
offsetnumberTrue8Popup offset distance (pixels).0.1.0
variant'dark' | 'light'True'light'Component style variant (light/dark).0.1.0
arrowbooleanTruetrueWhether to show arrow.0.1.0
disabledbooleanTruefalseWhether disabled.0.1.0
zIndexnumberTruez-index of the popup layer.0.1.0
rootHTMLElement | stringTrue'body'Mount element.0.1.0
destroyOnHidebooleanTruefalseWhether to destroy content when hidden.0.1.0
popoverPropsOmit<PopoverProps, 'visible' | 'content' | 'defaultVisible'> & EmitEvent<PopoverEvents>TrueProps passed through to the internal Popover.0.1.0
okButtonPropsButtonProps & EmitEvent<ButtonEvents> & RestAttrsTrueProps and events passed to the confirm button.0.1.0
cancelButtonPropsButtonProps & EmitEvent<ButtonEvents> & RestAttrsTrueProps and events passed to the cancel button.0.1.0
containerPropsRestAttrsTrueDOM attributes passed to the container area.0.1.0
contentPropsRestAttrsTrueDOM attributes passed to the content area container.0.1.0
footerPropsRestAttrsTrueDOM attributes passed to the footer area container.0.1.0

PopconfirmEvents

EventParameterDescriptionVersion
update:visiblevalue: booleanTriggered when v-model updates.0.1.0
beforeOkFor async confirmation. Must return a value of type Promise<boolean | void> | boolean | void. Confirmation succeeds if the result after await is not false.0.1.0
okevent: MouseEventTriggered when the confirm button is clicked (after beforeOk passes).0.1.0
cancelevent: MouseEvent | KeyboardEventTriggered when the cancel button is clicked.0.1.0
closee: MouseEventTriggered when the popup closes.0.1.0
opene: MouseEventTriggered when the popup opens.0.1.0

PopconfirmSlots

SlotParameterDescriptionVersion
defaultSlot for the trigger element.0.1.0
contentCustom content slot.0.1.0
iconCustom icon slot.0.1.0
footerCustom footer slot.0.1.0

PopconfirmExpose

AttributeTypeOptionalDefaultDescriptionVersion
open() => voidFalseOpens the confirmation popup.0.1.0
close() => voidFalseCloses the confirmation popup.0.1.0

RestAttrs

ts
import type { StyleValue } from 'vue'

export type VueClassValue = string | Record<string, any> | VueClassValue[]
export type VueStyleValue = StyleValue

export type RestAttrs = {
	style?: VueStyleValue | null
	class?: VueClassValue | null
	[x: string]: any
}

EmitEvent

ts
export type EmitEvent<T extends Record<string, any>> = {
	[K in keyof T as `on${Capitalize<K & string>}`]?: (...args: T[K]) => void
}