@umituz/react-native-design-system 2.6.87 → 2.6.88

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.
@@ -0,0 +1,413 @@
1
+ # BottomSheet
2
+
3
+ BottomSheet, ekranın altından açılan modal benzeri bir bileşendir. Filtreleme, seçim veya ekranda kalıcı aksiyonlar için idealdir.
4
+
5
+ ## Özellikler
6
+
7
+ - 📱 **4 Preset**: Small, Medium, Large, Full
8
+ - 🎯 **Snap Points**: Birden fazla yükseklik noktası
9
+ - 👆 **Gesture**: Kaydırma ile kapatma
10
+ - 🎨 **Özelleştirilebilir**: Renk ve stil
11
+ - 🔝 **Safe Area**: Safe area desteği
12
+ - ♿ **Erişilebilir**: Tam erişilebilirlik desteği
13
+
14
+ ## Kurulum
15
+
16
+ ```tsx
17
+ import { BottomSheet } from 'react-native-design-system';
18
+ ```
19
+
20
+ ## Temel Kullanım
21
+
22
+ ```tsx
23
+ import React, { useRef } from 'react';
24
+ import { View, Button } from 'react-native';
25
+ import { BottomSheet } from 'react-native-design-system';
26
+
27
+ export const BasicExample = () => {
28
+ const bottomSheetRef = useRef<BottomSheetRef>(null);
29
+
30
+ const openSheet = () => {
31
+ bottomSheetRef.current?.expand();
32
+ };
33
+
34
+ return (
35
+ <View style={{ flex: 1 }}>
36
+ <Button title="Bottom Sheet Aç" onPress={openSheet} />
37
+
38
+ <BottomSheet
39
+ ref={bottomSheetRef}
40
+ preset="medium"
41
+ >
42
+ <View style={{ padding: 24 }}>
43
+ <AtomicText>Bottom Sheet İçeriği</AtomicText>
44
+ </View>
45
+ </BottomSheet>
46
+ </View>
47
+ );
48
+ };
49
+ ```
50
+
51
+ ## Preset Yükseklikler
52
+
53
+ ```tsx
54
+ <View style={{ gap: 16 }}>
55
+ {/* Small - %35 */}
56
+ <BottomSheet ref={ref1} preset="small">
57
+ <SmallContent />
58
+ </BottomSheet>
59
+
60
+ {/* Medium - %60 (Varsayılan) */}
61
+ <BottomSheet ref={ref2} preset="medium">
62
+ <MediumContent />
63
+ </BottomSheet>
64
+
65
+ {/* Large - %85 */}
66
+ <BottomSheet ref={ref3} preset="large">
67
+ <LargeContent />
68
+ </BottomSheet>
69
+
70
+ {/* Full - %100 */}
71
+ <BottomSheet ref={ref4} preset="full">
72
+ <FullContent />
73
+ </BottomSheet>
74
+ </View>
75
+ ```
76
+
77
+ ## Custom Snap Points
78
+
79
+ ```tsx
80
+ <BottomSheet
81
+ ref={bottomSheetRef}
82
+ snapPoints={['25%', '50%', '75%']}
83
+ initialIndex={1}
84
+ >
85
+ <Content />
86
+ </BottomSheet>
87
+ ```
88
+
89
+ ## Custom Background Color
90
+
91
+ ```tsx
92
+ <BottomSheet
93
+ ref={bottomSheetRef}
94
+ backgroundColor="#f8f9fa"
95
+ >
96
+ <Content />
97
+ </BottomSheet>
98
+ ```
99
+
100
+ ## OnChange Callback
101
+
102
+ ```tsx
103
+ const [sheetIndex, setSheetIndex] = useState(-1);
104
+
105
+ <BottomSheet
106
+ ref={bottomSheetRef}
107
+ onChange={(index) => setSheetIndex(index)}
108
+ >
109
+ <Content />
110
+ </BottomSheet>
111
+ ```
112
+
113
+ ## OnClose Callback
114
+
115
+ ```tsx
116
+ <BottomSheet
117
+ ref={bottomSheetRef}
118
+ onClose={() => console.log('Sheet closed')}
119
+ >
120
+ <Content />
121
+ </BottomSheet>
122
+ ```
123
+
124
+ ## Örnek Kullanımlar
125
+
126
+ ### Seçim Bottom Sheet
127
+
128
+ ```tsx
129
+ export const SelectionBottomSheet = ({ ref, options, onSelect }) => {
130
+ return (
131
+ <BottomSheet ref={ref} preset="small">
132
+ <View style={{ padding: 24 }}>
133
+ <AtomicText type="titleLarge" style={{ marginBottom: 16 }}>
134
+ Seçim Yapın
135
+ </AtomicText>
136
+
137
+ {options.map((option) => (
138
+ <Pressable
139
+ key={option.id}
140
+ style={{ padding: 16 }}
141
+ onPress={() => {
142
+ onSelect(option);
143
+ ref.current?.close();
144
+ }}
145
+ >
146
+ <AtomicText type="bodyLarge">{option.label}</AtomicText>
147
+ </Pressable>
148
+ ))}
149
+ </View>
150
+ </BottomSheet>
151
+ );
152
+ };
153
+ ```
154
+
155
+ ### Paylaşım Bottom Sheet
156
+
157
+ ```tsx
158
+ export const ShareBottomSheet = ({ ref, item, onShare }) => {
159
+ const shareOptions = [
160
+ { id: 'copy', icon: 'copy-outline', label: 'Linki Kopyala' },
161
+ { id: 'whatsapp', icon: 'logo-whatsapp', label: 'WhatsApp' },
162
+ { id: 'twitter', icon: 'logo-twitter', label: 'Twitter' },
163
+ { id: 'facebook', icon: 'logo-facebook', label: 'Facebook' },
164
+ ];
165
+
166
+ return (
167
+ <BottomSheet ref={ref} preset="small">
168
+ <View style={{ padding: 24 }}>
169
+ <AtomicText type="titleLarge" style={{ marginBottom: 16 }}>
170
+ Paylaş
171
+ </AtomicText>
172
+
173
+ {shareOptions.map((option) => (
174
+ <Pressable
175
+ key={option.id}
176
+ style={{ flexDirection: 'row', alignItems: 'center', padding: 16 }}
177
+ onPress={() => onShare(option.id)}
178
+ >
179
+ <AtomicIcon name={option.icon} size="lg" style={{ marginRight: 16 }} />
180
+ <AtomicText type="bodyLarge">{option.label}</AtomicText>
181
+ </Pressable>
182
+ ))}
183
+ </View>
184
+ </BottomSheet>
185
+ );
186
+ };
187
+ ```
188
+
189
+ ### Filtre Bottom Sheet
190
+
191
+ ```tsx
192
+ export const FilterBottomSheet = ({ ref, filters, onApply }) => {
193
+ const [localFilters, setLocalFilters] = useState(filters);
194
+
195
+ return (
196
+ <BottomSheet ref={ref} preset="large">
197
+ <View style={{ padding: 24 }}>
198
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 24 }}>
199
+ <AtomicText type="titleLarge">Filtrele</AtomicText>
200
+ <Pressable onPress={() => ref.current?.close()}>
201
+ <AtomicIcon name="close" size="md" />
202
+ </Pressable>
203
+ </View>
204
+
205
+ {/* Filtre seçenekleri */}
206
+ <FilterOptions
207
+ filters={localFilters}
208
+ onChange={setLocalFilters}
209
+ />
210
+
211
+ <View style={{ flexDirection: 'row', gap: 16, marginTop: 24 }}>
212
+ <Button
213
+ title="Temizle"
214
+ mode="outlined"
215
+ style={{ flex: 1 }}
216
+ onPress={() => setLocalFilters({})}
217
+ />
218
+ <Button
219
+ title="Uygula"
220
+ mode="contained"
221
+ style={{ flex: 1 }}
222
+ onPress={() => onApply(localFilters)}
223
+ />
224
+ </View>
225
+ </View>
226
+ </BottomSheet>
227
+ );
228
+ };
229
+ ```
230
+
231
+ ### Ayarlar Bottom Sheet
232
+
233
+ ```tsx
234
+ export const SettingsBottomSheet = ({ ref }) => {
235
+ return (
236
+ <BottomSheet ref={ref} preset="medium">
237
+ <View style={{ padding: 24 }}>
238
+ <AtomicText type="titleLarge" style={{ marginBottom: 24 }}>
239
+ Ayarlar
240
+ </AtomicText>
241
+
242
+ <SettingItem icon="notifications-outline" label="Bildirimler" />
243
+ <SettingItem icon="moon-outline" label="Karanlık Mod" />
244
+ <SettingItem icon="globe-outline" label="Dil" />
245
+ <SettingItem icon="information-circle-outline" label="Hakkında" />
246
+ </View>
247
+ </BottomSheet>
248
+ );
249
+ };
250
+ ```
251
+
252
+ ### Eylem Bottom Sheet
253
+
254
+ ```tsx
255
+ export const ActionBottomSheet = ({ ref, item, onAction }) => {
256
+ const actions = [
257
+ { id: 'edit', icon: 'create-outline', label: 'Düzenle', color: 'primary' },
258
+ { id: 'share', icon: 'share-outline', label: 'Paylaş', color: 'primary' },
259
+ { id: 'archive', icon: 'archive-outline', label: 'Arşivle', color: 'primary' },
260
+ { id: 'delete', icon: 'trash-outline', label: 'Sil', color: 'error' },
261
+ ];
262
+
263
+ return (
264
+ <BottomSheet ref={ref} preset="small">
265
+ <View style={{ padding: 8 }}>
266
+ {actions.map((action) => (
267
+ <Pressable
268
+ key={action.id}
269
+ style={{
270
+ flexDirection: 'row',
271
+ alignItems: 'center',
272
+ padding: 16,
273
+ borderBottomWidth: 1,
274
+ borderBottomColor: '#e0e0e0',
275
+ }}
276
+ onPress={() => onAction(action.id)}
277
+ >
278
+ <AtomicIcon
279
+ name={action.icon}
280
+ size="md"
281
+ color={action.color}
282
+ style={{ marginRight: 16 }}
283
+ />
284
+ <AtomicText
285
+ type="bodyLarge"
286
+ color={action.color}
287
+ >
288
+ {action.label}
289
+ </AtomicText>
290
+ </Pressable>
291
+ ))}
292
+ </View>
293
+ </BottomSheet>
294
+ );
295
+ };
296
+ ```
297
+
298
+ ## Ref Methods
299
+
300
+ ### BottomSheetRef
301
+
302
+ ```typescript
303
+ interface BottomSheetRef {
304
+ snapToIndex(index: number): void; // Index'e git
305
+ snapToPosition(): void; // En üste git
306
+ expand(): void; // Genişlet
307
+ collapse(): void; // Daralt
308
+ close(): void; // Kapat
309
+ }
310
+ ```
311
+
312
+ ### Kullanım
313
+
314
+ ```tsx
315
+ const ref = useRef<BottomSheetRef>(null);
316
+
317
+ // Aç
318
+ ref.current?.expand();
319
+
320
+ // Kapat
321
+ ref.current?.close();
322
+
323
+ // Snap point'e git
324
+ ref.current?.snapToIndex(1);
325
+ ```
326
+
327
+ ## Props
328
+
329
+ ### BottomSheetProps
330
+
331
+ | Prop | Tip | Varsayılan | Açıklama |
332
+ |------|-----|------------|----------|
333
+ | `children` | `ReactNode` | - **(Zorunlu)** | Sheet içeriği |
334
+ | `preset` | `BottomSheetPreset` | `'medium'` | Yükseklik preset'i |
335
+ | `snapPoints` | `(number \| string)[]` | - | Custom snap points |
336
+ | `initialIndex` | `number` | - | Başlangıç index'i |
337
+ | `backgroundColor` | `string` | - | Arka plan rengi |
338
+ | `onChange` | `(index: number) => void` | - | Değişiklik callback'i |
339
+ | `onClose` | `() => void` | - | Kapatma callback'i |
340
+
341
+ ### BottomSheetPreset
342
+
343
+ ```typescript
344
+ type BottomSheetPreset =
345
+ | 'small' // %35
346
+ | 'medium' // %60 (varsayılan)
347
+ | 'large' // %85
348
+ | 'full'; // %100
349
+ ```
350
+
351
+ ## Best Practices
352
+
353
+ ### 1. Preset Seçimi
354
+
355
+ ```tsx
356
+ // Kısa içerik için
357
+ <BottomSheet preset="small" />
358
+
359
+ // Orta içerik için
360
+ <BottomSheet preset="medium" />
361
+
362
+ // Uzun içerik için
363
+ <BottomSheet preset="large" />
364
+
365
+ // Tam ekran için
366
+ <BottomSheet preset="full" />
367
+ ```
368
+
369
+ ### 2. Snap Points
370
+
371
+ ```tsx
372
+ // Birden fazla nokta
373
+ <BottomSheet
374
+ snapPoints={['25%', '50%', '75%']}
375
+ initialIndex={1}
376
+ />
377
+ ```
378
+
379
+ ### 3. Kapatma
380
+
381
+ ```tsx
382
+ // Manuel kapatma
383
+ ref.current?.close();
384
+
385
+ // Overlay tıklama ile otomatik
386
+ <BottomSheet onClose={handleClose} />
387
+ ```
388
+
389
+ ## Erişilebilirlik
390
+
391
+ BottomSheet, tam erişilebilirlik desteği sunar:
392
+
393
+ - ✅ Screen reader desteği
394
+ - ✅ Touch uygun boyut
395
+ - ✅ Escape key (web)
396
+ - ✅ Focus trap
397
+ - ✅ Accessibility label
398
+
399
+ ## Performans İpuçları
400
+
401
+ 1. **Lazy Loading**: İçeriği lazy load edin
402
+ 2. **Unmount**: Kapatıldığında unmount edin
403
+ 3. **Memoization**: İçeriği memo edin
404
+
405
+ ## İlgili Bileşenler
406
+
407
+ - [`BaseModal`](../BaseModal/README.md) - Modal bileşeni
408
+ - [`FilterBottomSheet`](./FilterBottomSheet/README.md) - Filtre sheet'i
409
+ - [`AtomicButton`](../../atoms/button/README.md) - Buton bileşeni
410
+
411
+ ## Lisans
412
+
413
+ MIT