@umituz/react-native-subscription 3.1.25 → 3.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "3.1.25",
3
+ "version": "3.1.26",
4
4
  "description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -12,6 +12,8 @@ interface PaywallFooterProps {
12
12
  onRestore?: () => Promise<void | boolean>;
13
13
  onLegalClick: (url: string | undefined) => void;
14
14
  purchaseButtonText?: string;
15
+ isTablet?: boolean;
16
+ isSmallDevice?: boolean;
15
17
  }
16
18
 
17
19
  export const PaywallFooter: React.FC<PaywallFooterProps> = React.memo(({
@@ -22,12 +24,33 @@ export const PaywallFooter: React.FC<PaywallFooterProps> = React.memo(({
22
24
  onRestore,
23
25
  onLegalClick,
24
26
  purchaseButtonText,
27
+ isTablet = false,
28
+ isSmallDevice = false,
25
29
  }) => {
26
30
  const tokens = useAppDesignTokens();
27
31
 
32
+ // Device-based sizing
33
+ const buttonHeight = React.useMemo(() => {
34
+ if (isTablet) return 64; // Larger button on tablet
35
+ if (isSmallDevice) return 52; // Slightly smaller on small phones
36
+ return 56; // Standard size
37
+ }, [isTablet, isSmallDevice]);
38
+
39
+ const fontSize = React.useMemo(() => {
40
+ if (isTablet) return 19;
41
+ if (isSmallDevice) return 16;
42
+ return 17;
43
+ }, [isTablet, isSmallDevice]);
44
+
45
+ const paddingVertical = React.useMemo(() => {
46
+ if (isTablet) return 20;
47
+ if (isSmallDevice) return 12;
48
+ return 16;
49
+ }, [isTablet, isSmallDevice]);
50
+
28
51
  return (
29
52
  <View style={footerStyles.container}>
30
- {/* Purchase Button - Large and prominent */}
53
+ {/* Purchase Button - Device-responsive */}
31
54
  {onPurchase && (
32
55
  <TouchableOpacity
33
56
  onPress={onPurchase}
@@ -35,7 +58,11 @@ export const PaywallFooter: React.FC<PaywallFooterProps> = React.memo(({
35
58
  activeOpacity={0.8}
36
59
  style={[
37
60
  footerStyles.purchaseButton,
38
- { backgroundColor: tokens.colors.primary },
61
+ {
62
+ backgroundColor: tokens.colors.primary,
63
+ height: buttonHeight,
64
+ paddingVertical: paddingVertical,
65
+ },
39
66
  isProcessing && footerStyles.buttonDisabled,
40
67
  ]}
41
68
  >
@@ -44,20 +71,20 @@ export const PaywallFooter: React.FC<PaywallFooterProps> = React.memo(({
44
71
  <AtomicSpinner size="sm" />
45
72
  </View>
46
73
  ) : (
47
- <AtomicText style={[footerStyles.purchaseButtonText, { color: tokens.colors.textPrimary }]}>
74
+ <AtomicText style={[footerStyles.purchaseButtonText, { color: tokens.colors.textPrimary, fontSize }]}>
48
75
  {purchaseButtonText || translations.purchaseButtonText}
49
76
  </AtomicText>
50
77
  )}
51
78
  </TouchableOpacity>
52
79
  )}
53
80
 
54
- {/* Restore Link - Minimal */}
81
+ {/* Restore Link - Device-spaced */}
55
82
  {onRestore && (
56
83
  <TouchableOpacity
57
84
  onPress={onRestore}
58
85
  disabled={isProcessing}
59
86
  activeOpacity={0.6}
60
- style={footerStyles.restoreButton}
87
+ style={[footerStyles.restoreButton, { marginTop: isTablet ? 16 : 8 }]}
61
88
  >
62
89
  <AtomicText style={[footerStyles.restoreText, { color: tokens.colors.textSecondary }]}>
63
90
  {translations.restoreButtonText}
@@ -65,7 +92,7 @@ export const PaywallFooter: React.FC<PaywallFooterProps> = React.memo(({
65
92
  </TouchableOpacity>
66
93
  )}
67
94
 
68
- {/* Legal Links - Minimal */}
95
+ {/* Legal Links - Responsive spacing */}
69
96
  <View style={footerStyles.legalContainer}>
70
97
  {legalUrls.termsUrl && (
71
98
  <TouchableOpacity
@@ -105,7 +132,6 @@ const footerStyles = StyleSheet.create({
105
132
  },
106
133
  purchaseButton: {
107
134
  width: '100%',
108
- height: 56,
109
135
  borderRadius: 16,
110
136
  justifyContent: 'center',
111
137
  alignItems: 'center',
@@ -123,16 +149,13 @@ const footerStyles = StyleSheet.create({
123
149
  alignItems: 'center',
124
150
  },
125
151
  purchaseButtonText: {
126
- fontSize: 17,
127
152
  fontWeight: '700',
128
153
  letterSpacing: 0.5,
129
154
  },
130
155
  restoreButton: {
131
156
  alignItems: 'center',
132
- paddingVertical: 4,
133
157
  },
134
158
  restoreText: {
135
- fontSize: 13,
136
159
  fontWeight: '500',
137
160
  textDecorationLine: 'underline',
138
161
  },
@@ -143,11 +166,9 @@ const footerStyles = StyleSheet.create({
143
166
  flexWrap: 'wrap',
144
167
  },
145
168
  legalText: {
146
- fontSize: 11,
147
169
  lineHeight: 16,
148
170
  },
149
171
  legalSeparator: {
150
- fontSize: 11,
151
172
  color: 'rgba(255, 255, 255, 0.4)',
152
173
  marginHorizontal: 4,
153
174
  },
@@ -18,6 +18,7 @@ import { useNavigation } from "@react-navigation/native";
18
18
  import { AtomicIcon, AtomicSpinner } from "@umituz/react-native-design-system/atoms";
19
19
  import { useSafeAreaInsets } from "@umituz/react-native-design-system/safe-area";
20
20
  import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
21
+ import { useResponsive } from "@umituz/react-native-design-system/responsive";
21
22
  import { paywallScreenStyles as styles } from "./PaywallScreen.styles";
22
23
  import { PaywallFooter } from "./PaywallFooter";
23
24
  import { usePaywallActions } from "../hooks/usePaywallActions";
@@ -61,6 +62,7 @@ export const PaywallScreen: React.FC<PaywallScreenProps> = React.memo((props) =>
61
62
 
62
63
  const tokens = useAppDesignTokens();
63
64
  const insets = useSafeAreaInsets();
65
+ const responsive = useResponsive();
64
66
 
65
67
  const handleClose = useCallback(() => {
66
68
  if (__DEV__) console.log('[PaywallScreen] 🔙 Closing paywall');
@@ -190,11 +192,11 @@ export const PaywallScreen: React.FC<PaywallScreenProps> = React.memo((props) =>
190
192
  <View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
191
193
  <StatusBar barStyle="light-content" />
192
194
 
193
- {/* Absolute Close Button */}
195
+ {/* Absolute Close Button - Responsive positioning */}
194
196
  <View style={{
195
197
  position: 'absolute',
196
198
  top: Math.max(insets.top, 16),
197
- right: 0,
199
+ right: 16,
198
200
  zIndex: 10,
199
201
  }}>
200
202
  <TouchableOpacity
@@ -206,7 +208,7 @@ export const PaywallScreen: React.FC<PaywallScreenProps> = React.memo((props) =>
206
208
  </TouchableOpacity>
207
209
  </View>
208
210
 
209
- {/* Main Content */}
211
+ {/* Main Content - Responsive spacing */}
210
212
  <FlatList
211
213
  data={flatData}
212
214
  renderItem={renderItem}
@@ -220,15 +222,16 @@ export const PaywallScreen: React.FC<PaywallScreenProps> = React.memo((props) =>
220
222
  contentContainerStyle={[
221
223
  styles.listContent,
222
224
  {
223
- paddingTop: Math.max(insets.top, 20) + 50,
224
- paddingBottom: 280 // Increased for footer
225
+ paddingTop: Math.max(insets.top, 20) + 60, // Responsive header spacing
226
+ paddingBottom: 280 + responsive.verticalPadding, // Dynamic footer spacing
227
+ paddingHorizontal: responsive.horizontalPadding, // Device-based horizontal padding
225
228
  }
226
229
  ]}
227
230
  showsVerticalScrollIndicator={false}
228
231
  />
229
232
 
230
- {/* Fixed Footer - Improved positioning */}
231
- <View style={[styles.footerContainer, { paddingBottom: insets.bottom + 20 }]}>
233
+ {/* Fixed Footer - Responsive positioning */}
234
+ <View style={[styles.footerContainer, { paddingBottom: insets.bottom + responsive.verticalPadding }]}>
232
235
  <PaywallFooter
233
236
  translations={translations}
234
237
  legalUrls={legalUrls}
@@ -236,6 +239,8 @@ export const PaywallScreen: React.FC<PaywallScreenProps> = React.memo((props) =>
236
239
  onPurchase={handlePurchase}
237
240
  onRestore={handleRestore}
238
241
  onLegalClick={handleLegalUrl}
242
+ isTablet={responsive.isTabletDevice}
243
+ isSmallDevice={responsive.isSmallDevice}
239
244
  />
240
245
  </View>
241
246
  </View>