@td-design/react-native
Version:
react-native UI组件库
113 lines (112 loc) • 3.26 kB
JavaScript
import React, { memo } from 'react';
import { StyleSheet } from 'react-native';
import Animated, { useAnimatedStyle, withSpring, withTiming } from 'react-native-reanimated';
import { useTheme } from '@shopify/restyle';
import { useBoolean, useMemoizedFn, useSafeState } from '@td-design/rn-hooks';
import Box from '../box';
import Flex from '../flex';
import helpers from '../helpers';
import Text from '../text';
const {
px
} = helpers;
const defaultNumberRange = Array(10).fill('').map((_, index) => index.toString());
const ScrollNumber = _ref => {
let {
numberRange = defaultNumberRange,
value,
height = 0,
containerStyle,
textStyle,
animationType = 'timing'
} = _ref;
const theme = useTheme();
const [measured, {
setTrue
}] = useBoolean(!!height);
const [currentHeight, setCurrentHeight] = useSafeState(height);
const handleLayout = useMemoizedFn(e => {
if (height) return;
const layoutHeight = e.nativeEvent.layout.height;
setCurrentHeight(layoutHeight);
setTrue();
});
const styles = StyleSheet.create({
height: {
height: currentHeight
},
opacity: {
opacity: 0
},
text: {
fontSize: 18,
color: theme.colors.gray500
}
});
return /*#__PURE__*/React.createElement(Box, {
overflow: "hidden",
style: measured ? styles.height : styles.opacity
}, /*#__PURE__*/React.createElement(Flex, null, value.toString().split('').map((item, index) => /*#__PURE__*/React.createElement(Box, {
key: index,
overflow: "hidden",
style: [containerStyle, measured ? styles.height : styles.opacity]
}, /*#__PURE__*/React.createElement(Tick, {
value: item,
height: currentHeight,
numberRange,
textStyle,
animationType
})))), /*#__PURE__*/React.createElement(Box, {
opacity: 0,
style: !!height && {
height
}
}, /*#__PURE__*/React.createElement(Text, {
fontSize: px(18),
color: "text",
style: textStyle,
onLayout: handleLayout
}, numberRange[0])));
};
ScrollNumber.displayName = 'ScrollNumber';
export default ScrollNumber;
const Tick = /*#__PURE__*/memo(_ref2 => {
let {
numberRange,
value,
height,
containerStyle,
textStyle,
animationType
} = _ref2;
const getPosition = (value, height) => {
'worklet';
const index = numberRange === null || numberRange === void 0 ? void 0 : numberRange.findIndex(item => item === value);
if (index && index > -1) return index * height * -1;
return 0;
};
const animatedStyle = useAnimatedStyle(() => {
const position = getPosition(value, height);
return {
transform: [{
translateY: animationType === 'timing' ? withTiming(position) : withSpring(position)
}]
};
});
if (!numberRange || numberRange.length === 0) return null;
return /*#__PURE__*/React.createElement(Animated.View, {
style: [animatedStyle]
}, numberRange.map(i => /*#__PURE__*/React.createElement(Box, {
key: i,
justifyContent: 'center',
alignItems: 'center',
style: [containerStyle, !!height && {
height
}]
}, /*#__PURE__*/React.createElement(Text, {
fontSize: px(18),
color: "text",
style: textStyle
}, i))));
});
//# sourceMappingURL=index.js.map