Spaces:
Running
Running
File size: 2,296 Bytes
6918275 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | // Inline button two-click confirmation for destructive actions.
// First click arms, second click confirms, timeout resets.
import { ICON_SELECTOR, getIconName, setIconName } from "./icons.js";
const CONFIRM_TIMEOUT = 2000;
const CONFIRM_CLASS = 'confirming';
const CONFIRM_ICON = 'check';
const CONFIRM_TEXT = 'Confirm';
const buttonStates = new WeakMap();
// Handles inline two-click confirmation for a button.
export function confirmClick(event, action) {
const button = event.currentTarget;
if (!button) return;
const state = buttonStates.get(button);
if (state?.confirming) {
clearTimeout(state.timeoutId);
resetButton(button, state);
buttonStates.delete(button);
action();
} else {
const iconEl = button.querySelector(ICON_SELECTOR);
const isIconButton = iconEl && button.textContent.trim() === iconEl.textContent.trim();
const newState = {
confirming: true,
isIconButton,
originalIcon: getIconName(iconEl),
originalHTML: isIconButton ? null : button.innerHTML,
timeoutId: setTimeout(() => {
resetButton(button, newState);
buttonStates.delete(button);
}, CONFIRM_TIMEOUT)
};
buttonStates.set(button, newState);
button.classList.add(CONFIRM_CLASS);
if (isIconButton && iconEl) {
// Icon-only button: just swap icon
setIconName(iconEl, CONFIRM_ICON);
} else {
// Text button: show icon + optional "Confirm" text
const originalText = button.textContent.trim();
const confirmContent = originalText.length >= 4
? `<x-icon name="${CONFIRM_ICON}"></x-icon>${CONFIRM_TEXT}`
: `<x-icon name="${CONFIRM_ICON}"></x-icon>`;
button.innerHTML = confirmContent;
}
}
}
// Reset button to original state
function resetButton(button, state) {
button.classList.remove(CONFIRM_CLASS);
if (state.isIconButton) {
const iconEl = button.querySelector(ICON_SELECTOR);
if (iconEl && state.originalIcon) {
setIconName(iconEl, state.originalIcon);
}
} else if (state.originalHTML) {
button.innerHTML = state.originalHTML;
}
}
// Register Alpine magic helper
export function registerAlpineMagic() {
if (globalThis.Alpine) {
globalThis.Alpine.magic('confirmClick', () => confirmClick);
}
}
|