@umituz/react-native-design-system 2.6.94 → 2.6.95
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 +1 -1
- package/src/atoms/AtomicAvatar.README.md +284 -397
- package/src/atoms/AtomicBadge.README.md +123 -358
- package/src/atoms/AtomicCard.README.md +358 -247
- package/src/atoms/AtomicDatePicker.README.md +127 -332
- package/src/atoms/AtomicFab.README.md +194 -352
- package/src/atoms/AtomicIcon.README.md +241 -274
- package/src/atoms/AtomicProgress.README.md +100 -338
- package/src/atoms/AtomicSpinner.README.md +304 -337
- package/src/atoms/AtomicText.README.md +153 -389
- package/src/atoms/AtomicTextArea.README.md +267 -268
- package/src/atoms/EmptyState.README.md +247 -292
- package/src/atoms/GlassView/README.md +313 -444
- package/src/atoms/button/README.md +186 -297
- package/src/atoms/button/STRATEGY.md +252 -0
- package/src/atoms/chip/README.md +242 -290
- package/src/atoms/input/README.md +296 -290
- package/src/atoms/picker/README.md +278 -309
- package/src/atoms/skeleton/AtomicSkeleton.README.md +394 -252
- package/src/molecules/BaseModal/README.md +356 -0
- package/src/molecules/BaseModal.README.md +324 -200
- package/src/molecules/ConfirmationModal.README.md +349 -302
- package/src/molecules/Divider/README.md +293 -376
- package/src/molecules/FormField.README.md +321 -534
- package/src/molecules/GlowingCard/GlowingCard.tsx +1 -1
- package/src/molecules/GlowingCard/README.md +230 -372
- package/src/molecules/List/README.md +281 -488
- package/src/molecules/ListItem.README.md +320 -315
- package/src/molecules/SearchBar/README.md +332 -430
- package/src/molecules/StepHeader/README.md +311 -411
- package/src/molecules/StepProgress/README.md +281 -448
- package/src/molecules/alerts/README.md +272 -355
- package/src/molecules/avatar/README.md +295 -356
- package/src/molecules/bottom-sheet/README.md +303 -340
- package/src/molecules/calendar/README.md +301 -265
- package/src/molecules/countdown/README.md +347 -456
- package/src/molecules/emoji/README.md +281 -514
- package/src/molecules/listitem/README.md +307 -399
- package/src/molecules/media-card/MediaCard.tsx +31 -34
- package/src/molecules/media-card/README.md +217 -319
- package/src/molecules/navigation/README.md +263 -284
- package/src/molecules/splash/README.md +76 -80
- package/src/molecules/swipe-actions/README.md +376 -588
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
# BaseModal
|
|
2
2
|
|
|
3
|
-
BaseModal
|
|
3
|
+
BaseModal is a generic fullscreen modal component for React Native. Works with responsive design and provides a consistent base for all modal types.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
- 📱 **Responsive**:
|
|
8
|
-
- 🎨 **
|
|
9
|
-
- ⬛ **Backdrop**:
|
|
10
|
-
- ❌ **Dismiss
|
|
11
|
-
- ♿ **
|
|
12
|
-
- 🔄 **Fade Animation**:
|
|
7
|
+
- 📱 **Responsive**: Adapts to device size
|
|
8
|
+
- 🎨 **Theme-Aware**: Full theme integration
|
|
9
|
+
- ⬛ **Backdrop**: Opaque background
|
|
10
|
+
- ❌ **Dismiss on Backdrop**: Close by tapping backdrop
|
|
11
|
+
- ♿ **Accessible**: Full accessibility support
|
|
12
|
+
- 🔄 **Fade Animation**: Smooth fade animation
|
|
13
|
+
- 📏 **Auto-sizing**: Responsive width and height
|
|
14
|
+
- 🔲 **Bordered**: Styled with border
|
|
13
15
|
|
|
14
|
-
##
|
|
16
|
+
## Installation
|
|
15
17
|
|
|
16
18
|
```tsx
|
|
17
19
|
import { BaseModal } from 'react-native-design-system';
|
|
18
20
|
```
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## Basic Usage
|
|
21
23
|
|
|
22
24
|
```tsx
|
|
23
25
|
import React, { useState } from 'react';
|
|
@@ -29,14 +31,14 @@ export const BasicExample = () => {
|
|
|
29
31
|
|
|
30
32
|
return (
|
|
31
33
|
<View style={{ padding: 16 }}>
|
|
32
|
-
<Button title="
|
|
34
|
+
<Button title="Open Modal" onPress={() => setVisible(true)} />
|
|
33
35
|
|
|
34
36
|
<BaseModal
|
|
35
37
|
visible={visible}
|
|
36
38
|
onClose={() => setVisible(false)}
|
|
37
39
|
>
|
|
38
40
|
<View style={{ padding: 24 }}>
|
|
39
|
-
<Text>Modal
|
|
41
|
+
<Text>Modal Content</Text>
|
|
40
42
|
</View>
|
|
41
43
|
</BaseModal>
|
|
42
44
|
</View>
|
|
@@ -55,10 +57,10 @@ const [visible, setVisible] = useState(false);
|
|
|
55
57
|
>
|
|
56
58
|
<View style={{ padding: 24 }}>
|
|
57
59
|
<Text style={{ fontSize: 20, fontWeight: 'bold' }}>
|
|
58
|
-
|
|
60
|
+
Title
|
|
59
61
|
</Text>
|
|
60
62
|
<Text style={{ marginTop: 16 }}>
|
|
61
|
-
Modal
|
|
63
|
+
Modal content goes here.
|
|
62
64
|
</Text>
|
|
63
65
|
</View>
|
|
64
66
|
</BaseModal>
|
|
@@ -72,7 +74,8 @@ const [visible, setVisible] = useState(false);
|
|
|
72
74
|
onClose={() => setVisible(false)}
|
|
73
75
|
dismissOnBackdrop={false}
|
|
74
76
|
>
|
|
75
|
-
{/*
|
|
77
|
+
{/* User must press close button */}
|
|
78
|
+
<Button title="Close" onPress={() => setVisible(false)} />
|
|
76
79
|
</BaseModal>
|
|
77
80
|
```
|
|
78
81
|
|
|
@@ -87,37 +90,46 @@ const [visible, setVisible] = useState(false);
|
|
|
87
90
|
padding: 32,
|
|
88
91
|
}}
|
|
89
92
|
>
|
|
90
|
-
<Text
|
|
93
|
+
<Text>Custom Style</Text>
|
|
91
94
|
</BaseModal>
|
|
92
95
|
```
|
|
93
96
|
|
|
94
|
-
##
|
|
97
|
+
## Example Usages
|
|
95
98
|
|
|
96
|
-
###
|
|
99
|
+
### Confirmation Modal
|
|
97
100
|
|
|
98
101
|
```tsx
|
|
99
102
|
export const ConfirmationModal = ({ visible, onClose, onConfirm }) => {
|
|
100
103
|
return (
|
|
101
|
-
<BaseModal
|
|
104
|
+
<BaseModal
|
|
105
|
+
visible={visible}
|
|
106
|
+
onClose={onClose}
|
|
107
|
+
>
|
|
102
108
|
<View style={{ padding: 24, alignItems: 'center' }}>
|
|
103
|
-
<AtomicIcon
|
|
104
|
-
name="warning"
|
|
105
|
-
size="xl"
|
|
106
|
-
color="warning"
|
|
107
|
-
style={{ marginBottom: 16 }}
|
|
108
|
-
/>
|
|
109
|
+
<AtomicIcon name="warning" size="xl" color="warning" />
|
|
109
110
|
|
|
110
|
-
<Text style={{ fontSize: 20, fontWeight: 'bold',
|
|
111
|
-
|
|
111
|
+
<Text style={{ fontSize: 20, fontWeight: 'bold', marginTop: 16 }}>
|
|
112
|
+
Confirm Action
|
|
112
113
|
</Text>
|
|
113
114
|
|
|
114
|
-
<Text style={{
|
|
115
|
-
|
|
115
|
+
<Text style={{ marginTop: 8, textAlign: 'center' }}>
|
|
116
|
+
Are you sure you want to proceed?
|
|
116
117
|
</Text>
|
|
117
118
|
|
|
118
|
-
<View style={{ flexDirection: 'row', gap: 12 }}>
|
|
119
|
-
<Button
|
|
120
|
-
|
|
119
|
+
<View style={{ flexDirection: 'row', marginTop: 24, gap: 12 }}>
|
|
120
|
+
<Button
|
|
121
|
+
title="Cancel"
|
|
122
|
+
variant="ghost"
|
|
123
|
+
onPress={onClose}
|
|
124
|
+
/>
|
|
125
|
+
<Button
|
|
126
|
+
title="Confirm"
|
|
127
|
+
variant="primary"
|
|
128
|
+
onPress={() => {
|
|
129
|
+
onConfirm();
|
|
130
|
+
onClose();
|
|
131
|
+
}}
|
|
132
|
+
/>
|
|
121
133
|
</View>
|
|
122
134
|
</View>
|
|
123
135
|
</BaseModal>
|
|
@@ -125,212 +137,323 @@ export const ConfirmationModal = ({ visible, onClose, onConfirm }) => {
|
|
|
125
137
|
};
|
|
126
138
|
```
|
|
127
139
|
|
|
128
|
-
### Form
|
|
140
|
+
### Form Modal
|
|
129
141
|
|
|
130
142
|
```tsx
|
|
131
|
-
export const FormModal = ({ visible, onClose }) => {
|
|
143
|
+
export const FormModal = ({ visible, onClose, onSubmit }) => {
|
|
132
144
|
const [formData, setFormData] = useState({
|
|
133
145
|
name: '',
|
|
134
146
|
email: '',
|
|
135
147
|
});
|
|
136
148
|
|
|
137
|
-
const handleSubmit = () => {
|
|
138
|
-
console.log(formData);
|
|
139
|
-
onClose();
|
|
140
|
-
};
|
|
141
|
-
|
|
142
149
|
return (
|
|
143
|
-
<BaseModal
|
|
150
|
+
<BaseModal
|
|
151
|
+
visible={visible}
|
|
152
|
+
onClose={onClose}
|
|
153
|
+
>
|
|
144
154
|
<View style={{ padding: 24 }}>
|
|
145
|
-
<Text style={{ fontSize:
|
|
146
|
-
|
|
155
|
+
<Text style={{ fontSize: 24, fontWeight: 'bold' }}>
|
|
156
|
+
Add User
|
|
147
157
|
</Text>
|
|
148
158
|
|
|
149
159
|
<FormField
|
|
150
|
-
label="
|
|
160
|
+
label="Name"
|
|
151
161
|
value={formData.name}
|
|
152
162
|
onChangeText={(text) => setFormData({ ...formData, name: text })}
|
|
153
|
-
placeholder="
|
|
154
|
-
style={{
|
|
163
|
+
placeholder="Enter name"
|
|
164
|
+
style={{ marginTop: 16 }}
|
|
155
165
|
/>
|
|
156
166
|
|
|
157
167
|
<FormField
|
|
158
|
-
label="
|
|
168
|
+
label="Email"
|
|
159
169
|
value={formData.email}
|
|
160
170
|
onChangeText={(text) => setFormData({ ...formData, email: text })}
|
|
161
|
-
placeholder="
|
|
171
|
+
placeholder="Enter email"
|
|
162
172
|
keyboardType="email-address"
|
|
163
|
-
style={{
|
|
173
|
+
style={{ marginTop: 16 }}
|
|
164
174
|
/>
|
|
165
175
|
|
|
166
|
-
<
|
|
176
|
+
<View style={{ flexDirection: 'row', justifyContent: 'flex-end', marginTop: 24, gap: 12 }}>
|
|
177
|
+
<Button
|
|
178
|
+
title="Cancel"
|
|
179
|
+
variant="ghost"
|
|
180
|
+
onPress={onClose}
|
|
181
|
+
/>
|
|
182
|
+
<Button
|
|
183
|
+
title="Save"
|
|
184
|
+
onPress={() => {
|
|
185
|
+
onSubmit(formData);
|
|
186
|
+
onClose();
|
|
187
|
+
}}
|
|
188
|
+
/>
|
|
189
|
+
</View>
|
|
167
190
|
</View>
|
|
168
191
|
</BaseModal>
|
|
169
192
|
);
|
|
170
193
|
};
|
|
171
194
|
```
|
|
172
195
|
|
|
173
|
-
###
|
|
196
|
+
### Image Preview Modal
|
|
174
197
|
|
|
175
198
|
```tsx
|
|
176
|
-
export const
|
|
199
|
+
export const ImagePreviewModal = ({ visible, onClose, imageUri }) => {
|
|
177
200
|
return (
|
|
178
|
-
<BaseModal
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
<BaseModal
|
|
202
|
+
visible={visible}
|
|
203
|
+
onClose={onClose}
|
|
204
|
+
dismissOnBackdrop={true}
|
|
205
|
+
contentStyle={{
|
|
206
|
+
backgroundColor: 'transparent',
|
|
207
|
+
borderColor: 'transparent',
|
|
208
|
+
}}
|
|
209
|
+
>
|
|
210
|
+
<TouchableOpacity
|
|
211
|
+
style={{ flex: 1 }}
|
|
212
|
+
onPress={onClose}
|
|
213
|
+
activeOpacity={1}
|
|
214
|
+
>
|
|
215
|
+
<Image
|
|
216
|
+
source={{ uri: imageUri }}
|
|
217
|
+
style={{ width: '100%', height: '100%' }}
|
|
218
|
+
resizeMode="contain"
|
|
185
219
|
/>
|
|
220
|
+
</TouchableOpacity>
|
|
221
|
+
</BaseModal>
|
|
222
|
+
);
|
|
223
|
+
};
|
|
224
|
+
```
|
|
186
225
|
|
|
187
|
-
|
|
188
|
-
{title}
|
|
189
|
-
</Text>
|
|
226
|
+
### Settings Modal
|
|
190
227
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
228
|
+
```tsx
|
|
229
|
+
export const SettingsModal = ({ visible, onClose }) => {
|
|
230
|
+
return (
|
|
231
|
+
<BaseModal
|
|
232
|
+
visible={visible}
|
|
233
|
+
onClose={onClose}
|
|
234
|
+
>
|
|
235
|
+
<View style={{ padding: 24 }}>
|
|
236
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
237
|
+
<Text style={{ fontSize: 24, fontWeight: 'bold' }}>
|
|
238
|
+
Settings
|
|
239
|
+
</Text>
|
|
240
|
+
<TouchableOpacity onPress={onClose}>
|
|
241
|
+
<AtomicIcon name="close-outline" size="lg" />
|
|
242
|
+
</TouchableOpacity>
|
|
243
|
+
</View>
|
|
244
|
+
|
|
245
|
+
<Divider style={{ marginTop: 16 }} />
|
|
246
|
+
|
|
247
|
+
<ListItem
|
|
248
|
+
title="Dark Mode"
|
|
249
|
+
subtitle="Enable dark theme"
|
|
250
|
+
leftIcon="moon-outline"
|
|
251
|
+
onPress={() => toggleDarkMode()}
|
|
252
|
+
rightIcon="chevron-forward-outline"
|
|
253
|
+
/>
|
|
194
254
|
|
|
195
|
-
<
|
|
255
|
+
<Divider />
|
|
256
|
+
|
|
257
|
+
<ListItem
|
|
258
|
+
title="Notifications"
|
|
259
|
+
subtitle="Manage notifications"
|
|
260
|
+
leftIcon="notifications-outline"
|
|
261
|
+
onPress={() => navigation.navigate('Notifications')}
|
|
262
|
+
rightIcon="chevron-forward-outline"
|
|
263
|
+
/>
|
|
264
|
+
|
|
265
|
+
<Divider />
|
|
266
|
+
|
|
267
|
+
<ListItem
|
|
268
|
+
title="Privacy"
|
|
269
|
+
subtitle="Privacy settings"
|
|
270
|
+
leftIcon="shield-checkmark-outline"
|
|
271
|
+
onPress={() => navigation.navigate('Privacy')}
|
|
272
|
+
rightIcon="chevron-forward-outline"
|
|
273
|
+
/>
|
|
196
274
|
</View>
|
|
197
275
|
</BaseModal>
|
|
198
276
|
);
|
|
199
277
|
};
|
|
200
278
|
```
|
|
201
279
|
|
|
202
|
-
###
|
|
280
|
+
### Info Modal
|
|
203
281
|
|
|
204
282
|
```tsx
|
|
205
|
-
export const
|
|
283
|
+
export const InfoModal = ({ visible, onClose, title, message }) => {
|
|
206
284
|
return (
|
|
207
|
-
<BaseModal
|
|
285
|
+
<BaseModal
|
|
286
|
+
visible={visible}
|
|
287
|
+
onClose={onClose}
|
|
288
|
+
>
|
|
208
289
|
<View style={{ padding: 24, alignItems: 'center' }}>
|
|
209
|
-
<
|
|
210
|
-
style={{
|
|
211
|
-
width: 80,
|
|
212
|
-
height: 80,
|
|
213
|
-
borderRadius: 40,
|
|
214
|
-
backgroundColor: '#d4edda',
|
|
215
|
-
justifyContent: 'center',
|
|
216
|
-
alignItems: 'center',
|
|
217
|
-
marginBottom: 16,
|
|
218
|
-
}}
|
|
219
|
-
>
|
|
220
|
-
<AtomicIcon name="checkmark" size="xl" color="success" />
|
|
221
|
-
</View>
|
|
290
|
+
<AtomicIcon name="information-circle" size="xl" color="primary" />
|
|
222
291
|
|
|
223
|
-
<Text style={{ fontSize: 20, fontWeight: 'bold',
|
|
224
|
-
|
|
292
|
+
<Text style={{ fontSize: 20, fontWeight: 'bold', marginTop: 16 }}>
|
|
293
|
+
{title}
|
|
225
294
|
</Text>
|
|
226
295
|
|
|
227
|
-
<Text style={{ textAlign: 'center', color: '
|
|
296
|
+
<Text style={{ marginTop: 12, textAlign: 'center', color: '#666' }}>
|
|
228
297
|
{message}
|
|
229
298
|
</Text>
|
|
230
299
|
|
|
231
|
-
<Button
|
|
300
|
+
<Button
|
|
301
|
+
title="OK"
|
|
302
|
+
onPress={onClose}
|
|
303
|
+
style={{ marginTop: 24 }}
|
|
304
|
+
/>
|
|
232
305
|
</View>
|
|
233
306
|
</BaseModal>
|
|
234
307
|
);
|
|
235
308
|
};
|
|
236
309
|
```
|
|
237
310
|
|
|
238
|
-
###
|
|
311
|
+
### Success Modal
|
|
239
312
|
|
|
240
313
|
```tsx
|
|
241
|
-
export const
|
|
314
|
+
export const SuccessModal = ({ visible, onClose, message }) => {
|
|
242
315
|
return (
|
|
243
|
-
<BaseModal
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
316
|
+
<BaseModal
|
|
317
|
+
visible={visible}
|
|
318
|
+
onClose={onClose}
|
|
319
|
+
>
|
|
320
|
+
<View style={{ padding: 32, alignItems: 'center' }}>
|
|
321
|
+
<View style={{
|
|
322
|
+
width: 80,
|
|
323
|
+
height: 80,
|
|
324
|
+
borderRadius: 40,
|
|
325
|
+
backgroundColor: '#4caf50',
|
|
326
|
+
justifyContent: 'center',
|
|
327
|
+
alignItems: 'center',
|
|
328
|
+
}}>
|
|
329
|
+
<AtomicIcon name="checkmark" size="xl" customColor="#fff" />
|
|
330
|
+
</View>
|
|
251
331
|
|
|
252
|
-
<Text style={{ fontSize: 20, fontWeight: 'bold',
|
|
253
|
-
|
|
332
|
+
<Text style={{ fontSize: 20, fontWeight: 'bold', marginTop: 24 }}>
|
|
333
|
+
Success!
|
|
254
334
|
</Text>
|
|
255
335
|
|
|
256
|
-
<Text style={{ textAlign: 'center', color: '
|
|
257
|
-
{
|
|
336
|
+
<Text style={{ marginTop: 12, textAlign: 'center', color: '#666' }}>
|
|
337
|
+
{message}
|
|
258
338
|
</Text>
|
|
259
339
|
|
|
260
|
-
<Button
|
|
340
|
+
<Button
|
|
341
|
+
title="Continue"
|
|
342
|
+
onPress={onClose}
|
|
343
|
+
style={{ marginTop: 32 }}
|
|
344
|
+
/>
|
|
261
345
|
</View>
|
|
262
346
|
</BaseModal>
|
|
263
347
|
);
|
|
264
348
|
};
|
|
265
349
|
```
|
|
266
350
|
|
|
267
|
-
###
|
|
351
|
+
### Loading Modal
|
|
268
352
|
|
|
269
353
|
```tsx
|
|
270
|
-
export const
|
|
354
|
+
export const LoadingModal = ({ visible }) => {
|
|
271
355
|
return (
|
|
272
356
|
<BaseModal
|
|
273
357
|
visible={visible}
|
|
274
|
-
onClose={
|
|
358
|
+
onClose={() => {}}
|
|
359
|
+
dismissOnBackdrop={false}
|
|
275
360
|
contentStyle={{
|
|
276
361
|
backgroundColor: 'transparent',
|
|
277
|
-
|
|
362
|
+
borderColor: 'transparent',
|
|
278
363
|
}}
|
|
279
364
|
>
|
|
280
|
-
<
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
365
|
+
<View style={{
|
|
366
|
+
backgroundColor: '#fff',
|
|
367
|
+
padding: 32,
|
|
368
|
+
borderRadius: 16,
|
|
369
|
+
alignItems: 'center',
|
|
370
|
+
}}>
|
|
371
|
+
<AtomicSpinner size="lg" />
|
|
372
|
+
<Text style={{ marginTop: 16 }}>
|
|
373
|
+
Please wait...
|
|
374
|
+
</Text>
|
|
375
|
+
</View>
|
|
287
376
|
</BaseModal>
|
|
288
377
|
);
|
|
289
378
|
};
|
|
290
379
|
```
|
|
291
380
|
|
|
292
|
-
###
|
|
381
|
+
### Alert Modal
|
|
293
382
|
|
|
294
383
|
```tsx
|
|
295
|
-
export const
|
|
296
|
-
if (!item) return null;
|
|
297
|
-
|
|
384
|
+
export const AlertModal = ({ visible, onClose, title, message, onAction }) => {
|
|
298
385
|
return (
|
|
299
|
-
<BaseModal
|
|
386
|
+
<BaseModal
|
|
387
|
+
visible={visible}
|
|
388
|
+
onClose={onClose}
|
|
389
|
+
>
|
|
300
390
|
<View style={{ padding: 24 }}>
|
|
301
|
-
<View style={{ flexDirection: 'row',
|
|
302
|
-
<
|
|
303
|
-
|
|
391
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 16 }}>
|
|
392
|
+
<AtomicIcon name="warning" size="lg" color="warning" style={{ marginRight: 12 }} />
|
|
393
|
+
<Text style={{ fontSize: 20, fontWeight: 'bold', flex: 1 }}>
|
|
394
|
+
{title}
|
|
304
395
|
</Text>
|
|
305
|
-
<Pressable onPress={onClose}>
|
|
306
|
-
<AtomicIcon name="close" size="md" />
|
|
307
|
-
</Pressable>
|
|
308
396
|
</View>
|
|
309
397
|
|
|
310
|
-
<
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
</Text>
|
|
314
|
-
<Text>{item.description}</Text>
|
|
315
|
-
</View>
|
|
398
|
+
<Text style={{ color: '#666', lineHeight: 22 }}>
|
|
399
|
+
{message}
|
|
400
|
+
</Text>
|
|
316
401
|
|
|
317
|
-
<View style={{ marginTop:
|
|
318
|
-
<
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
402
|
+
<View style={{ flexDirection: 'row', justifyContent: 'flex-end', marginTop: 24, gap: 12 }}>
|
|
403
|
+
<Button
|
|
404
|
+
title="Cancel"
|
|
405
|
+
variant="ghost"
|
|
406
|
+
onPress={onClose}
|
|
407
|
+
/>
|
|
408
|
+
<Button
|
|
409
|
+
title="OK"
|
|
410
|
+
onPress={() => {
|
|
411
|
+
onAction?.();
|
|
412
|
+
onClose();
|
|
413
|
+
}}
|
|
414
|
+
/>
|
|
329
415
|
</View>
|
|
416
|
+
</View>
|
|
417
|
+
</BaseModal>
|
|
418
|
+
);
|
|
419
|
+
};
|
|
420
|
+
```
|
|
330
421
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
422
|
+
### Menu Modal
|
|
423
|
+
|
|
424
|
+
```tsx
|
|
425
|
+
export const MenuModal = ({ visible, onClose, options }) => {
|
|
426
|
+
return (
|
|
427
|
+
<BaseModal
|
|
428
|
+
visible={visible}
|
|
429
|
+
onClose={onClose}
|
|
430
|
+
contentStyle={{
|
|
431
|
+
position: 'absolute',
|
|
432
|
+
bottom: 0,
|
|
433
|
+
margin: 16,
|
|
434
|
+
marginBottom: 32,
|
|
435
|
+
}}
|
|
436
|
+
>
|
|
437
|
+
<View style={{ padding: 8 }}>
|
|
438
|
+
{options.map((option, index) => (
|
|
439
|
+
<TouchableOpacity
|
|
440
|
+
key={index}
|
|
441
|
+
style={{
|
|
442
|
+
paddingVertical: 12,
|
|
443
|
+
paddingHorizontal: 16,
|
|
444
|
+
borderBottomWidth: 1,
|
|
445
|
+
borderBottomColor: '#f0f0f0',
|
|
446
|
+
}}
|
|
447
|
+
onPress={() => {
|
|
448
|
+
option.onPress();
|
|
449
|
+
onClose();
|
|
450
|
+
}}
|
|
451
|
+
>
|
|
452
|
+
<Text style={{ fontSize: 16 }}>
|
|
453
|
+
{option.label}
|
|
454
|
+
</Text>
|
|
455
|
+
</TouchableOpacity>
|
|
456
|
+
))}
|
|
334
457
|
</View>
|
|
335
458
|
</BaseModal>
|
|
336
459
|
);
|
|
@@ -341,95 +464,96 @@ export const DetailModal = ({ visible, onClose, item }) => {
|
|
|
341
464
|
|
|
342
465
|
### BaseModalProps
|
|
343
466
|
|
|
344
|
-
| Prop |
|
|
345
|
-
|
|
346
|
-
| `visible` | `boolean` | - **(
|
|
347
|
-
| `onClose` | `() => void` | - **(
|
|
348
|
-
| `children` | `ReactNode` | - **(
|
|
349
|
-
| `dismissOnBackdrop` | `boolean` | `true` |
|
|
350
|
-
| `contentStyle` | `ViewStyle` | - |
|
|
351
|
-
| `testID` | `string` | `'base-modal'` | Test ID
|
|
467
|
+
| Prop | Type | Default | Description |
|
|
468
|
+
|------|------|---------|-------------|
|
|
469
|
+
| `visible` | `boolean` | - **(Required)** | Modal visibility |
|
|
470
|
+
| `onClose` | `() => void` | - **(Required)** | Close callback |
|
|
471
|
+
| `children` | `ReactNode` | - **(Required)** | Modal content |
|
|
472
|
+
| `dismissOnBackdrop` | `boolean` | `true` | Close on backdrop tap |
|
|
473
|
+
| `contentStyle` | `ViewStyle` | - | Custom content style |
|
|
474
|
+
| `testID` | `string` | `'base-modal'` | Test ID for testing |
|
|
352
475
|
|
|
353
476
|
## Best Practices
|
|
354
477
|
|
|
355
|
-
### 1.
|
|
478
|
+
### 1. Modal Size
|
|
356
479
|
|
|
357
480
|
```tsx
|
|
358
|
-
//
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
dismissOnBackdrop={false}
|
|
363
|
-
>
|
|
364
|
-
<Text>İşlemi tamamlamalısınız</Text>
|
|
365
|
-
<Button title="Tamam" onPress={onComplete} />
|
|
481
|
+
// BaseModal is responsive by default
|
|
482
|
+
// Content determines height automatically
|
|
483
|
+
<BaseModal visible={visible} onClose={onClose}>
|
|
484
|
+
{/* Content */}
|
|
366
485
|
</BaseModal>
|
|
367
486
|
```
|
|
368
487
|
|
|
369
|
-
### 2.
|
|
488
|
+
### 2. Dismiss Behavior
|
|
370
489
|
|
|
371
490
|
```tsx
|
|
372
|
-
//
|
|
373
|
-
|
|
374
|
-
visible: false,
|
|
375
|
-
data: null,
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
const openModal = (data) => {
|
|
379
|
-
setModalState({ visible: true, data });
|
|
380
|
-
};
|
|
491
|
+
// ✅ Good: Allow dismiss for non-critical modals
|
|
492
|
+
<BaseModal dismissOnBackdrop={true} />
|
|
381
493
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
};
|
|
494
|
+
// ✅ Good: Prevent dismiss for critical modals
|
|
495
|
+
<BaseModal dismissOnBackdrop={false} />
|
|
385
496
|
```
|
|
386
497
|
|
|
387
|
-
### 3.
|
|
498
|
+
### 3. Close Buttons
|
|
388
499
|
|
|
389
500
|
```tsx
|
|
390
|
-
//
|
|
501
|
+
// ✅ Good: Always provide close option
|
|
391
502
|
<BaseModal visible={visible} onClose={onClose}>
|
|
392
|
-
<
|
|
393
|
-
{
|
|
394
|
-
|
|
503
|
+
<View style={{ flexDirection: 'row', justifyContent: 'flex-end' }}>
|
|
504
|
+
<TouchableOpacity onPress={onClose}>
|
|
505
|
+
<AtomicIcon name="close-outline" size="lg" />
|
|
506
|
+
</TouchableOpacity>
|
|
507
|
+
</View>
|
|
508
|
+
|
|
509
|
+
{/* Content */}
|
|
395
510
|
</BaseModal>
|
|
396
511
|
```
|
|
397
512
|
|
|
398
|
-
### 4.
|
|
513
|
+
### 4. Scrollable Content
|
|
399
514
|
|
|
400
515
|
```tsx
|
|
401
|
-
//
|
|
516
|
+
// ✅ Good: Use ScrollView for long content
|
|
402
517
|
<BaseModal visible={visible} onClose={onClose}>
|
|
403
|
-
<
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
<FormField label="E-posta" />
|
|
407
|
-
</View>
|
|
408
|
-
</KeyboardAvoidingView>
|
|
518
|
+
<ScrollView style={{ padding: 24 }}>
|
|
519
|
+
{/* Long content */}
|
|
520
|
+
</ScrollView>
|
|
409
521
|
</BaseModal>
|
|
410
522
|
```
|
|
411
523
|
|
|
412
|
-
##
|
|
524
|
+
## Accessibility
|
|
413
525
|
|
|
414
|
-
BaseModal
|
|
526
|
+
BaseModal provides full accessibility support:
|
|
415
527
|
|
|
416
|
-
- ✅ Screen reader
|
|
528
|
+
- ✅ Screen reader support
|
|
417
529
|
- ✅ Focus trap
|
|
418
|
-
- ✅
|
|
419
|
-
- ✅
|
|
530
|
+
- ✅ Keyboard navigation
|
|
531
|
+
- ✅ Semantic roles
|
|
532
|
+
- ✅ Accessibility labels
|
|
533
|
+
- ✅ Escape key support (Android)
|
|
534
|
+
|
|
535
|
+
## Performance Tips
|
|
536
|
+
|
|
537
|
+
1. **Lazy Loading**: Load modal content only when visible
|
|
538
|
+
2. **Memoization**: Memo modal content
|
|
539
|
+
3. **Conditional Rendering**: Don't render when not visible
|
|
540
|
+
4. **Cleanup**: Clean up resources on close
|
|
541
|
+
|
|
542
|
+
## Responsive Behavior
|
|
420
543
|
|
|
421
|
-
|
|
544
|
+
BaseModal automatically adjusts its size based on device:
|
|
422
545
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
546
|
+
- **Mobile**: Full width with margin
|
|
547
|
+
- **Tablet**: Fixed width (e.g., 600px)
|
|
548
|
+
- **Desktop**: Fixed width centered
|
|
426
549
|
|
|
427
|
-
##
|
|
550
|
+
## Related Components
|
|
428
551
|
|
|
429
|
-
- [`ConfirmationModal`](./
|
|
430
|
-
- [`BottomSheet`](./bottom-sheet/README.md) -
|
|
431
|
-
- [`FormField`](./FormField
|
|
552
|
+
- [`ConfirmationModal`](./ConfirmationModal.README.md) - Pre-styled confirmation modal
|
|
553
|
+
- [`BottomSheet`](./bottom-sheet/README.md) - Bottom sheet modal
|
|
554
|
+
- [`FormField`](./FormField.README.md) - Form field component
|
|
555
|
+
- [`Button`](../atoms/button/README.md) - Button component
|
|
432
556
|
|
|
433
|
-
##
|
|
557
|
+
## License
|
|
434
558
|
|
|
435
559
|
MIT
|