This commit is contained in:
41
src/components/IconRenderer.tsx
Normal file
41
src/components/IconRenderer.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { Icon } from 'astro-icon/components';
|
||||
import type { IconType, LucideIcon, AstroIconName, CustomIconComponent } from '../types';
|
||||
|
||||
interface IconRendererProps {
|
||||
icon: IconType;
|
||||
size?: number;
|
||||
class?: string;
|
||||
[key: string]: any; // For additional props like client:load for custom components
|
||||
}
|
||||
|
||||
// Type guard functions
|
||||
function isLucideIcon(icon: IconType): icon is LucideIcon {
|
||||
return typeof icon === 'function' && icon.length <= 1; // Lucide icons are function components
|
||||
}
|
||||
|
||||
function isAstroIconName(icon: IconType): icon is AstroIconName {
|
||||
return typeof icon === 'string';
|
||||
}
|
||||
|
||||
function isCustomComponent(icon: IconType): icon is CustomIconComponent {
|
||||
return typeof icon === 'function' && !isLucideIcon(icon);
|
||||
}
|
||||
|
||||
export default function IconRenderer({ icon, size, class: className, ...props }: IconRendererProps) {
|
||||
if (isLucideIcon(icon)) {
|
||||
const LucideComponent = icon;
|
||||
return <LucideComponent size={size} class={className} {...props} />;
|
||||
}
|
||||
|
||||
if (isAstroIconName(icon)) {
|
||||
return <Icon name={icon} class={className} {...props} />;
|
||||
}
|
||||
|
||||
if (isCustomComponent(icon)) {
|
||||
const CustomComponent = icon;
|
||||
return <CustomComponent class={className} {...props} />;
|
||||
}
|
||||
|
||||
// Fallback
|
||||
return null;
|
||||
}
|
Reference in New Issue
Block a user