UNPKG

@fruits-chain/react-native-xiaoshu

Version:
130 lines (124 loc) 3.94 kB
import React, { useState, useCallback, useRef, useEffect, memo } from 'react'; import { View, Text, Animated } from 'react-native'; import { getDefaultValue } from '../helpers'; import * as helpers from '../helpers'; import { usePersistFn } from '../hooks'; import Theme from '../theme'; import { varCreator } from './style'; /** * Progress 进度条 */ const Progress = _ref => { let { percentage = 0, pivotText, color, trackColor, pivotColor, textColor, strokeWidth, inactive = false, showPivot = true, square = false, animated = false, animationDuration, onAnimationEnd } = _ref; const AnimatedValue = useRef(new Animated.Value(0)).current; const StartPercentage = useRef(percentage); const onAnimationEndPersistFn = usePersistFn(n => { onAnimationEnd === null || onAnimationEnd === void 0 ? void 0 : onAnimationEnd(n); }); const TOKENS = Theme.useThemeTokens(); const CV = Theme.createVar(TOKENS, varCreator); // 默认值 color = getDefaultValue(color, CV.progress_color); if (inactive) { color = '#cacaca'; } trackColor = getDefaultValue(trackColor, CV.progress_background_color); pivotColor = getDefaultValue(pivotColor, color); textColor = getDefaultValue(textColor, CV.progress_pivot_text_color); pivotText = getDefaultValue(pivotText, `${percentage}%`); strokeWidth = getDefaultValue(strokeWidth, CV.progress_height); animationDuration = getDefaultValue(animationDuration, TOKENS.animation_duration_base); const borderRadius = square ? 0 : strokeWidth / 2; const [progressLayout, setProgressLayout] = useState({ width: 0, height: 0 }); const [textLayout, setTextLayout] = useState({ width: 0, height: 0 }); useEffect(() => { const action = Animated.timing(AnimatedValue, { toValue: progressLayout.width * percentage / 100, duration: animated ? animationDuration : 0, easing: helpers.easing.easeInCubic, useNativeDriver: false }); action.start(_ref2 => { let { finished } = _ref2; if (finished) { onAnimationEndPersistFn(percentage); } }); return () => { action.stop(); }; }, [AnimatedValue, percentage, animationDuration, progressLayout.width, animated, onAnimationEndPersistFn]); const barStyle = { position: 'absolute', left: 0, top: 0, width: AnimatedValue, height: strokeWidth, backgroundColor: color, borderRadius: borderRadius }; const textBoxStyle = { position: 'absolute', left: AnimatedValue, top: 0, justifyContent: 'center', alignItems: 'center', backgroundColor: pivotColor, paddingHorizontal: CV.progress_pivot_padding_horizontal, borderRadius: TOKENS.border_radius_max, transform: [{ translateX: -textLayout.width / 2 }, { translateY: -(textLayout.height - strokeWidth) / 2 }] }; const onLayoutProgress = useCallback(e => { AnimatedValue.setValue(e.nativeEvent.layout.width * StartPercentage.current / 100); setProgressLayout(e.nativeEvent.layout); }, [AnimatedValue]); const onLayoutText = useCallback(e => { setTextLayout(e.nativeEvent.layout); }, []); return /*#__PURE__*/React.createElement(View, { onLayout: onLayoutProgress, style: { height: strokeWidth, backgroundColor: trackColor, borderRadius: borderRadius } }, /*#__PURE__*/React.createElement(Animated.View, { style: barStyle }), showPivot ? /*#__PURE__*/React.createElement(Animated.View, { onLayout: onLayoutText, style: textBoxStyle }, /*#__PURE__*/React.createElement(Text, { style: { color: textColor, fontSize: CV.progress_pivot_font_size, lineHeight: CV.progress_pivot_line_height_scale * CV.progress_pivot_font_size } }, pivotText)) : null); }; export default /*#__PURE__*/memo(Progress); //# sourceMappingURL=progress.js.map