import type { ReactElement } from 'react'; import React, { useEffect, useRef, useState } from 'react'; import { Animated } from 'react-native'; import type { StyleProp, ViewStyle, ViewProps } from 'react-native'; import { StyledWrapper, StyledInner } from './StyledProgressBar'; export interface ProgressBarProps extends ViewProps { /** * The progress completion percentage: 0-100. */ value: number; /** * Set intent for your progress. */ intent?: | 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'archived' | 'primary-inverted' | 'success-inverted' | 'warning-inverted' | 'danger-inverted' | 'info-inverted' | 'archived-inverted'; /** * Additional style. */ style?: StyleProp; /* * Testing id of the component. * */ testID?: string; } const ProgressBar = ({ value, intent = 'primary', style, testID, ...nativeProps }: ProgressBarProps): ReactElement => { const [width, setWidth] = useState(0); const progressAnimatedValue = useRef(new Animated.Value(0)); useEffect(() => { const animation = Animated.timing(progressAnimatedValue.current, { toValue: value, useNativeDriver: true, }); animation.start(); return () => animation.stop(); }, [value]); const interpolateTranslateX = progressAnimatedValue.current.interpolate({ inputRange: [0, 100], outputRange: [-width, 0], extrapolate: 'clamp', }); const interpolateBorderRadius = progressAnimatedValue.current.interpolate({ inputRange: [99, 100], // Transition range to remove bother when reached 100% outputRange: [999, 0], extrapolate: 'clamp', }); return ( setWidth(nativeEvent.layout.width)} style={{ transform: [{ translateX: interpolateTranslateX }], borderTopRightRadius: interpolateBorderRadius, borderBottomRightRadius: interpolateBorderRadius, }} /> ); }; export default ProgressBar;