All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m44s
52 lines
1.2 KiB
TypeScript
52 lines
1.2 KiB
TypeScript
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;
|
|
}
|