Introduction
Components
- Accordion
- Action Sheet
- Alert
- Audio Player
- Audio Recorder
- Audio Waveform
- Avatar
- Badge
- BottomSheet
- Button
- Camera
- Camera Preview
- Card
- Carousel
- Checkbox
- Collapsible
- Color Picker
- Combobox
- Date Picker
- File Picker
- Gallery
- Hello Wave
- Icon
- Image
- Input
- Input OTP
- Link
- MediaPicker
- Mode Toggle
- Onboarding
- ParallaxScrollView
- Picker
- Popover
- Progress
- Radio
- ScrollView
- SearchBar
- Separator
- Share
- Sheet
- Skeleton
- Spinner
- Switch
- Table
- Tabs
- Text
- Toast
- Toggle
- Video
- View
Charts
import { Icon } from '@/components/ui/icon';
import { Heart } from 'lucide-react-native';
import React from 'react';
export function IconDemo() {
return <Icon name={Heart} size={24} />;
}
Installation
pnpm dlx bna-ui add icon
Usage
import { Icon } from '@/components/ui/icon';
import { Heart, Star, Home } from 'lucide-react-native';
<Icon name={Heart} size={24} />
<Icon name={Star} color="#FFD700" />
<Icon name={Home} lightColor="#000" darkColor="#fff" />
Examples
Default
import { Icon } from '@/components/ui/icon';
import { Heart } from 'lucide-react-native';
import React from 'react';
export function IconDemo() {
return <Icon name={Heart} size={24} />;
}
Sizes
import { Icon } from '@/components/ui/icon';
import { View } from '@/components/ui/view';
import { Star } from 'lucide-react-native';
import React from 'react';
export function IconSizes() {
const sizes = [16, 20, 24, 32, 40, 48];
return (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
gap: 16,
flexWrap: 'wrap',
}}
>
{sizes.map((size) => (
<Icon key={size} name={Star} size={size} color='#FFD700' />
))}
</View>
);
}
Colors
import { Icon } from '@/components/ui/icon';
import { View } from '@/components/ui/view';
import { Circle } from 'lucide-react-native';
import React from 'react';
export function IconColors() {
const colors = [
'#FF6B6B', // Red
'#4ECDC4', // Teal
'#45B7D1', // Blue
'#96CEB4', // Green
'#FECA57', // Yellow
'#FF9FF3', // Pink
'#54A0FF', // Light Blue
'#5F27CD', // Purple
];
return (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
gap: 12,
flexWrap: 'wrap',
}}
>
{colors.map((color, index) => (
<Icon
key={index}
name={Circle}
size={24}
color={color}
fill={color}
fillOpacity={0.2}
/>
))}
</View>
);
}
Stroke Weights
import { Icon } from '@/components/ui/icon';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Zap } from 'lucide-react-native';
import React from 'react';
export function IconStroke() {
const strokeWeights = [
{ weight: 1, label: 'Light' },
{ weight: 1.5, label: 'Regular' },
{ weight: 2, label: 'Medium' },
{ weight: 2.5, label: 'Bold' },
];
return (
<View style={{ gap: 16 }}>
{strokeWeights.map(({ weight, label }) => (
<View
key={weight}
style={{
flexDirection: 'row',
alignItems: 'center',
gap: 12,
}}
>
<Icon name={Zap} size={24} strokeWidth={weight} color='#F39C12' />
<Text variant='body' style={{ minWidth: 60 }}>
{label}
</Text>
</View>
))}
</View>
);
}
Interactive Icons
import { Button } from '@/components/ui/button';
import { Icon } from '@/components/ui/icon';
import { View } from '@/components/ui/view';
import { Bookmark, Heart, Share, ThumbsUp } from 'lucide-react-native';
import React, { useState } from 'react';
export function IconInteractive() {
const [liked, setLiked] = useState(false);
const [thumbsUp, setThumbsUp] = useState(false);
const [bookmarked, setBookmarked] = useState(false);
const iconButtons = [
{
icon: Heart,
active: liked,
onPress: () => setLiked(!liked),
activeColor: '#FF6B6B',
inactiveColor: '#888',
},
{
icon: ThumbsUp,
active: thumbsUp,
onPress: () => setThumbsUp(!thumbsUp),
activeColor: '#4ECDC4',
inactiveColor: '#888',
},
{
icon: Bookmark,
active: bookmarked,
onPress: () => setBookmarked(!bookmarked),
activeColor: '#FECA57',
inactiveColor: '#888',
},
{
icon: Share,
active: false,
onPress: () => {},
activeColor: '#45B7D1',
inactiveColor: '#888',
},
];
return (
<View
style={{
flexDirection: 'row',
gap: 20,
alignItems: 'center',
}}
>
{iconButtons.map(
({ icon, active, onPress, activeColor, inactiveColor }, index) => (
<Button key={index} variant='ghost' size='icon' onPress={onPress}>
<Icon
name={icon}
size={24}
color={active ? activeColor : inactiveColor}
fill={active ? activeColor : 'transparent'}
fillOpacity={active ? 0.2 : 0}
/>
</Button>
)
)}
</View>
);
}
Icon Grid
import { Icon } from '@/components/ui/icon';
import { View } from '@/components/ui/view';
import {
Bell,
Calendar,
Camera,
Download,
Edit,
Heart,
Home,
Mail,
Minus,
Plus,
Search,
Settings,
Star,
Trash,
Upload,
User,
} from 'lucide-react-native';
import React from 'react';
export function IconGrid() {
const icons = [
Home,
Search,
Bell,
User,
Settings,
Heart,
Star,
Mail,
Calendar,
Camera,
Download,
Upload,
Edit,
Trash,
Plus,
Minus,
];
return (
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
gap: 16,
}}
>
{icons.map((IconComponent, index) => (
<View
key={index}
style={{
padding: 12,
backgroundColor: '#f8f9fa',
borderRadius: 8,
alignItems: 'center',
justifyContent: 'center',
width: 48,
height: 48,
}}
>
<Icon name={IconComponent} size={20} color='#495057' />
</View>
))}
</View>
);
}
Themed Icons
import { Icon } from '@/components/ui/icon';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Monitor, Moon, Palette, Sun } from 'lucide-react-native';
import React from 'react';
export function IconThemed() {
const themedIcons = [
{
icon: Sun,
label: 'Light Theme',
lightColor: '#FFA500',
darkColor: '#FFD700',
},
{
icon: Moon,
label: 'Dark Theme',
lightColor: '#4A5568',
darkColor: '#E2E8F0',
},
{
icon: Monitor,
label: 'System',
lightColor: '#2D3748',
darkColor: '#F7FAFC',
},
{
icon: Palette,
label: 'Custom',
lightColor: '#E53E3E',
darkColor: '#FC8181',
},
];
return (
<View style={{ gap: 16 }}>
{themedIcons.map(({ icon, label, lightColor, darkColor }, index) => (
<View
key={index}
style={{
flexDirection: 'row',
alignItems: 'center',
gap: 12,
}}
>
<Icon
name={icon}
size={24}
lightColor={lightColor}
darkColor={darkColor}
/>
<Text variant='body'>{label}</Text>
</View>
))}
</View>
);
}
API Reference
Icon
The main icon component that renders Lucide React Native icons with theming support.
Prop | Type | Default | Description |
---|---|---|---|
name | React.ComponentType<LucideProps> | - | The Lucide icon component to render. |
size | number | 24 | The size of the icon in pixels. |
color | string | - | Custom color for the icon. |
lightColor | string | - | Color to use in light theme. |
darkColor | string | - | Color to use in dark theme. |
strokeWidth | number | 1.8 | The stroke width of the icon. |
...rest | LucideProps | - | Additional props passed to the Lucide icon component. |
LucideProps
The Icon component accepts all props from Lucide React Native icons:
Prop | Type | Default | Description |
---|---|---|---|
strokeLinecap | string | round | The line cap style for strokes. |
strokeLinejoin | string | - | The line join style for strokes. |
fill | string | - | Fill color for the icon. |
fillOpacity | number | - | Opacity of the fill color. |
strokeOpacity | number | - | Opacity of the stroke color. |
Accessibility
The Icon component is built with accessibility in mind:
- Icons are decorative by default and hidden from screen readers
- When icons convey important information, wrap them with accessible text
- Proper color contrast for themed icons
- Supports dynamic text sizing through size prop
Common Icon Patterns
With Labels
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
<Icon name={Heart} size={16} />
<Text>Favorites</Text>
</View>;
As Buttons
import { Pressable } from 'react-native';
<Pressable onPress={handlePress}>
<Icon name={Settings} size={24} />
</Pressable>;
Navigation Icons
<View style={{ flexDirection: 'row', justifyContent: 'space-around' }}>
<Icon name={Home} />
<Icon name={Search} />
<Icon name={Bell} />
<Icon name={User} />
</View>