@umituz/react-native-settings 4.20.11 → 4.20.17

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-settings",
3
- "version": "4.20.11",
3
+ "version": "4.20.17",
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",
@@ -15,7 +15,8 @@ export interface ThemeOptionConfig {
15
15
  title: string;
16
16
  subtitle?: string;
17
17
  description?: string;
18
- features: string[];
18
+ features?: string[];
19
+ featuresTitle?: string;
19
20
  }
20
21
 
21
22
  export interface ThemeModeSectionProps {
@@ -58,9 +59,10 @@ export const ThemeModeSection: React.FC<ThemeModeSectionProps> = ({
58
59
  key={theme.mode}
59
60
  mode={theme.mode}
60
61
  title={theme.title}
61
- subtitle={theme.subtitle || ""}
62
- description={theme.description || ""}
62
+ subtitle={theme.subtitle}
63
+ description={theme.description}
63
64
  features={theme.features}
65
+ featuresTitle={theme.featuresTitle}
64
66
  isSelected={themeMode === theme.mode}
65
67
  onSelect={() => handleThemeSelect(theme.mode)}
66
68
  />
@@ -14,9 +14,10 @@ import type { ThemeMode } from "../../types";
14
14
  interface ThemeOptionProps {
15
15
  mode: ThemeMode;
16
16
  title: string;
17
- subtitle: string;
18
- description: string;
19
- features: string[];
17
+ subtitle?: string;
18
+ description?: string;
19
+ features?: string[];
20
+ featuresTitle?: string;
20
21
  isSelected: boolean;
21
22
  onSelect: () => void;
22
23
  }
@@ -27,6 +28,7 @@ export const ThemeOption: React.FC<ThemeOptionProps> = ({
27
28
  subtitle,
28
29
  description,
29
30
  features,
31
+ featuresTitle,
30
32
  isSelected,
31
33
  onSelect,
32
34
  }) => {
@@ -47,9 +49,11 @@ export const ThemeOption: React.FC<ThemeOptionProps> = ({
47
49
  <AtomicText type="titleLarge" color="primary">
48
50
  {title}
49
51
  </AtomicText>
50
- <AtomicText type="bodyMedium" color="secondary">
51
- {subtitle}
52
- </AtomicText>
52
+ {subtitle ? (
53
+ <AtomicText type="bodyMedium" color="secondary">
54
+ {subtitle}
55
+ </AtomicText>
56
+ ) : null}
53
57
  </View>
54
58
  <AtomicIcon
55
59
  name={isSelected ? "checkmark-circle-outline" : "ellipse-outline"}
@@ -58,33 +62,39 @@ export const ThemeOption: React.FC<ThemeOptionProps> = ({
58
62
  />
59
63
  </View>
60
64
 
61
- <AtomicText
62
- type="bodyMedium"
63
- color="secondary"
64
- style={styles.description}
65
- >
66
- {description}
67
- </AtomicText>
68
-
69
- <View style={styles.featuresContainer}>
65
+ {description ? (
70
66
  <AtomicText
71
- type="labelLarge"
72
- color="primary"
73
- style={styles.featuresTitle}
67
+ type="bodyMedium"
68
+ color="secondary"
69
+ style={styles.description}
74
70
  >
75
- Features
71
+ {description}
76
72
  </AtomicText>
77
- {features.map((feature, index) => (
78
- <AtomicText
79
- key={index}
80
- type="bodySmall"
81
- color="secondary"
82
- style={styles.feature}
83
- >
84
- • {feature}
85
- </AtomicText>
86
- ))}
87
- </View>
73
+ ) : null}
74
+
75
+ {features && features.length > 0 ? (
76
+ <View style={styles.featuresContainer}>
77
+ {featuresTitle ? (
78
+ <AtomicText
79
+ type="labelLarge"
80
+ color="primary"
81
+ style={styles.featuresTitle}
82
+ >
83
+ {featuresTitle}
84
+ </AtomicText>
85
+ ) : null}
86
+ {features.map((feature, index) => (
87
+ <AtomicText
88
+ key={index}
89
+ type="bodySmall"
90
+ color="secondary"
91
+ style={styles.feature}
92
+ >
93
+ • {feature}
94
+ </AtomicText>
95
+ ))}
96
+ </View>
97
+ ) : null}
88
98
  </TouchableOpacity>
89
99
  );
90
100
  };
@@ -64,27 +64,24 @@ export const AppearanceScreen: React.FC<AppearanceScreenProps> = ({
64
64
  const themeSectionMemo = useMemo(() => {
65
65
  if (!showThemeSection) return null;
66
66
 
67
- const themes: ThemeOptionConfig[] = [];
68
-
69
- if (texts?.lightMode) {
70
- themes.push({
71
- mode: 'light' as const,
72
- title: texts.lightMode.title,
73
- subtitle: texts.lightMode.subtitle,
74
- description: texts.lightMode.description,
75
- features: texts.lightMode.features
76
- });
77
- }
78
-
79
- if (texts?.darkMode) {
80
- themes.push({
81
- mode: 'dark' as const,
82
- title: texts.darkMode.title,
83
- subtitle: texts.darkMode.subtitle,
84
- description: texts.darkMode.description,
85
- features: texts.darkMode.features
86
- });
87
- }
67
+ const themes: ThemeOptionConfig[] = [
68
+ {
69
+ mode: "light",
70
+ title: texts?.lightMode?.title ?? "settings.themeMode.light.title",
71
+ subtitle: texts?.lightMode?.subtitle,
72
+ description: texts?.lightMode?.description,
73
+ features: texts?.lightMode?.features,
74
+ featuresTitle: texts?.featuresSectionTitle,
75
+ },
76
+ {
77
+ mode: "dark",
78
+ title: texts?.darkMode?.title ?? "settings.themeMode.dark.title",
79
+ subtitle: texts?.darkMode?.subtitle,
80
+ description: texts?.darkMode?.description,
81
+ features: texts?.darkMode?.features,
82
+ featuresTitle: texts?.featuresSectionTitle,
83
+ },
84
+ ];
88
85
 
89
86
  return (
90
87
  <ThemeModeSection
@@ -93,7 +90,7 @@ export const AppearanceScreen: React.FC<AppearanceScreenProps> = ({
93
90
  onThemeSelect={handleThemeSelect}
94
91
  title={texts?.themeSectionTitle}
95
92
  description={texts?.themeSectionDescription}
96
- themes={themes.length > 0 ? themes : undefined}
93
+ themes={themes}
97
94
  />
98
95
  );
99
96
  }, [
@@ -105,6 +102,7 @@ export const AppearanceScreen: React.FC<AppearanceScreenProps> = ({
105
102
  texts?.themeSectionDescription,
106
103
  texts?.lightMode,
107
104
  texts?.darkMode,
105
+ texts?.featuresSectionTitle,
108
106
  ]);
109
107
 
110
108
  const colorsSectionMemo = useMemo(() => {
@@ -44,6 +44,7 @@ export interface AppearanceTexts {
44
44
  subtitle?: string;
45
45
  themeSectionTitle?: string;
46
46
  themeSectionDescription?: string;
47
+ featuresSectionTitle?: string;
47
48
  colorsSectionTitle?: string;
48
49
  colorsSectionDescription?: string;
49
50
  previewSectionTitle?: string;
@@ -15,6 +15,7 @@ export interface FeedbackConfig {
15
15
  description?: string;
16
16
  initialType?: FeedbackType;
17
17
  onSubmit?: (data: { type: any; rating: number; description: string; title: string }) => Promise<void>;
18
+ onPress?: () => void;
18
19
  }
19
20
 
20
21
  export interface RatingConfig {
@@ -83,9 +84,20 @@ export const SupportSection: React.FC<SupportSectionProps> = ({
83
84
  }
84
85
 
85
86
  if (config?.storeUrl) {
86
- const supported = await Linking.canOpenURL(config.storeUrl);
87
- if (supported) {
88
- await Linking.openURL(config.storeUrl);
87
+ try {
88
+ // Safely handle URL for App Store - itunes.apple.com is more reliable for deep links
89
+ let url = config.storeUrl;
90
+ if (url.includes('apps.apple.com')) {
91
+ url = url.replace('apps.apple.com', 'itunes.apple.com');
92
+ }
93
+
94
+ // Try opening the modified URL
95
+ await Linking.openURL(url);
96
+ } catch (error) {
97
+ // Final fallback to original URL
98
+ if (config.storeUrl) {
99
+ Linking.openURL(config.storeUrl).catch(() => {});
100
+ }
89
101
  }
90
102
  }
91
103
  }, [ratingConfig.config]);
@@ -110,7 +122,7 @@ export const SupportSection: React.FC<SupportSectionProps> = ({
110
122
  {showFeedback && feedbackConfig.config?.description && renderItem({
111
123
  title: feedbackConfig.config.description,
112
124
  icon: "mail",
113
- onPress: () => setModalVisible(true),
125
+ onPress: feedbackConfig.config.onPress || (() => setModalVisible(true)),
114
126
  isLast: !showRating
115
127
  })}
116
128
 
@@ -5,13 +5,14 @@
5
5
  * Can be extended by apps to add custom screens
6
6
  */
7
7
 
8
- import React from "react";
8
+ import React, { useMemo } from "react";
9
9
  import { createStackNavigator } from "@react-navigation/stack";
10
10
  import { useAppDesignTokens } from "@umituz/react-native-design-system";
11
11
  import { SettingsScreen } from "../screens/SettingsScreen";
12
12
  import { AppearanceScreen } from "../screens/AppearanceScreen";
13
- import type { SettingsConfig, CustomSettingsSection } from "../screens/types";
13
+ import type { SettingsConfig, CustomSettingsSection, AppearanceConfig } from "../screens/types";
14
14
  import type { DevSettingsProps } from "../components/DevSettingsSection";
15
+ import type { AppearanceTexts } from "../../domains/appearance/types";
15
16
 
16
17
  // Default param list - can be extended by apps
17
18
  export type SettingsStackParamList = {
@@ -3,7 +3,7 @@
3
3
  * Core types for feature visibility and configuration
4
4
  */
5
5
 
6
- import type { ComponentType, ReactNode } from "react";
6
+ import type { AppearanceTexts } from "../../../domains/appearance/types";
7
7
 
8
8
  /**
9
9
  * Feature visibility configuration
@@ -33,6 +33,8 @@ export interface AppearanceConfig {
33
33
  sectionTitle?: string;
34
34
  /** Default route name when no custom route provided */
35
35
  defaultRoute?: string;
36
+ /** Appearance screen texts (theme mode labels, descriptions, etc.) */
37
+ texts?: AppearanceTexts;
36
38
  }
37
39
 
38
40
  /**
@@ -169,6 +171,8 @@ export interface FeedbackConfig {
169
171
  initialType?: FeedbackType;
170
172
  /** Feedback submission handler */
171
173
  onSubmit?: (data: { type: any; rating: number; description: string; title: string }) => Promise<void>;
174
+ /** Custom handler to open feedback screen (overrides default modal) */
175
+ onPress?: () => void;
172
176
  }
173
177
 
174
178
  export interface FAQConfig {