deploy-ease-platform/frontend/src/components/DynamicIcon/index.tsx
2025-10-24 22:02:45 +08:00

61 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import { icons, LucideProps } from 'lucide-react';
import { FolderKanban } from 'lucide-react';
interface DynamicIconProps extends Omit<LucideProps, 'ref'> {
/** 图标名称Lucide React 图标名)或 emoji */
name?: string;
/** 默认图标(当找不到指定图标时显示) */
fallback?: React.ComponentType<LucideProps>;
}
/**
* 动态图标组件
*
* 支持:
* 1. Lucide React 的所有图标(通过图标名称字符串)
* 2. Emoji 表情
*
* @example
* ```tsx
* // 使用 Lucide 图标名称
* <DynamicIcon name="Calendar" className="h-4 w-4" />
*
* // 使用 emoji
* <DynamicIcon name="📅" />
*
* // 自定义默认图标
* <DynamicIcon name="NonExistent" fallback={Star} />
* ```
*/
const DynamicIcon: React.FC<DynamicIconProps> = ({
name,
fallback: FallbackIcon = FolderKanban,
className = "h-4 w-4",
...props
}) => {
if (!name) {
return <FallbackIcon className={className} {...props} />;
}
// 检测是否为 emoji包括各种 Unicode emoji 范围)
const isEmoji = name.length <= 4 && /[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{1F1E0}-\u{1F1FF}]/u.test(name);
if (isEmoji) {
return <span className="inline-flex items-center justify-center text-lg">{name}</span>;
}
// 从 lucide-react 的 icons 对象中动态获取图标组件
const IconComponent = icons[name as keyof typeof icons];
if (IconComponent) {
return <IconComponent className={className} {...props} />;
}
// 如果找不到,显示默认图标
return <FallbackIcon className={className} {...props} />;
};
export default DynamicIcon;