@umituz/react-native-settings 1.6.1 → 1.7.0

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": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "Settings management for React Native apps - user preferences, theme, language, notifications",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
package/src/index.ts CHANGED
@@ -41,7 +41,7 @@ export { LanguageSelectionScreen } from './presentation/screens/LanguageSelectio
41
41
  // PRESENTATION LAYER - Types
42
42
  // =============================================================================
43
43
 
44
- export type { SettingsConfig } from './presentation/screens/types';
44
+ export type { SettingsConfig, CustomSettingsSection } from './presentation/screens/types';
45
45
 
46
46
  // =============================================================================
47
47
  // PRESENTATION LAYER - Components
@@ -1,23 +1,21 @@
1
1
  /**
2
2
  * Appearance Settings Screen
3
- *
4
- * Modern appearance settings with Paper List.Section:
5
- * - React Native Paper List.Section pattern
6
- * - Lucide icons (Languages, Moon, Sun)
7
- * - Language + Theme settings combined
8
- * - Dynamic icon based on theme mode
9
- * - Material Design 3 compliance
3
+ * Modern appearance settings with language and theme controls
10
4
  */
11
5
 
12
- import React from 'react';
13
- import { View, StyleSheet } from 'react-native';
14
-
15
- import { useNavigation } from '@react-navigation/native';
16
- import { useDesignSystemTheme, useAppDesignTokens, type DesignTokens } from '@umituz/react-native-design-system-theme';
17
- import { AtomicText } from '@umituz/react-native-design-system-atoms';
18
- import { ScreenLayout } from '@umituz/react-native-design-system-organisms';
19
- import { useLocalization, getLanguageByCode } from '@umituz/react-native-localization';
20
- import { SettingItem } from '../components/SettingItem';
6
+ import React from "react";
7
+ import { View, StyleSheet } from "react-native";
8
+ import { Languages, Moon, Sun } from "lucide-react-native";
9
+ import { useNavigation } from "@react-navigation/native";
10
+ import {
11
+ useDesignSystemTheme,
12
+ useAppDesignTokens,
13
+ type DesignTokens,
14
+ } from "@umituz/react-native-design-system-theme";
15
+ import { ScreenLayout } from "@umituz/react-native-design-system-organisms";
16
+ import { useLocalization, getLanguageByCode } from "@umituz/react-native-localization";
17
+ import { SettingItem } from "../components/SettingItem";
18
+ import { SettingsSection } from "../components/SettingsSection";
21
19
 
22
20
  export const AppearanceScreen: React.FC = () => {
23
21
  const { t, currentLanguage } = useLocalization();
@@ -27,63 +25,43 @@ export const AppearanceScreen: React.FC = () => {
27
25
  const styles = getStyles(tokens);
28
26
 
29
27
  const currentLang = getLanguageByCode(currentLanguage);
30
- const languageDisplay = currentLang ? `${currentLang.flag} ${currentLang.nativeName}` : 'English';
31
- const themeDisplay = themeMode === 'dark' ? t('settings.darkMode') : t('settings.lightMode');
28
+ const languageDisplay = currentLang
29
+ ? `${currentLang.flag} ${currentLang.nativeName}`
30
+ : "English";
31
+ const themeDisplay =
32
+ themeMode === "dark" ? t("settings.darkMode") : t("settings.lightMode");
32
33
 
33
34
  const handleLanguagePress = () => {
34
- navigation.navigate('LanguageSelection' as never);
35
+ navigation.navigate("LanguageSelection" as never);
35
36
  };
36
37
 
37
38
  const handleThemeToggle = () => {
38
- const newMode = themeMode === 'dark' ? 'light' : 'dark';
39
+ const newMode = themeMode === "dark" ? "light" : "dark";
39
40
  setThemeMode(newMode);
40
41
  };
41
42
 
42
43
  return (
43
44
  <ScreenLayout testID="appearance-screen" hideScrollIndicator>
44
- {/* Header */}
45
- <View style={styles.header}>
46
- <AtomicText type="headlineLarge" color="primary">
47
- {t('settings.appearance.title')}
48
- </AtomicText>
49
- <AtomicText type="bodyMedium" color="secondary" style={styles.headerSubtitle}>
50
- {t('settings.appearance.themeDescription')}
51
- </AtomicText>
52
- </View>
53
-
54
45
  {/* Language Section */}
55
- <View style={{ marginBottom: tokens.spacing.md }}>
56
- <AtomicText type="labelMedium" color="textSecondary" style={styles.sectionHeader}>
57
- {t('settings.language')}
58
- </AtomicText>
46
+ <SettingsSection title={t("settings.language")}>
59
47
  <SettingItem
60
- icon="Languages"
61
- iconGradient={((tokens.colors as any).settingGradients?.language as unknown as string[]) || [tokens.colors.primary, tokens.colors.secondary]}
62
- title={t('settings.language')}
48
+ icon={Languages}
49
+ title={t("settings.language")}
63
50
  value={languageDisplay}
64
51
  onPress={handleLanguagePress}
65
- testID="language-button"
66
52
  />
67
- </View>
53
+ </SettingsSection>
68
54
 
69
55
  {/* Theme Section */}
70
- <View style={{ marginBottom: tokens.spacing.md }}>
71
- <AtomicText type="labelMedium" color="textSecondary" style={styles.sectionHeader}>
72
- {t('settings.appearance.darkMode')}
73
- </AtomicText>
56
+ <SettingsSection title={t("settings.appearance.darkMode")}>
74
57
  <SettingItem
75
- icon={themeMode === 'dark' ? 'Moon' : 'Sun'}
76
- iconGradient={
77
- themeMode === 'dark'
78
- ? (((tokens.colors as any).settingGradients?.themeDark as unknown as string[]) || [tokens.colors.primary, tokens.colors.secondary])
79
- : (((tokens.colors as any).settingGradients?.themeLight as unknown as string[]) || [tokens.colors.secondary, tokens.colors.primary])
80
- }
81
- title={t('settings.appearance.darkMode')}
58
+ icon={themeMode === "dark" ? Moon : Sun}
59
+ title={t("settings.appearance.darkMode")}
82
60
  value={themeDisplay}
83
61
  onPress={handleThemeToggle}
84
- testID="theme-button"
62
+ isLast={true}
85
63
  />
86
- </View>
64
+ </SettingsSection>
87
65
  </ScreenLayout>
88
66
  );
89
67
  };
@@ -91,23 +69,20 @@ export const AppearanceScreen: React.FC = () => {
91
69
  const getStyles = (tokens: DesignTokens) =>
92
70
  StyleSheet.create({
93
71
  header: {
94
- paddingBottom: tokens.spacing.lg,
95
- paddingTop: tokens.spacing.md,
96
72
  paddingHorizontal: tokens.spacing.lg,
73
+ paddingTop: tokens.spacing.lg,
74
+ paddingBottom: tokens.spacing.md,
97
75
  },
98
76
  headerSubtitle: {
99
- marginTop: tokens.spacing.sm,
100
- lineHeight: 20,
101
- opacity: 0.8,
77
+ marginTop: tokens.spacing.xs,
102
78
  },
103
79
  sectionHeader: {
104
80
  paddingHorizontal: tokens.spacing.lg,
105
81
  paddingTop: tokens.spacing.lg,
106
82
  paddingBottom: tokens.spacing.md,
107
- textTransform: 'uppercase',
83
+ textTransform: "uppercase",
108
84
  letterSpacing: 1,
109
- fontWeight: '600',
85
+ fontWeight: "600",
110
86
  fontSize: 12,
111
87
  },
112
88
  });
113
-
@@ -24,7 +24,7 @@ import { SettingItem } from "../components/SettingItem";
24
24
  import { SettingsSection } from "../components/SettingsSection";
25
25
  import { SettingsFooter } from "../components/SettingsFooter";
26
26
  import { UserProfileHeader } from "../components/UserProfileHeader";
27
- import { SettingsConfig } from "./types";
27
+ import { SettingsConfig, CustomSettingsSection } from "./types";
28
28
 
29
29
  // Optional notification service
30
30
  let notificationService: any = null;
@@ -92,6 +92,8 @@ export interface SettingsScreenProps {
92
92
  showFooter?: boolean;
93
93
  /** Custom footer text */
94
94
  footerText?: string;
95
+ /** Custom sections to render */
96
+ customSections?: CustomSettingsSection[];
95
97
  }
96
98
 
97
99
  export const SettingsScreen: React.FC<SettingsScreenProps> = ({
@@ -100,6 +102,7 @@ export const SettingsScreen: React.FC<SettingsScreenProps> = ({
100
102
  userProfile,
101
103
  showFooter = true,
102
104
  footerText,
105
+ customSections = [],
103
106
  }) => {
104
107
  const navigation = useNavigation();
105
108
  const { themeMode } = useDesignSystemTheme();
@@ -234,7 +237,16 @@ export const SettingsScreen: React.FC<SettingsScreenProps> = ({
234
237
  </SettingsSection>
235
238
  )}
236
239
 
237
- {!hasAnyFeatures && (
240
+ {/* Custom Sections */}
241
+ {customSections
242
+ .sort((a, b) => (a.order ?? 999) - (b.order ?? 999))
243
+ .map((section, index) => (
244
+ <SettingsSection key={`custom-${index}`} title={section.title}>
245
+ {section.content}
246
+ </SettingsSection>
247
+ ))}
248
+
249
+ {!hasAnyFeatures && customSections.length === 0 && (
238
250
  <View style={styles.emptyContainer}>
239
251
  <SettingsSection
240
252
  title={t("settings.noOptionsAvailable") || "No settings available"}
@@ -33,3 +33,16 @@ export interface SettingsConfig {
33
33
  legal?: boolean | 'auto';
34
34
  }
35
35
 
36
+ /**
37
+ * Custom Settings Section
38
+ * Allows apps to add custom sections to the settings screen
39
+ */
40
+ export interface CustomSettingsSection {
41
+ /** Section title */
42
+ title: string;
43
+ /** Section content (React nodes) */
44
+ content: React.ReactNode;
45
+ /** Section order (lower = higher in list) */
46
+ order?: number;
47
+ }
48
+