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>Custom Footer and Icon
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
| Attribute | Type | Optional | Default | Description | Version |
|---|---|---|---|---|---|
| content | string | True | | Text content of the confirmation popup. | 0.1.0 |
| visible | boolean | null | True | | Whether to display (controlled mode, supports v-model). | 0.1.0 |
| defaultVisible | boolean | null | True | | Default visibility state in uncontrolled mode. | 0.1.0 |
| loading | boolean | True | false | Pass 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 |
| okText | string | True | | Text for the confirm button. | 0.1.0 |
| cancelText | string | True | | Text for the cancel button. | 0.1.0 |
| showIcon | boolean | True | true | Whether to show the default icon. | 0.1.0 |
| showCancel | boolean | True | true | Whether to show the cancel button. | 0.1.0 |
| showFooter | boolean | True | true | Whether to show the footer area. | 0.1.0 |
| offset | number | True | 8 | Popup offset distance (pixels). | 0.1.0 |
| variant | 'dark' | 'light' | True | 'light' | Component style variant (light/dark). | 0.1.0 |
| arrow | boolean | True | true | Whether to show arrow. | 0.1.0 |
| disabled | boolean | True | false | Whether disabled. | 0.1.0 |
| zIndex | number | True | | z-index of the popup layer. | 0.1.0 |
| root | HTMLElement | string | True | 'body' | Mount element. | 0.1.0 |
| destroyOnHide | boolean | True | false | Whether to destroy content when hidden. | 0.1.0 |
| popoverProps | Omit<PopoverProps, 'visible' | 'content' | 'defaultVisible'> & EmitEvent<PopoverEvents> | True | | Props passed through to the internal Popover. | 0.1.0 |
| okButtonProps | ButtonProps & EmitEvent<ButtonEvents> & RestAttrs | True | | Props and events passed to the confirm button. | 0.1.0 |
| cancelButtonProps | ButtonProps & EmitEvent<ButtonEvents> & RestAttrs | True | | Props and events passed to the cancel button. | 0.1.0 |
| containerProps | RestAttrs | True | | DOM attributes passed to the container area. | 0.1.0 |
| contentProps | RestAttrs | True | | DOM attributes passed to the content area container. | 0.1.0 |
| footerProps | RestAttrs | True | | DOM attributes passed to the footer area container. | 0.1.0 |
PopconfirmEvents
| Event | Parameter | Description | Version |
|---|---|---|---|
| update:visible | value: boolean | Triggered when v-model updates. | 0.1.0 |
| beforeOk | | For 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 |
| ok | event: MouseEvent | Triggered when the confirm button is clicked (after beforeOk passes). | 0.1.0 |
| cancel | event: MouseEvent | KeyboardEvent | Triggered when the cancel button is clicked. | 0.1.0 |
| close | e: MouseEvent | Triggered when the popup closes. | 0.1.0 |
| open | e: MouseEvent | Triggered when the popup opens. | 0.1.0 |
PopconfirmSlots
| Slot | Parameter | Description | Version |
|---|---|---|---|
| default | | Slot for the trigger element. | 0.1.0 |
| content | | Custom content slot. | 0.1.0 |
| icon | | Custom icon slot. | 0.1.0 |
| footer | | Custom footer slot. | 0.1.0 |
PopconfirmExpose
| Attribute | Type | Optional | Default | Description | Version |
|---|---|---|---|---|---|
| open | () => void | False | | Opens the confirmation popup. | 0.1.0 |
| close | () => void | False | | Closes the confirmation popup. | 0.1.0 |
RestAttrs
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
export type EmitEvent<T extends Record<string, any>> = {
[K in keyof T as `on${Capitalize<K & string>}`]?: (...args: T[K]) => void
}