Components
Card
Card component for React Native.
Installation
npx rn-glow add card
🔲 CardHeader
Props
Prop | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | undefined | Content inside the card header (e.g., title, subtitle). |
style | ViewStyle | undefined | Custom style for the header container. |
spacing | "sm" | "md" | "lg" | "md" | Vertical spacing between children. |
align | "left" | "center" | "right" | "left" | Horizontal alignment of content. |
🏷️ CardTitle
Props
Prop | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | required | Title text or element. |
style | TextStyle | undefined | Custom style for the title text. |
size | "sm" | "md" | "lg" | "xl" | "md" | Size of the title text. |
weight | "normal" | "medium" | "semibold" | "bold" | "semibold" | Font weight of the title. |
color | string | undefined | Text color of the title. |
numberOfLines | number | undefined | Max number of lines to display (text will be truncated). |
📝 CardDescription
Props
Prop | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | required | Description or subtext inside the card. |
style | TextStyle | undefined | Custom style for the description text. |
size | "xs" | "sm" | "md" | "sm" | Size of the description text. |
color | string | undefined | Text color of the description. |
numberOfLines | number | undefined | Limits the number of lines displayed. |
📦 CardContent
Props
Prop | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | undefined | Content inside the main card body. |
style | ViewStyle | undefined | Custom style for the content container. |
spacing | "sm" | "md" | "lg" | "md" | Padding between content elements. |
🧩 CardFooter
Props
Prop | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | undefined | Elements like buttons or tags at the bottom. |
style | ViewStyle | undefined | Style for the footer container. |
spacing | "sm" | "md" | "lg" | "md" | Vertical padding/margin inside the footer. |
justify | "start" | "center" | "end" | "between" | "around" | "start" | Horizontal layout of footer content. |
🚀 Full Example
import React, { forwardRef } from "react";
import {
View,
Text,
TouchableOpacity,
ViewStyle,
TextStyle,
StyleSheet,
Pressable,
ScrollView,
} from "react-native";
import { MaterialIcons, Feather, FontAwesome5 } from "@expo/vector-icons";
import {
Card,
CardHeader,
CardContent,
CardFooter,
CardTitle,
CardDescription,
theme,
} from "@/components";
const CardDemo: React.FC = () => {
return (
<ScrollView
style={demoStyles.container}
contentContainerStyle={demoStyles.content}
scrollEnabled
contentInsetAdjustmentBehavior="always"
showsVerticalScrollIndicator={false}
>
<View style={demoStyles.header}>
<View style={demoStyles.iconContainer}>
<MaterialIcons name="dashboard" size={32} color="#60a5fa" />
</View>
<Text style={demoStyles.headerTitle}>Card Component</Text>
<Text style={demoStyles.subtitle}>
Beautiful cards with animations and various styles
</Text>
</View>
<View style={demoStyles.section}>
<Text style={demoStyles.sectionTitle}>Card Variants</Text>
<Card variant="default" size="md" style={demoStyles.demoCard}>
<CardHeader spacing="md">
<View style={demoStyles.variantHeader}>
<View style={demoStyles.variantIcon}>
<Feather name="square" size={20} color="#60a5fa" />
</View>
<View>
<CardTitle size="lg" weight="semibold">
Default Card
</CardTitle>
<Text style={demoStyles.variantLabel}>Standard styling</Text>
</View>
</View>
</CardHeader>
<CardContent>
<Text style={demoStyles.cardDescription}>
The default card variant with subtle shadow and clean background.
</Text>
</CardContent>
</Card>
<Card variant="elevated" size="md" style={demoStyles.demoCard}>
<CardHeader spacing="md">
<View style={demoStyles.variantHeader}>
<View style={demoStyles.variantIcon}>
<MaterialIcons name="layers" size={20} color="#10b981" />
</View>
<View>
<CardTitle size="lg" weight="semibold">
Elevated Card
</CardTitle>
<Text style={demoStyles.variantLabel}>Enhanced depth</Text>
</View>
</View>
</CardHeader>
<CardContent>
<Text style={demoStyles.cardDescription}>
Elevated cards create more visual hierarchy with enhanced shadows.
</Text>
</CardContent>
</Card>
<Card variant="outlined" size="md" style={demoStyles.demoCard}>
<CardHeader spacing="md">
<View style={demoStyles.variantHeader}>
<View style={demoStyles.variantIcon}>
<Feather name="circle" size={20} color="#f59e0b" />
</View>
<View>
<CardTitle size="lg" weight="semibold">
Outlined Card
</CardTitle>
<Text style={demoStyles.variantLabel}>Border focus</Text>
</View>
</View>
</CardHeader>
<CardContent>
<Text style={demoStyles.cardDescription}>
Clean bordered design perfect for minimal interfaces.
</Text>
</CardContent>
</Card>
<Card variant="ghost" size="md" style={demoStyles.demoCard}>
<CardHeader spacing="md">
<View style={demoStyles.variantHeader}>
<View style={demoStyles.variantIcon}>
<Feather name="eye-off" size={20} color="#8b5cf6" />
</View>
<View>
<CardTitle size="lg" weight="semibold">
Ghost Card
</CardTitle>
<Text style={demoStyles.variantLabel}>Transparent</Text>
</View>
</View>
</CardHeader>
<CardContent>
<Text style={demoStyles.cardDescription}>
Subtle transparent background for overlaid content.
</Text>
</CardContent>
</Card>
</View>
<View style={demoStyles.section}>
<Text style={demoStyles.sectionTitle}>Animation Types</Text>
<View style={demoStyles.animationGrid}>
<Card
variant="elevated"
size="sm"
pressable
animationType="scale"
onPress={() => console.log("Scale animation")}
style={demoStyles.animationCard}
>
<CardHeader spacing="sm">
<View className="items-center justify-center gap-3 mt-3">
<View style={demoStyles.animationIcon}>
<Feather name="maximize-2" size={20} color="#60a5fa" />
</View>
<CardTitle size="md" weight="medium">
Scale
</CardTitle>
</View>
</CardHeader>
</Card>
<Card
variant="elevated"
size="sm"
pressable
animationType="fade"
onPress={() => console.log("Fade animation")}
style={demoStyles.animationCard}
>
<CardHeader spacing="sm">
<View className="items-center justify-center gap-3 mt-3">
<View style={demoStyles.animationIcon}>
<Feather name="sun" size={16} color="#f59e0b" />
</View>
<CardTitle size="md" weight="medium">
Fade
</CardTitle>
</View>
</CardHeader>
</Card>
<Card
variant="elevated"
size="sm"
pressable
animationType="bounce"
onPress={() => console.log("Bounce animation")}
style={demoStyles.animationCard}
>
<CardHeader spacing="sm">
<View className="items-center justify-center gap-3 mt-3">
<View style={demoStyles.animationIcon}>
<MaterialIcons
name="sports-basketball"
size={16}
color="#10b981"
/>
</View>
<CardTitle size="md" weight="medium">
Bounce
</CardTitle>
</View>
</CardHeader>
</Card>
<Card
variant="elevated"
size="sm"
pressable
animationType="slide"
onPress={() => console.log("Slide animation")}
style={demoStyles.animationCard}
>
<CardHeader spacing="sm">
<View className="items-center justify-center gap-3 mt-3">
<View style={demoStyles.animationIcon}>
<Feather name="move" size={16} color="#8b5cf6" />
</View>
<CardTitle size="md" weight="medium">
Slide
</CardTitle>
</View>
</CardHeader>
</Card>
</View>
</View>
<View style={demoStyles.section}>
<Text style={demoStyles.sectionTitle}>Real-world Examples</Text>
<Card
variant="elevated"
size="lg"
pressable
animationType="scale"
onPress={() => console.log("Profile pressed")}
style={demoStyles.demoCard}
>
<CardHeader spacing="lg">
<View style={demoStyles.profileHeader}>
<View style={demoStyles.avatar}>
<FontAwesome5 name="user-circle" size={48} color="#60a5fa" />
</View>
<View style={demoStyles.profileInfo}>
<CardTitle size="xl" weight="bold">
Alex Chen
</CardTitle>
<CardDescription size="md">
Senior Frontend Developer
</CardDescription>
<Text style={demoStyles.companyText}>@ TechFlow Inc.</Text>
</View>
<View style={demoStyles.statusBadge}>
<View style={demoStyles.statusDot} />
<Text style={demoStyles.statusText}>Online</Text>
</View>
</View>
</CardHeader>
<CardContent spacing="md">
<View style={demoStyles.statsContainer}>
<View style={demoStyles.statItem}>
<Feather name="code" size={16} color="#10b981" />
<Text style={demoStyles.statNumber}>127</Text>
<Text style={demoStyles.statLabel}>Projects</Text>
</View>
<View style={demoStyles.statItem}>
<Feather name="users" size={16} color="#f59e0b" />
<Text style={demoStyles.statNumber}>2.4k</Text>
<Text style={demoStyles.statLabel}>Followers</Text>
</View>
<View style={demoStyles.statItem}>
<Feather name="star" size={16} color="#8b5cf6" />
<Text style={demoStyles.statNumber}>4.9</Text>
<Text style={demoStyles.statLabel}>Rating</Text>
</View>
</View>
</CardContent>
</Card>
<Card
variant="outlined"
size="md"
pressable
animationType="bounce"
onPress={() => console.log("Article pressed")}
style={demoStyles.demoCard}
>
<CardHeader spacing="md">
<View style={demoStyles.articleMeta}>
<View style={demoStyles.categoryTag}>
<Text style={demoStyles.categoryText}>TECH</Text>
</View>
<Text style={demoStyles.readTime}>∙ 8 min read</Text>
</View>
<CardTitle size="lg" weight="semibold" numberOfLines={2}>
The Future of React Native Development
</CardTitle>
<CardDescription size="md" numberOfLines={2}>
Exploring the latest trends and innovations shaping mobile
development
</CardDescription>
</CardHeader>
<CardFooter justify="between" spacing="md">
<Text style={demoStyles.articleDate}>March 20, 2024</Text>
<View style={demoStyles.articleActions}>
<View style={demoStyles.actionItem}>
<Feather name="heart" size={16} color="#ef4444" />
<Text style={demoStyles.actionCount}>142</Text>
</View>
<View style={demoStyles.actionItem}>
<Feather name="message-circle" size={16} color="#60a5fa" />
<Text style={demoStyles.actionCount}>23</Text>
</View>
<View style={demoStyles.actionItem}>
<Feather name="share" size={16} color="#10b981" />
<Text style={demoStyles.actionCount}>8</Text>
</View>
</View>
</CardFooter>
</Card>
<Card
variant="elevated"
size="lg"
interactive
animationType="fade"
style={demoStyles.demoCard}
>
<CardHeader spacing="md">
<View style={demoStyles.dashboardHeader}>
<View style={demoStyles.dashboardIcon}>
<MaterialIcons name="trending-up" size={24} color="#10b981" />
</View>
<View>
<CardTitle size="lg" weight="bold">
Revenue Analytics
</CardTitle>
<CardDescription>Monthly performance overview</CardDescription>
</View>
</View>
</CardHeader>
<CardContent spacing="lg">
<View style={demoStyles.metricsGrid}>
<View style={demoStyles.metricCard}>
<Text style={demoStyles.metricValue}>$24.5k</Text>
<Text style={demoStyles.metricLabel}>Total Revenue</Text>
<View style={demoStyles.metricChange}>
<Feather name="trending-up" size={12} color="#10b981" />
<Text style={demoStyles.metricChangeText}>+12.5%</Text>
</View>
</View>
<View style={demoStyles.metricCard}>
<Text style={demoStyles.metricValue}>1,847</Text>
<Text style={demoStyles.metricLabel}>New Users</Text>
<View style={demoStyles.metricChange}>
<Feather name="trending-up" size={12} color="#10b981" />
<Text style={demoStyles.metricChangeText}>+8.2%</Text>
</View>
</View>
</View>
</CardContent>
</Card>
<Card
variant="default"
size="md"
pressable
animationType="slide"
onPress={() => console.log("Feature pressed")}
style={demoStyles.demoCard}
>
<CardHeader spacing="md">
<View style={demoStyles.featureHeader}>
<View style={demoStyles.featureIconLarge}>
<Feather name="zap" size={28} color="#f59e0b" />
</View>
<View>
<CardTitle size="xl" weight="bold">
Lightning Fast
</CardTitle>
<CardDescription size="md">
Optimized performance
</CardDescription>
</View>
</View>
</CardHeader>
<CardContent spacing="md">
<Text style={demoStyles.featureDescription}>
Experience blazing-fast load times with our advanced optimization
techniques and intelligent caching mechanisms.
</Text>
<View style={demoStyles.featureStats}>
<View style={demoStyles.featureStat}>
<Text style={demoStyles.featureStatNumber}>99.9%</Text>
<Text style={demoStyles.featureStatLabel}>Uptime</Text>
</View>
<View style={demoStyles.featureStat}>
<Text style={demoStyles.featureStatNumber}><50ms</Text>
<Text style={demoStyles.featureStatLabel}>Response</Text>
</View>
</View>
</CardContent>
</Card>
</View>
<View style={demoStyles.section}>
<Text style={demoStyles.sectionTitle}>Interactive States</Text>
<Card
variant="elevated"
size="md"
loading={true}
style={demoStyles.demoCard}
>
<CardHeader spacing="md">
<CardTitle size="lg" weight="semibold">
Loading State
</CardTitle>
<CardDescription>Card with loading overlay</CardDescription>
</CardHeader>
<CardContent>
<Text
style={[demoStyles.cardDescription, { top: 10, marginTop: 10 }]}
>
This card demonstrates the loading state with animated spinner.
</Text>
</CardContent>
</Card>
<Card
variant="outlined"
size="md"
disabled={true}
style={demoStyles.demoCard}
>
<CardHeader spacing="md">
<CardTitle size="lg" weight="semibold">
Disabled State
</CardTitle>
<CardDescription>Card with disabled styling</CardDescription>
</CardHeader>
<CardContent>
<Text style={demoStyles.cardDescription}>
This card is disabled and shows reduced opacity.
</Text>
</CardContent>
</Card>
</View>
<View style={demoStyles.footer}>
<View style={demoStyles.footerIcon}>
<MaterialIcons name="dashboard" size={16} color="#71717a" />
</View>
<Text style={demoStyles.footerText}>
The Card component provides flexible layouts with beautiful animations
and consistent theming
</Text>
</View>
</ScrollView>
);
};
const demoStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#09090b",
},
content: {
padding: 24,
paddingBottom: 48,
},
header: {
alignItems: "center",
marginBottom: 32,
paddingTop: 20,
},
iconContainer: {
width: 64,
height: 64,
borderRadius: 32,
backgroundColor: "#18181b",
alignItems: "center",
justifyContent: "center",
marginBottom: 16,
borderWidth: 1,
borderColor: "#27272a",
},
headerTitle: {
fontSize: 28,
color: "#fafafa",
textAlign: "center",
fontWeight: "700",
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: "#a1a1aa",
textAlign: "center",
lineHeight: 24,
maxWidth: 320,
},
section: {
marginBottom: 32,
},
sectionTitle: {
fontSize: 18,
fontWeight: "600",
color: "#e4e4e7",
marginBottom: 16,
marginLeft: 4,
},
demoCard: {
marginBottom: 16,
backgroundColor: "rgba(24, 24, 27, 0.5)",
},
variantHeader: {
flexDirection: "row",
alignItems: "center",
},
variantIcon: {
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: "#09090b",
alignItems: "center",
justifyContent: "center",
marginRight: 12,
},
variantLabel: {
fontSize: 14,
color: "#a1a1aa",
marginTop: 2,
},
cardDescription: {
fontSize: 14,
color: "#a1a1aa",
lineHeight: 20,
},
animationGrid: {
flexDirection: "row",
flexWrap: "wrap",
gap: 12,
},
animationCard: {
flex: 1,
minWidth: "47%",
alignItems: "center",
backgroundColor: "#141414",
},
animationIcon: {
width: 42,
height: 42,
borderRadius: 16,
backgroundColor: "#09090b",
alignItems: "center",
justifyContent: "center",
},
profileHeader: {
flexDirection: "row",
alignItems: "flex-start",
},
avatar: {
marginRight: 16,
},
profileInfo: {
flex: 1,
},
companyText: {
fontSize: 14,
color: "#71717a",
marginTop: 4,
},
statusBadge: {
flexDirection: "row",
alignItems: "center",
backgroundColor: "#18181b",
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 12,
borderWidth: 1,
borderColor: "#27272a",
},
statusDot: {
width: 6,
height: 6,
borderRadius: 3,
backgroundColor: "#10b981",
marginRight: 6,
},
statusText: {
fontSize: 12,
color: "#10b981",
fontWeight: "500",
},
statsContainer: {
flexDirection: "row",
justifyContent: "space-around",
},
statItem: {
alignItems: "center",
flex: 1,
},
statNumber: {
fontSize: 18,
color: "#fafafa",
fontWeight: "700",
marginTop: 4,
},
statLabel: {
fontSize: 12,
color: "#71717a",
marginTop: 2,
},
articleMeta: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
marginBottom: 12,
},
categoryTag: {
backgroundColor: "#60a5fa",
paddingHorizontal: 4,
paddingVertical: 4,
borderRadius: 8,
width: 50,
alignItems: "center",
},
categoryText: {
fontSize: 8,
color: "#fafafa",
fontWeight: "700",
letterSpacing: 1,
},
readTime: {
fontSize: 12,
color: "#71717a",
marginLeft: 4,
},
articleDate: {
fontSize: 12,
color: "#71717a",
},
articleActions: {
flexDirection: "row",
alignItems: "center",
gap: 16,
},
actionItem: {
flexDirection: "row",
alignItems: "center",
gap: 4,
},
actionCount: {
fontSize: 12,
color: "#71717a",
},
dashboardHeader: {
flexDirection: "row",
alignItems: "center",
},
dashboardIcon: {
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: "#09090b",
alignItems: "center",
justifyContent: "center",
marginRight: 16,
},
metricsGrid: {
flexDirection: "row",
gap: 16,
},
metricCard: {
flex: 1,
backgroundColor: "#09090b",
padding: 16,
borderRadius: 8,
borderWidth: 1,
borderColor: "#27272a",
},
metricValue: {
fontSize: 20,
color: "#fafafa",
fontWeight: "700",
},
metricLabel: {
fontSize: 12,
color: "#71717a",
marginTop: 4,
},
metricChange: {
flexDirection: "row",
alignItems: "center",
marginTop: 8,
gap: 4,
},
metricChangeText: {
fontSize: 12,
color: "#10b981",
fontWeight: "500",
},
featureHeader: {
flexDirection: "row",
alignItems: "center",
},
featureIconLarge: {
width: 56,
height: 56,
borderRadius: 28,
backgroundColor: "#09090b",
alignItems: "center",
justifyContent: "center",
marginRight: 16,
},
featureDescription: {
fontSize: 14,
color: "#a1a1aa",
lineHeight: 22,
marginBottom: 16,
},
featureStats: {
flexDirection: "row",
gap: 24,
},
featureStat: {
alignItems: "center",
},
featureStatNumber: {
fontSize: 16,
color: "#10b981",
fontWeight: "700",
},
featureStatLabel: {
fontSize: 12,
color: "#71717a",
marginTop: 2,
},
footer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
marginTop: 16,
padding: 16,
backgroundColor: "#18181b",
borderRadius: 8,
borderWidth: 1,
borderColor: "#27272a",
},
footerIcon: {
marginRight: 8,
},
footerText: {
fontSize: 14,
color: "#a1a1aa",
textAlign: "center",
flex: 0,
lineHeight: 20,
},
});
export default CardDemo;