Usage
import { ThemeIcon } from '@kivora/react';
import { Bell } from 'lucide-react';
<ThemeIcon color="primary" variant="light">
<Bell size={20} />
</ThemeIcon>
Examples
Basic Icon
import { Bell } from 'lucide-react';
<ThemeIcon>
<Bell size={20} />
</ThemeIcon>
Colors
<ThemeIcon color="primary">
<Bell size={20} />
</ThemeIcon>
Variants
<ThemeIcon color="primary" variant="filled">
<Bell size={20} />
</ThemeIcon>
Sizes
<ThemeIcon size="xs">
<Bell size={12} />
</ThemeIcon>
Border Radius
<ThemeIcon radius="sm">
<Bell size={20} />
</ThemeIcon>
Status Indicators
<div className="flex gap-3">
<ThemeIcon color="success" variant="light" size="lg">
<Check size={24} />
</ThemeIcon>
<ThemeIcon color="warning" variant="light" size="lg">
<AlertTriangle size={24} />
</ThemeIcon>
<ThemeIcon color="error" variant="light" size="lg">
<X size={24} />
</ThemeIcon>
<ThemeIcon color="info" variant="light" size="lg">
<Info size={24} />
</ThemeIcon>
</div>
Feature Cards
import { Zap, Shield, Globe } from 'lucide-react';
function FeatureCards() {
const features = [
{
icon: Zap,
color: 'warning',
title: 'Fast Performance',
description: 'Lightning-fast load times',
},
{
icon: Shield,
color: 'success',
title: 'Secure',
description: 'Enterprise-grade security',
},
{
icon: Globe,
color: 'info',
title: 'Global',
description: 'Available worldwide',
},
];
return (
<div className="grid grid-cols-3 gap-4">
{features.map((feature, i) => (
<Card key={i}>
<ThemeIcon
color={feature.color}
variant="light"
size="lg"
className="mb-3"
>
<feature.icon size={24} />
</ThemeIcon>
<h3 className="font-semibold mb-1">{feature.title}</h3>
<p className="text-sm text-muted-foreground">
{feature.description}
</p>
</Card>
))}
</div>
);
}
import { Edit, Trash, Share } from 'lucide-react';
<div className="flex gap-2">
<button className="hover:scale-110 transition-transform">
<ThemeIcon color="info" variant="light" size="md">
<Edit size={16} />
</ThemeIcon>
</button>
<button className="hover:scale-110 transition-transform">
<ThemeIcon color="error" variant="light" size="md">
<Trash size={16} />
</ThemeIcon>
</button>
<button className="hover:scale-110 transition-transform">
<ThemeIcon color="success" variant="light" size="md">
<Share size={16} />
</ThemeIcon>
</button>
</div>
Notification Badge
import { Bell } from 'lucide-react';
<div className="relative inline-block">
<ThemeIcon color="primary" variant="light" size="lg">
<Bell size={24} />
</ThemeIcon>
<span className="absolute -top-1 -right-1 flex h-5 w-5 items-center justify-center rounded-full bg-error text-white text-xs font-semibold">
3
</span>
</div>
All Combinations
const colors = ['primary', 'success', 'warning', 'error', 'info'];
const variants = ['filled', 'light', 'outline'];
<div className="space-y-4">
{variants.map(variant => (
<div key={variant}>
<h4 className="text-sm font-medium mb-2 capitalize">{variant}</h4>
<div className="flex gap-2">
{colors.map(color => (
<ThemeIcon key={color} color={color} variant={variant}>
<Bell size={20} />
</ThemeIcon>
))}
</div>
</div>
))}
</div>
Props
Icon element (typically an SVG icon from lucide-react or similar)
color
'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | 'muted'
default:"primary"
Theme color
variant
'filled' | 'light' | 'outline'
default:"light"
Style variant:
filled: Solid background with contrasting text
light: Subtle translucent background
outline: Border with transparent background
size
'xs' | 'sm' | 'md' | 'lg' | 'xl'
default:"md"
Container size (automatically sizes icon inside)
radius
'sm' | 'md' | 'lg' | 'full'
default:"md"
Border radius:
sm: Small rounded corners
md: Medium rounded corners
lg: Large rounded corners
full: Circular
Icon Sizing
ThemeIcon automatically constrains child icon size based on the size prop:
xs: Icon should be ~12-14px
sm: Icon should be ~16px
md: Icon should be ~20px
lg: Icon should be ~24px
xl: Icon should be ~32px
The component applies sizing via CSS, so icons will be constrained even if you specify a different size.
Accessibility
- Rendered as a
<span> element for semantic correctness
- When used as a button, wrap in a
<button> element
- Include appropriate
aria-label on parent button when interactive
- Decorative icons should have
aria-hidden="true"
Best Practices
- Use consistent variant across similar elements
- Match icon size to container size for proper proportions
- Use
filled variant sparingly for primary actions
- Prefer
light variant for most UI elements
- Use
outline variant for subtle emphasis
- Choose colors that convey meaning (success = green, error = red, etc.)
- Use
radius="full" for profile pictures or avatars