UNPKG

@metamask/design-system-react-native

Version:
48 lines 2.01 kB
function $importDefault(module) { if (module?.__esModule) { return module.default; } return module; } import { useTailwind } from "@metamask/design-system-twrnc-preset"; import $React, { useEffect } from "react"; const React = $importDefault($React); import { View } from "react-native/index.js"; import Animated, { useSharedValue, useAnimatedStyle, withRepeat, withTiming, Easing } from "react-native-reanimated"; import { Icon, IconColor, IconName, IconSize } from "../../Icon/index.mjs"; import { Text, TextVariant, TextColor } from "../../Text/index.mjs"; export const Spinner = ({ color = IconColor.IconDefault, spinnerIconProps, loadingText, loadingTextProps, twClassName = '', style, ...props }) => { const tw = useTailwind(); // Create a shared value for rotation const rotation = useSharedValue(0); // Start the animation when the component mounts useEffect(() => { rotation.value = withRepeat(withTiming(360, { duration: 1000, easing: Easing.linear }), // Complete a full spin in 1 second -1, // Infinite repetitions false); }, []); // Define the animated style const animatedStyle = useAnimatedStyle(() => ({ transform: [{ rotate: `${rotation.value % 360}deg` }], })); const finalSpinnerIconProps = { size: IconSize.Md, name: IconName.Loading, testID: 'spinner-icon', color, ...spinnerIconProps, }; const finalLoadingTextProps = { variant: TextVariant.BodyMd, color: TextColor.TextDefault, testID: 'spinner-text', ...loadingTextProps, }; return (<View style={[tw `flex-row items-center gap-x-2 ${twClassName}`, style]} testID="spinner" {...props}> <Animated.View style={[animatedStyle]} testID="spinner-animated-view"> <Icon {...finalSpinnerIconProps}/> </Animated.View> {loadingText && <Text {...finalLoadingTextProps}>{loadingText}</Text>} </View>); }; //# sourceMappingURL=Spinner.mjs.map