Components
Progress
Progress component for React Native.
Installation
npx rn-glow add progress
📶 AnimatedProgressBarProps
Prop | Type | Default |
---|---|---|
onAnimationComplete? | () => void | - |
gradientColors? | string[] | ['#4dabf7', '#3b5bdb'] |
useGradient? | boolean | false |
pulsate? | boolean | false |
indeterminate? | boolean | false |
formatPercentage? | (value: number) => string | (value) => `${Math.round(value * 100)}%` |
containerStyle? | ViewStyle | - |
percentageTextStyle? | TextStyle | - |
percentagePosition? | "left" | "right" | "top" | "bottom" | "inside" | 'right' |
showPercentage? | boolean | false |
borderRadius? | number | 4 |
trackColor? | string | '#e0e0e0' |
progressColor? | string | '#2089dc' |
height? | number | 10 |
width? | number | string | '100%' |
animationDuration? | number | 800 |
progress | number | 0 |
🚀 Example
import React, { useState, useEffect } from "react";
import {
View,
StyleSheet,
TouchableOpacity,
ScrollView,
Text,
SafeAreaView,
Dimensions,
} from "react-native";
import { AnimatedProgressBar } from "@/components/organisms/progress/AnimatedProgress";
import { Ionicons, MaterialIcons, Feather } from "@expo/vector-icons";
const { width: screenWidth } = Dimensions.get("window");
const ProgressDemo: React.FC = () => {
const [progress, setProgress] = useState<number>(0);
const [isAnimating, setIsAnimating] = useState<boolean>(false);
const handleReset = () => {
setProgress(0);
setIsAnimating(false);
};
const handleIncrement = () => {
setProgress((prev) => Math.min(prev + 0.1, 1));
};
const handleDecrement = () => {
setProgress((prev) => Math.max(prev - 0.1, 0));
};
const handleAnimate = () => {
setIsAnimating(true);
setProgress(0);
const interval = setInterval(() => {
setProgress((prev) => {
if (prev >= 1) {
clearInterval(interval);
setIsAnimating(false);
return 1;
}
return prev + 0.02;
});
}, 50);
};
return (
<ScrollView
style={styles.container}
contentContainerStyle={styles.contentContainer}
scrollEnabled
showsVerticalScrollIndicator={false}
contentInsetAdjustmentBehavior="always"
>
<SafeAreaView style={styles.safeArea}>
<View style={styles.header}>
<View style={styles.titleContainer}>
<Ionicons name="bar-chart" size={32} color="#8b5cf6" />
<Text style={styles.title}>Progress Components</Text>
</View>
<Text style={styles.subtitle}>
Beautifully designed progress indicators
</Text>
</View>
<View style={styles.card}>
<View style={styles.cardHeader}>
<View style={styles.cardTitleContainer}>
<Feather name="activity" size={20} color="#ffffff" />
<Text style={styles.cardTitle}>Basic Progress</Text>
</View>
<Text style={styles.cardDescription}>
A simple progress bar with smooth animations
</Text>
</View>
<View style={styles.progressContainer}>
<View style={styles.progressBarContainer}>
<AnimatedProgressBar
progress={progress}
width="100%"
height={8}
progressColor="#ffffff"
trackColor="#1e1e1e"
borderRadius={12}
animationDuration={600}
/>
</View>
<View style={styles.progressTextContainer}>
<Text style={styles.progressText}>
{Math.round(progress * 100)}%
</Text>
</View>
</View>
</View>
<View style={styles.card}>
<View style={styles.cardHeader}>
<View style={styles.cardTitleContainer}>
<MaterialIcons name="gradient" size={20} color="#8b5cf6" />
<Text style={styles.cardTitle}>Gradient Progress</Text>
</View>
<Text style={styles.cardDescription}>
Enhanced with beautiful gradient colors
</Text>
</View>
<View style={styles.progressContainer}>
<View style={styles.progressBarContainer}>
<AnimatedProgressBar
progress={progress}
width="100%"
height={12}
useGradient={true}
gradientColors={["#8b5cf6", "#06b6d4"]}
trackColor="#262626"
borderRadius={16}
animationDuration={800}
/>
</View>
<View style={styles.progressTextContainer}>
<Text style={styles.progressText}>
{Math.round(progress * 100)}%
</Text>
</View>
</View>
</View>
<View style={styles.card}>
<View style={styles.cardHeader}>
<View style={styles.cardTitleContainer}>
<Ionicons name="pulse" size={20} color="#f59e0b" />
<Text style={styles.cardTitle}>Pulsating Progress</Text>
</View>
<Text style={styles.cardDescription}>
With subtle pulsing animation effect
</Text>
</View>
<View style={styles.progressContainer}>
<View style={styles.progressBarContainer}>
<AnimatedProgressBar
progress={progress}
width="100%"
height={10}
pulsate={true}
useGradient={true}
gradientColors={["#f59e0b", "#ef4444"]}
trackColor="#1f1f1f"
borderRadius={14}
animationDuration={1000}
/>
</View>
<View style={styles.progressTextContainer}>
<Text style={styles.progressText}>
{Math.round(progress * 100)}%
</Text>
</View>
</View>
</View>
<View style={styles.card}>
<View style={styles.cardHeader}>
<View style={styles.cardTitleContainer}>
<MaterialIcons name="line-weight" size={20} color="#10b981" />
<Text style={styles.cardTitle}>Thick Progress</Text>
</View>
<Text style={styles.cardDescription}>
Larger size for better visibility
</Text>
</View>
<View style={styles.progressContainer}>
<View style={styles.progressBarContainer}>
<AnimatedProgressBar
progress={progress}
width="100%"
height={20}
useGradient={true}
gradientColors={["#10b981", "#059669"]}
trackColor="#171717"
borderRadius={20}
animationDuration={1200}
/>
</View>
<View style={styles.progressTextContainer}>
<Text style={styles.progressTextLarge}>
{Math.round(progress * 100)}%
</Text>
</View>
</View>
</View>
<View style={styles.controlsCard}>
<View style={styles.controlsTitleContainer}>
<Ionicons name="settings" size={20} color="#ffffff" />
<Text style={styles.controlsTitle}>Controls</Text>
</View>
<View style={styles.buttonRow}>
<TouchableOpacity
style={[styles.button, styles.buttonSecondary]}
onPress={handleDecrement}
disabled={progress <= 0}
>
<Ionicons
name="remove"
size={16}
color={progress <= 0 ? "#525252" : "#ffffff"}
/>
<Text
style={[
styles.buttonText,
progress <= 0 && styles.buttonTextDisabled,
]}
>
10%
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.buttonSecondary]}
onPress={handleIncrement}
disabled={progress >= 1}
>
<Ionicons
name="add"
size={16}
color={progress >= 1 ? "#525252" : "#ffffff"}
/>
<Text
style={[
styles.buttonText,
progress >= 1 && styles.buttonTextDisabled,
]}
>
10%
</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonRow}>
<TouchableOpacity
style={[styles.button, styles.buttonPrimary]}
onPress={handleAnimate}
disabled={isAnimating}
>
<Ionicons
name="play"
size={16}
color={isAnimating ? "#525252" : "#000000"}
/>
<Text
style={[
styles.buttonTextPrimary,
isAnimating && styles.buttonTextDisabled,
]}
>
{isAnimating ? "Animating..." : "Animate"}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.buttonDestructive]}
onPress={handleReset}
>
<Ionicons name="refresh" size={16} color="#ffffff" />
<Text style={styles.buttonTextDestructive}>Reset</Text>
</TouchableOpacity>
</View>
</View>
</SafeAreaView>
</ScrollView>
);
};
const styles = StyleSheet.create({
safeArea: {
flex: 1,
backgroundColor: "#0a0a0a",
},
container: {
flex: 1,
backgroundColor: "#0a0a0a",
},
contentContainer: {
padding: 20,
paddingBottom: 40,
},
header: {
marginBottom: 32,
},
titleContainer: {
flexDirection: "row",
alignItems: "center",
gap: 12,
marginBottom: 8,
},
title: {
fontSize: 22,
fontWeight: "700",
color: "#ffffff",
letterSpacing: -0.5,
},
subtitle: {
fontSize: 16,
color: "#a1a1aa",
lineHeight: 24,
},
card: {
backgroundColor: "#111111",
borderRadius: 16,
padding: 24,
marginBottom: 20,
borderWidth: 1,
borderColor: "#1f1f1f",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 4,
},
cardHeader: {
marginBottom: 20,
},
cardTitleContainer: {
flexDirection: "row",
alignItems: "center",
gap: 8,
marginBottom: 4,
},
cardTitle: {
fontSize: 18,
fontWeight: "600",
color: "#ffffff",
},
cardDescription: {
fontSize: 14,
color: "#71717a",
lineHeight: 20,
},
progressContainer: {
flexDirection: "row",
alignItems: "center",
gap: 16,
},
progressBarContainer: {
flex: 1,
},
progressTextContainer: {
minWidth: 50,
alignItems: "flex-end",
},
progressText: {
fontSize: 14,
fontWeight: "500",
color: "#d4d4d8",
fontFamily: "monospace",
},
progressTextLarge: {
fontSize: 16,
fontWeight: "600",
color: "#d4d4d8",
fontFamily: "monospace",
},
controlsCard: {
backgroundColor: "#111111",
borderRadius: 16,
padding: 24,
marginTop: 12,
borderWidth: 1,
borderColor: "#1f1f1f",
},
controlsTitleContainer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 8,
marginBottom: 20,
},
controlsTitle: {
fontSize: 18,
fontWeight: "600",
color: "#ffffff",
},
buttonRow: {
flexDirection: "row",
gap: 12,
marginBottom: 12,
},
button: {
flex: 1,
paddingVertical: 12,
paddingHorizontal: 16,
borderRadius: 8,
alignItems: "center",
justifyContent: "center",
minHeight: 44,
flexDirection: "row",
gap: 8,
},
buttonPrimary: {
backgroundColor: "#ffffff",
},
buttonSecondary: {
backgroundColor: "#262626",
borderWidth: 1,
borderColor: "#404040",
},
buttonDestructive: {
backgroundColor: "#dc2626",
},
buttonText: {
fontSize: 14,
fontWeight: "500",
color: "#ffffff",
},
buttonTextPrimary: {
fontSize: 14,
fontWeight: "500",
color: "#000000",
},
buttonTextDestructive: {
fontSize: 14,
fontWeight: "500",
color: "#ffffff",
},
buttonTextDisabled: {
opacity: 0.5,
},
});
export default ProgressDemo;