Поставьте зависимости:
npm install expo-linear-gradient react-native-reanimatedpnpm add expo-linear-gradient react-native-reanimatedyarn add expo-linear-gradient react-native-reanimatedbun add expo-linear-gradient react-native-reanimatedСкопируйте эти файлы в src/shared/components/organisms/progress/:
Проверьте алиас путей. Импорты в коде выше записаны так, как их пишет astra-rn add: @/shared/components, @/shared/utils и @/shared/hooks. Нужен алиас "@/*": ["./src/*"] в tsconfig.json — или поправьте импорты под свои пути.
import { AnimatedProgressBar } from "@/shared/components/organisms/progress";
import React, { useMemo, useRef, useState } from "react";
import { Pressable, StyleSheet, Text, View } from "react-native";
import { Showcase, useAutoplay, useCustomize } from "~/showcase";
const AUTOPLAY_STEPS: [number, number][] = [
[0.1, 220],
[0.2, 220],
[0.3, 700],
[0.4, 200],
[0.5, 200],
[0.6, 200],
[0.7, 200],
[0.8, 200],
[0.9, 450],
[0.8, 230],
[0.7, 230],
[0.6, 230],
[0.5, 230],
[0.4, 230],
[0.3, 230],
[0.2, 230],
[0.1, 230],
[0, 900],
];
const CUSTOMIZE = [
{ key: "colorFrom", label: "Цвет начала", type: "color", default: "#FFF3BF" },
{ key: "colorTo", label: "Цвет конца", type: "color", default: "#FFD43B" },
{ key: "gradient", label: "Градиент", type: "toggle", default: true },
{ key: "track", label: "Цвет дорожки", type: "color", default: "#e0e0e0" },
{ key: "height", label: "Толщина", type: "slider", min: 2, max: 32, step: 1, unit: "px", default: 10 },
{ key: "radius", label: "Скругление", type: "slider", min: 0, max: 99, step: 1, unit: "px", default: 99 },
{ key: "duration", label: "Анимация", type: "slider", min: 100, max: 2000, step: 50, unit: "ms", default: 800 },
{ key: "percent", label: "Проценты", type: "toggle", default: false },
{ key: "tempo", label: "Темп автопоказа", type: "slider", min: 0.5, max: 3, step: 0.1, default: 1 },
] as const;
export default function ProgressScreen() {
const [progress, setProgress] = useState<number>(0);
const custom = useCustomize(CUSTOMIZE);
const tempo = useRef(custom.tempo);
tempo.current = custom.tempo;
const { colorFrom, colorTo } = custom;
const gradientColors = useMemo(() => [colorFrom, colorTo], [colorFrom, colorTo]);
useAutoplay(async ({ wait }) => {
setProgress(0);
await wait(500 / tempo.current);
for (const [value, delay] of AUTOPLAY_STEPS) {
setProgress(value);
await wait(delay / tempo.current);
}
});
return (
<Showcase>
<View style={styles.container}>
<AnimatedProgressBar
progress={progress}
containerStyle={{
padding: 50,
width: "100%",
}}
useGradient={custom.gradient}
gradientColors={gradientColors}
progressColor={custom.gradient ? undefined : colorTo}
trackColor={custom.track}
height={custom.height}
animationDuration={custom.duration}
showPercentage={custom.percent}
percentageTextStyle={PERCENT_TEXT}
borderRadius={custom.radius}
/>
<View style={styles.row}>
<Pressable
style={styles.button}
onPress={() => setProgress((v) => v + 0.1)}
>
<Text style={styles.buttonText}>+1</Text>
</Pressable>
<Pressable
style={styles.button}
onPress={() => setProgress((v) => v - 0.1)}
>
<Text style={styles.buttonText}>-1</Text>
</Pressable>
</View>
</View>
</Showcase>
);
}
const PERCENT_TEXT = { color: "#fff" };
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#0a0a0a",
justifyContent: "center",
alignItems: "center",
},
button: {
paddingHorizontal: 16,
paddingVertical: 10,
borderRadius: 12,
backgroundColor: "#1c1c1e",
},
buttonText: { color: "#fff", fontSize: 14, fontWeight: "600" },
row: { flexDirection: "row", gap: 12 },
});progressProgress value between 0 and 1
Тип number·По умолчанию 0
animationDuration?Duration of the animation in milliseconds
Тип number·По умолчанию 800
width?Width of the progress bar container
Тип number | string·По умолчанию '100%'
height?Height of the progress bar
Тип number·По умолчанию 10
progressColor?Color of the progress indicator
Тип string·По умолчанию '#2089dc'
trackColor?Color of the background track
Тип string·По умолчанию '#e0e0e0'
borderRadius?Border radius of the progress bar
Тип number·По умолчанию 4
showPercentage?Whether to show the progress percentage
Тип boolean·По умолчанию false
percentagePosition?Position of the percentage text
Тип "left" | "right" | "top" | "bottom" | "inside"·По умолчанию 'right'
percentageTextStyle?Style for the percentage text
Тип TextStyle
containerStyle?Style for the container
Тип ViewStyle
formatPercentage?Format function for the percentage display
Тип (value: number) => string·По умолчанию (value: number) => `${Math.round(value * 100)}%`
indeterminate?Whether to use indeterminate animation style for unknown progress
Тип boolean·По умолчанию false
pulsate?Whether to show the pulse animation effect
Тип boolean·По умолчанию false
useGradient?Whether to use a gradient for the progress bar
Тип boolean·По умолчанию false
gradientColors?Colors for gradient (requires useGradient to be true)
Тип string[]·По умолчанию ['#4dabf7', '#3b5bdb']
onAnimationComplete?Optional callback when animation completes
Тип () => void