@umituz/react-native-settings 4.20.17 → 4.20.19
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 +1 -1
- package/src/domains/faqs/presentation/components/FAQSection.tsx +5 -2
- package/src/domains/faqs/presentation/screens/FAQScreen.tsx +2 -2
- package/src/presentation/components/SettingItem.tsx +1 -1
- package/src/presentation/components/SettingsItemCard.tsx +50 -33
- package/src/presentation/screens/components/sections/ProfileSectionLoader.tsx +11 -1
- package/src/presentation/screens/components/sections/SubscriptionSettingsSection.tsx +11 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-settings",
|
|
3
|
-
"version": "4.20.
|
|
3
|
+
"version": "4.20.19",
|
|
4
4
|
"description": "Complete settings hub for React Native apps - consolidated package with settings, about, legal, appearance, feedback, FAQs, and rating",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -32,7 +32,10 @@ export const FAQSection: React.FC<FAQSectionProps> = ({
|
|
|
32
32
|
renderSection,
|
|
33
33
|
renderItem,
|
|
34
34
|
}) => {
|
|
35
|
-
|
|
35
|
+
// onPress is required for FAQ section to be functional
|
|
36
|
+
if (!config.enabled || !config.title || !config.description || !config.onPress) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
36
39
|
|
|
37
40
|
return (
|
|
38
41
|
<>
|
|
@@ -41,7 +44,7 @@ export const FAQSection: React.FC<FAQSectionProps> = ({
|
|
|
41
44
|
children: renderItem({
|
|
42
45
|
title: config.description,
|
|
43
46
|
icon: 'help-circle',
|
|
44
|
-
onPress: config.onPress
|
|
47
|
+
onPress: config.onPress,
|
|
45
48
|
isLast: true,
|
|
46
49
|
}),
|
|
47
50
|
})}
|
|
@@ -116,12 +116,12 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
116
116
|
);
|
|
117
117
|
};
|
|
118
118
|
|
|
119
|
-
if (renderHeader) {
|
|
119
|
+
if (renderHeader && onBack) {
|
|
120
120
|
return (
|
|
121
121
|
<View style={{ flex: 1, backgroundColor: tokens.colors.backgroundPrimary }}>
|
|
122
122
|
<View style={[styles.container, customStyles?.container]}>
|
|
123
123
|
<View style={{ alignSelf: 'center', width: '100%', maxWidth: contentMaxWidth }}>
|
|
124
|
-
{renderHeader({ onBack
|
|
124
|
+
{renderHeader({ onBack })}
|
|
125
125
|
</View>
|
|
126
126
|
{renderContent()}
|
|
127
127
|
</View>
|
|
@@ -14,18 +14,20 @@ export interface SettingsItemCardProps {
|
|
|
14
14
|
description?: string;
|
|
15
15
|
/** Icon name from AtomicIcon */
|
|
16
16
|
icon: IconName;
|
|
17
|
-
/** On press handler */
|
|
18
|
-
onPress
|
|
17
|
+
/** On press handler - if undefined, item is not clickable */
|
|
18
|
+
onPress?: () => void;
|
|
19
19
|
/** Optional container style */
|
|
20
20
|
containerStyle?: ViewStyle;
|
|
21
21
|
/** Optional section title (shows above the card) */
|
|
22
22
|
sectionTitle?: string;
|
|
23
|
-
/** Optional right icon (defaults to chevron-forward) */
|
|
23
|
+
/** Optional right icon (defaults to chevron-forward, hidden if not clickable) */
|
|
24
24
|
rightIcon?: IconName;
|
|
25
25
|
/** Optional icon background color (defaults to primary with opacity) */
|
|
26
26
|
iconBgColor?: string;
|
|
27
27
|
/** Optional icon color */
|
|
28
28
|
iconColor?: string;
|
|
29
|
+
/** Show chevron even if not clickable */
|
|
30
|
+
showChevron?: boolean;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -44,12 +46,41 @@ export const SettingsItemCard: React.FC<SettingsItemCardProps> = ({
|
|
|
44
46
|
rightIcon = "chevron-forward",
|
|
45
47
|
iconBgColor,
|
|
46
48
|
iconColor,
|
|
49
|
+
showChevron,
|
|
47
50
|
}) => {
|
|
48
51
|
const tokens = useAppDesignTokens();
|
|
49
52
|
const colors = tokens.colors;
|
|
50
53
|
|
|
51
54
|
const defaultIconBg = iconBgColor || `${colors.primary}15`;
|
|
52
55
|
const defaultIconColor = iconColor || colors.primary;
|
|
56
|
+
const isClickable = !!onPress;
|
|
57
|
+
const shouldShowChevron = showChevron ?? isClickable;
|
|
58
|
+
|
|
59
|
+
const renderContent = () => (
|
|
60
|
+
<View style={styles.content}>
|
|
61
|
+
<View style={[styles.iconContainer, { backgroundColor: defaultIconBg }]}>
|
|
62
|
+
<AtomicIcon name={icon} size="lg" customColor={defaultIconColor} />
|
|
63
|
+
</View>
|
|
64
|
+
<View style={styles.textContainer}>
|
|
65
|
+
<AtomicText
|
|
66
|
+
type="bodyLarge"
|
|
67
|
+
color="onSurface"
|
|
68
|
+
numberOfLines={1}
|
|
69
|
+
style={{ marginBottom: 4 }}
|
|
70
|
+
>
|
|
71
|
+
{title}
|
|
72
|
+
</AtomicText>
|
|
73
|
+
{!!description && (
|
|
74
|
+
<AtomicText type="bodyMedium" color="secondary" numberOfLines={2}>
|
|
75
|
+
{description}
|
|
76
|
+
</AtomicText>
|
|
77
|
+
)}
|
|
78
|
+
</View>
|
|
79
|
+
{shouldShowChevron && (
|
|
80
|
+
<AtomicIcon name={rightIcon} size="sm" color="secondary" />
|
|
81
|
+
)}
|
|
82
|
+
</View>
|
|
83
|
+
);
|
|
53
84
|
|
|
54
85
|
return (
|
|
55
86
|
<View
|
|
@@ -66,37 +97,23 @@ export const SettingsItemCard: React.FC<SettingsItemCardProps> = ({
|
|
|
66
97
|
</AtomicText>
|
|
67
98
|
</View>
|
|
68
99
|
)}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
type="bodyLarge"
|
|
85
|
-
color="onSurface"
|
|
86
|
-
numberOfLines={1}
|
|
87
|
-
style={{ marginBottom: 4 }}
|
|
88
|
-
>
|
|
89
|
-
{title}
|
|
90
|
-
</AtomicText>
|
|
91
|
-
{!!description && (
|
|
92
|
-
<AtomicText type="bodyMedium" color="secondary" numberOfLines={2}>
|
|
93
|
-
{description}
|
|
94
|
-
</AtomicText>
|
|
95
|
-
)}
|
|
96
|
-
</View>
|
|
97
|
-
<AtomicIcon name={rightIcon} size="sm" color="secondary" />
|
|
100
|
+
{isClickable ? (
|
|
101
|
+
<Pressable
|
|
102
|
+
style={({ pressed }) => [
|
|
103
|
+
styles.itemContainer,
|
|
104
|
+
{
|
|
105
|
+
backgroundColor: pressed ? `${colors.primary}08` : "transparent",
|
|
106
|
+
},
|
|
107
|
+
]}
|
|
108
|
+
onPress={onPress}
|
|
109
|
+
>
|
|
110
|
+
{renderContent()}
|
|
111
|
+
</Pressable>
|
|
112
|
+
) : (
|
|
113
|
+
<View style={styles.itemContainer}>
|
|
114
|
+
{renderContent()}
|
|
98
115
|
</View>
|
|
99
|
-
|
|
116
|
+
)}
|
|
100
117
|
</View>
|
|
101
118
|
);
|
|
102
119
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { View, StyleSheet } from "react-native";
|
|
3
|
+
import { useNavigation } from "@react-navigation/native";
|
|
3
4
|
import { ProfileSection } from "@umituz/react-native-auth";
|
|
4
5
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
5
6
|
|
|
@@ -17,9 +18,18 @@ export interface ProfileSectionLoaderProps {
|
|
|
17
18
|
|
|
18
19
|
export const ProfileSectionLoader: React.FC<ProfileSectionLoaderProps> = ({ userProfile }) => {
|
|
19
20
|
const { t } = useLocalization();
|
|
21
|
+
const navigation = useNavigation<any>();
|
|
20
22
|
|
|
21
23
|
if (!userProfile) return null;
|
|
22
24
|
|
|
25
|
+
const handlePress = () => {
|
|
26
|
+
if (userProfile.onPress) {
|
|
27
|
+
userProfile.onPress();
|
|
28
|
+
} else if (userProfile.accountSettingsRoute) {
|
|
29
|
+
navigation.navigate(userProfile.accountSettingsRoute);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
23
33
|
return (
|
|
24
34
|
<View style={styles.profileContainer}>
|
|
25
35
|
<ProfileSection
|
|
@@ -30,7 +40,7 @@ export const ProfileSectionLoader: React.FC<ProfileSectionLoaderProps> = ({ user
|
|
|
30
40
|
avatarUrl: userProfile.avatarUrl,
|
|
31
41
|
accountSettingsRoute: userProfile.accountSettingsRoute,
|
|
32
42
|
}}
|
|
33
|
-
onPress={
|
|
43
|
+
onPress={handlePress}
|
|
34
44
|
onSignIn={userProfile.onPress}
|
|
35
45
|
signInText={t("auth.signIn")}
|
|
36
46
|
anonymousText={t("settings.profile.anonymousName")}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
ListItem,
|
|
4
|
-
AtomicBadge,
|
|
5
|
-
} from "@umituz/react-native-design-system";
|
|
6
2
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
7
|
-
import {
|
|
3
|
+
import type { IconName } from "@umituz/react-native-design-system";
|
|
4
|
+
import { SettingsItemCard } from "../../../components/SettingsItemCard";
|
|
8
5
|
import type { SubscriptionConfig } from "../../types";
|
|
9
6
|
|
|
10
7
|
interface SubscriptionSettingsSectionProps {
|
|
@@ -16,16 +13,16 @@ export const SubscriptionSettingsSection: React.FC<SubscriptionSettingsSectionPr
|
|
|
16
13
|
}) => {
|
|
17
14
|
const { t } = useLocalization();
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
// onPress is required for subscription section to be functional
|
|
17
|
+
if (!config || !config.onPress) return null;
|
|
20
18
|
|
|
21
19
|
return (
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</SettingsSection>
|
|
20
|
+
<SettingsItemCard
|
|
21
|
+
title={config.title || t("settings.subscription.title")}
|
|
22
|
+
description={config.description || t("settings.subscription.description")}
|
|
23
|
+
icon={(config.icon || "star") as IconName}
|
|
24
|
+
onPress={config.onPress}
|
|
25
|
+
sectionTitle={config.sectionTitle || t("settings.sections.subscription")}
|
|
26
|
+
/>
|
|
30
27
|
);
|
|
31
28
|
};
|