171 lines
5.4 KiB
JavaScript
171 lines
5.4 KiB
JavaScript
/**
|
|
* 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() };
|
|
}
|