update
This commit is contained in:
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* MicroModal Global Utilities
|
||||
* Provides helper functions for MicroModal management
|
||||
*/
|
||||
|
||||
class ModalManager {
|
||||
constructor() {
|
||||
this.initialized = false;
|
||||
this.modals = new Map();
|
||||
this.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize MicroModal with default settings
|
||||
*/
|
||||
init() {
|
||||
if (typeof MicroModal === 'undefined') {
|
||||
console.warn('MicroModal is not loaded');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
MicroModal.init({
|
||||
onShow: (modal) => {
|
||||
this.onModalShow(modal);
|
||||
},
|
||||
onClose: (modal) => {
|
||||
this.onModalClose(modal);
|
||||
},
|
||||
openTrigger: 'data-micromodal-trigger',
|
||||
closeTrigger: 'data-micromodal-close',
|
||||
openClass: 'is-open',
|
||||
disableScroll: true,
|
||||
disableFocus: false,
|
||||
awaitOpenAnimation: false,
|
||||
awaitCloseAnimation: false,
|
||||
debugMode: false
|
||||
});
|
||||
|
||||
this.initialized = true;
|
||||
console.log('MicroModal initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when modal is shown
|
||||
*/
|
||||
onModalShow(modal) {
|
||||
// Re-initialize Lucide icons when modal opens
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
|
||||
// Add body class to prevent scrolling
|
||||
document.body.classList.add('modal-open');
|
||||
|
||||
// Execute custom show callback if exists
|
||||
if (modal && this.modals.has(modal.id)) {
|
||||
const config = this.modals.get(modal.id);
|
||||
if (config.onShow && typeof config.onShow === 'function') {
|
||||
config.onShow(modal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when modal is closed
|
||||
*/
|
||||
onModalClose(modal) {
|
||||
// Remove body class
|
||||
document.body.classList.remove('modal-open');
|
||||
|
||||
// Execute custom close callback if exists
|
||||
if (modal && this.modals.has(modal.id)) {
|
||||
const config = this.modals.get(modal.id);
|
||||
if (config.onClose && typeof config.onClose === 'function') {
|
||||
config.onClose(modal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show modal with optional data
|
||||
*/
|
||||
show(modalId, data = {}) {
|
||||
if (typeof MicroModal === 'undefined') {
|
||||
console.error('MicroModal is not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Update modal content if data is provided
|
||||
if (Object.keys(data).length > 0) {
|
||||
this.updateModalContent(modalId, data);
|
||||
}
|
||||
|
||||
MicroModal.show(modalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close modal
|
||||
*/
|
||||
close(modalId) {
|
||||
if (typeof MicroModal === 'undefined') {
|
||||
console.error('MicroModal is not available');
|
||||
return;
|
||||
}
|
||||
|
||||
MicroModal.close(modalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a modal with custom configuration
|
||||
*/
|
||||
register(modalId, config = {}) {
|
||||
this.modals.set(modalId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update modal content dynamically
|
||||
*/
|
||||
updateModalContent(modalId, data) {
|
||||
const modal = document.getElementById(modalId);
|
||||
if (!modal) {
|
||||
console.error(`Modal ${modalId} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update text content for elements with data-modal-* attributes
|
||||
Object.keys(data).forEach(key => {
|
||||
const element = modal.querySelector(`[data-modal-${key}]`);
|
||||
if (element) {
|
||||
if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {
|
||||
element.value = data[key];
|
||||
} else {
|
||||
element.textContent = data[key];
|
||||
}
|
||||
}
|
||||
|
||||
// Also support getElementById for backward compatibility
|
||||
const elementById = modal.querySelector(`#${key}`);
|
||||
if (elementById) {
|
||||
if (elementById.tagName === 'INPUT' || elementById.tagName === 'TEXTAREA') {
|
||||
elementById.value = data[key];
|
||||
} else {
|
||||
elementById.textContent = data[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Update form action if provided
|
||||
if (data.formAction) {
|
||||
const form = modal.querySelector('form');
|
||||
if (form) {
|
||||
form.action = data.formAction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a confirmation modal dynamically
|
||||
*/
|
||||
showConfirmation(options = {}) {
|
||||
const defaults = {
|
||||
modalId: 'confirmationModal',
|
||||
title: 'Confirm Action',
|
||||
message: 'Are you sure?',
|
||||
confirmText: 'Confirm',
|
||||
cancelText: 'Cancel',
|
||||
confirmClass: 'btn btn-primary btn-sm',
|
||||
cancelClass: 'btn btn-outline-secondary btn-sm',
|
||||
onConfirm: null,
|
||||
onCancel: null
|
||||
};
|
||||
|
||||
const config = { ...defaults, ...options };
|
||||
|
||||
// Create modal HTML if it doesn't exist
|
||||
let modal = document.getElementById(config.modalId);
|
||||
if (!modal) {
|
||||
modal = this.createConfirmationModal(config);
|
||||
document.body.appendChild(modal);
|
||||
} else {
|
||||
// Update existing modal
|
||||
this.updateConfirmationModal(modal, config);
|
||||
}
|
||||
|
||||
// Register callbacks
|
||||
this.register(config.modalId, {
|
||||
onShow: () => {
|
||||
const confirmBtn = modal.querySelector('.modal__confirm');
|
||||
const cancelBtn = modal.querySelector('.modal__cancel');
|
||||
|
||||
// Remove existing event listeners
|
||||
confirmBtn.replaceWith(confirmBtn.cloneNode(true));
|
||||
cancelBtn.replaceWith(cancelBtn.cloneNode(true));
|
||||
|
||||
// Add new event listeners
|
||||
modal.querySelector('.modal__confirm').addEventListener('click', (e) => {
|
||||
if (config.onConfirm && typeof config.onConfirm === 'function') {
|
||||
config.onConfirm(e);
|
||||
}
|
||||
this.close(config.modalId);
|
||||
});
|
||||
|
||||
modal.querySelector('.modal__cancel').addEventListener('click', (e) => {
|
||||
if (config.onCancel && typeof config.onCancel === 'function') {
|
||||
config.onCancel(e);
|
||||
}
|
||||
this.close(config.modalId);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.show(config.modalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create confirmation modal HTML
|
||||
*/
|
||||
createConfirmationModal(config) {
|
||||
const modalHtml = `
|
||||
<div class="modal micromodal-slide" id="${config.modalId}" aria-hidden="true">
|
||||
<div class="modal__overlay" tabindex="-1" data-micromodal-close>
|
||||
<div class="modal__container modal--sm" role="dialog" aria-modal="true">
|
||||
<header class="modal__header bg-primary text-white">
|
||||
<h6 class="modal__title">${config.title}</h6>
|
||||
<button class="modal__close" aria-label="Close modal" data-micromodal-close>
|
||||
<i data-lucide="x"></i>
|
||||
</button>
|
||||
</header>
|
||||
<main class="modal__content">
|
||||
<div class="text-center">
|
||||
<p class="mb-0">${config.message}</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="modal__footer justify-content-center">
|
||||
<button type="button" class="modal__cancel ${config.cancelClass}" data-micromodal-close>
|
||||
${config.cancelText}
|
||||
</button>
|
||||
<button type="button" class="modal__confirm ${config.confirmClass}">
|
||||
${config.confirmText}
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = modalHtml;
|
||||
return div.firstElementChild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update existing confirmation modal
|
||||
*/
|
||||
updateConfirmationModal(modal, config) {
|
||||
modal.querySelector('.modal__title').textContent = config.title;
|
||||
modal.querySelector('.modal__content p').textContent = config.message;
|
||||
modal.querySelector('.modal__confirm').textContent = config.confirmText;
|
||||
modal.querySelector('.modal__cancel').textContent = config.cancelText;
|
||||
|
||||
// Update button classes
|
||||
modal.querySelector('.modal__confirm').className = `modal__confirm ${config.confirmClass}`;
|
||||
modal.querySelector('.modal__cancel').className = `modal__cancel ${config.cancelClass}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Global instance
|
||||
window.ModalManager = new ModalManager();
|
||||
|
||||
// Helper functions for backward compatibility
|
||||
window.showModal = (modalId, data = {}) => {
|
||||
window.ModalManager.show(modalId, data);
|
||||
};
|
||||
|
||||
window.closeModal = (modalId) => {
|
||||
window.ModalManager.close(modalId);
|
||||
};
|
||||
|
||||
window.showConfirmation = (options) => {
|
||||
window.ModalManager.showConfirmation(options);
|
||||
};
|
||||
|
||||
// Auto-initialize when DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Initialize Lucide icons
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
|
||||
console.log('Modal utilities loaded');
|
||||
});
|
||||
|
||||
// Export for ES modules
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = ModalManager;
|
||||
}
|
||||
Reference in New Issue
Block a user