Files

192 lines
5.5 KiB
JavaScript

// eveai_chat_client/static/assets/js/composables/useIconManager.js
import { onMounted, watch, ref } from 'vue';
/**
* Vue 3 Composable for Material Symbols Outlined icon management
* Self-contained modern icon management without legacy dependencies
*/
export function useIconManager() {
const isIconManagerReady = ref(true); // Always ready since we're self-contained
const loadedIcons = ref([]);
/**
* Load a single Material Symbols Outlined icon
* @param {string} iconName - Name of the icon to load
* @param {Object} options - Icon options (opsz, wght, FILL, GRAD)
*/
const loadIcon = (iconName, options = {}) => {
if (!iconName) {
console.warn('No icon name provided');
return;
}
// Check if icon is already loaded
if (loadedIcons.value.includes(iconName)) {
return;
}
// Default options for Material Symbols Outlined
const defaultOptions = {
opsz: 24,
wght: 400,
FILL: 0,
GRAD: 0
};
const iconOptions = { ...defaultOptions, ...options };
// Create CSS for the icon with specific options
const cssRule = `
.material-symbols-outlined.icon-${iconName} {
font-variation-settings:
'FILL' ${iconOptions.FILL},
'wght' ${iconOptions.wght},
'GRAD' ${iconOptions.GRAD},
'opsz' ${iconOptions.opsz};
}
`;
// Add CSS rule to document
const style = document.createElement('style');
style.textContent = cssRule;
document.head.appendChild(style);
// Mark icon as loaded
loadedIcons.value.push(iconName);
console.log(`Icon loaded: ${iconName}`);
};
/**
* Load multiple icons
* @param {Array} iconNames - Array of icon names to load
* @param {Object} options - Icon options (opsz, wght, FILL, GRAD)
*/
const loadIcons = (iconNames, options = {}) => {
if (!Array.isArray(iconNames)) {
console.warn('iconNames must be an array');
return;
}
iconNames.forEach(iconName => {
loadIcon(iconName, options);
});
};
/**
* Ensure icons are loaded (alias for loadIcons for backward compatibility)
* @param {Object} options - Icon options (opsz, wght, FILL, GRAD)
* @param {Array} iconNames - Array of icon names to load
*/
const ensureIconsLoaded = (options = {}, iconNames = []) => {
if (iconNames && iconNames.length > 0) {
loadIcons(iconNames, options);
}
};
/**
* Watch a reactive property for icon changes and automatically load icons
* @param {Ref|Function} iconSource - Reactive source that contains icon name(s)
* @param {Object} options - Icon options
*/
const watchIcon = (iconSource, options = {}) => {
watch(
iconSource,
(newIcon) => {
if (newIcon) {
if (Array.isArray(newIcon)) {
loadIcons(newIcon, options);
} else {
loadIcon(newIcon, options);
}
}
},
{ immediate: true }
);
};
/**
* Watch formData for icon changes (common pattern in Vue components)
* @param {Ref} formData - Reactive formData object
* @param {Object} options - Icon options
*/
const watchFormDataIcon = (formData, options = {}) => {
watch(
() => formData.value?.icon,
(newIcon) => {
if (newIcon) {
loadIcon(newIcon, options);
}
},
{ immediate: true }
);
};
/**
* Preload common icons used throughout the application
* @param {Array} commonIcons - Array of commonly used icon names
* @param {Object} options - Icon options
*/
const preloadCommonIcons = (commonIcons = [], options = {}) => {
const defaultCommonIcons = [
'send', 'attach_file', 'mic', 'more_vert', 'close', 'check',
'error', 'warning', 'info', 'expand_more', 'expand_less'
];
const iconsToLoad = commonIcons.length > 0 ? commonIcons : defaultCommonIcons;
loadIcons(iconsToLoad, options);
};
return {
// State
isIconManagerReady,
// Methods
loadIcon,
loadIcons,
ensureIconsLoaded,
// Watchers
watchIcon,
watchFormDataIcon,
// Utilities
preloadCommonIcons
};
}
/**
* Simplified composable for basic icon loading
* Use this when you only need basic icon loading functionality
*/
export function useIcon(iconName, options = {}) {
const { loadIcon, isIconManagerReady } = useIconManager();
onMounted(() => {
if (iconName) {
loadIcon(iconName, options);
}
});
return {
loadIcon,
isIconManagerReady
};
}
/**
* Composable for form-related icon management
* Automatically handles formData.icon watching
*/
export function useFormIcon(formData, options = {}) {
const { watchFormDataIcon, loadIcon, isIconManagerReady } = useIconManager();
// Automatically watch formData for icon changes
watchFormDataIcon(formData, options);
return {
loadIcon,
isIconManagerReady
};
}