@umituz/react-native-settings 4.20.56 → 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 +146 -4
- package/package.json +1 -2
- package/src/__tests__/setup.ts +1 -4
- package/src/application/README.md +322 -0
- package/src/domains/about/README.md +452 -0
- package/src/domains/about/presentation/hooks/README.md +350 -0
- package/src/domains/appearance/README.md +596 -0
- package/src/domains/appearance/hooks/README.md +366 -0
- package/src/domains/appearance/infrastructure/services/README.md +455 -0
- package/src/domains/appearance/presentation/components/README.md +493 -0
- package/src/domains/cloud-sync/README.md +451 -0
- package/src/domains/cloud-sync/presentation/components/README.md +493 -0
- package/src/domains/dev/README.md +477 -0
- package/src/domains/disclaimer/README.md +421 -0
- package/src/domains/disclaimer/presentation/components/README.md +394 -0
- package/src/domains/faqs/README.md +586 -0
- package/src/domains/feedback/README.md +565 -0
- package/src/domains/feedback/presentation/hooks/README.md +428 -0
- package/src/domains/legal/README.md +549 -0
- package/src/domains/rating/README.md +452 -0
- package/src/domains/rating/presentation/components/README.md +475 -0
- package/src/domains/video-tutorials/README.md +482 -0
- package/src/domains/video-tutorials/presentation/components/README.md +433 -0
- package/src/infrastructure/README.md +509 -0
- package/src/infrastructure/repositories/README.md +475 -0
- package/src/infrastructure/services/README.md +510 -0
- package/src/presentation/components/README.md +482 -0
- package/src/presentation/components/SettingsErrorBoundary/README.md +455 -0
- package/src/presentation/components/SettingsFooter/README.md +446 -0
- package/src/presentation/components/SettingsItemCard/README.md +457 -0
- package/src/presentation/components/SettingsSection/README.md +421 -0
- package/src/presentation/hooks/README.md +413 -0
- package/src/presentation/hooks/mutations/README.md +430 -0
- package/src/presentation/hooks/queries/README.md +441 -0
- package/src/presentation/navigation/README.md +532 -0
- package/src/presentation/navigation/components/README.md +330 -0
- package/src/presentation/navigation/hooks/README.md +399 -0
- package/src/presentation/navigation/utils/README.md +442 -0
- package/src/presentation/screens/README.md +525 -0
- package/src/presentation/screens/components/SettingsContent/README.md +404 -0
- package/src/presentation/screens/components/SettingsHeader/README.md +322 -0
- package/src/presentation/screens/components/sections/CustomSettingsList/README.md +388 -0
- package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +232 -0
- package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +325 -0
- package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +480 -0
- package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +391 -0
- package/src/presentation/screens/hooks/README.md +383 -0
- package/src/presentation/screens/types/README.md +439 -0
- package/src/presentation/screens/utils/README.md +288 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# Settings Content
|
|
2
|
+
|
|
3
|
+
Main content composer component that orchestrates all sections of the settings screen including profile, features, identity, support, and footer.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Section Composition**: Orchestrates all settings sections
|
|
8
|
+
- **Profile Header**: Optional user profile display
|
|
9
|
+
- **Custom Sections**: Support for app-specific sections
|
|
10
|
+
- **Feature Sections**: Appearance, language, notifications
|
|
11
|
+
- **Identity Sections**: About and legal information
|
|
12
|
+
- **Support Sections**: Feedback, rating, and FAQs
|
|
13
|
+
- **Empty State**: Graceful handling of empty configuration
|
|
14
|
+
- **Footer**: App version and build information
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
This component is part of `@umituz/react-native-settings`.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Basic Usage
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { SettingsContent } from '@umituz/react-native-settings';
|
|
26
|
+
|
|
27
|
+
function MySettingsScreen() {
|
|
28
|
+
const normalizedConfig = {
|
|
29
|
+
appearance: { config: {} },
|
|
30
|
+
language: { config: {} },
|
|
31
|
+
notifications: { config: {} },
|
|
32
|
+
about: { config: {} },
|
|
33
|
+
legal: { config: {} },
|
|
34
|
+
feedback: { config: {} },
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const features = {
|
|
38
|
+
appearance: true,
|
|
39
|
+
language: true,
|
|
40
|
+
notifications: true,
|
|
41
|
+
about: true,
|
|
42
|
+
legal: true,
|
|
43
|
+
feedback: true,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<SettingsContent
|
|
48
|
+
normalizedConfig={normalizedConfig}
|
|
49
|
+
features={features}
|
|
50
|
+
showFooter={true}
|
|
51
|
+
appVersion="1.0.0"
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Props
|
|
58
|
+
|
|
59
|
+
### SettingsContentProps
|
|
60
|
+
|
|
61
|
+
| Prop | Type | Default | Description |
|
|
62
|
+
|------|------|---------|-------------|
|
|
63
|
+
| `normalizedConfig` | `NormalizedConfig` | **Required** | Normalized configuration object |
|
|
64
|
+
| `config` | `any` | `undefined` | Raw config object |
|
|
65
|
+
| `features` | `FeatureFlags` | **Required** | Feature visibility flags |
|
|
66
|
+
| `showUserProfile` | `boolean` | `false` | Show user profile header |
|
|
67
|
+
| `userProfile` | `UserProfile` | `undefined` | User profile data |
|
|
68
|
+
| `showFooter` | `boolean` | `true` | Show footer with version |
|
|
69
|
+
| `footerText` | `string` | `undefined` | Custom footer text |
|
|
70
|
+
| `appVersion` | `string` | `undefined` | App version number |
|
|
71
|
+
| `customSections` | `CustomSection[]` | `[]` | Custom settings sections |
|
|
72
|
+
| `showCloseButton` | `boolean` | `false` | Show close button (unused) |
|
|
73
|
+
| `devSettings` | `DevSettingsProps` | `undefined` | Dev settings configuration |
|
|
74
|
+
|
|
75
|
+
### FeatureFlags
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
interface FeatureFlags {
|
|
79
|
+
appearance: boolean; // Show appearance settings
|
|
80
|
+
language: boolean; // Show language selection
|
|
81
|
+
notifications: boolean; // Show notification settings
|
|
82
|
+
about: boolean; // Show about section
|
|
83
|
+
legal: boolean; // Show legal section
|
|
84
|
+
disclaimer: boolean; // Show disclaimer
|
|
85
|
+
userProfile: boolean; // Show user profile
|
|
86
|
+
feedback: boolean; // Show feedback option
|
|
87
|
+
rating: boolean; // Show rating option
|
|
88
|
+
faqs: boolean; // Show FAQ access
|
|
89
|
+
subscription: boolean; // Show subscription option
|
|
90
|
+
wallet: boolean; // Show wallet option
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Component Structure
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
SettingsContent
|
|
98
|
+
├── ProfileSectionLoader (if showUserProfile)
|
|
99
|
+
├── CustomSettingsList (if customSections)
|
|
100
|
+
├── Subscription Item (if features.subscription)
|
|
101
|
+
├── Wallet Item (if features.wallet)
|
|
102
|
+
├── FeatureSettingsSection
|
|
103
|
+
│ ├── AppearanceSection (if features.appearance)
|
|
104
|
+
│ ├── Language Selection (if features.language)
|
|
105
|
+
│ └── NotificationsSection (if features.notifications)
|
|
106
|
+
├── IdentitySettingsSection
|
|
107
|
+
│ ├── AboutSection (if features.about)
|
|
108
|
+
│ └── LegalSection (if features.legal)
|
|
109
|
+
├── SupportSettingsSection
|
|
110
|
+
│ ├── Feedback (if features.feedback)
|
|
111
|
+
│ ├── Rating (if features.rating)
|
|
112
|
+
│ └── FAQ (if features.faqs)
|
|
113
|
+
├── DisclaimerSetting (if features.disclaimer)
|
|
114
|
+
├── Empty State (if no features)
|
|
115
|
+
├── DevSettingsSection (if devSettings)
|
|
116
|
+
└── SettingsFooter (if showFooter)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Examples
|
|
120
|
+
|
|
121
|
+
### Minimal Settings
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
function MinimalSettings() {
|
|
125
|
+
return (
|
|
126
|
+
<SettingsContent
|
|
127
|
+
normalizedConfig={{}}
|
|
128
|
+
features={{}}
|
|
129
|
+
showFooter={true}
|
|
130
|
+
/>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### With User Profile
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
function SettingsWithProfile() {
|
|
139
|
+
const userProfile = {
|
|
140
|
+
displayName: 'John Doe',
|
|
141
|
+
userId: 'user123',
|
|
142
|
+
avatarUrl: 'https://example.com/avatar.jpg',
|
|
143
|
+
onPress: () => navigation.navigate('Account'),
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<SettingsContent
|
|
148
|
+
normalizedConfig={{}}
|
|
149
|
+
features={{ userProfile: true }}
|
|
150
|
+
showUserProfile={true}
|
|
151
|
+
userProfile={userProfile}
|
|
152
|
+
/>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Full Featured Settings
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
function FullSettings() {
|
|
161
|
+
const normalizedConfig = {
|
|
162
|
+
appearance: { config: { showThemeSection: true } },
|
|
163
|
+
language: { config: { route: 'LanguageSelection' } },
|
|
164
|
+
notifications: { config: { showQuietHours: true } },
|
|
165
|
+
about: {
|
|
166
|
+
config: {
|
|
167
|
+
appName: 'My App',
|
|
168
|
+
version: '1.0.0',
|
|
169
|
+
developer: 'My Company',
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
legal: {
|
|
173
|
+
config: {
|
|
174
|
+
privacyPolicyUrl: 'https://example.com/privacy',
|
|
175
|
+
termsOfServiceUrl: 'https://example.com/terms',
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
subscription: {
|
|
179
|
+
config: {
|
|
180
|
+
title: 'Upgrade to Pro',
|
|
181
|
+
description: 'Get all features',
|
|
182
|
+
onPress: () => navigation.navigate('Upgrade'),
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const features = {
|
|
188
|
+
appearance: true,
|
|
189
|
+
language: true,
|
|
190
|
+
notifications: true,
|
|
191
|
+
about: true,
|
|
192
|
+
legal: true,
|
|
193
|
+
disclaimer: true,
|
|
194
|
+
feedback: true,
|
|
195
|
+
rating: true,
|
|
196
|
+
faqs: true,
|
|
197
|
+
subscription: true,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<SettingsContent
|
|
202
|
+
normalizedConfig={normalizedConfig}
|
|
203
|
+
features={features}
|
|
204
|
+
showUserProfile={true}
|
|
205
|
+
userProfile={userProfile}
|
|
206
|
+
showFooter={true}
|
|
207
|
+
appVersion="1.0.0"
|
|
208
|
+
/>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### With Custom Sections
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
function SettingsWithCustomSections() {
|
|
217
|
+
const customSections = [
|
|
218
|
+
{
|
|
219
|
+
title: 'INTEGRATIONS',
|
|
220
|
+
items: [
|
|
221
|
+
{
|
|
222
|
+
title: 'Google',
|
|
223
|
+
icon: 'logo-google',
|
|
224
|
+
onPress: () => manageGoogle(),
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<SettingsContent
|
|
232
|
+
normalizedConfig={{}}
|
|
233
|
+
features={{}}
|
|
234
|
+
customSections={customSections}
|
|
235
|
+
/>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### With Dev Settings
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
import { DevSettingsSection } from '@umituz/react-native-settings';
|
|
244
|
+
|
|
245
|
+
function DevelopmentSettings() {
|
|
246
|
+
return (
|
|
247
|
+
<SettingsContent
|
|
248
|
+
normalizedConfig={{}}
|
|
249
|
+
features={{}}
|
|
250
|
+
devSettings={{
|
|
251
|
+
enabled: true,
|
|
252
|
+
onAfterClear: async () => {
|
|
253
|
+
await resetApp();
|
|
254
|
+
Updates.reloadAsync();
|
|
255
|
+
},
|
|
256
|
+
}}
|
|
257
|
+
/>
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Custom Footer Text
|
|
263
|
+
|
|
264
|
+
```tsx
|
|
265
|
+
function CustomFooterSettings() {
|
|
266
|
+
return (
|
|
267
|
+
<SettingsContent
|
|
268
|
+
normalizedConfig={{}}
|
|
269
|
+
features={{}}
|
|
270
|
+
showFooter={true}
|
|
271
|
+
footerText="© 2025 My Company. All rights reserved."
|
|
272
|
+
/>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Empty State
|
|
278
|
+
|
|
279
|
+
When no features are enabled, shows empty state:
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
// Renders empty state section
|
|
283
|
+
<SettingsContent
|
|
284
|
+
normalizedConfig={{}}
|
|
285
|
+
features={{}}
|
|
286
|
+
/>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Empty state text can be customized via `config.emptyStateText` or translation key `settings.noOptionsAvailable`.
|
|
290
|
+
|
|
291
|
+
## Sub-Components
|
|
292
|
+
|
|
293
|
+
### ProfileSectionLoader
|
|
294
|
+
|
|
295
|
+
Loads and displays user profile header.
|
|
296
|
+
|
|
297
|
+
```tsx
|
|
298
|
+
<ProfileSectionLoader userProfile={userProfile} />
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### CustomSettingsList
|
|
302
|
+
|
|
303
|
+
Renders custom app-specific sections.
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
<CustomSettingsList customSections={customSections} />
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Subscription Item
|
|
310
|
+
|
|
311
|
+
Special item for subscription/upgrade.
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
<SettingsItemCard
|
|
315
|
+
title="Upgrade to Pro"
|
|
316
|
+
description="Get all features"
|
|
317
|
+
icon="star"
|
|
318
|
+
onPress={handleUpgrade}
|
|
319
|
+
sectionTitle="SUBSCRIPTION"
|
|
320
|
+
/>
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Wallet Item
|
|
324
|
+
|
|
325
|
+
Special item for wallet/payment settings.
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
<WalletSettingsItem
|
|
329
|
+
config={{
|
|
330
|
+
title: 'Wallet',
|
|
331
|
+
description: 'Manage payment',
|
|
332
|
+
icon: 'wallet',
|
|
333
|
+
route: 'Wallet',
|
|
334
|
+
}}
|
|
335
|
+
t={t}
|
|
336
|
+
/>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Feature Detection
|
|
340
|
+
|
|
341
|
+
Uses `hasAnyFeatures` to determine if empty state should be shown:
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
const hasAnyFeatures = useMemo(() =>
|
|
345
|
+
features.appearance ||
|
|
346
|
+
features.language ||
|
|
347
|
+
features.notifications ||
|
|
348
|
+
features.about ||
|
|
349
|
+
features.legal ||
|
|
350
|
+
features.disclaimer ||
|
|
351
|
+
features.feedback ||
|
|
352
|
+
features.rating ||
|
|
353
|
+
features.faqs ||
|
|
354
|
+
features.subscription ||
|
|
355
|
+
features.wallet ||
|
|
356
|
+
customSections.length > 0,
|
|
357
|
+
[features, customSections.length]
|
|
358
|
+
);
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Internationalization
|
|
362
|
+
|
|
363
|
+
Translation keys used:
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
// Section titles
|
|
367
|
+
t("settings.title")
|
|
368
|
+
|
|
369
|
+
// Subscription
|
|
370
|
+
t("settings.subscription.title")
|
|
371
|
+
t("settings.subscription.description")
|
|
372
|
+
|
|
373
|
+
// Wallet
|
|
374
|
+
t("wallet.title")
|
|
375
|
+
t("wallet.description")
|
|
376
|
+
|
|
377
|
+
// Footer
|
|
378
|
+
t("settings.footer.version")
|
|
379
|
+
|
|
380
|
+
// Empty state
|
|
381
|
+
t("settings.noOptionsAvailable")
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## Best Practices
|
|
385
|
+
|
|
386
|
+
1. **Normalize Config**: Always normalize config before passing
|
|
387
|
+
2. **Feature Flags**: Use feature flags to control visibility
|
|
388
|
+
3. **Order Matters**: Sections render in defined order
|
|
389
|
+
4. **User Profile**: Show profile only for authenticated users
|
|
390
|
+
5. **Footer Info**: Always include app version in footer
|
|
391
|
+
6. **Empty State**: Provide meaningful empty state message
|
|
392
|
+
7. **Dev Settings**: Include dev settings for development builds
|
|
393
|
+
8. **Custom Sections**: Use custom sections for app-specific features
|
|
394
|
+
|
|
395
|
+
## Related
|
|
396
|
+
|
|
397
|
+
- **SettingsScreen**: Main screen component
|
|
398
|
+
- **SettingsHeader**: Header component
|
|
399
|
+
- **ProfileSectionLoader**: Profile component
|
|
400
|
+
- **Feature Sections**: Individual section components
|
|
401
|
+
|
|
402
|
+
## License
|
|
403
|
+
|
|
404
|
+
MIT
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Settings Header
|
|
2
|
+
|
|
3
|
+
Header component for the settings screen with optional close button functionality.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Screen Title**: Displays localized "Settings" title
|
|
8
|
+
- **Close Button**: Optional close button for modal/presentation
|
|
9
|
+
- **Auto Navigation**: Automatically goes back if no custom handler
|
|
10
|
+
- **Design System**: Uses design system tokens for styling
|
|
11
|
+
- **Internationalization**: Supports i18n
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
This component is part of `@umituz/react-native-settings`.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Basic Header
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { SettingsHeader } from '@umituz/react-native-settings';
|
|
23
|
+
|
|
24
|
+
function MySettingsScreen() {
|
|
25
|
+
return (
|
|
26
|
+
<>
|
|
27
|
+
<SettingsHeader />
|
|
28
|
+
{/* Rest of screen content */}
|
|
29
|
+
</>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### With Close Button
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
function ModalSettingsScreen() {
|
|
38
|
+
const handleClose = () => {
|
|
39
|
+
navigation.goBack();
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<>
|
|
44
|
+
<SettingsHeader
|
|
45
|
+
showCloseButton={true}
|
|
46
|
+
onClose={handleClose}
|
|
47
|
+
/>
|
|
48
|
+
{/* Settings content */}
|
|
49
|
+
</>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Props
|
|
55
|
+
|
|
56
|
+
### SettingsHeaderProps
|
|
57
|
+
|
|
58
|
+
| Prop | Type | Default | Description |
|
|
59
|
+
|------|------|---------|-------------|
|
|
60
|
+
| `showCloseButton` | `boolean` | `false` | Show close button |
|
|
61
|
+
| `onClose` | `() => void` | `undefined` | Custom close handler |
|
|
62
|
+
|
|
63
|
+
## Behavior
|
|
64
|
+
|
|
65
|
+
### Close Button
|
|
66
|
+
|
|
67
|
+
When `showCloseButton` is `true`:
|
|
68
|
+
|
|
69
|
+
- If `onClose` provided: Calls `onClose()`
|
|
70
|
+
- If no `onClose`: Calls `navigation.goBack()`
|
|
71
|
+
|
|
72
|
+
### Close Handler
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
const handleClose = () => {
|
|
76
|
+
if (onClose) {
|
|
77
|
+
onClose(); // Use custom handler
|
|
78
|
+
} else {
|
|
79
|
+
navigation.goBack(); // Default navigation
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Examples
|
|
85
|
+
|
|
86
|
+
### Modal Settings
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { SettingsHeader } from '@umituz/react-native-settings';
|
|
90
|
+
import { Modal } from 'react-native';
|
|
91
|
+
|
|
92
|
+
function SettingsModal({ visible, onClose }) {
|
|
93
|
+
return (
|
|
94
|
+
<Modal visible={visible} animationType="slide">
|
|
95
|
+
<SettingsHeader
|
|
96
|
+
showCloseButton={true}
|
|
97
|
+
onClose={onClose}
|
|
98
|
+
/>
|
|
99
|
+
<SettingsContent />
|
|
100
|
+
</Modal>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Presentation Style
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { SettingsHeader } from '@umituz/react-native-settings';
|
|
109
|
+
|
|
110
|
+
function PresentationSettings() {
|
|
111
|
+
const navigation = useNavigation();
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<Stack.Screen
|
|
115
|
+
name="Settings"
|
|
116
|
+
options={{
|
|
117
|
+
presentation: 'modal',
|
|
118
|
+
headerShown: false,
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
{() => (
|
|
122
|
+
<View>
|
|
123
|
+
<SettingsHeader
|
|
124
|
+
showCloseButton={true}
|
|
125
|
+
onClose={() => navigation.goBack()}
|
|
126
|
+
/>
|
|
127
|
+
<SettingsContent />
|
|
128
|
+
</View>
|
|
129
|
+
)}
|
|
130
|
+
</Stack.Screen>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Custom Close Action
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
function SettingsWithCustomClose() {
|
|
139
|
+
const handleClose = () => {
|
|
140
|
+
// Custom logic before closing
|
|
141
|
+
saveDraftChanges();
|
|
142
|
+
navigation.goBack();
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<SettingsHeader
|
|
147
|
+
showCloseButton={true}
|
|
148
|
+
onClose={handleClose}
|
|
149
|
+
/>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Close with Confirmation
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
function SettingsWithConfirmation() {
|
|
158
|
+
const handleClose = () => {
|
|
159
|
+
Alert.alert(
|
|
160
|
+
'Discard Changes?',
|
|
161
|
+
'You have unsaved changes',
|
|
162
|
+
[
|
|
163
|
+
{ text: 'Keep Editing', style: 'cancel' },
|
|
164
|
+
{
|
|
165
|
+
text: 'Discard',
|
|
166
|
+
style: 'destructive',
|
|
167
|
+
onPress: () => navigation.goBack(),
|
|
168
|
+
},
|
|
169
|
+
]
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<SettingsHeader
|
|
175
|
+
showCloseButton={true}
|
|
176
|
+
onClose={handleClose}
|
|
177
|
+
/>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Styling
|
|
183
|
+
|
|
184
|
+
### Layout
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const styles = StyleSheet.create({
|
|
188
|
+
container: {
|
|
189
|
+
flexDirection: 'row',
|
|
190
|
+
justifyContent: 'space-between',
|
|
191
|
+
alignItems: 'center',
|
|
192
|
+
padding: tokens.spacing.lg, // 16px
|
|
193
|
+
},
|
|
194
|
+
closeButton: {
|
|
195
|
+
width: 44,
|
|
196
|
+
height: 44,
|
|
197
|
+
justifyContent: 'center',
|
|
198
|
+
alignItems: 'center',
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Pressable Style
|
|
204
|
+
|
|
205
|
+
The close button uses Pressable with pressed state:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
style={({ pressed }) => [
|
|
209
|
+
styles.closeButton,
|
|
210
|
+
{
|
|
211
|
+
backgroundColor: pressed
|
|
212
|
+
? tokens.colors.surfaceVariant
|
|
213
|
+
: tokens.colors.surface,
|
|
214
|
+
borderRadius: tokens.borderRadius.full,
|
|
215
|
+
},
|
|
216
|
+
]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Internationalization
|
|
220
|
+
|
|
221
|
+
Uses translation key for title:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
t('settings.title')
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Design System Integration
|
|
228
|
+
|
|
229
|
+
- **Typography**: `tokens.typography.headingLarge` for title
|
|
230
|
+
- **Colors**: `tokens.colors.textPrimary` for close icon
|
|
231
|
+
- **Spacing**: `tokens.spacing.lg` for padding
|
|
232
|
+
- **Border Radius**: `tokens.borderRadius.full` for button
|
|
233
|
+
- **Icons**: `AtomicIcon` from design system
|
|
234
|
+
|
|
235
|
+
## Accessibility
|
|
236
|
+
|
|
237
|
+
### Hit Slop
|
|
238
|
+
|
|
239
|
+
Close button has increased hit area:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Icon
|
|
246
|
+
|
|
247
|
+
Uses `close-outline` icon from Ionicons:
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
<AtomicIcon name="close-outline" size="lg" color="textPrimary" />
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Best Practices
|
|
254
|
+
|
|
255
|
+
1. **Modal Screens**: Always use close button in modal presentation
|
|
256
|
+
2. **Custom Handler**: Provide custom close handler when needed
|
|
257
|
+
3. **Confirmation**: Ask for confirmation if there are unsaved changes
|
|
258
|
+
4. **Consistent Position**: Keep header at top of screen
|
|
259
|
+
5. **Padding**: Use design system spacing for consistency
|
|
260
|
+
6. **Accessibility**: Ensure close button is easily tappable
|
|
261
|
+
|
|
262
|
+
## Use Cases
|
|
263
|
+
|
|
264
|
+
### Modal Presentation
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
<Stack.Screen
|
|
268
|
+
name="Settings"
|
|
269
|
+
options={{
|
|
270
|
+
presentation: 'modal',
|
|
271
|
+
headerShown: false,
|
|
272
|
+
}}
|
|
273
|
+
>
|
|
274
|
+
{() => (
|
|
275
|
+
<View>
|
|
276
|
+
<SettingsHeader showCloseButton={true} />
|
|
277
|
+
<SettingsContent />
|
|
278
|
+
</View>
|
|
279
|
+
)}
|
|
280
|
+
</Stack.Screen>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Full Screen with Close
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
function FullScreenSettings() {
|
|
287
|
+
return (
|
|
288
|
+
<ScreenLayout
|
|
289
|
+
header={<SettingsHeader showCloseButton={true} />}
|
|
290
|
+
>
|
|
291
|
+
<SettingsContent />
|
|
292
|
+
</ScreenLayout>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### No Close Button (Default)
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
function RegularSettingsScreen() {
|
|
301
|
+
return (
|
|
302
|
+
<Stack.Screen name="Settings">
|
|
303
|
+
{() => (
|
|
304
|
+
<View>
|
|
305
|
+
<SettingsHeader />
|
|
306
|
+
<SettingsContent />
|
|
307
|
+
</View>
|
|
308
|
+
)}
|
|
309
|
+
</Stack.Screen>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Related
|
|
315
|
+
|
|
316
|
+
- **SettingsScreen**: Main screen component
|
|
317
|
+
- **SettingsContent**: Content component
|
|
318
|
+
- **Design System**: Styling and theming
|
|
319
|
+
|
|
320
|
+
## License
|
|
321
|
+
|
|
322
|
+
MIT
|