1
// Custom confirmation dialog. CSS in /css/modals.css
2
3
+import { callJsExtensions } from "/js/extensions.js";
4
+
5
const DIALOG_TYPES = {
6
warning: { icon: 'warning', color: 'var(--color-warning, #f59e0b)' },
7
danger: { icon: 'error', color: 'var(--color-error, #ef4444)' },
14
message = '',
15
confirmText = 'Confirm',
16
cancelText = 'Cancel',
15
- type = 'warning'
17
+ type = 'warning',
18
+ extensionContext = null,
19
} = options;
20
21
const typeConfig = DIALOG_TYPES[type] || DIALOG_TYPES.warning;
43
backdrop.appendChild(dialog);
44
document.body.appendChild(backdrop);
45
46
+ const titleElement = dialog.querySelector('.confirm-dialog-title');
47
+ const bodyElement = dialog.querySelector('.confirm-dialog-body');
48
+ const footerElement = dialog.querySelector('.confirm-dialog-footer');
49
+ const cancelButton = dialog.querySelector('.confirm-dialog-cancel');
50
+ const confirmButton = dialog.querySelector('.confirm-dialog-confirm');
51
+ let isClosed = false;
52
+
53
// Show with animation
44
- requestAnimationFrame(() => {
45
- backdrop.classList.add('visible');
46
- dialog.querySelector('.confirm-dialog-cancel').focus();
47
- });
54
+ const showDialog = () => {
55
+ requestAnimationFrame(() => {
56
+ backdrop.classList.add('visible');
57
+ cancelButton?.focus();
58
+ });
59
+ };
60
61
// Close handler
62
const close = (result) => {
63
+ if (isClosed) return;
64
+ isClosed = true;
65
backdrop.classList.remove('visible');
66
document.removeEventListener('keydown', handleKeydown);
67
setTimeout(() => {
71
};
72
73
// Event listeners
60
- dialog.querySelector('.confirm-dialog-cancel').addEventListener('click', () => close(false));
61
- dialog.querySelector('.confirm-dialog-confirm').addEventListener('click', () => close(true));
74
+ cancelButton.addEventListener('click', () => close(false));
75
+ confirmButton.addEventListener('click', () => close(true));
76
backdrop.addEventListener('click', (e) => e.target === backdrop && close(false));
77
78
// Keyboard handling
79
const handleKeydown = (e) => {
66
- if (e.key === 'Escape') close(false);
67
- else if (e.key === 'Enter') close(true);
80
+ if (e.key === 'Escape') {
81
+ e.preventDefault();
82
+ close(false);
83
+ return;
84
+ }
85
+
86
+ if (e.key !== 'Enter') return;
87
+
88
+ const activeElement = document.activeElement;
89
+ if (
90
+ activeElement
91
+ && dialog.contains(activeElement)
92
+ && (
93
+ activeElement.tagName === 'BUTTON'
94
+ || activeElement.tagName === 'A'
95
+ || activeElement.tagName === 'INPUT'
96
+ || activeElement.tagName === 'TEXTAREA'
97
+ || activeElement.tagName === 'SELECT'
98
+ || activeElement.isContentEditable
99
+ )
100
+ ) {
101
+ return;
102
+ }
103
+
104
+ e.preventDefault();
105
+ close(true);
106
};
107
document.addEventListener('keydown', handleKeydown);
108
+
109
+ const extensionData = {
110
+ options,
111
+ dialog,
112
+ backdrop,
113
+ titleElement,
114
+ bodyElement,
115
+ footerElement,
116
+ confirmButton,
117
+ cancelButton,
118
+ close,
119
+ title,
120
+ message,
121
+ type,
122
+ confirmText,
123
+ cancelText,
124
+ extensionContext,
125
+ };
126
+
127
+ callJsExtensions('confirm_dialog_after_render', extensionData)
128
+ .finally(showDialog);
129
});
130
}