@metamask/design-system-react-native
Version:
48 lines • 2.01 kB
JavaScript
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