feat: 新增图标选择器组件及相关功能;更新路由配置和类型定义;修复依赖地址
This commit is contained in:
149
src/utils/icon-loader.ts
Normal file
149
src/utils/icon-loader.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import type { IconifyJSON } from '@iconify/types';
|
||||
import materialSymbolsIcons from '@iconify-json/material-symbols/icons.json';
|
||||
import cryptoCurrencyIcons from '@iconify-json/cryptocurrency-color/icons.json';
|
||||
|
||||
/**
|
||||
* 图标集缓存
|
||||
*/
|
||||
interface IconCache {
|
||||
/** 图标名称列表 */
|
||||
icons: string[];
|
||||
/** 图标别名映射 */
|
||||
aliases: Record<string, string>;
|
||||
/** 加载时间戳 */
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
const iconCacheMap = new Map<string, IconCache>();
|
||||
|
||||
/**
|
||||
* 加载 Material Symbols 图标集
|
||||
* @returns 图标名称数组
|
||||
*/
|
||||
export function loadMaterialSymbolsIcons(): string[] {
|
||||
const collectionName = 'material-symbols';
|
||||
|
||||
// 返回缓存的图标
|
||||
if (iconCacheMap.has(collectionName)) {
|
||||
const cache = iconCacheMap.get(collectionName)!;
|
||||
return cache.icons;
|
||||
}
|
||||
|
||||
try {
|
||||
const iconSet = materialSymbolsIcons as unknown as IconifyJSON;
|
||||
|
||||
// 获取所有图标名称
|
||||
const icons = Object.keys(iconSet.icons || {});
|
||||
|
||||
// 处理别名
|
||||
const aliases: Record<string, string> = {};
|
||||
if (iconSet.aliases) {
|
||||
Object.entries(iconSet.aliases).forEach(([alias, config]) => {
|
||||
if (typeof config === 'object' && 'parent' in config) {
|
||||
aliases[alias] = config.parent;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 缓存结果
|
||||
iconCacheMap.set(collectionName, {
|
||||
icons,
|
||||
aliases,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
return icons;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to load material symbols icons:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载 cryptocurrency-color 图标集
|
||||
* @returns 图标名称数组
|
||||
*/
|
||||
export function loadCryptoCurrencyIcons(): string[] {
|
||||
const collectionName = 'cryptocurrency-color';
|
||||
|
||||
// 返回缓存的图标
|
||||
if (iconCacheMap.has(collectionName)) {
|
||||
const cache = iconCacheMap.get(collectionName)!;
|
||||
return cache.icons;
|
||||
}
|
||||
|
||||
try {
|
||||
const iconSet = cryptoCurrencyIcons as IconifyJSON;
|
||||
|
||||
// 获取所有图标名称
|
||||
const icons = Object.keys(iconSet.icons || {});
|
||||
|
||||
// 缓存结果
|
||||
iconCacheMap.set(collectionName, {
|
||||
icons,
|
||||
aliases: {},
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
return icons;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to load material icon theme icons:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用图标集加载器
|
||||
* @param collectionName 图标集名称,如 'material-symbols'
|
||||
* @returns 图标名称数组
|
||||
*/
|
||||
export function loadIconCollection(collectionName: string): string[] {
|
||||
// 根据图标集名称调用对应的加载函数
|
||||
switch (collectionName) {
|
||||
case 'material-symbols':
|
||||
return loadMaterialSymbolsIcons();
|
||||
case 'cryptocurrency-color':
|
||||
return loadCryptoCurrencyIcons();
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Unknown icon collection: ${collectionName}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索图标
|
||||
* @param icons 图标列表
|
||||
* @param keyword 搜索关键词
|
||||
* @returns 匹配的图标列表
|
||||
*/
|
||||
export function searchIcons(icons: string[], keyword: string): string[] {
|
||||
if (!keyword.trim()) return icons;
|
||||
|
||||
const lowerKeyword = keyword.toLowerCase();
|
||||
return icons.filter(icon => icon.toLowerCase().includes(lowerKeyword));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除图标缓存
|
||||
* @param collectionName 可选,指定清除的图标集,不传则清除所有
|
||||
*/
|
||||
export function clearIconCache(collectionName?: string): void {
|
||||
if (collectionName) {
|
||||
iconCacheMap.delete(collectionName);
|
||||
} else {
|
||||
iconCacheMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图标完整路径
|
||||
* @param collection 图标集名称
|
||||
* @param iconName 图标名称
|
||||
* @returns 完整图标路径,如 'material-symbols:home'
|
||||
*/
|
||||
export function getIconPath(collection: string, iconName: string): string {
|
||||
return `${collection}:${iconName}`;
|
||||
}
|
||||
Reference in New Issue
Block a user