Components
Flexible icon wrapper component for SVGs and icon components. Supports size presets and custom styling. Works with any icon library.
npx shadcn@latest add https://21st.dev/r/ivlev.danich/icon-wrapperLoading preview...
import { Icon } from "@/components/ui/icon-wrapper";
const StarIcon = ({ className }: { className?: string }) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
</svg>
)
const HeartIcon = ({ className }: { className?: string }) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
</svg>
)
const CheckIcon = ({ className }: { className?: string }) => (
<svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
<polyline points="20,6 9,17 4,12" />
</svg>
)
export default function IconDemo() {
return (
<div className="flex flex-col gap-8 p-6">
{/* With Component */}
<div className="space-y-3">
<h3 className="text-sm font-medium text-zinc-500">With Component</h3>
<div className="flex items-center gap-4">
<Icon component={StarIcon} size="sm" className="text-yellow-500" />
<Icon component={HeartIcon} size="md" className="text-red-500" />
<Icon component={CheckIcon} size="lg" className="text-green-500" />
</div>
</div>
{/* With Inline SVG */}
<div className="space-y-3">
<h3 className="text-sm font-medium text-zinc-500">With Inline SVG Children</h3>
<div className="flex items-center gap-4">
<Icon size="lg" className="text-blue-500">
<svg viewBox="0 0 24 24" fill="currentColor" className="w-full h-full">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
</svg>
</Icon>
</div>
</div>
{/* Sizes */}
<div className="space-y-3">
<h3 className="text-sm font-medium text-zinc-500">Sizes</h3>
<div className="flex items-end gap-4">
<div className="flex flex-col items-center gap-1">
<Icon component={StarIcon} size="xs" className="text-zinc-600" />
<span className="text-xs text-zinc-400">xs</span>
</div>
<div className="flex flex-col items-center gap-1">
<Icon component={StarIcon} size="sm" className="text-zinc-600" />
<span className="text-xs text-zinc-400">sm</span>
</div>
<div className="flex flex-col items-center gap-1">
<Icon component={StarIcon} size="md" className="text-zinc-600" />
<span className="text-xs text-zinc-400">md</span>
</div>
<div className="flex flex-col items-center gap-1">
<Icon component={StarIcon} size="lg" className="text-zinc-600" />
<span className="text-xs text-zinc-400">lg</span>
</div>
<div className="flex flex-col items-center gap-1">
<Icon component={StarIcon} size="xl" className="text-zinc-600" />
<span className="text-xs text-zinc-400">xl</span>
</div>
</div>
</div>
{/* Emoji Fallback */}
<div className="space-y-3">
<h3 className="text-sm font-medium text-zinc-500">Emoji Fallback</h3>
<div className="flex items-center gap-4">
<Icon name="⭐" size="lg" />
<Icon name="🚀" size="lg" />
<Icon name="💡" size="lg" />
<Icon name="🎉" size="lg" />
</div>
</div>
</div>
)
}