@umituz/react-native-localization 3.5.57 → 3.5.59

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-localization",
3
- "version": "3.5.57",
3
+ "version": "3.5.59",
4
4
  "description": "Generic localization system for React Native apps with i18n support",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -4,7 +4,9 @@
4
4
  */
5
5
 
6
6
  import React, { useMemo } from 'react';
7
- import { TouchableOpacity, Text } from 'react-native';
7
+ import { TouchableOpacity, View } from 'react-native';
8
+ // @ts-ignore - Optional peer dependency
9
+ import { useAppDesignTokens, AtomicText } from '@umituz/react-native-design-system';
8
10
  import { useLanguageSwitcher } from './useLanguageSwitcher';
9
11
  import { styles, DEFAULT_CONFIG_VALUES } from './LanguageSwitcher.styles';
10
12
 
@@ -21,41 +23,6 @@ export interface LanguageSwitcherProps {
21
23
  accessibilityLabel?: string;
22
24
  }
23
25
 
24
- const renderContent = (
25
- showFlag: boolean,
26
- showName: boolean,
27
- flag: string | undefined,
28
- nativeName: string,
29
- color: string | undefined,
30
- iconStyle: any,
31
- textStyle: any
32
- ) => {
33
- if (showFlag && showName) {
34
- return (
35
- <>
36
- <Text style={[styles.flag, iconStyle]}>{flag}</Text>
37
- <Text style={[styles.languageName, { color }, textStyle]}>
38
- {nativeName}
39
- </Text>
40
- </>
41
- );
42
- }
43
-
44
- if (showFlag) {
45
- return <Text style={[styles.flag, iconStyle]}>{flag}</Text>;
46
- }
47
-
48
- if (showName) {
49
- return (
50
- <Text style={[styles.languageName, { color }, textStyle]}>
51
- {nativeName}
52
- </Text>
53
- );
54
- }
55
-
56
- return <Text style={[styles.icon, { color }, iconStyle]}>🌐</Text>;
57
- };
58
-
59
26
  export const LanguageSwitcher: React.FC<LanguageSwitcherProps> = ({
60
27
  showName = false,
61
28
  showFlag = true,
@@ -68,6 +35,7 @@ export const LanguageSwitcher: React.FC<LanguageSwitcherProps> = ({
68
35
  disabled = false,
69
36
  accessibilityLabel,
70
37
  }) => {
38
+ const tokens = useAppDesignTokens();
71
39
  const { currentLang, handlePress } = useLanguageSwitcher({ onPress, disabled });
72
40
 
73
41
  const accessibilityProps = useMemo(() => ({
@@ -77,9 +45,16 @@ export const LanguageSwitcher: React.FC<LanguageSwitcherProps> = ({
77
45
  accessible: true,
78
46
  }), [accessibilityLabel, currentLang.nativeName, disabled]);
79
47
 
48
+ const textColor = color || tokens.colors.textPrimary;
49
+
80
50
  return (
81
51
  <TouchableOpacity
82
- style={[styles.container, style, disabled && styles.disabled]}
52
+ style={[
53
+ styles.container,
54
+ { gap: tokens.spacing.xs },
55
+ style,
56
+ disabled && styles.disabled
57
+ ]}
83
58
  onPress={handlePress}
84
59
  activeOpacity={disabled ? 1 : DEFAULT_CONFIG_VALUES.activeOpacity}
85
60
  hitSlop={DEFAULT_CONFIG_VALUES.hitSlop}
@@ -87,9 +62,27 @@ export const LanguageSwitcher: React.FC<LanguageSwitcherProps> = ({
87
62
  disabled={disabled}
88
63
  {...accessibilityProps}
89
64
  >
90
- {renderContent(showFlag, showName, currentLang.flag, currentLang.nativeName, color, iconStyle, textStyle)}
65
+ {showFlag && (
66
+ <AtomicText style={[styles.flag, iconStyle]}>
67
+ {currentLang.flag || '🌐'}
68
+ </AtomicText>
69
+ )}
70
+ {showName && (
71
+ <AtomicText
72
+ type="bodySmall"
73
+ style={[styles.languageName, { color: textColor, fontWeight: '600' }, textStyle]}
74
+ >
75
+ {currentLang.nativeName}
76
+ </AtomicText>
77
+ )}
78
+ {!showFlag && !showName && (
79
+ <AtomicText style={[styles.icon, { color: textColor }, iconStyle]}>
80
+ 🌐
81
+ </AtomicText>
82
+ )}
91
83
  </TouchableOpacity>
92
84
  );
93
85
  };
94
86
 
95
87
  export default LanguageSwitcher;
88
+
@@ -1,11 +1,11 @@
1
1
  // @ts-ignore - Optional peer dependency
2
- import { useNavigation } from '@react-navigation/native';
2
+ import { useAppNavigation } from '@umituz/react-native-design-system';
3
3
  import { useLocalization } from '../hooks/useLocalization';
4
4
  import { languageRepository } from '../repository/LanguageRepository';
5
5
 
6
6
 
7
7
  export const useLanguageNavigation = (navigationScreen: string) => {
8
- const navigation = useNavigation();
8
+ const navigation = useAppNavigation();
9
9
  const { currentLanguage } = useLocalization();
10
10
  const currentLang = languageRepository.getLanguageByCode(currentLanguage) || languageRepository.getDefaultLanguage();
11
11
 
@@ -9,10 +9,7 @@ export const styles = StyleSheet.create({
9
9
  flexDirection: 'row',
10
10
  alignItems: 'center',
11
11
  justifyContent: 'space-between',
12
- padding: 16,
13
- borderRadius: 12,
14
12
  borderWidth: 1,
15
- marginBottom: 8,
16
13
  },
17
14
  selectedLanguageItem: {
18
15
  borderWidth: 2,
@@ -29,18 +26,15 @@ export const styles = StyleSheet.create({
29
26
  languageText: {
30
27
  flex: 1,
31
28
  flexShrink: 1,
32
- marginRight: 12,
33
29
  },
34
30
  nativeName: {
35
- fontSize: 16,
36
- fontWeight: '600',
37
- marginBottom: 4,
31
+ // Styling moved to themedStyles in component for token support
38
32
  },
39
33
  languageName: {
40
- fontSize: 14,
34
+ // Styling moved to themedStyles in component for token support
41
35
  },
42
36
  checkIcon: {
43
- fontSize: 18,
44
- fontWeight: 'bold',
37
+ // Replaced by AtomicIcon
45
38
  },
46
39
  });
40
+
@@ -9,13 +9,12 @@ import React, { useMemo } from 'react';
9
9
  import {
10
10
  View,
11
11
  TouchableOpacity,
12
- Text,
13
12
  type StyleProp,
14
13
  type ViewStyle,
15
14
  type TextStyle,
16
15
  } from 'react-native';
17
16
  // @ts-ignore - Optional peer dependency
18
- import { useAppDesignTokens } from '@umituz/react-native-design-system';
17
+ import { useAppDesignTokens, AtomicText, AtomicIcon } from '@umituz/react-native-design-system';
19
18
  import type { Language } from '../../infrastructure/storage/types/Language';
20
19
  import { styles } from './LanguageItem.styles';
21
20
 
@@ -42,22 +41,24 @@ export const LanguageItem: React.FC<LanguageItemProps> = ({
42
41
 
43
42
  const themedStyles = useMemo(() => ({
44
43
  languageItem: {
44
+ padding: tokens.spacing.md,
45
+ borderRadius: tokens.borders.radius.md,
45
46
  backgroundColor: tokens.colors.backgroundSecondary,
46
47
  borderColor: tokens.colors.border,
48
+ marginBottom: tokens.spacing.sm,
47
49
  } as ViewStyle,
48
50
  selectedLanguageItem: {
49
51
  borderColor: tokens.colors.primary,
50
- backgroundColor: tokens.colors.primaryLight,
52
+ backgroundColor: tokens.colors.primaryContainer,
53
+ borderWidth: 2,
51
54
  } as ViewStyle,
52
55
  nativeName: {
53
56
  color: tokens.colors.textPrimary,
57
+ marginBottom: tokens.spacing.xs / 2,
54
58
  } as TextStyle,
55
59
  languageName: {
56
60
  color: tokens.colors.textSecondary,
57
61
  } as TextStyle,
58
- checkIcon: {
59
- color: tokens.colors.primary,
60
- } as TextStyle,
61
62
  }), [tokens]);
62
63
 
63
64
  return (
@@ -66,28 +67,35 @@ export const LanguageItem: React.FC<LanguageItemProps> = ({
66
67
  style={[
67
68
  styles.languageItem,
68
69
  themedStyles.languageItem,
69
- customStyles?.languageItem,
70
70
  isSelected ? [styles.selectedLanguageItem, themedStyles.selectedLanguageItem] : undefined,
71
+ customStyles?.languageItem,
71
72
  ]}
72
73
  onPress={() => onSelect(item.code)}
73
74
  activeOpacity={0.7}
74
75
  >
75
76
  <View style={[styles.languageContent, customStyles?.languageContent]}>
76
- <Text style={[styles.flag, customStyles?.flag]}>
77
+ <AtomicText style={[styles.flag, customStyles?.flag]}>
77
78
  {item.flag || '🌐'}
78
- </Text>
79
- <View style={[styles.languageText, customStyles?.languageText]}>
80
- <Text style={[styles.nativeName, themedStyles.nativeName, customStyles?.nativeName]}>
79
+ </AtomicText>
80
+ <View style={[styles.languageText, { gap: tokens.spacing.xs / 2 }, customStyles?.languageText]}>
81
+ <AtomicText
82
+ type="bodyMedium"
83
+ style={[themedStyles.nativeName, { fontWeight: '700' }, customStyles?.nativeName]}
84
+ >
81
85
  {item.nativeName}
82
- </Text>
83
- <Text style={[styles.languageName, themedStyles.languageName, customStyles?.nativeName]}>
86
+ </AtomicText>
87
+ <AtomicText
88
+ type="labelMedium"
89
+ style={[themedStyles.languageName, customStyles?.nativeName]}
90
+ >
84
91
  {item.name}
85
- </Text>
92
+ </AtomicText>
86
93
  </View>
87
94
  </View>
88
95
  {isSelected && (
89
- <Text style={[styles.checkIcon, themedStyles.checkIcon, customStyles?.flag]}>✓</Text>
96
+ <AtomicIcon name="checkmark" size="sm" color="primary" />
90
97
  )}
91
98
  </TouchableOpacity>
92
99
  );
93
100
  };
101
+
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
2
  import { View, StyleSheet, type ViewStyle } from 'react-native';
3
3
  // @ts-ignore - Optional peer dependency
4
- import { useNavigation } from '@react-navigation/native';
5
- // @ts-ignore - Optional peer dependency
6
4
  import {
7
5
  useAppDesignTokens,
8
6
  AtomicText,
9
- ListItem
7
+ ListItem,
8
+ useAppNavigation,
10
9
  } from '@umituz/react-native-design-system';
11
10
  import { useLocalization } from '../../infrastructure/hooks/useLocalization';
12
11
  import { getLanguageByCode } from '../../infrastructure/config/languages';
@@ -29,7 +28,7 @@ export const LanguageSection: React.FC<LanguageSectionProps> = ({
29
28
  containerStyle,
30
29
  sectionTitle,
31
30
  }) => {
32
- const navigation = useNavigation();
31
+ const navigation = useAppNavigation();
33
32
  const tokens = useAppDesignTokens();
34
33
  const { t, currentLanguage } = useLocalization();
35
34
 
@@ -6,10 +6,11 @@ import { StyleSheet } from 'react-native';
6
6
 
7
7
  export const styles = StyleSheet.create({
8
8
  container: {
9
- flex: 1,
9
+ // Styling handled by ScreenLayout
10
10
  },
11
11
  listContent: {
12
- paddingHorizontal: 20,
13
- paddingBottom: 32,
12
+ // Horizontal padding handled by ScreenLayout contentWrapper
13
+ // Bottom padding handled in component using tokens
14
14
  },
15
15
  });
16
+
@@ -4,11 +4,15 @@
4
4
  */
5
5
 
6
6
  import React from 'react';
7
- import { View, FlatList } from 'react-native';
7
+ import { FlatList } from 'react-native';
8
8
  // @ts-ignore - Optional peer dependency
9
- import { useNavigation } from '@react-navigation/native';
10
- // @ts-ignore - Optional peer dependency
11
- import { useAppDesignTokens, SearchBar } from '@umituz/react-native-design-system';
9
+ import {
10
+ useAppDesignTokens,
11
+ SearchBar,
12
+ ScreenLayout,
13
+ NavigationHeader,
14
+ useAppNavigation,
15
+ } from '@umituz/react-native-design-system';
12
16
  import { useLanguageSelection } from '../../infrastructure/hooks/useLanguageSelection';
13
17
  import { LanguageItem } from '../components/LanguageItem';
14
18
  import type { Language } from '../../infrastructure/storage/types/Language';
@@ -17,7 +21,8 @@ import { styles } from './LanguageSelectionScreen.styles';
17
21
  interface LanguageSelectionScreenProps {
18
22
  renderLanguageItem?: (item: Language, isSelected: boolean, onSelect: (code: string) => void) => React.ReactNode;
19
23
  renderSearchInput?: (value: string, onChange: (value: string) => void, placeholder: string) => React.ReactNode;
20
- containerComponent?: React.ComponentType<{ children: React.ReactNode }>;
24
+ headerTitle?: string;
25
+ onBackPress?: () => void;
21
26
  styles?: {
22
27
  container?: any;
23
28
  searchContainer?: any;
@@ -38,12 +43,13 @@ interface LanguageSelectionScreenProps {
38
43
  export const LanguageSelectionScreen: React.FC<LanguageSelectionScreenProps> = ({
39
44
  renderLanguageItem,
40
45
  renderSearchInput,
41
- containerComponent: Container,
46
+ headerTitle,
47
+ onBackPress,
42
48
  styles: customStyles,
43
49
  searchPlaceholder = "settings.languageSelection.searchPlaceholder",
44
50
  testID = 'language-selection-screen',
45
51
  }) => {
46
- const navigation = useNavigation();
52
+ const navigation = useAppNavigation();
47
53
  const tokens = useAppDesignTokens();
48
54
  const {
49
55
  searchQuery,
@@ -84,27 +90,53 @@ export const LanguageSelectionScreen: React.FC<LanguageSelectionScreenProps> = (
84
90
  value={searchQuery}
85
91
  onChangeText={setSearchQuery}
86
92
  placeholder={searchPlaceholder}
87
- containerStyle={customStyles?.searchContainer}
93
+ containerStyle={[
94
+ { marginBottom: tokens.spacing.md },
95
+ customStyles?.searchContainer
96
+ ]}
88
97
  inputStyle={customStyles?.searchInput}
89
98
  />
90
99
  );
91
100
  };
92
101
 
93
- const content = (
94
- <View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }, customStyles?.container]} testID={testID}>
102
+ const handleBack = () => {
103
+ if (onBackPress) {
104
+ onBackPress();
105
+ } else {
106
+ navigation.goBack();
107
+ }
108
+ };
109
+
110
+ return (
111
+ <ScreenLayout
112
+ testID={testID}
113
+ scrollable={false}
114
+ edges={['top', 'bottom', 'left', 'right']}
115
+ backgroundColor={tokens.colors.backgroundPrimary}
116
+ header={
117
+ <NavigationHeader
118
+ title={headerTitle || ""}
119
+ onBackPress={handleBack}
120
+ />
121
+ }
122
+ containerStyle={customStyles?.container}
123
+ >
95
124
  {renderSearchComponent()}
96
125
  <FlatList
97
126
  data={filteredLanguages}
98
127
  renderItem={renderItem}
99
128
  keyExtractor={item => item.code}
100
- contentContainerStyle={[styles.listContent, customStyles?.listContent]}
129
+ contentContainerStyle={[
130
+ styles.listContent,
131
+ { paddingBottom: tokens.spacing.xl },
132
+ customStyles?.listContent
133
+ ]}
101
134
  showsVerticalScrollIndicator={false}
102
135
  keyboardShouldPersistTaps="handled"
103
136
  />
104
- </View>
137
+ </ScreenLayout>
105
138
  );
106
-
107
- return Container ? <Container>{content}</Container> : content;
108
139
  };
109
140
 
110
141
  export default LanguageSelectionScreen;
142
+