@umituz/react-native-settings 4.20.57 → 4.20.58

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/README.md CHANGED
@@ -33,7 +33,7 @@ npm install @umituz/react-native-settings
33
33
  ## Peer Dependencies
34
34
 
35
35
  ```bash
36
- npm install zustand @umituz/react-native-storage @umituz/react-native-design-system @umituz/react-native-localization @react-navigation/native @react-navigation/stack react-native-safe-area-context expo-linear-gradient
36
+ npm install zustand @umituz/react-native-storage @umituz/react-native-design-system @umituz/react-native-localization @react-navigation/native @react-navigation/stack react-native-safe-area-context
37
37
  ```
38
38
 
39
39
  ## Usage
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-settings",
3
- "version": "4.20.57",
3
+ "version": "4.20.58",
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",
@@ -122,10 +122,7 @@ jest.mock('react-native-safe-area-context', () => ({
122
122
  }),
123
123
  }));
124
124
 
125
- // Mock linear gradient
126
- jest.mock('expo-linear-gradient', () => ({
127
- LinearGradient: ({ children }: any) => children,
128
- }));
125
+
129
126
 
130
127
  // Mock notification service
131
128
  jest.mock('@umituz/react-native-notifications', () => ({
@@ -0,0 +1,493 @@
1
+ # Appearance Components
2
+
3
+ Components for theme management and appearance customization including theme selection, color picking, and live preview.
4
+
5
+ ## Components
6
+
7
+ ### AppearanceScreen
8
+
9
+ Main screen for managing appearance settings including theme mode and custom colors.
10
+
11
+ ```tsx
12
+ import { AppearanceScreen } from '@umituz/react-native-settings';
13
+
14
+ function AppearanceStack() {
15
+ return (
16
+ <Stack.Screen
17
+ name="Appearance"
18
+ component={AppearanceScreen}
19
+ options={{ title: 'Appearance' }}
20
+ />
21
+ );
22
+ }
23
+ ```
24
+
25
+ #### Features
26
+
27
+ - Theme mode selection (light/dark/auto)
28
+ - Custom color palette configuration
29
+ - Live theme preview
30
+ - Reset to defaults
31
+
32
+ #### Props
33
+
34
+ | Prop | Type | Default | Description |
35
+ |------|------|---------|-------------|
36
+ | `route` | `RouteProp` | **Required** | Route with optional config |
37
+ | `navigation` | `NavigationProp` | **Required** | Navigation object |
38
+
39
+ #### Route Params
40
+
41
+ ```typescript
42
+ interface AppearanceScreenParams {
43
+ showThemeSection?: boolean;
44
+ showColorsSection?: boolean;
45
+ showPreviewSection?: boolean;
46
+ }
47
+ ```
48
+
49
+ ### ThemeModeSection
50
+
51
+ Section component for selecting theme mode (light, dark, or auto/system).
52
+
53
+ ```tsx
54
+ import { ThemeModeSection } from '@umituz/react-native-settings';
55
+
56
+ function ThemeSelector() {
57
+ const { themeMode, setThemeMode } = useAppearance();
58
+
59
+ return (
60
+ <ThemeModeSection
61
+ themeMode={themeMode}
62
+ onThemeModeChange={setThemeMode}
63
+ />
64
+ );
65
+ }
66
+ ```
67
+
68
+ #### Props
69
+
70
+ | Prop | Type | Default | Description |
71
+ |------|------|---------|-------------|
72
+ | `themeMode` | `'light' \| 'dark' \| 'auto'` | **Required** | Current theme mode |
73
+ | `onThemeModeChange` | `(mode: 'light' \| 'dark' \| 'auto') => void` | **Required** | Theme change handler |
74
+ | `showPreview` | `boolean` | `true` | Show theme preview |
75
+ | `title` | `string` | `'Theme'` | Section title |
76
+
77
+ #### Example
78
+
79
+ ```tsx
80
+ <ThemeModeSection
81
+ themeMode="dark"
82
+ onThemeModeChange={(mode) => {
83
+ console.log('Theme changed to:', mode);
84
+ setThemeMode(mode);
85
+ }}
86
+ showPreview={true}
87
+ title="Appearance"
88
+ />
89
+ ```
90
+
91
+ ### CustomColorsSection
92
+
93
+ Section component for customizing color palette.
94
+
95
+ ```tsx
96
+ import { CustomColorsSection } from '@umituz/react-native-settings';
97
+
98
+ function ColorCustomizer() {
99
+ const { customColors, setCustomColors } = useAppearanceActions();
100
+
101
+ return (
102
+ <CustomColorsSection
103
+ colors={customColors || defaultColors}
104
+ onColorsChange={setCustomColors}
105
+ />
106
+ );
107
+ }
108
+ ```
109
+
110
+ #### Props
111
+
112
+ | Prop | Type | Default | Description |
113
+ |------|------|---------|-------------|
114
+ | `colors` | `ColorPalette` | **Required** | Current color palette |
115
+ | `onColorsChange` | `(colors: ColorPalette) => void` | **Required** | Color change handler |
116
+ | `availableColors` | `string[]` | `undefined` | Predefined color options |
117
+ | `showPreview` | `boolean` | `true` | Show color preview |
118
+ | `title` | `string` | `'Colors'` | Section title |
119
+
120
+ #### Example
121
+
122
+ ```tsx
123
+ <CustomColorsSection
124
+ colors={{
125
+ primary: '#FF5722',
126
+ secondary: '#2196F3',
127
+ accent: '#FFC107',
128
+ background: '#FFFFFF',
129
+ surface: '#F5F5F5',
130
+ }}
131
+ onColorsChange={(newColors) => {
132
+ setCustomColors(newColors);
133
+ }}
134
+ availableColors={[
135
+ '#FF5722', '#2196F3', '#4CAF50', '#FF9800',
136
+ '#9C27B0', '#00BCD4', '#8BC34A', '#FFC107'
137
+ ]}
138
+ />
139
+ ```
140
+
141
+ ### AppearancePreview
142
+
143
+ Component showing live preview of theme changes.
144
+
145
+ ```tsx
146
+ import { AppearancePreview } from '@umituz/react-native-settings';
147
+
148
+ function ThemePreview() {
149
+ const { themeMode, customColors } = useAppearance();
150
+
151
+ return (
152
+ <AppearancePreview
153
+ themeMode={themeMode}
154
+ customColors={customColors}
155
+ />
156
+ );
157
+ }
158
+ ```
159
+
160
+ #### Props
161
+
162
+ | Prop | Type | Default | Description |
163
+ |------|------|---------|-------------|
164
+ | `themeMode` | `'light' \| 'dark' \| 'auto'` | **Required** | Theme mode |
165
+ | `customColors` | `ColorPalette` | `undefined` | Custom colors |
166
+ | `showSystemTheme` | `boolean` | `true` | Show system theme |
167
+
168
+ ### ThemeOption
169
+
170
+ Individual theme option button/card.
171
+
172
+ ```tsx
173
+ import { ThemeOption } from '@umituz/react-native-settings';
174
+
175
+ function ThemeOptions() {
176
+ return (
177
+ <View>
178
+ <ThemeOption
179
+ mode="light"
180
+ title="Light"
181
+ icon="sunny-outline"
182
+ selected={themeMode === 'light'}
183
+ onPress={() => setThemeMode('light')}
184
+ />
185
+
186
+ <ThemeOption
187
+ mode="dark"
188
+ title="Dark"
189
+ icon="moon-outline"
190
+ selected={themeMode === 'dark'}
191
+ onPress={() => setThemeMode('dark')}
192
+ />
193
+
194
+ <ThemeOption
195
+ mode="auto"
196
+ title="Auto"
197
+ icon="phone-portrait-outline"
198
+ selected={themeMode === 'auto'}
199
+ onPress={() => setThemeMode('auto')}
200
+ />
201
+ </View>
202
+ );
203
+ }
204
+ ```
205
+
206
+ #### Props
207
+
208
+ | Prop | Type | Default | Description |
209
+ |------|------|---------|-------------|
210
+ | `mode` | `'light' \| 'dark' \| 'auto'` | **Required** | Theme mode |
211
+ | `title` | `string` | **Required** | Theme title |
212
+ | `icon` | `IconName` | **Required** | Theme icon |
213
+ | `selected` | `boolean` | `false` | Selected state |
214
+ | `onPress` | `() => void` | **Required** | Press handler |
215
+ | `description` | `string` | `undefined` | Theme description |
216
+
217
+ ### ColorPicker
218
+
219
+ Color picker component for selecting custom colors.
220
+
221
+ ```tsx
222
+ import { ColorPicker } from '@umituz/react-native-settings';
223
+
224
+ function PrimaryColorPicker() {
225
+ const [color, setColor] = useState('#FF5722');
226
+
227
+ return (
228
+ <ColorPicker
229
+ label="Primary Color"
230
+ value={color}
231
+ onChange={setColor}
232
+ availableColors={['#FF5722', '#2196F3', '#4CAF50', '#FF9800']}
233
+ />
234
+ );
235
+ }
236
+ ```
237
+
238
+ #### Props
239
+
240
+ | Prop | Type | Default | Description |
241
+ |------|------|---------|-------------|
242
+ | `label` | `string` | **Required** | Color label |
243
+ | `value` | `string` | **Required** | Current color (hex) |
244
+ | `onChange` | `(color: string) => void` | **Required** | Change handler |
245
+ | `availableColors` | `string[]` | `undefined` | Predefined colors |
246
+ | `showCustomPicker` | `boolean` | `true` | Show custom color picker |
247
+ | `allowAlpha` | `boolean` | `false` | Allow alpha channel |
248
+
249
+ ## Examples
250
+
251
+ ### Complete Appearance Screen
252
+
253
+ ```tsx
254
+ function AppearanceScreen() {
255
+ const { themeMode, customColors } = useAppearance();
256
+ const { setThemeMode, setCustomColors, resetColors } = useAppearanceActions();
257
+
258
+ return (
259
+ <ScrollView>
260
+ <AppearancePreview
261
+ themeMode={themeMode}
262
+ customColors={customColors}
263
+ />
264
+
265
+ <ThemeModeSection
266
+ themeMode={themeMode}
267
+ onThemeModeChange={setThemeMode}
268
+ showPreview={true}
269
+ />
270
+
271
+ <CustomColorsSection
272
+ colors={customColors || defaultColors}
273
+ onColorsChange={setCustomColors}
274
+ showPreview={true}
275
+ />
276
+
277
+ <TouchableOpacity onPress={resetColors}>
278
+ <Text>Reset to Defaults</Text>
279
+ </TouchableOpacity>
280
+ </ScrollView>
281
+ );
282
+ }
283
+ ```
284
+
285
+ ### Custom Color Palette
286
+
287
+ ```tsx
288
+ function CustomThemeBuilder() {
289
+ const [colors, setColors] = useState(defaultColors);
290
+ const { setCustomColors } = useAppearanceActions();
291
+
292
+ const handleColorChange = (key: string, value: string) => {
293
+ setColors(prev => ({ ...prev, [key]: value }));
294
+ };
295
+
296
+ return (
297
+ <View>
298
+ <ColorPicker
299
+ label="Primary"
300
+ value={colors.primary}
301
+ onChange={(color) => handleColorChange('primary', color)}
302
+ />
303
+
304
+ <ColorPicker
305
+ label="Secondary"
306
+ value={colors.secondary}
307
+ onChange={(color) => handleColorChange('secondary', color)}
308
+ />
309
+
310
+ <ColorPicker
311
+ label="Accent"
312
+ value={colors.accent}
313
+ onChange={(color) => handleColorChange('accent', color)}
314
+ />
315
+
316
+ <Button
317
+ onPress={() => setCustomColors(colors)}
318
+ title="Apply Theme"
319
+ />
320
+ </View>
321
+ );
322
+ }
323
+ ```
324
+
325
+ ### Theme Switcher
326
+
327
+ ```tsx
328
+ function QuickThemeSwitcher() {
329
+ const { themeMode, setThemeMode } = useAppearanceActions();
330
+
331
+ return (
332
+ <View style={styles.container}>
333
+ <TouchableOpacity
334
+ style={[styles.option, themeMode === 'light' && styles.selected]}
335
+ onPress={() => setThemeMode('light')}
336
+ >
337
+ <Ionicons name="sunny" size={24} />
338
+ <Text>Light</Text>
339
+ </TouchableOpacity>
340
+
341
+ <TouchableOpacity
342
+ style={[styles.option, themeMode === 'dark' && styles.selected]}
343
+ onPress={() => setThemeMode('dark')}
344
+ >
345
+ <Ionicons name="moon" size={24} />
346
+ <Text>Dark</Text>
347
+ </TouchableOpacity>
348
+
349
+ <TouchableOpacity
350
+ style={[styles.option, themeMode === 'auto' && styles.selected]}
351
+ onPress={() => setThemeMode('auto')}
352
+ >
353
+ <Ionicons name="phone-portrait" size={24} />
354
+ <Text>Auto</Text>
355
+ </TouchableOpacity>
356
+ </View>
357
+ );
358
+ }
359
+ ```
360
+
361
+ ### Preset Themes
362
+
363
+ ```tsx
364
+ function ThemePresets() {
365
+ const { setCustomColors } = useAppearanceActions();
366
+
367
+ const presets = {
368
+ ocean: {
369
+ primary: '#2196F3',
370
+ secondary: '#00BCD4',
371
+ accent: '#4FC3F7',
372
+ },
373
+ sunset: {
374
+ primary: '#FF5722',
375
+ secondary: '#FF9800',
376
+ accent: '#FFC107',
377
+ },
378
+ forest: {
379
+ primary: '#4CAF50',
380
+ secondary: '#8BC34A',
381
+ accent: '#CDDC39',
382
+ },
383
+ };
384
+
385
+ return (
386
+ <View>
387
+ <Text>Choose a preset theme:</Text>
388
+
389
+ {Object.entries(presets).map(([name, colors]) => (
390
+ <TouchableOpacity
391
+ key={name}
392
+ onPress={() => setCustomColors(colors)}
393
+ >
394
+ <View style={{ flexDirection: 'row' }}>
395
+ <View style={{ backgroundColor: colors.primary, width: 20, height: 20 }} />
396
+ <View style={{ backgroundColor: colors.secondary, width: 20, height: 20 }} />
397
+ <View style={{ backgroundColor: colors.accent, width: 20, height: 20 }} />
398
+ <Text>{name}</Text>
399
+ </View>
400
+ </TouchableOpacity>
401
+ ))}
402
+ </View>
403
+ );
404
+ }
405
+ ```
406
+
407
+ ## Styling
408
+
409
+ ### Theme Styles
410
+
411
+ ```typescript
412
+ const styles = StyleSheet.create({
413
+ container: {
414
+ padding: tokens.spacing.lg,
415
+ },
416
+ themeOption: {
417
+ flexDirection: 'row',
418
+ alignItems: 'center',
419
+ padding: tokens.spacing.md,
420
+ backgroundColor: tokens.colors.surface,
421
+ borderRadius: tokens.borderRadius.md,
422
+ marginBottom: tokens.spacing.sm,
423
+ },
424
+ themeOptionSelected: {
425
+ borderWidth: 2,
426
+ borderColor: tokens.colors.primary,
427
+ },
428
+ themeIcon: {
429
+ marginRight: tokens.spacing.md,
430
+ },
431
+ themeTitle: {
432
+ fontSize: tokens.typography.fontSize.base,
433
+ fontWeight: '600',
434
+ color: tokens.colors.textPrimary,
435
+ },
436
+ themeDescription: {
437
+ fontSize: tokens.typography.fontSize.sm,
438
+ color: tokens.colors.textSecondary,
439
+ },
440
+ });
441
+ ```
442
+
443
+ ## Color Palettes
444
+
445
+ ### Light Theme Default
446
+
447
+ ```typescript
448
+ const lightColors: ColorPalette = {
449
+ primary: '#2196F3',
450
+ secondary: '#00BCD4',
451
+ accent: '#FFC107',
452
+ background: '#FFFFFF',
453
+ surface: '#F5F5F5',
454
+ error: '#F44336',
455
+ success: '#4CAF50',
456
+ warning: '#FF9800',
457
+ };
458
+ ```
459
+
460
+ ### Dark Theme Default
461
+
462
+ ```typescript
463
+ const darkColors: ColorPalette = {
464
+ primary: '#2196F3',
465
+ secondary: '#00BCD4',
466
+ accent: '#FFC107',
467
+ background: '#121212',
468
+ surface: '#1E1E1E',
469
+ error: '#EF5350',
470
+ success: '#66BB6A',
471
+ warning: '#FFA726',
472
+ };
473
+ ```
474
+
475
+ ## Best Practices
476
+
477
+ 1. **Preview**: Always show theme preview
478
+ 2. **System Theme**: Respect system preference in auto mode
479
+ 3. **Persistence**: Save theme changes immediately
480
+ 4. **Validation**: Validate color hex codes
481
+ 5. **Reset**: Provide reset to defaults
482
+ 6. **Performance**: Use smooth transitions
483
+ 7. **Accessibility**: Ensure sufficient contrast
484
+
485
+ ## Related
486
+
487
+ - **Appearance Hooks**: Theme management hooks
488
+ - **Appearance Services**: System theme detection
489
+ - **Appearance Domain**: Appearance domain documentation
490
+
491
+ ## License
492
+
493
+ MIT
@@ -355,48 +355,42 @@ function NavigationBoundary() {
355
355
  ```tsx
356
356
  function StyledFallback({ error, resetError }) {
357
357
  return (
358
- <View style={styles.container}>
359
- <LinearGradient
360
- colors={['#667eea', '#764ba2']}
361
- style={styles.gradient}
362
- >
363
- <View style={styles.content}>
364
- <Ionicons
365
- name="warning-outline"
366
- size={80}
367
- color="white"
368
- style={styles.icon}
369
- />
370
-
371
- <Text style={styles.title}>Oops!</Text>
372
-
373
- <Text style={styles.message}>
374
- Something went wrong
375
- </Text>
376
-
377
- {__DEV__ && (
378
- <View style={styles.details}>
379
- <Text style={styles.errorText}>
380
- {error.message}
381
- </Text>
382
- </View>
383
- )}
358
+ <View style={[styles.container, { backgroundColor: '#f5f5f5' }]}>
359
+ <View style={styles.content}>
360
+ <Ionicons
361
+ name="warning-outline"
362
+ size={80}
363
+ color="#667eea"
364
+ style={styles.icon}
365
+ />
366
+
367
+ <Text style={styles.title}>Oops!</Text>
368
+
369
+ <Text style={styles.message}>
370
+ Something went wrong
371
+ </Text>
384
372
 
385
- <TouchableOpacity
386
- style={styles.button}
387
- onPress={resetError}
388
- >
389
- <Text style={styles.buttonText}>Try Again</Text>
390
- </TouchableOpacity>
391
- </View>
392
- </LinearGradient>
373
+ {__DEV__ && (
374
+ <View style={styles.details}>
375
+ <Text style={styles.errorText}>
376
+ {error.message}
377
+ </Text>
378
+ </View>
379
+ )}
380
+
381
+ <TouchableOpacity
382
+ style={styles.button}
383
+ onPress={resetError}
384
+ >
385
+ <Text style={styles.buttonText}>Try Again</Text>
386
+ </TouchableOpacity>
387
+ </View>
393
388
  </View>
394
389
  );
395
390
  }
396
391
 
397
392
  const styles = StyleSheet.create({
398
393
  container: { flex: 1 },
399
- gradient: { flex: 1 },
400
394
  content: {
401
395
  flex: 1,
402
396
  justifyContent: 'center',
@@ -407,34 +401,34 @@ const styles = StyleSheet.create({
407
401
  title: {
408
402
  fontSize: 32,
409
403
  fontWeight: 'bold',
410
- color: 'white',
404
+ color: '#333',
411
405
  marginBottom: 10,
412
406
  },
413
407
  message: {
414
408
  fontSize: 16,
415
- color: 'white',
409
+ color: '#666',
416
410
  textAlign: 'center',
417
411
  marginBottom: 20,
418
412
  },
419
413
  details: {
420
- backgroundColor: 'rgba(0,0,0,0.2)',
414
+ backgroundColor: '#eee',
421
415
  padding: 10,
422
416
  borderRadius: 8,
423
417
  marginBottom: 20,
424
418
  },
425
419
  errorText: {
426
- color: 'white',
420
+ color: '#666',
427
421
  fontSize: 12,
428
422
  fontFamily: 'monospace',
429
423
  },
430
424
  button: {
431
- backgroundColor: 'white',
425
+ backgroundColor: '#667eea',
432
426
  paddingHorizontal: 30,
433
427
  paddingVertical: 15,
434
428
  borderRadius: 25,
435
429
  },
436
430
  buttonText: {
437
- color: '#667eea',
431
+ color: 'white',
438
432
  fontWeight: 'bold',
439
433
  },
440
434
  });
@@ -8,7 +8,7 @@ A premium, consistent card component for settings items with icons, text, option
8
8
  - **Customizable**: Icon, title, subtitle, colors, and styles
9
9
  - **Interactive**: Press feedback, switch controls, right icons
10
10
  - **Accessible**: Full accessibility support with proper labels
11
- - **Modern**: Gradient overlays, smooth animations
11
+ - **Modern**: Sleek design, smooth animations
12
12
  - **Design System**: Uses tokens for consistent styling
13
13
 
14
14
  ## Installation
@@ -111,7 +111,7 @@ function CustomColoredItem() {
111
111
  ```
112
112
  SettingsItemCard
113
113
  ├── Icon Container
114
- │ ├── Icon Background (gradient)
114
+ │ ├── Icon Background
115
115
  │ └── Icon
116
116
  ├── Content
117
117
  │ ├── Title
@@ -324,7 +324,7 @@ const defaultIconColors = {
324
324
  title="Favorites"
325
325
  />
326
326
 
327
- // With gradient
327
+ // Custom color
328
328
  <SettingsItemCard
329
329
  icon="star"
330
330
  iconBgColor="#FFD700"