diff --git a/android/src/main/java/com/makepayment/GooglePayButtonComponentManager.kt b/android/src/main/java/com/makepayment/GooglePayButtonComponentManager.kt index 2b351c6..c703a39 100644 --- a/android/src/main/java/com/makepayment/GooglePayButtonComponentManager.kt +++ b/android/src/main/java/com/makepayment/GooglePayButtonComponentManager.kt @@ -31,7 +31,7 @@ class GooglePayButtonComponentManager(context: ReactApplicationContext) : Simple view?.allowedPaymentMethods = value!! } - @ReactProp(name = "type") + @ReactProp(name = "buttonType") override fun setType(view: GooglePayButtonComponent, type: Int) { view.type = type } diff --git a/src/GooglePayButton.tsx b/src/GooglePayButton.tsx index bbe77b6..dd87b49 100644 --- a/src/GooglePayButton.tsx +++ b/src/GooglePayButton.tsx @@ -1,8 +1,13 @@ -import { StyleSheet, Pressable } from 'react-native'; +import { StyleSheet, Pressable, View } from 'react-native'; import type { ViewProps, StyleProp, ViewStyle } from 'react-native'; +import type { ReactNode } from 'react'; import GooglePayButtonComponent from './specs/NativeGooglePayButtonComponent'; import GooglePayButtonConstantsModule from './specs/NativeGooglePayButtonConstantsModule'; -import type { GooglePayPaymentMethod } from './specs/NativeGooglePayButtonComponent' +import type { GooglePayPaymentMethod } from './specs/NativeGooglePayButtonComponent'; +import { Loader } from './Loader'; + +const GooglePayButtonConstants = + GooglePayButtonConstantsModule?.loadConstants(); export interface Props extends ViewProps { allowedPaymentMethods: GooglePayPaymentMethod[]; @@ -12,6 +17,8 @@ export interface Props extends ViewProps { onPress: () => void; disabled: boolean; style: StyleProp; + loading?: boolean; + loader?: ReactNode; } const GooglePayButton = ({ @@ -22,13 +29,15 @@ const GooglePayButton = ({ type, radius, style, + loading, + loader, }: Props) => { return ( + {loading && ( + + {loader || } + + )} ); }; @@ -67,8 +81,14 @@ const styles = StyleSheet.create({ nobg: { backgroundColor: 'rgba(0, 0, 0, 0)', }, + hidden: { + opacity: 0, + }, + loaderContainer: { + ...StyleSheet.absoluteFillObject, + justifyContent: 'center', + alignItems: 'center', + }, }); -const GooglePayButtonConstants = GooglePayButtonConstantsModule?.loadConstants(); - export { GooglePayButton, GooglePayButtonConstants }; diff --git a/src/Loader.tsx b/src/Loader.tsx new file mode 100644 index 0000000..a2c8f3c --- /dev/null +++ b/src/Loader.tsx @@ -0,0 +1,62 @@ +import { useEffect, useRef } from 'react'; +import { StyleSheet, Animated, Easing } from 'react-native'; +import type { ViewStyle, StyleProp } from 'react-native'; + +export interface LoaderProps { + theme?: number; + color?: string; + style?: StyleProp; +} + +/** + * A custom Google Pay style loading spinner. + * Features a smooth rotating arc. + */ +export const Loader = ({ theme, color, style }: LoaderProps) => { + const spinValue = useRef(new Animated.Value(0)).current; + + useEffect(() => { + const animation = Animated.loop( + Animated.timing(spinValue, { + toValue: 1, + duration: 800, + easing: Easing.linear, + useNativeDriver: true, + }) + ); + animation.start(); + return () => animation.stop(); + }, [spinValue]); + + const spin = spinValue.interpolate({ + inputRange: [0, 1], + outputRange: ['0deg', '360deg'], + }); + + // Default color logic based on theme if no explicit color provided + // theme === 1 is usually Dark (GooglePayButtonConstants.Themes.Dark) + const finalColor = color || (theme === 1 ? 'white' : 'black'); + + return ( + + ); +}; + +const styles = StyleSheet.create({ + loader: { + width: 24, + height: 24, + borderRadius: 12, + borderWidth: 2, + borderTopColor: 'transparent', + }, +}); diff --git a/src/index.tsx b/src/index.tsx index 9502fab..d0d1ec0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,5 @@ export * from './PaymentRequest'; export { GooglePayButton, GooglePayButtonConstants } from './GooglePayButton'; +export { Loader } from './Loader'; export type * from './specs/NativeMakePaymentModule'; export * from './constants';