Refactored modules and updated loader.
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* UI Helper
|
||||
* Provides utility functions for UI components
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create and append a UI element
|
||||
* @param {string} type - Element type (div, input, button, etc.)
|
||||
* @param {Object} attributes - Attributes to set on the element
|
||||
* @param {string} [text] - Text content for the element
|
||||
* @param {HTMLElement} parent - Parent element
|
||||
* @returns {HTMLElement} - Created element
|
||||
*/
|
||||
export function createUIElement(type, attributes = {}, text = '', parent = null) {
|
||||
const element = document.createElement(type);
|
||||
|
||||
// Set attributes
|
||||
for (const [key, value] of Object.entries(attributes || {})) {
|
||||
if (key === 'className') {
|
||||
element.className = value;
|
||||
} else {
|
||||
element.setAttribute(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Set text content if provided
|
||||
if (text) {
|
||||
element.textContent = text;
|
||||
}
|
||||
|
||||
// Append to parent if provided
|
||||
if (parent) {
|
||||
parent.appendChild(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate a dropdown with options
|
||||
* @param {HTMLSelectElement} dropdown - Dropdown element
|
||||
* @param {Array} items - Array of items
|
||||
* @param {string} valueKey - Key for item value
|
||||
* @param {string} textKey - Key for item text
|
||||
* @param {string} [selectedValue] - Value to select
|
||||
*/
|
||||
export function populateDropdown(dropdown, items, valueKey, textKey, selectedValue) {
|
||||
// Clear existing options
|
||||
dropdown.innerHTML = '';
|
||||
|
||||
// Add options
|
||||
items.forEach(item => {
|
||||
const option = document.createElement('option');
|
||||
option.value = item[valueKey];
|
||||
option.textContent = item[textKey];
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
|
||||
// Set selected value if provided
|
||||
if (selectedValue !== undefined && selectedValue !== null) {
|
||||
dropdown.value = selectedValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event handler for a UI element
|
||||
* @param {HTMLElement} element - UI element
|
||||
* @param {string} eventType - Event type (change, input, click, etc.)
|
||||
* @param {Function} handler - Event handler function
|
||||
*/
|
||||
export function registerHandler(element, eventType, handler) {
|
||||
if (element) {
|
||||
element.addEventListener(eventType, handler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a preference binding between a UI element and persistence manager
|
||||
* @param {HTMLElement} element - UI element
|
||||
* @param {Object} persistenceManager - Persistence manager instance
|
||||
* @param {string} category - Preference category
|
||||
* @param {string} key - Preference key
|
||||
* @param {Function} [updateUIFunc] - Function to update UI when preference changes
|
||||
* @param {Function} [valueTransform] - Function to transform value before saving
|
||||
*/
|
||||
export function createPreferenceBinding(element, persistenceManager, category, key, updateUIFunc, valueTransform) {
|
||||
if (!element || !persistenceManager) return;
|
||||
|
||||
// Get initial value from persistence
|
||||
const value = persistenceManager.getPreference(category, key);
|
||||
|
||||
// Update UI initially if value exists and update function provided
|
||||
if (value !== null && value !== undefined && updateUIFunc) {
|
||||
updateUIFunc(element, value);
|
||||
} else {
|
||||
// Default UI update based on element type
|
||||
if (element.type === 'checkbox') {
|
||||
element.checked = !!value;
|
||||
} else if (element.tagName === 'SELECT' || element.type === 'text' || element.type === 'password') {
|
||||
element.value = value !== null && value !== undefined ? value : '';
|
||||
} else if (element.type === 'range') {
|
||||
element.value = value !== null && value !== undefined ? value : 50;
|
||||
}
|
||||
}
|
||||
|
||||
// Add event listener
|
||||
const eventType = element.type === 'checkbox' ? 'change' : 'input';
|
||||
element.addEventListener(eventType, () => {
|
||||
let newValue;
|
||||
|
||||
if (element.type === 'checkbox') {
|
||||
newValue = element.checked;
|
||||
} else if (element.type === 'range' || element.type === 'number') {
|
||||
newValue = parseFloat(element.value);
|
||||
} else {
|
||||
newValue = element.value;
|
||||
}
|
||||
|
||||
// Apply transform if provided
|
||||
if (valueTransform) {
|
||||
newValue = valueTransform(newValue, element);
|
||||
}
|
||||
|
||||
// Save to persistence
|
||||
persistenceManager.updatePreference(category, key, newValue);
|
||||
|
||||
// Dispatch event for other modules
|
||||
document.dispatchEvent(new CustomEvent('preference:changed', {
|
||||
detail: {
|
||||
category,
|
||||
key,
|
||||
value: newValue
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up common modal behaviors (show/hide/close)
|
||||
* @param {HTMLElement} modal - Modal element
|
||||
* @param {HTMLElement} [closeButton] - Close button element
|
||||
* @returns {Object} - Modal control functions
|
||||
*/
|
||||
export function setupModalControls(modal, closeButton) {
|
||||
if (!modal) return {};
|
||||
|
||||
const show = () => {
|
||||
modal.style.display = 'flex';
|
||||
document.body.classList.add('modal-open');
|
||||
};
|
||||
|
||||
const hide = () => {
|
||||
modal.style.display = 'none';
|
||||
document.body.classList.remove('modal-open');
|
||||
};
|
||||
|
||||
// Set up close button if provided
|
||||
if (closeButton) {
|
||||
closeButton.addEventListener('click', hide);
|
||||
}
|
||||
|
||||
// Set up ESC key to close
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && modal.style.display === 'flex') {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
return { show, hide, toggle: () => modal.style.display === 'flex' ? hide() : show() };
|
||||
}
|
||||
Reference in New Issue
Block a user