/** * Modale de confirmation glassmorphism. * * Remplace les confirm() / electronAPI.showConfirm() natifs * par une modale cohérente avec le design Obsidienne. */ let overlay: HTMLElement | null = null; function ensureOverlay(): HTMLElement { if (overlay && overlay.parentNode) return overlay; overlay = document.createElement('div'); overlay.className = 'confirm-overlay confirm-hidden'; document.body.appendChild(overlay); return overlay; } export const ConfirmModal = { /** * Affiche une modale de confirmation. * @returns true si l'utilisateur confirme, false sinon. */ show(title: string, message: string): Promise { return new Promise(resolve => { const ov = ensureOverlay(); const box = document.createElement('div'); box.className = 'confirm-box'; const iconEl = document.createElement('span'); iconEl.className = 'confirm-icon material-symbols-outlined'; iconEl.textContent = 'warning'; const titleEl = document.createElement('h3'); titleEl.className = 'confirm-title'; titleEl.textContent = title; const msgEl = document.createElement('p'); msgEl.className = 'confirm-msg'; msgEl.textContent = message; const footer = document.createElement('div'); footer.className = 'confirm-footer'; const cancelBtn = document.createElement('button'); cancelBtn.className = 'confirm-btn confirm-btn-cancel'; cancelBtn.textContent = 'Annuler'; const okBtn = document.createElement('button'); okBtn.className = 'confirm-btn confirm-btn-ok'; okBtn.textContent = 'Confirmer'; footer.appendChild(cancelBtn); footer.appendChild(okBtn); box.appendChild(iconEl); box.appendChild(titleEl); box.appendChild(msgEl); box.appendChild(footer); ov.innerHTML = ''; ov.appendChild(box); ov.classList.remove('confirm-hidden'); const close = (result: boolean) => { ov.classList.add('confirm-hidden'); resolve(result); }; cancelBtn.addEventListener('click', () => close(false), { once: true }); okBtn.addEventListener('click', () => close(true), { once: true }); ov.addEventListener('click', (e) => { if (e.target === ov) close(false); }, { once: true }); // Focus sur le bouton Annuler pour éviter les confirmations accidentelles requestAnimationFrame(() => cancelBtn.focus()); }); }, };