@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.
- package/package.json +1 -6
- package/src/atoms/AtomicProgress.README.md +402 -0
- package/src/atoms/EmptyState.README.md +372 -0
- package/src/atoms/skeleton/AtomicSkeleton.README.md +339 -0
- package/src/molecules/ConfirmationModal.README.md +370 -0
- package/src/molecules/Divider/README.md +470 -0
- package/src/molecules/StepHeader/README.md +487 -0
- package/src/molecules/alerts/README.md +471 -0
- package/src/molecules/avatar/README.md +431 -0
- package/src/molecules/bottom-sheet/README.md +413 -0
- package/src/molecules/calendar/README.md +339 -0
- package/src/molecules/countdown/README.md +558 -0
- package/src/molecules/media-card/README.md +384 -0
- package/src/molecules/navigation/README.md +377 -0
- package/src/molecules/splash/README.md +474 -0
- package/src/molecules/splash/components/SplashScreen.tsx +0 -14
|
@@ -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
|