@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.
Files changed (43) hide show
  1. package/package.json +1 -1
  2. package/src/atoms/AtomicAvatar.README.md +284 -397
  3. package/src/atoms/AtomicBadge.README.md +123 -358
  4. package/src/atoms/AtomicCard.README.md +358 -247
  5. package/src/atoms/AtomicDatePicker.README.md +127 -332
  6. package/src/atoms/AtomicFab.README.md +194 -352
  7. package/src/atoms/AtomicIcon.README.md +241 -274
  8. package/src/atoms/AtomicProgress.README.md +100 -338
  9. package/src/atoms/AtomicSpinner.README.md +304 -337
  10. package/src/atoms/AtomicText.README.md +153 -389
  11. package/src/atoms/AtomicTextArea.README.md +267 -268
  12. package/src/atoms/EmptyState.README.md +247 -292
  13. package/src/atoms/GlassView/README.md +313 -444
  14. package/src/atoms/button/README.md +186 -297
  15. package/src/atoms/button/STRATEGY.md +252 -0
  16. package/src/atoms/chip/README.md +242 -290
  17. package/src/atoms/input/README.md +296 -290
  18. package/src/atoms/picker/README.md +278 -309
  19. package/src/atoms/skeleton/AtomicSkeleton.README.md +394 -252
  20. package/src/molecules/BaseModal/README.md +356 -0
  21. package/src/molecules/BaseModal.README.md +324 -200
  22. package/src/molecules/ConfirmationModal.README.md +349 -302
  23. package/src/molecules/Divider/README.md +293 -376
  24. package/src/molecules/FormField.README.md +321 -534
  25. package/src/molecules/GlowingCard/GlowingCard.tsx +1 -1
  26. package/src/molecules/GlowingCard/README.md +230 -372
  27. package/src/molecules/List/README.md +281 -488
  28. package/src/molecules/ListItem.README.md +320 -315
  29. package/src/molecules/SearchBar/README.md +332 -430
  30. package/src/molecules/StepHeader/README.md +311 -411
  31. package/src/molecules/StepProgress/README.md +281 -448
  32. package/src/molecules/alerts/README.md +272 -355
  33. package/src/molecules/avatar/README.md +295 -356
  34. package/src/molecules/bottom-sheet/README.md +303 -340
  35. package/src/molecules/calendar/README.md +301 -265
  36. package/src/molecules/countdown/README.md +347 -456
  37. package/src/molecules/emoji/README.md +281 -514
  38. package/src/molecules/listitem/README.md +307 -399
  39. package/src/molecules/media-card/MediaCard.tsx +31 -34
  40. package/src/molecules/media-card/README.md +217 -319
  41. package/src/molecules/navigation/README.md +263 -284
  42. package/src/molecules/splash/README.md +76 -80
  43. package/src/molecules/swipe-actions/README.md +376 -588
@@ -1,568 +1,361 @@
1
1
  # List
2
2
 
3
- List, FlatList wrapper'ı olan responsive bir liste bileşenidir. Pull-to-refresh desteği, içerik padding'i ve theme-aware renkler sunar.
3
+ List is a responsive FlatList wrapper component with pull-to-refresh support, content padding, and theme-aware colors.
4
4
 
5
- ## Özellikler
5
+ ## Import & Usage
6
6
 
7
- - 📜 **FlatList Wrapper**: React Native FlatList'in tüm özellikleri
8
- - 🔄 **Pull-to-Refresh**: Yenileme desteği
9
- - 📏 **Content Padding**: Responsive içerik padding'i
10
- - 🎨 **Theme-Aware**: Design token uyumlu
11
- - ⚡ **Performanslı**: Optimize edilmiş liste performansı
12
- - ♿ **Erişilebilir**: Tam erişilebilirlik desteği
13
-
14
- ## Kurulum
15
-
16
- ```tsx
17
- import { List } from 'react-native-design-system';
7
+ ```typescript
8
+ import { List } from 'react-native-design-system/src/molecules/List';
18
9
  ```
19
10
 
20
- ## Temel Kullanım
11
+ **Location:** `src/molecules/List/List.tsx`
21
12
 
22
- ```tsx
23
- import React from 'react';
24
- import { View } from 'react-native';
25
- import { List } from 'react-native-design-system';
26
-
27
- export const BasicExample = () => {
28
- const data = [
29
- { id: '1', title: 'Öğe 1' },
30
- { id: '2', title: 'Öğe 2' },
31
- { id: '3', title: 'Öğe 3' },
32
- ];
33
-
34
- return (
35
- <List
36
- data={data}
37
- renderItem={({ item }) => (
38
- <View style={{ padding: 16 }}>
39
- <AtomicText>{item.title}</AtomicText>
40
- </View>
41
- )}
42
- keyExtractor={(item) => item.id}
43
- />
44
- );
45
- };
46
- ```
47
-
48
- ## Basit Liste
13
+ ## Basic Usage
49
14
 
50
15
  ```tsx
51
- const users = [
52
- { id: '1', name: 'Ahmet Yılmaz' },
53
- { id: '2', name: 'Ayşe Demir' },
54
- { id: '3', name: 'Mehmet Kaya' },
55
- ];
56
-
57
16
  <List
58
- data={users}
59
- renderItem={({ item }) => (
60
- <ListItem title={item.name} />
61
- )}
17
+ data={items}
18
+ renderItem={({ item }) => <ItemCard item={item} />}
62
19
  keyExtractor={(item) => item.id}
63
20
  />
64
21
  ```
65
22
 
66
- ## Pull-to-Refresh
23
+ ## Strategy
67
24
 
68
- ```tsx
69
- export const RefreshableList = () => {
70
- const [data, setData] = useState([]);
71
- const [refreshing, setRefreshing] = useState(false);
72
-
73
- const onRefresh = async () => {
74
- setRefreshing(true);
75
- const newData = await fetchData();
76
- setData(newData);
77
- setRefreshing(false);
78
- };
79
-
80
- return (
81
- <List
82
- data={data}
83
- renderItem={({ item }) => <ItemCard item={item} />}
84
- keyExtractor={(item) => item.id}
85
- onRefresh={onRefresh}
86
- refreshing={refreshing}
87
- />
88
- );
89
- };
90
- ```
25
+ **Purpose**: Provide a performant, theme-aware list component that wraps React Native's FlatList with sensible defaults.
26
+
27
+ **When to Use**:
28
+ - Displaying scrolling lists of data
29
+ - Rendering large datasets efficiently
30
+ - Implementing pull-to-refresh functionality
31
+ - Creating infinite scroll lists
32
+
33
+ **When NOT to Use**:
34
+ - For small static lists - use ScrollView or map
35
+ - For simple layouts - use FlatList directly
36
+ - For grid layouts - use FlatList with numColumns
91
37
 
92
- ## Content Padding
38
+ ## Rules
39
+
40
+ ### Required
41
+
42
+ 1. **ALWAYS** provide `data` array
43
+ 2. **MUST** provide `renderItem` function
44
+ 3. **ALWAYS** provide `keyExtractor` function
45
+ 4. **NEVER** use array index as key
46
+ 5. **MUST** handle empty state
47
+
48
+ ### Performance
49
+
50
+ 1. **ALWAYS** use stable keys from data
51
+ 2. **MUST** memoize renderItem with useCallback
52
+ 3. **SHOULD** use `getItemLayout` for fixed-size items
53
+ 4. **NEVER** inline renderItem function
54
+
55
+ ### Key Extraction
56
+
57
+ 1. **ALWAYS** use unique IDs from data
58
+ 2. **NEVER** use array index as key
59
+ 3. **MUST** be stable across re-renders
60
+ 4. **SHOULD** be unique across all items
61
+
62
+ ## Forbidden
63
+
64
+ ❌ **NEVER** do these:
93
65
 
94
66
  ```tsx
67
+ // ❌ Missing required props
68
+ <List /> {/* Missing data, renderItem, keyExtractor */}
69
+
70
+ // ❌ Using index as key
95
71
  <List
96
72
  data={items}
97
73
  renderItem={({ item }) => <ItemCard item={item} />}
74
+ keyExtractor={(item, index) => index.toString()} // ❌ Bad
75
+ />
76
+
77
+ // ❌ Inline renderItem
78
+ <List
79
+ data={items}
80
+ renderItem={({ item }) => ( // ❌ Not memoized
81
+ <ItemCard item={item} />
82
+ )}
98
83
  keyExtractor={(item) => item.id}
99
- contentPadding
100
84
  />
101
- ```
102
85
 
103
- ## Örnek Kullanımlar
86
+ // No keyExtractor
87
+ <List
88
+ data={items}
89
+ renderItem={({ item }) => <ItemCard item={item} />}
90
+ // Missing keyExtractor ❌
91
+ />
104
92
 
105
- ### Kullanıcı Listesi
93
+ // No empty state
94
+ <List
95
+ data={[]} // Empty but no empty state shown
96
+ renderItem={renderItem}
97
+ keyExtractor={keyExtractor}
98
+ />
106
99
 
107
- ```tsx
108
- export const UserList = () => {
109
- const [users, setUsers] = useState([]);
110
-
111
- useEffect(() => {
112
- fetchUsers().then(setUsers);
113
- }, []);
114
-
115
- const renderUser = ({ item }) => (
116
- <ListItem
117
- title={item.name}
118
- subtitle={item.email}
119
- left={() => (
120
- <Avatar
121
- uri={item.avatar}
122
- name={item.name}
123
- size="md"
124
- />
125
- )}
126
- onPress={() => navigation.navigate('UserProfile', { userId: item.id })}
127
- />
128
- );
129
-
130
- return (
131
- <List
132
- data={users}
133
- renderItem={renderUser}
134
- keyExtractor={(item) => item.id}
135
- contentPadding
136
- />
137
- );
138
- };
100
+ // ❌ Wrong data type
101
+ <List
102
+ data="not an array" // ❌ Should be array
103
+ renderItem={renderItem}
104
+ keyExtractor={keyExtractor}
105
+ />
139
106
  ```
140
107
 
141
- ### Sonsuz Kaydırma
108
+ ## Best Practices
109
+
110
+ ### Key Extraction
142
111
 
112
+ ✅ **DO**:
143
113
  ```tsx
144
- export const InfiniteList = () => {
145
- const [data, setData] = useState([]);
146
- const [loading, setLoading] = useState(false);
147
- const [page, setPage] = useState(1);
148
-
149
- const loadMore = async () => {
150
- if (loading) return;
151
- setLoading(true);
152
- const newData = await fetchItems(page);
153
- setData([...data, ...newData]);
154
- setPage(page + 1);
155
- setLoading(false);
156
- };
157
-
158
- const renderFooter = () => {
159
- if (!loading) return null;
160
- return (
161
- <View style={{ padding: 16 }}>
162
- <AtomicSpinner size="md" />
163
- </View>
164
- );
165
- };
166
-
167
- return (
168
- <List
169
- data={data}
170
- renderItem={({ item }) => <ItemCard item={item} />}
171
- keyExtractor={(item) => item.id}
172
- onEndReached={loadMore}
173
- onEndReachedThreshold={0.5}
174
- ListFooterComponent={renderFooter}
175
- contentPadding
176
- />
177
- );
178
- };
179
- ```
114
+ // Use unique ID
115
+ keyExtractor={(item) => item.id}
180
116
 
181
- ### Ürün Listesi
117
+ // Use composite key
118
+ keyExtractor={(item) => `${item.type}-${item.id}`}
182
119
 
183
- ```tsx
184
- export const ProductList = () => {
185
- const [products, setProducts] = useState([]);
186
- const [refreshing, setRefreshing] = useState(false);
187
-
188
- const onRefresh = async () => {
189
- setRefreshing(true);
190
- const data = await fetchProducts();
191
- setProducts(data);
192
- setRefreshing(false);
193
- };
194
-
195
- const renderProduct = ({ item }) => (
196
- <MediaCard
197
- uri={item.image}
198
- title={item.name}
199
- subtitle={`${item.price} TL`}
200
- onPress={() => navigation.navigate('ProductDetail', { productId: item.id })}
201
- />
202
- );
203
-
204
- return (
205
- <List
206
- data={products}
207
- renderItem={renderProduct}
208
- keyExtractor={(item) => item.id}
209
- onRefresh={onRefresh}
210
- refreshing={refreshing}
211
- numColumns={2}
212
- columnWrapperStyle={{ gap: 8 }}
213
- contentPadding
214
- />
215
- );
216
- };
120
+ // Use slug/UUID
121
+ keyExtractor={(item) => item.slug}
217
122
  ```
218
123
 
219
- ### Haber Listesi
220
-
124
+ **DON'T**:
221
125
  ```tsx
222
- export const NewsList = () => {
223
- const [articles, setArticles] = useState([]);
224
-
225
- const renderArticle = ({ item }) => (
226
- <AtomicCard
227
- variant="outlined"
228
- style={{ marginBottom: 16 }}
229
- onPress={() => navigation.navigate('Article', { articleId: item.id })}
230
- >
231
- <View style={{ padding: 16 }}>
232
- <AtomicText type="titleMedium" style={{ marginBottom: 8 }}>
233
- {item.title}
234
- </AtomicText>
235
- <AtomicText type="bodyMedium" color="secondary" numberOfLines={2}>
236
- {item.excerpt}
237
- </AtomicText>
238
- <View style={{ flexDirection: 'row', marginTop: 8 }}>
239
- <AtomicText type="labelSmall" color="tertiary">
240
- {item.category}
241
- </AtomicText>
242
- <AtomicText type="labelSmall" color="tertiary" style={{ marginLeft: 16 }}>
243
- {formatDate(item.publishedAt)}
244
- </AtomicText>
245
- </View>
246
- </View>
247
- </AtomicCard>
248
- );
249
-
250
- return (
251
- <List
252
- data={articles}
253
- renderItem={renderArticle}
254
- keyExtractor={(item) => item.id}
255
- contentPadding
256
- />
257
- );
258
- };
126
+ // Don't use index
127
+ keyExtractor={(item, index) => index.toString()} // ❌
128
+
129
+ // Don't use mutable values
130
+ keyExtractor={(item) => item.name} // May change ❌
259
131
  ```
260
132
 
261
- ### Sohbet Listesi
133
+ ### Performance
262
134
 
135
+ ✅ **DO**:
263
136
  ```tsx
264
- export const ChatList = () => {
265
- const [conversations, setConversations] = useState([]);
266
-
267
- const renderConversation = ({ item }) => (
268
- <Pressable
269
- style={{ flexDirection: 'row', alignItems: 'center', padding: 16 }}
270
- onPress={() => navigation.navigate('Chat', { chatId: item.id })}
271
- >
272
- <Avatar
273
- uri={item.avatar}
274
- name={item.name}
275
- showStatus
276
- status={item.online ? 'online' : 'offline'}
277
- size="md"
278
- />
279
-
280
- <View style={{ flex: 1, marginLeft: 12 }}>
281
- <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
282
- <AtomicText type="bodyLarge" fontWeight="600">
283
- {item.name}
284
- </AtomicText>
285
- <AtomicText type="bodySmall" color="tertiary">
286
- {formatTime(item.lastMessageAt)}
287
- </AtomicText>
288
- </View>
289
-
290
- <AtomicText
291
- type="bodyMedium"
292
- color="secondary"
293
- numberOfLines={1}
294
- style={{ marginTop: 4 }}
295
- >
296
- {item.lastMessage}
297
- </AtomicText>
298
- </View>
299
- </Pressable>
300
- );
301
-
302
- return (
303
- <List
304
- data={conversations}
305
- renderItem={renderConversation}
306
- keyExtractor={(item) => item.id}
307
- contentPadding
308
- />
309
- );
310
- };
311
- ```
137
+ // Memoize renderItem
138
+ const renderItem = useCallback(({ item }) => (
139
+ <ItemCard item={item} />
140
+ ), []);
312
141
 
313
- ### Arama Sonuçları
142
+ // Use getItemLayout for fixed sizes
143
+ getItemLayout={(data, index) => ({
144
+ length: ITEM_HEIGHT,
145
+ offset: ITEM_HEIGHT * index,
146
+ index,
147
+ })}
148
+ ```
314
149
 
150
+ ❌ **DON'T**:
315
151
  ```tsx
316
- export const SearchResults = ({ query }) => {
317
- const [results, setResults] = useState([]);
318
- const [loading, setLoading] = useState(false);
319
-
320
- useEffect(() => {
321
- const search = async () => {
322
- setLoading(true);
323
- const data = await searchItems(query);
324
- setResults(data);
325
- setLoading(false);
326
- };
327
-
328
- if (query.length > 2) {
329
- search();
330
- }
331
- }, [query]);
332
-
333
- const renderResult = ({ item }) => (
334
- <ListItem
335
- title={item.title}
336
- subtitle={item.description}
337
- left={() => <AtomicIcon name="search-outline" size="md" />}
338
- onPress={() => navigation.navigate('Detail', { id: item.id })}
339
- />
340
- );
341
-
342
- if (loading) {
343
- return <AtomicSpinner fullContainer />;
344
- }
345
-
346
- if (results.length === 0) {
347
- return (
348
- <EmptyState
349
- icon="search-outline"
350
- title="Sonuç bulunamadı"
351
- message={`"${query}" için sonuç bulunamadı`}
352
- />
353
- );
354
- }
355
-
356
- return (
357
- <List
358
- data={results}
359
- renderItem={renderResult}
360
- keyExtractor={(item) => item.id}
361
- contentPadding
362
- />
363
- );
364
- };
152
+ // Don't create functions in render
153
+ <List
154
+ renderItem={({ item }) => <ItemCard item={item} />} // ❌ New function each render
155
+ />
365
156
  ```
366
157
 
367
- ### Bildirim Listesi
158
+ ### Content Padding
368
159
 
160
+ ✅ **DO**:
369
161
  ```tsx
370
- export const NotificationList = () => {
371
- const [notifications, setNotifications] = useState([]);
372
-
373
- const renderNotification = ({ item }) => (
374
- <View
375
- style={{
376
- flexDirection: 'row',
377
- padding: 16,
378
- backgroundColor: item.read ? 'transparent' : `${tokens.colors.primary}10`,
379
- borderBottomWidth: 1,
380
- borderBottomColor: tokens.colors.border,
381
- }}
382
- >
383
- <View style={{ marginRight: 12 }}>
384
- <AtomicIcon
385
- name={item.type === 'success' ? 'checkmark-circle' : 'information-circle'}
386
- size="lg"
387
- color={item.type === 'success' ? 'success' : 'primary'}
388
- />
389
- </View>
390
-
391
- <View style={{ flex: 1 }}>
392
- <AtomicText type="bodyLarge" fontWeight="600">
393
- {item.title}
394
- </AtomicText>
395
- <AtomicText type="bodyMedium" color="secondary" style={{ marginTop: 4 }}>
396
- {item.message}
397
- </AtomicText>
398
- <AtomicText type="labelSmall" color="tertiary" style={{ marginTop: 8 }}>
399
- {formatRelativeTime(item.createdAt)}
400
- </AtomicText>
401
- </View>
402
- </View>
403
- );
404
-
405
- return (
406
- <List
407
- data={notifications}
408
- renderItem={renderNotification}
409
- keyExtractor={(item) => item.id}
410
- contentPadding
411
- />
412
- );
413
- };
414
- ```
162
+ // Use built-in contentPadding
163
+ <List contentPadding />
415
164
 
416
- ### Görev Listesi
165
+ // Manual padding for custom layouts
166
+ <List
167
+ contentContainerStyle={{ padding: 16 }}
168
+ />
169
+ ```
417
170
 
171
+ ❌ **DON'T**:
418
172
  ```tsx
419
- export const TaskList = () => {
420
- const [tasks, setTasks] = useState([]);
421
-
422
- const toggleTask = (taskId) => {
423
- setTasks(tasks.map(task =>
424
- task.id === taskId ? { ...task, completed: !task.completed } : task
425
- ));
426
- };
427
-
428
- const renderTask = ({ item }) => (
429
- <View
430
- style={{
431
- flexDirection: 'row',
432
- alignItems: 'center',
433
- padding: 16,
434
- borderBottomWidth: 1,
435
- borderBottomColor: tokens.colors.border,
436
- }}
437
- >
438
- <Pressable onPress={() => toggleTask(item.id)}>
439
- <AtomicIcon
440
- name={item.completed ? 'checkmark-circle' : 'ellipse-outline'}
441
- size="md"
442
- color={item.completed ? 'success' : 'secondary'}
443
- />
444
- </Pressable>
445
-
446
- <View style={{ flex: 1, marginLeft: 12 }}>
447
- <AtomicText
448
- type="bodyLarge"
449
- style={{
450
- textDecorationLine: item.completed ? 'line-through' : 'none',
451
- opacity: item.completed ? 0.6 : 1,
452
- }}
453
- >
454
- {item.title}
455
- </AtomicText>
456
-
457
- {item.dueDate && (
458
- <AtomicText type="labelSmall" color="tertiary" style={{ marginTop: 4 }}>
459
- {formatDate(item.dueDate)}
460
- </AtomicText>
461
- )}
462
- </View>
463
-
464
- {item.priority === 'high' && (
465
- <AtomicIcon name="alert-circle" size="sm" color="error" />
466
- )}
467
- </View>
468
- );
469
-
470
- return (
471
- <List
472
- data={tasks}
473
- renderItem={renderTask}
474
- keyExtractor={(item) => item.id}
475
- contentPadding
476
- />
477
- );
478
- };
173
+ // Don't add unnecessary wrapper
174
+ <View style={{ padding: 16 }}>
175
+ <List /> {/* Extra wrapper ❌ */}
176
+ </View>
479
177
  ```
480
178
 
481
- ## Props
482
-
483
- ### ListProps
484
-
485
- | Prop | Tip | Varsayılan | Açıklama |
486
- |------|-----|------------|----------|
487
- | `data` | `T[]` | - **(Zorunlu)** | Liste verisi |
488
- | `renderItem` | `ListRenderItem<T>` | - **(Zorunlu)** | Render fonksiyonu |
489
- | `keyExtractor` | `(item, index) => string` | - **(Zorunlu)** | Key extractor |
490
- | `onRefresh` | `() => void` | - | Yenileme callback'i |
491
- | `refreshing` | `boolean` | `false` | Yeneleniyor durumunda |
492
- | `contentPadding` | `boolean` | `false` | İçerik padding'i |
493
-
494
- **Not:** List, FlatList'in tüm props'larını destekler.
495
-
496
- ## Best Practices
497
-
498
- ### 1. Key Extractor
179
+ ### Empty State
499
180
 
181
+ ✅ **DO**:
500
182
  ```tsx
501
- // İyi - Unique ve stable
502
- keyExtractor={(item) => item.id}
503
-
504
- // ❌ Kötü - Index kullanımı
505
- keyExtractor={(item, index) => index.toString()}
183
+ {data.length === 0 ? (
184
+ <EmptyState
185
+ icon="inbox-outline"
186
+ title="No items"
187
+ message="Get started by adding your first item"
188
+ />
189
+ ) : (
190
+ <List data={data} />
191
+ )}
506
192
  ```
507
193
 
508
- ### 2. Performans
194
+ **DON'T**:
195
+ ```tsx
196
+ // Don't show empty list
197
+ <List data={[]} /> {/* Shows nothing ❌ */}
198
+ ```
509
199
 
200
+ ## AI Coding Guidelines
201
+
202
+ ### For AI Agents
203
+
204
+ When generating List components, follow these rules:
205
+
206
+ 1. **Always import from correct path**:
207
+ ```typescript
208
+ import { List } from 'react-native-design-system/src/molecules/List';
209
+ ```
210
+
211
+ 2. **Always provide required props**:
212
+ ```tsx
213
+ <List
214
+ data={dataArray}
215
+ renderItem={renderItemFunction}
216
+ keyExtractor={keyExtractorFunction}
217
+ />
218
+ ```
219
+
220
+ 3. **Always use unique keys**:
221
+ ```tsx
222
+ // ✅ Good
223
+ keyExtractor={(item) => item.id}
224
+
225
+ // ❌ Bad
226
+ keyExtractor={(item, index) => index.toString()}
227
+ ```
228
+
229
+ 4. **Always memoize renderItem**:
230
+ ```tsx
231
+ const renderItem = useCallback(({ item }) => (
232
+ <ItemCard item={item} />
233
+ ), []);
234
+ ```
235
+
236
+ 5. **Never use inline functions**:
237
+ ```tsx
238
+ // ❌ Bad
239
+ <List
240
+ renderItem={({ item }) => <ItemCard item={item} />}
241
+ />
242
+
243
+ // ✅ Good
244
+ const renderItem = useCallback(({ item }) => (
245
+ <ItemCard item={item} />
246
+ ), []);
247
+ <List renderItem={renderItem} />
248
+ ```
249
+
250
+ ### Common Patterns
251
+
252
+ #### Basic List
510
253
  ```tsx
511
- // ✅ Memo kullan
512
254
  const renderItem = useCallback(({ item }) => (
513
- <ItemCard item={item} />
255
+ <ListItem
256
+ title={item.title}
257
+ onPress={() => navigateToDetail(item.id)}
258
+ />
514
259
  ), []);
515
260
 
516
- // ✅ Inline function değil
517
- renderItem={renderItem}
261
+ <List
262
+ data={items}
263
+ renderItem={renderItem}
264
+ keyExtractor={(item) => item.id}
265
+ contentPadding
266
+ />
518
267
  ```
519
268
 
520
- ### 3. Content Padding
521
-
269
+ #### Pull-to-Refresh
522
270
  ```tsx
523
- // Liste için
524
- <List contentPadding />
271
+ const [refreshing, setRefreshing] = useState(false);
525
272
 
526
- // Manuel padding
527
- <View style={{ padding: 16 }}>
528
- <List />
529
- </View> // ❌ Gereksiz
273
+ const onRefresh = useCallback(async () => {
274
+ setRefreshing(true);
275
+ await loadData();
276
+ setRefreshing(false);
277
+ }, []);
278
+
279
+ <List
280
+ data={items}
281
+ renderItem={renderItem}
282
+ keyExtractor={(item) => item.id}
283
+ onRefresh={onRefresh}
284
+ refreshing={refreshing}
285
+ />
530
286
  ```
531
287
 
532
- ### 4. Empty State
288
+ #### Infinite Scroll
289
+ ```tsx
290
+ const [loading, setLoading] = useState(false);
291
+
292
+ const loadMore = useCallback(async () => {
293
+ if (loading) return;
294
+ setLoading(true);
295
+ const newItems = await fetchMore();
296
+ setItems([...items, ...newItems]);
297
+ setLoading(false);
298
+ }, [loading, items]);
299
+
300
+ <List
301
+ data={items}
302
+ renderItem={renderItem}
303
+ keyExtractor={(item) => item.id}
304
+ onEndReached={loadMore}
305
+ onEndReachedThreshold={0.5}
306
+ ListFooterComponent={loading ? <LoadingSpinner /> : null}
307
+ />
308
+ ```
533
309
 
310
+ #### Grid Layout
534
311
  ```tsx
535
- {data.length === 0 ? (
536
- <EmptyState />
537
- ) : (
538
- <List data={data} />
539
- )}
312
+ <List
313
+ data={items}
314
+ renderItem={renderItem}
315
+ keyExtractor={(item) => item.id}
316
+ numColumns={2}
317
+ columnWrapperStyle={{ gap: 8 }}
318
+ contentPadding
319
+ />
540
320
  ```
541
321
 
542
- ## Erişilebilirlik
322
+ ## Props Reference
323
+
324
+ | Prop | Type | Required | Default | Description |
325
+ |------|------|----------|---------|-------------|
326
+ | `data` | `T[]` | Yes | - | List data array |
327
+ | `renderItem` | `ListRenderItem<T>` | Yes | - | Render function |
328
+ | `keyExtractor` | `(item, index) => string` | Yes | - | Key extractor |
329
+ | `onRefresh` | `() => void` | No | - | Refresh callback |
330
+ | `refreshing` | `boolean` | No | `false` | Refreshing state |
331
+ | `contentPadding` | `boolean` | No | `false` | Add content padding |
332
+
333
+ **Note:** List supports all FlatList props.
543
334
 
544
- List, tam erişilebilirlik desteği sunar:
335
+ ## Accessibility
545
336
 
546
- - ✅ Screen reader desteği
547
- - ✅ Semantic list anlamları
548
- - ✅ Focus management
549
- - ✅ Keyboard navigation
337
+ - ✅ Screen reader announces list items
338
+ - ✅ Semantic list structure
339
+ - ✅ Focus management for keyboard navigation
340
+ - ✅ Accessibility labels supported
341
+ - ✅ Proper list semantics
550
342
 
551
- ## Performans İpuçları
343
+ ## Performance
552
344
 
553
- 1. **keyExtractor**: Her item için unique key kullanın
554
- 2. **Memoization**: renderItem fonksiyonunu memo edin
555
- 3. **removeClippedSubviews**: Büyük listelerde kullanın
556
- 4. **getItemLayout**: Sabit boyutlu item'larda kullanın
557
- 5. **windowSize**: Viewport dışındaki item sayısını sınırlayın
345
+ 1. **Key extraction**: Use unique, stable keys
346
+ 2. **Memoization**: Memo renderItem function
347
+ 3. **Windowing**: Uses FlatList windowing
348
+ 4. **Optimization**: Consider `removeClippedSubviews` for large lists
349
+ 5. **Layout**: Use `getItemLayout` for fixed-size items
350
+ 6. **Batching**: Batch updates to data
558
351
 
559
- ## İlgili Bileşenler
352
+ ## Related Components
560
353
 
561
354
  - [`FlatList`](https://reactnative.dev/docs/flatlist) - React Native FlatList
562
- - [`ListItem`](../listitem/README.md) - Liste öğesi
563
- - [`MediaCard`](../media-card/README.md) - Medya kartı
564
- - [`Avatar`](../avatar/README.md) - Avatar bileşeni
355
+ - [`ListItem`](../listitem/README.md) - List item component
356
+ - [`MediaCard`](../media-card/README.md) - Media card component
357
+ - [`Avatar`](../avatar/README.md) - Avatar component
565
358
 
566
- ## Lisans
359
+ ## License
567
360
 
568
361
  MIT