@umituz/react-native-design-system 2.6.94 → 2.6.96
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/navigation/components/NavigationHeader.tsx +77 -0
- package/src/molecules/navigation/index.ts +1 -0
- package/src/molecules/splash/README.md +76 -80
- package/src/molecules/swipe-actions/README.md +376 -588
|
@@ -1,402 +1,407 @@
|
|
|
1
1
|
# ListItem
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A versatile list item component with title, subtitle, and optional icons for menus, settings, and navigation lists.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Import & Usage
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- 👆 **Pressable**: Tıklanabilir öğeler
|
|
10
|
-
- ♿ **Erişilebilir**: Tam erişilebilirlik desteği
|
|
11
|
-
- 🎨 **Tema Bilinci**: Otomatik tema uyumu
|
|
12
|
-
|
|
13
|
-
## Kurulum
|
|
14
|
-
|
|
15
|
-
```tsx
|
|
16
|
-
import { ListItem } from 'react-native-design-system';
|
|
7
|
+
```typescript
|
|
8
|
+
import { ListItem } from 'react-native-design-system/src/molecules/listitem';
|
|
17
9
|
```
|
|
18
10
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```tsx
|
|
22
|
-
import React from 'react';
|
|
23
|
-
import { View } from 'react-native';
|
|
24
|
-
import { ListItem } from 'react-native-design-system';
|
|
25
|
-
|
|
26
|
-
export const BasicExample = () => {
|
|
27
|
-
return (
|
|
28
|
-
<View>
|
|
29
|
-
<ListItem
|
|
30
|
-
title="Başlık"
|
|
31
|
-
subtitle="Alt başlık"
|
|
32
|
-
/>
|
|
33
|
-
</View>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
```
|
|
11
|
+
**Location:** `src/molecules/listitem/ListItem.tsx`
|
|
37
12
|
|
|
38
|
-
## Basic
|
|
13
|
+
## Basic Usage
|
|
39
14
|
|
|
40
15
|
```tsx
|
|
41
16
|
<ListItem
|
|
42
|
-
title="
|
|
17
|
+
title="Settings"
|
|
18
|
+
subtitle="Configure your preferences"
|
|
19
|
+
leftIcon="settings-outline"
|
|
20
|
+
rightIcon="chevron-forward-outline"
|
|
21
|
+
onPress={() => navigateTo('Settings')}
|
|
43
22
|
/>
|
|
44
23
|
```
|
|
45
24
|
|
|
46
|
-
##
|
|
25
|
+
## Strategy
|
|
26
|
+
|
|
27
|
+
**Purpose**: Provide a consistent, accessible list item component for navigation, settings, and content display.
|
|
28
|
+
|
|
29
|
+
**When to Use**:
|
|
30
|
+
- Navigation menus and drawers
|
|
31
|
+
- Settings pages
|
|
32
|
+
- User lists and contacts
|
|
33
|
+
- File/item listings
|
|
34
|
+
- Action menus (edit, share, delete)
|
|
35
|
+
- Selection lists (radio buttons, checkboxes)
|
|
36
|
+
|
|
37
|
+
**When NOT to Use**:
|
|
38
|
+
- For card-based content (use AtomicCard instead)
|
|
39
|
+
- For complex row layouts (use custom View instead)
|
|
40
|
+
- For table data (use Table component instead)
|
|
41
|
+
- For simple dividers (use Divider instead)
|
|
42
|
+
|
|
43
|
+
## Rules
|
|
44
|
+
|
|
45
|
+
### Required
|
|
46
|
+
|
|
47
|
+
1. **MUST** have a `title` prop
|
|
48
|
+
2. **ALWAYS** provide `onPress` when item is interactive
|
|
49
|
+
3. **SHOULD** have descriptive icons (leftIcon for context, rightIcon for navigation)
|
|
50
|
+
4. **MUST** have proper touch feedback when pressable
|
|
51
|
+
5. **SHOULD** keep subtitles concise (1 line max recommended)
|
|
52
|
+
6. **ALWAYS** use unique `key` props when rendering lists
|
|
53
|
+
7. **MUST** respect disabled state (no feedback)
|
|
54
|
+
|
|
55
|
+
### Icon Usage
|
|
56
|
+
|
|
57
|
+
1. **Left icon**: Use for context/category (settings, profile, notifications)
|
|
58
|
+
2. **Right icon**: Use for navigation indication (chevron, checkmark)
|
|
59
|
+
3. **Consistency**: Use same icon style within list
|
|
60
|
+
4. **Size**: Use appropriate icon size (md recommended)
|
|
61
|
+
|
|
62
|
+
### Press Behavior
|
|
63
|
+
|
|
64
|
+
1. **Must have onPress**: Always provide when using rightIcon for navigation
|
|
65
|
+
2. **Visual feedback**: Show press effect
|
|
66
|
+
3. **Disabled state**: No press effect when disabled
|
|
67
|
+
4. **Action delay**: Add confirmation for destructive actions
|
|
68
|
+
|
|
69
|
+
### Content Guidelines
|
|
70
|
+
|
|
71
|
+
1. **Title**: Clear, concise (1-2 words recommended)
|
|
72
|
+
2. **Subtitle**: Additional context, max 1 line
|
|
73
|
+
3. **Truncation**: Titles should not wrap awkwardly
|
|
74
|
+
4. **Grouping**: Use dividers or section headers for groups
|
|
75
|
+
|
|
76
|
+
## Forbidden
|
|
77
|
+
|
|
78
|
+
❌ **NEVER** do these:
|
|
47
79
|
|
|
48
80
|
```tsx
|
|
81
|
+
// ❌ No title
|
|
49
82
|
<ListItem
|
|
50
|
-
title
|
|
51
|
-
subtitle="
|
|
83
|
+
// Missing title prop
|
|
84
|
+
subtitle="No title"
|
|
52
85
|
/>
|
|
53
|
-
```
|
|
54
86
|
|
|
55
|
-
|
|
87
|
+
// ❌ Right icon without press handler
|
|
88
|
+
<ListItem
|
|
89
|
+
title="Settings"
|
|
90
|
+
rightIcon="chevron-forward-outline" // ❌ Indicates navigation
|
|
91
|
+
// Missing onPress
|
|
92
|
+
/>
|
|
56
93
|
|
|
57
|
-
|
|
94
|
+
// ❌ Generic icons
|
|
58
95
|
<ListItem
|
|
59
|
-
title="
|
|
60
|
-
|
|
61
|
-
leftIcon="settings-outline"
|
|
62
|
-
rightIcon="chevron-forward"
|
|
63
|
-
onPress={() => console.log('Ayarlar')}
|
|
96
|
+
title="Settings"
|
|
97
|
+
leftIcon="ellipse-outline" // ❌ Not descriptive
|
|
64
98
|
/>
|
|
65
|
-
```
|
|
66
99
|
|
|
67
|
-
|
|
100
|
+
// ❌ Too long subtitle
|
|
101
|
+
<ListItem
|
|
102
|
+
title="User"
|
|
103
|
+
subtitle="Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore" // ❌ Too long
|
|
104
|
+
/>
|
|
68
105
|
|
|
69
|
-
|
|
106
|
+
// ❌ Destructive action without confirmation
|
|
70
107
|
<ListItem
|
|
71
|
-
title="
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
rightIcon="chevron-forward"
|
|
75
|
-
onPress={() => navigation.navigate('Profile')}
|
|
108
|
+
title="Delete Account"
|
|
109
|
+
leftIcon="trash-outline"
|
|
110
|
+
onPress={() => deleteAccount()} // ❌ No confirmation
|
|
76
111
|
/>
|
|
77
|
-
```
|
|
78
112
|
|
|
79
|
-
|
|
113
|
+
// ❌ Missing keys in lists
|
|
114
|
+
{items.map((item) => (
|
|
115
|
+
<ListItem
|
|
116
|
+
title={item.title} // ❌ No key prop
|
|
117
|
+
/>
|
|
118
|
+
))}
|
|
80
119
|
|
|
81
|
-
|
|
120
|
+
// ❌ Disabled but pressable
|
|
82
121
|
<ListItem
|
|
83
|
-
title="
|
|
84
|
-
subtitle="Bu öğe tıklanamaz"
|
|
85
|
-
leftIcon="lock-closed-outline"
|
|
122
|
+
title="Premium Feature"
|
|
86
123
|
disabled
|
|
124
|
+
onPress={() => {}} // ❌ Should not have onPress when disabled
|
|
87
125
|
/>
|
|
88
126
|
```
|
|
89
127
|
|
|
90
|
-
##
|
|
91
|
-
|
|
92
|
-
### Ayarlar Listesi
|
|
93
|
-
|
|
94
|
-
```tsx
|
|
95
|
-
export const SettingsList = () => {
|
|
96
|
-
const settings = [
|
|
97
|
-
{
|
|
98
|
-
id: '1',
|
|
99
|
-
title: 'Profil',
|
|
100
|
-
subtitle: 'Profil bilgilerinizi yönetin',
|
|
101
|
-
icon: 'person-outline',
|
|
102
|
-
onPress: () => navigation.navigate('Profile'),
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
id: '2',
|
|
106
|
-
title: 'Bildirimler',
|
|
107
|
-
subtitle: 'Bildirim tercihlerinizi ayarlayın',
|
|
108
|
-
icon: 'notifications-outline',
|
|
109
|
-
onPress: () => navigation.navigate('Notifications'),
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
id: '3',
|
|
113
|
-
title: 'Gizlilik',
|
|
114
|
-
subtitle: 'Gizlilik ayarlarınızı yönetin',
|
|
115
|
-
icon: 'lock-closed-outline',
|
|
116
|
-
onPress: () => navigation.navigate('Privacy'),
|
|
117
|
-
},
|
|
118
|
-
];
|
|
119
|
-
|
|
120
|
-
return (
|
|
121
|
-
<View>
|
|
122
|
-
{settings.map((setting) => (
|
|
123
|
-
<ListItem
|
|
124
|
-
key={setting.id}
|
|
125
|
-
title={setting.title}
|
|
126
|
-
subtitle={setting.subtitle}
|
|
127
|
-
leftIcon={setting.icon}
|
|
128
|
-
rightIcon="chevron-forward"
|
|
129
|
-
onPress={setting.onPress}
|
|
130
|
-
/>
|
|
131
|
-
))}
|
|
132
|
-
</View>
|
|
133
|
-
);
|
|
134
|
-
};
|
|
135
|
-
```
|
|
128
|
+
## Best Practices
|
|
136
129
|
|
|
137
|
-
###
|
|
130
|
+
### Navigation Items
|
|
138
131
|
|
|
132
|
+
✅ **DO**:
|
|
139
133
|
```tsx
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
onPress={() => navigation.navigate('Home')}
|
|
147
|
-
/>
|
|
148
|
-
|
|
149
|
-
<ListItem
|
|
150
|
-
title="Arama"
|
|
151
|
-
leftIcon="search-outline"
|
|
152
|
-
onPress={() => navigation.navigate('Search')}
|
|
153
|
-
/>
|
|
154
|
-
|
|
155
|
-
<ListItem
|
|
156
|
-
title="Profilim"
|
|
157
|
-
leftIcon="person-outline"
|
|
158
|
-
onPress={() => navigation.navigate('Profile')}
|
|
159
|
-
/>
|
|
160
|
-
|
|
161
|
-
<ListItem
|
|
162
|
-
title="Ayarlar"
|
|
163
|
-
leftIcon="settings-outline"
|
|
164
|
-
onPress={() => navigation.navigate('Settings')}
|
|
165
|
-
/>
|
|
166
|
-
</View>
|
|
167
|
-
);
|
|
168
|
-
};
|
|
134
|
+
<ListItem
|
|
135
|
+
title="Settings"
|
|
136
|
+
leftIcon="settings-outline"
|
|
137
|
+
rightIcon="chevron-forward-outline"
|
|
138
|
+
onPress={() => navigation.navigate('Settings')}
|
|
139
|
+
/>
|
|
169
140
|
```
|
|
170
141
|
|
|
171
|
-
|
|
172
|
-
|
|
142
|
+
❌ **DON'T**:
|
|
173
143
|
```tsx
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
<ListItem
|
|
181
|
-
title={item.name}
|
|
182
|
-
subtitle={item.email}
|
|
183
|
-
leftIcon="person-outline"
|
|
184
|
-
onPress={() => navigation.navigate('UserDetail', { userId: item.id })}
|
|
185
|
-
/>
|
|
186
|
-
)}
|
|
187
|
-
/>
|
|
188
|
-
);
|
|
189
|
-
};
|
|
144
|
+
// ❌ Navigation indicator without action
|
|
145
|
+
<ListItem
|
|
146
|
+
title="Settings"
|
|
147
|
+
rightIcon="chevron-forward-outline"
|
|
148
|
+
// Missing onPress
|
|
149
|
+
/>
|
|
190
150
|
```
|
|
191
151
|
|
|
192
|
-
###
|
|
152
|
+
### Icon Selection
|
|
193
153
|
|
|
154
|
+
✅ **DO**:
|
|
194
155
|
```tsx
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
onPress={() => onSelect(option.id)}
|
|
205
|
-
/>
|
|
206
|
-
))}
|
|
207
|
-
</View>
|
|
208
|
-
);
|
|
209
|
-
};
|
|
156
|
+
// Descriptive icons
|
|
157
|
+
<ListItem
|
|
158
|
+
title="Notifications"
|
|
159
|
+
leftIcon="notifications-outline"
|
|
160
|
+
/>
|
|
161
|
+
<ListItem
|
|
162
|
+
title="Profile"
|
|
163
|
+
leftIcon="person-outline"
|
|
164
|
+
/>
|
|
210
165
|
```
|
|
211
166
|
|
|
212
|
-
|
|
213
|
-
|
|
167
|
+
❌ **DON'T**:
|
|
214
168
|
```tsx
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
{ id: '4', title: 'Customers', icon: 'people-outline', screen: 'Customers' },
|
|
221
|
-
];
|
|
222
|
-
|
|
223
|
-
return (
|
|
224
|
-
<View>
|
|
225
|
-
{routes.map((route) => (
|
|
226
|
-
<ListItem
|
|
227
|
-
key={route.id}
|
|
228
|
-
title={route.title}
|
|
229
|
-
leftIcon={route.icon}
|
|
230
|
-
rightIcon="chevron-forward"
|
|
231
|
-
onPress={() => navigation.navigate(route.screen)}
|
|
232
|
-
/>
|
|
233
|
-
))}
|
|
234
|
-
</View>
|
|
235
|
-
);
|
|
236
|
-
};
|
|
169
|
+
// Generic icons
|
|
170
|
+
<ListItem
|
|
171
|
+
title="Notifications"
|
|
172
|
+
leftIcon="ellipse-outline" // ❌ Not descriptive
|
|
173
|
+
/>
|
|
237
174
|
```
|
|
238
175
|
|
|
239
|
-
###
|
|
176
|
+
### List Rendering
|
|
240
177
|
|
|
178
|
+
✅ **DO**:
|
|
241
179
|
```tsx
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
/>
|
|
251
|
-
|
|
252
|
-
<ListItem
|
|
253
|
-
title="Düzenle"
|
|
254
|
-
subtitle="Öğeyi düzenleyin"
|
|
255
|
-
leftIcon="create-outline"
|
|
256
|
-
onPress={() => console.log('Edit')}
|
|
257
|
-
/>
|
|
258
|
-
|
|
259
|
-
<ListItem
|
|
260
|
-
title="Sil"
|
|
261
|
-
subtitle="Öğeyi silin"
|
|
262
|
-
leftIcon="trash-outline"
|
|
263
|
-
onPress={() => console.log('Delete')}
|
|
264
|
-
/>
|
|
265
|
-
|
|
266
|
-
<ListItem
|
|
267
|
-
title="Paylaş"
|
|
268
|
-
subtitle="Öğeyi paylaşın"
|
|
269
|
-
leftIcon="share-outline"
|
|
270
|
-
onPress={() => console.log('Share')}
|
|
271
|
-
/>
|
|
272
|
-
</View>
|
|
273
|
-
);
|
|
274
|
-
};
|
|
180
|
+
{users.map((user) => (
|
|
181
|
+
<ListItem
|
|
182
|
+
key={user.id} // ✅ Unique key
|
|
183
|
+
title={user.name}
|
|
184
|
+
subtitle={user.email}
|
|
185
|
+
onPress={() => navigateToUser(user.id)}
|
|
186
|
+
/>
|
|
187
|
+
))}
|
|
275
188
|
```
|
|
276
189
|
|
|
277
|
-
|
|
278
|
-
|
|
190
|
+
❌ **DON'T**:
|
|
279
191
|
```tsx
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
leftIcon="globe-outline"
|
|
287
|
-
rightIcon="open-outline"
|
|
288
|
-
onPress={() => Linking.openURL('https://www.example.com')}
|
|
289
|
-
/>
|
|
290
|
-
|
|
291
|
-
<ListItem
|
|
292
|
-
title="Twitter"
|
|
293
|
-
subtitle="@example"
|
|
294
|
-
leftIcon="logo-twitter"
|
|
295
|
-
rightIcon="open-outline"
|
|
296
|
-
onPress={() => Linking.openURL('https://twitter.com/example')}
|
|
297
|
-
/>
|
|
298
|
-
|
|
299
|
-
<ListItem
|
|
300
|
-
title="GitHub"
|
|
301
|
-
subtitle="github.com/example"
|
|
302
|
-
leftIcon="logo-github"
|
|
303
|
-
rightIcon="open-outline"
|
|
304
|
-
onPress={() => Linking.openURL('https://github.com/example')}
|
|
305
|
-
/>
|
|
306
|
-
</View>
|
|
307
|
-
);
|
|
308
|
-
};
|
|
192
|
+
{users.map((user, index) => (
|
|
193
|
+
<ListItem
|
|
194
|
+
key={index} // ❌ Index as key
|
|
195
|
+
title={user.name}
|
|
196
|
+
/>
|
|
197
|
+
))}
|
|
309
198
|
```
|
|
310
199
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
### ListItemProps
|
|
314
|
-
|
|
315
|
-
| Prop | Tip | Varsayılan | Açıklama |
|
|
316
|
-
|------|-----|------------|----------|
|
|
317
|
-
| `title` | `string` | - **(Zorunlu)** | Başlık metni |
|
|
318
|
-
| `subtitle` | `string` | - | Alt başlık metni |
|
|
319
|
-
| `leftIcon` | `string` | - | Sol ikon ismi |
|
|
320
|
-
| `rightIcon` | `string` | - | Sağ ikon ismi |
|
|
321
|
-
| `onPress` | `() => void` | - | Tıklama olayı |
|
|
322
|
-
| `disabled` | `boolean` | `false` | Devre dışı |
|
|
323
|
-
| `style` | `ViewStyle` | - | Özel stil |
|
|
324
|
-
| `testID` | `string` | - | Test ID'si |
|
|
325
|
-
|
|
326
|
-
## Best Practices
|
|
327
|
-
|
|
328
|
-
### 1. İkon Seçimi
|
|
200
|
+
### Destructive Actions
|
|
329
201
|
|
|
202
|
+
✅ **DO**:
|
|
330
203
|
```tsx
|
|
331
|
-
// Navigasyon için
|
|
332
204
|
<ListItem
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
205
|
+
title="Delete Account"
|
|
206
|
+
leftIcon="trash-outline"
|
|
207
|
+
onPress={() => {
|
|
208
|
+
showConfirmation({
|
|
209
|
+
title: 'Delete Account',
|
|
210
|
+
message: 'This action cannot be undone',
|
|
211
|
+
onConfirm: deleteAccount,
|
|
212
|
+
});
|
|
213
|
+
}}
|
|
340
214
|
/>
|
|
215
|
+
```
|
|
341
216
|
|
|
342
|
-
|
|
217
|
+
❌ **DON'T**:
|
|
218
|
+
```tsx
|
|
343
219
|
<ListItem
|
|
344
|
-
|
|
220
|
+
title="Delete Account"
|
|
221
|
+
leftIcon="trash-outline"
|
|
222
|
+
onPress={() => deleteAccount()} // ❌ No confirmation
|
|
345
223
|
/>
|
|
346
224
|
```
|
|
347
225
|
|
|
348
|
-
|
|
349
|
-
|
|
226
|
+
## AI Coding Guidelines
|
|
227
|
+
|
|
228
|
+
### For AI Agents
|
|
229
|
+
|
|
230
|
+
When generating ListItem components, follow these rules:
|
|
231
|
+
|
|
232
|
+
1. **Always import from correct path**:
|
|
233
|
+
```typescript
|
|
234
|
+
import { ListItem } from 'react-native-design-system/src/molecules/listitem';
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
2. **Always provide a title**:
|
|
238
|
+
```tsx
|
|
239
|
+
// ✅ Good
|
|
240
|
+
<ListItem
|
|
241
|
+
title="Settings"
|
|
242
|
+
onPress={handlePress}
|
|
243
|
+
/>
|
|
244
|
+
|
|
245
|
+
// ❌ Bad - no title
|
|
246
|
+
<ListItem
|
|
247
|
+
onPress={handlePress}
|
|
248
|
+
/>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
3. **Always match icons with context**:
|
|
252
|
+
```tsx
|
|
253
|
+
// ✅ Good - descriptive icons
|
|
254
|
+
const iconMap = {
|
|
255
|
+
settings: 'settings-outline',
|
|
256
|
+
profile: 'person-outline',
|
|
257
|
+
notifications: 'notifications-outline',
|
|
258
|
+
privacy: 'shield-checkmark-outline',
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// ❌ Bad - generic icons
|
|
262
|
+
const icons = ['ellipse-outline', 'circle-outline'];
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
4. **Always use unique keys in lists**:
|
|
266
|
+
```tsx
|
|
267
|
+
// ✅ Good - unique ID as key
|
|
268
|
+
{items.map((item) => (
|
|
269
|
+
<ListItem
|
|
270
|
+
key={item.id}
|
|
271
|
+
title={item.title}
|
|
272
|
+
onPress={() => handleItem(item)}
|
|
273
|
+
/>
|
|
274
|
+
))}
|
|
275
|
+
|
|
276
|
+
// ❌ Bad - index as key
|
|
277
|
+
{items.map((item, index) => (
|
|
278
|
+
<ListItem
|
|
279
|
+
key={index}
|
|
280
|
+
title={item.title}
|
|
281
|
+
/>
|
|
282
|
+
))}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
5. **Always add confirmation for destructive actions**:
|
|
286
|
+
```tsx
|
|
287
|
+
// ✅ Good - confirmation dialog
|
|
288
|
+
<ListItem
|
|
289
|
+
title="Delete"
|
|
290
|
+
leftIcon="trash-outline"
|
|
291
|
+
onPress={() => {
|
|
292
|
+
Alert.alert(
|
|
293
|
+
'Confirm Delete',
|
|
294
|
+
'This action cannot be undone',
|
|
295
|
+
[
|
|
296
|
+
{ text: 'Cancel', style: 'cancel' },
|
|
297
|
+
{ text: 'Delete', style: 'destructive', onPress: handleDelete },
|
|
298
|
+
]
|
|
299
|
+
);
|
|
300
|
+
}}
|
|
301
|
+
/>
|
|
302
|
+
|
|
303
|
+
// ❌ Bad - immediate action
|
|
304
|
+
<ListItem
|
|
305
|
+
title="Delete"
|
|
306
|
+
leftIcon="trash-outline"
|
|
307
|
+
onPress={handleDelete} // No confirmation
|
|
308
|
+
/>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Common Patterns
|
|
312
|
+
|
|
313
|
+
#### Settings Menu Item
|
|
350
314
|
```tsx
|
|
351
|
-
// Açıklama için
|
|
352
315
|
<ListItem
|
|
353
|
-
title="
|
|
354
|
-
|
|
316
|
+
title="Settings"
|
|
317
|
+
leftIcon="settings-outline"
|
|
318
|
+
rightIcon="chevron-forward-outline"
|
|
319
|
+
onPress={() => navigation.navigate('Settings')}
|
|
355
320
|
/>
|
|
321
|
+
```
|
|
356
322
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
323
|
+
#### User List Item
|
|
324
|
+
```tsx
|
|
325
|
+
{users.map((user) => (
|
|
326
|
+
<ListItem
|
|
327
|
+
key={user.id}
|
|
328
|
+
title={user.name}
|
|
329
|
+
subtitle={user.email}
|
|
330
|
+
leftIcon="person-outline"
|
|
331
|
+
onPress={() => navigation.navigate('UserProfile', { userId: user.id })}
|
|
332
|
+
/>
|
|
333
|
+
))}
|
|
362
334
|
```
|
|
363
335
|
|
|
364
|
-
|
|
336
|
+
#### Selection List Item
|
|
337
|
+
```tsx
|
|
338
|
+
{options.map((option) => (
|
|
339
|
+
<ListItem
|
|
340
|
+
key={option.id}
|
|
341
|
+
title={option.title}
|
|
342
|
+
leftIcon={option.icon}
|
|
343
|
+
rightIcon={selectedId === option.id ? 'checkmark' : undefined}
|
|
344
|
+
onPress={() => setSelectedId(option.id)}
|
|
345
|
+
/>
|
|
346
|
+
))}
|
|
347
|
+
```
|
|
365
348
|
|
|
349
|
+
#### Action Menu Item
|
|
366
350
|
```tsx
|
|
367
|
-
// Navigasyon
|
|
368
351
|
<ListItem
|
|
369
|
-
|
|
352
|
+
title="Edit"
|
|
353
|
+
leftIcon="create-outline"
|
|
354
|
+
rightIcon="chevron-forward-outline"
|
|
355
|
+
onPress={() => onAction('edit')}
|
|
370
356
|
/>
|
|
357
|
+
```
|
|
371
358
|
|
|
372
|
-
|
|
359
|
+
#### Contact Item
|
|
360
|
+
```tsx
|
|
373
361
|
<ListItem
|
|
374
|
-
|
|
362
|
+
title={contact.name}
|
|
363
|
+
subtitle={contact.phone}
|
|
364
|
+
leftIcon="person-outline"
|
|
365
|
+
rightIcon="call-outline"
|
|
366
|
+
onPress={() => Linking.openURL(`tel:${contact.phone}`)}
|
|
375
367
|
/>
|
|
376
368
|
```
|
|
377
369
|
|
|
378
|
-
##
|
|
370
|
+
## Props Reference
|
|
371
|
+
|
|
372
|
+
| Prop | Type | Required | Default | Description |
|
|
373
|
+
|------|------|----------|---------|-------------|
|
|
374
|
+
| `title` | `string` | Yes | - | Primary text |
|
|
375
|
+
| `subtitle` | `string` | No | - | Secondary text |
|
|
376
|
+
| `leftIcon` | `string` | No | - | Left icon name (Ionicons) |
|
|
377
|
+
| `rightIcon` | `string` | No | - | Right icon name (Ionicons) |
|
|
378
|
+
| `onPress` | `() => void` | No | - | Press callback |
|
|
379
|
+
| `disabled` | `boolean` | No | `false` | Disable the item |
|
|
380
|
+
| `style` | `ViewStyle` | No | - | Custom container style |
|
|
379
381
|
|
|
380
|
-
|
|
382
|
+
## Accessibility
|
|
381
383
|
|
|
382
|
-
- ✅
|
|
383
|
-
- ✅
|
|
384
|
-
- ✅
|
|
385
|
-
- ✅
|
|
386
|
-
- ✅
|
|
384
|
+
- ✅ Screen reader announces title and subtitle
|
|
385
|
+
- ✅ Touch target size maintained (min 44x44pt)
|
|
386
|
+
- ✅ Press feedback for screen readers
|
|
387
|
+
- ✅ Disabled state announced
|
|
388
|
+
- ✅ Semantic list item role
|
|
389
|
+
- ✅ Icon accessibility labels
|
|
387
390
|
|
|
388
|
-
##
|
|
391
|
+
## Performance Tips
|
|
389
392
|
|
|
390
|
-
1. **
|
|
391
|
-
2. **
|
|
392
|
-
3. **
|
|
393
|
+
1. **Memoization**: Memo ListItem components for large lists
|
|
394
|
+
2. **Unique keys**: Always use unique IDs as keys (not index)
|
|
395
|
+
3. **Avoid inline functions**: Use useCallback for onPress handlers
|
|
396
|
+
4. **FlatList**: Use FlatList for long lists instead of map
|
|
393
397
|
|
|
394
|
-
##
|
|
398
|
+
## Related Components
|
|
395
399
|
|
|
396
|
-
- [`List`](../List/README.md) -
|
|
397
|
-
- [`
|
|
398
|
-
- [`
|
|
400
|
+
- [`List`](../List/README.md) - List container component
|
|
401
|
+
- [`Avatar`](../avatar/README.md) - User avatar component
|
|
402
|
+
- [`Divider`](../Divider/README.md) - List divider component
|
|
403
|
+
- [`AtomicIcon`](../../atoms/AtomicIcon/README.md) - Icon component
|
|
399
404
|
|
|
400
|
-
##
|
|
405
|
+
## License
|
|
401
406
|
|
|
402
407
|
MIT
|