Vanilla UI Kit Popconfirm v1.0.0 · tooltip →

Are you sure? Inline.

A confirmation anchored to the button that asked — lighter than a modal. Focus starts on Cancel, Escape backs out, and intercepted clicks only proceed once you say OK. Every card below is live.

Promise-based ask()

Anchor a one-shot confirm to any element and await the answer. Escape, outside click, or Cancel resolve false.

const ok = await Popconfirm.ask(
  '#archive', 'Archive this project?')
if (ok) archive()

Danger delete

danger: true reddens the OK button and the icon — focus still lands on Cancel, so a reflexive Enter is safe.

Popconfirm.ask(btn, {
  title: 'Delete account',
  message: 'This cannot be undone.',
  okLabel: 'Delete', danger: true
})

Declarative

Buttons with data-vpc are auto-bound at load. The click is intercepted; on confirm it proceeds — watch the inline onclick fire only after OK.

<button data-vpc="Remove this member?"
        data-vpc-danger data-vpc-ok="Remove">

Form submit button

A type=submit trigger holds the form until confirmed, then submits it for real via requestSubmit() — validation included (try submitting empty).

<form>
  <input name="email" required>
  <button type="submit"
    data-vpc="Unsubscribe this address?">
</form>

Custom labels, no icon

Rename the buttons per call (or once via Popconfirm.defaults.labels) and drop the icon with icon: false.

Popconfirm.ask(btn, {
  message: 'Log out on all devices?',
  okLabel: 'Log out', cancelLabel: 'Stay',
  icon: false, width: 240
})

Placements

Four sides with auto-flip when there's no room, plus an arrow that stays pointed at the trigger even when the panel is clamped.

<button data-vpc="I open below"
        data-vpc-placement="bottom">

Persistent binding + callbacks

new Popconfirm(el, opts) keeps intercepting until destroy(). onConfirm(el) / onCancel() report each answer.

var pc = new Popconfirm('#reset', {
  message: 'Reset all settings?',
  onConfirm: function (el) { … },
  onCancel:  function () { … }
})
pc.destroy()   // unbinds

Headless & family theming

Popconfirm.defaults.styles = false injects no CSS — the interception, focus management, and ARIA stay, the look is yours (see Popconfirm.css). With the VC core loaded, one call themes every family component.

<script src="https://cdn.jsdelivr.net/gh/vanilla-ui-kit/components/popconfirm/popconfirm.js"></script>
VC.config({ accent: '#b45309' })