@umituz/react-native-design-system 2.6.93 → 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/exports/theme.ts +0 -1
- 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/IconContainer.tsx +1 -1
- 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 -92
- package/src/molecules/swipe-actions/README.md +376 -588
|
@@ -1,483 +1,370 @@
|
|
|
1
1
|
# AtomicAvatar
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A user profile image component with fallback to initials when image is not available.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Import & Usage
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- 🎨 **Özelleştirilebilir**: Renk, border, stil
|
|
11
|
-
- ♿ **Erişilebilir**: Tam erişilebilirlik desteği
|
|
12
|
-
- 🌐 **Responsive**: Otomatik boyutlandırma
|
|
7
|
+
```typescript
|
|
8
|
+
import { AtomicAvatar } from 'react-native-design-system/src/atoms/AtomicAvatar';
|
|
9
|
+
```
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
**Location:** `src/atoms/AtomicAvatar.tsx`
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
15
14
|
|
|
16
15
|
```tsx
|
|
17
|
-
|
|
16
|
+
<AtomicAvatar name="John Doe" />
|
|
18
17
|
```
|
|
19
18
|
|
|
20
|
-
##
|
|
19
|
+
## Strategy
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
import React from 'react';
|
|
24
|
-
import { View } from 'react-native';
|
|
25
|
-
import { AtomicAvatar } from 'react-native-design-system';
|
|
26
|
-
|
|
27
|
-
export const BasicExample = () => {
|
|
28
|
-
return (
|
|
29
|
-
<View style={{ padding: 16 }}>
|
|
30
|
-
{/* Resim ile */}
|
|
31
|
-
<AtomicAvatar
|
|
32
|
-
source={{ uri: 'https://example.com/avatar.jpg' }}
|
|
33
|
-
/>
|
|
21
|
+
**Purpose**: Display user profile pictures with automatic fallback to initials when image unavailable.
|
|
34
22
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
};
|
|
42
|
-
```
|
|
23
|
+
**When to Use**:
|
|
24
|
+
- User profile images in lists or cards
|
|
25
|
+
- Comment/user activity sections
|
|
26
|
+
- Navigation headers with user info
|
|
27
|
+
- Team member displays
|
|
28
|
+
- Anywhere user identity needs visual representation
|
|
43
29
|
|
|
44
|
-
|
|
30
|
+
**When NOT to Use**:
|
|
31
|
+
- For non-user images (products, content) - use Image component
|
|
32
|
+
- When initials don't make sense (company logos, icons)
|
|
33
|
+
- For decorative images without user context
|
|
45
34
|
|
|
46
|
-
|
|
47
|
-
<View style={{ flexDirection: 'row', gap: 8, alignItems: 'center' }}>
|
|
48
|
-
{/* Extra Small */}
|
|
49
|
-
<AtomicAvatar
|
|
50
|
-
name="AY"
|
|
51
|
-
size="xs"
|
|
52
|
-
/>
|
|
35
|
+
## Rules
|
|
53
36
|
|
|
54
|
-
|
|
55
|
-
<AtomicAvatar
|
|
56
|
-
name="Ahmet"
|
|
57
|
-
size="sm"
|
|
58
|
-
/>
|
|
37
|
+
### Required
|
|
59
38
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
39
|
+
1. **MUST** provide either `source` or `name` prop
|
|
40
|
+
2. **ALWAYS** use appropriate size for context
|
|
41
|
+
3. **SHOULD** provide `name` even when using image (for fallback)
|
|
42
|
+
4. **MUST** maintain accessible labeling
|
|
43
|
+
5. **ALWAYS** handle image loading errors gracefully
|
|
44
|
+
6. **SHOULD** use consistent sizes across related contexts
|
|
45
|
+
7. **MUST** not use for non-user avatars
|
|
65
46
|
|
|
66
|
-
|
|
67
|
-
<AtomicAvatar
|
|
68
|
-
name="Ahmet"
|
|
69
|
-
size="lg"
|
|
70
|
-
/>
|
|
47
|
+
### Size Selection
|
|
71
48
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
49
|
+
1. **xs (24px)**: Inline text, tiny mentions
|
|
50
|
+
2. **sm (32px)**: List items, compact displays
|
|
51
|
+
3. **md (40px)**: Default, most use cases
|
|
52
|
+
4. **lg (56px)**: Cards, profile headers
|
|
53
|
+
5. **xl (80px)**: Profile pages, large displays
|
|
54
|
+
6. **xxl (120px)**: Hero sections, featured profiles
|
|
77
55
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
56
|
+
### Initials Fallback
|
|
57
|
+
|
|
58
|
+
1. **Single name**: First letter
|
|
59
|
+
2. **Two names**: First letter of each (John Doe → JD)
|
|
60
|
+
3. **Three+ names**: First letter of first two names
|
|
61
|
+
4. **No name**: Shows "?" placeholder
|
|
62
|
+
|
|
63
|
+
### Image Loading
|
|
64
|
+
|
|
65
|
+
1. **Cache images**: Use FastImage or cached images
|
|
66
|
+
2. **Handle errors**: Always provide name fallback
|
|
67
|
+
3. **Lazy load**: In lists, use lazy loading
|
|
85
68
|
|
|
86
|
-
##
|
|
69
|
+
## Forbidden
|
|
70
|
+
|
|
71
|
+
❌ **NEVER** do these:
|
|
87
72
|
|
|
88
73
|
```tsx
|
|
89
|
-
|
|
74
|
+
// ❌ No source or name
|
|
75
|
+
<AtomicAvatar /> {/* ❌ Shows "?" */}
|
|
76
|
+
|
|
77
|
+
// ❌ Wrong size for context
|
|
78
|
+
<AtomicList>
|
|
79
|
+
<AtomicItem>
|
|
80
|
+
<AtomicAvatar size="xxl" /> {/* ❌ Too large for list */}
|
|
81
|
+
</AtomicItem>
|
|
82
|
+
</AtomicList>
|
|
83
|
+
|
|
84
|
+
// ❌ No name fallback
|
|
90
85
|
<AtomicAvatar
|
|
91
|
-
source={{ uri:
|
|
86
|
+
source={{ uri: avatarUrl }}
|
|
87
|
+
// ❌ No name, shows "?" if image fails
|
|
92
88
|
/>
|
|
93
89
|
|
|
94
|
-
|
|
90
|
+
// ❌ Name for non-user
|
|
95
91
|
<AtomicAvatar
|
|
96
|
-
|
|
92
|
+
name="Product Name"
|
|
93
|
+
source={{ uri: productImage }}
|
|
94
|
+
// ❌ Should use Image component
|
|
95
|
+
/>
|
|
96
|
+
|
|
97
|
+
// ❌ Inconsistent sizes in list
|
|
98
|
+
<FlatList
|
|
99
|
+
data={users}
|
|
100
|
+
renderItem={({ item }) => (
|
|
101
|
+
<UserItem>
|
|
102
|
+
<AtomicAvatar
|
|
103
|
+
name={item.name}
|
|
104
|
+
size={item.index % 2 === 0 ? 'sm' : 'lg'} {/* ❌ Inconsistent */}
|
|
105
|
+
/>
|
|
106
|
+
</UserItem>
|
|
107
|
+
)}
|
|
97
108
|
/>
|
|
98
109
|
|
|
99
|
-
|
|
110
|
+
// ❌ Hardcoded border radius on circular avatar
|
|
100
111
|
<AtomicAvatar
|
|
101
|
-
|
|
102
|
-
|
|
112
|
+
name="John"
|
|
113
|
+
borderRadius={8} {/* ❌ Avatar is meant to be circular */}
|
|
103
114
|
/>
|
|
104
115
|
```
|
|
105
116
|
|
|
106
|
-
##
|
|
107
|
-
|
|
108
|
-
```tsx
|
|
109
|
-
{/* Tek isim */}
|
|
110
|
-
<AtomicAvatar name="Ahmet" /> {/* A */}
|
|
111
|
-
|
|
112
|
-
{/* İki isim */}
|
|
113
|
-
<AtomicAvatar name="Ahmet Yılmaz" /> {/* AY */}
|
|
114
|
-
|
|
115
|
-
{/* Üç isim */}
|
|
116
|
-
<AtomicAvatar name="Ahmet Can Yılmaz" /> {/* AC */}
|
|
117
|
-
|
|
118
|
-
{/* Boş isim */}
|
|
119
|
-
<AtomicAvatar /> {/* ? */}
|
|
120
|
-
```
|
|
117
|
+
## Best Practices
|
|
121
118
|
|
|
122
|
-
|
|
119
|
+
### Size Selection
|
|
123
120
|
|
|
121
|
+
✅ **DO**:
|
|
124
122
|
```tsx
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
// ✅ List items
|
|
124
|
+
<FlatList
|
|
125
|
+
data={users}
|
|
126
|
+
renderItem={({ item }) => (
|
|
127
|
+
<ListItem>
|
|
128
|
+
<AtomicAvatar name={item.name} size="sm" />
|
|
129
|
+
</ListItem>
|
|
130
|
+
)}
|
|
131
|
+
/>
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
name="Ayşe"
|
|
136
|
-
backgroundColor="#ec4899"
|
|
137
|
-
textColor="#ffffff"
|
|
138
|
-
/>
|
|
139
|
-
</View>
|
|
140
|
-
```
|
|
133
|
+
// ✅ Profile header
|
|
134
|
+
<AtomicAvatar name={user.name} size="xxl" />
|
|
141
135
|
|
|
142
|
-
|
|
136
|
+
// ✅ Default size
|
|
137
|
+
<AtomicAvatar name="John Doe" /> {/* md (40px) */}
|
|
138
|
+
```
|
|
143
139
|
|
|
140
|
+
❌ **DON'T**:
|
|
144
141
|
```tsx
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
<AtomicAvatar
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
/>
|
|
152
|
-
|
|
153
|
-
{/* Custom border */}
|
|
154
|
-
<AtomicAvatar
|
|
155
|
-
name="Ayşe"
|
|
156
|
-
borderWidth={3}
|
|
157
|
-
borderColor="#ec4899"
|
|
158
|
-
/>
|
|
159
|
-
</View>
|
|
142
|
+
// ❌ Wrong sizes
|
|
143
|
+
<ListItem>
|
|
144
|
+
<AtomicAvatar name="John" size="xxl" /> {/* Too large */}
|
|
145
|
+
</ListItem>
|
|
146
|
+
|
|
147
|
+
<ProfileHeader>
|
|
148
|
+
<AtomicAvatar name="John" size="xs" /> {/* Too small */}
|
|
149
|
+
</ProfileHeader>
|
|
160
150
|
```
|
|
161
151
|
|
|
162
|
-
|
|
152
|
+
### Fallback Handling
|
|
163
153
|
|
|
154
|
+
✅ **DO**:
|
|
164
155
|
```tsx
|
|
165
|
-
|
|
156
|
+
// ✅ Always provide name
|
|
166
157
|
<AtomicAvatar
|
|
167
|
-
|
|
168
|
-
|
|
158
|
+
source={{ uri: user.avatar }}
|
|
159
|
+
name={user.name} // Fallback to initials
|
|
169
160
|
/>
|
|
170
161
|
|
|
171
|
-
|
|
162
|
+
// ✅ Handle missing data
|
|
172
163
|
<AtomicAvatar
|
|
173
|
-
name=
|
|
174
|
-
|
|
175
|
-
borderRadius={8}
|
|
176
|
-
/>
|
|
177
|
-
|
|
178
|
-
<!-- Köşeli yuvarlatılmış -->
|
|
179
|
-
<AtomicAvatar
|
|
180
|
-
name="Ahmet"
|
|
181
|
-
size="lg"
|
|
182
|
-
borderRadius={16}
|
|
164
|
+
name={user.name || 'Unknown User'}
|
|
165
|
+
source={user.avatar ? { uri: user.avatar } : undefined}
|
|
183
166
|
/>
|
|
184
167
|
```
|
|
185
168
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
### Kullanıcı Listesi
|
|
189
|
-
|
|
169
|
+
❌ **DON'T**:
|
|
190
170
|
```tsx
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
renderItem={({ item }) => (
|
|
197
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', padding: 16 }}>
|
|
198
|
-
<AtomicAvatar
|
|
199
|
-
source={item.avatar ? { uri: item.avatar } : undefined}
|
|
200
|
-
name={item.name}
|
|
201
|
-
size="md"
|
|
202
|
-
style={{ marginRight: 12 }}
|
|
203
|
-
/>
|
|
204
|
-
|
|
205
|
-
<View>
|
|
206
|
-
<AtomicText type="bodyLarge" fontWeight="600">
|
|
207
|
-
{item.name}
|
|
208
|
-
</AtomicText>
|
|
209
|
-
<AtomicText type="bodySmall" color="textSecondary">
|
|
210
|
-
{item.email}
|
|
211
|
-
</AtomicText>
|
|
212
|
-
</View>
|
|
213
|
-
</View>
|
|
214
|
-
)}
|
|
215
|
-
/>
|
|
216
|
-
);
|
|
217
|
-
};
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### Profil Başlığı
|
|
221
|
-
|
|
222
|
-
```tsx
|
|
223
|
-
export const ProfileHeader = ({ user }) => {
|
|
224
|
-
return (
|
|
225
|
-
<View style={{ alignItems: 'center', padding: 24 }}>
|
|
226
|
-
<AtomicAvatar
|
|
227
|
-
source={user.avatar ? { uri: user.avatar } : undefined}
|
|
228
|
-
name={user.name}
|
|
229
|
-
size="xxl"
|
|
230
|
-
borderWidth={3}
|
|
231
|
-
borderColor={tokens.colors.primary}
|
|
232
|
-
style={{ marginBottom: 16 }}
|
|
233
|
-
/>
|
|
234
|
-
|
|
235
|
-
<AtomicText type="headlineSmall">
|
|
236
|
-
{user.name}
|
|
237
|
-
</AtomicText>
|
|
171
|
+
// ❌ No fallback
|
|
172
|
+
<AtomicAvatar
|
|
173
|
+
source={{ uri: user.avatar }}
|
|
174
|
+
// Shows "?" if image fails
|
|
175
|
+
/>
|
|
238
176
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
</AtomicText>
|
|
242
|
-
</View>
|
|
243
|
-
);
|
|
244
|
-
};
|
|
177
|
+
// ❌ Empty name
|
|
178
|
+
<AtomicAvatar name="" />
|
|
245
179
|
```
|
|
246
180
|
|
|
247
|
-
### Avatar
|
|
181
|
+
### Avatar Groups
|
|
248
182
|
|
|
183
|
+
✅ **DO**:
|
|
249
184
|
```tsx
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
{
|
|
271
|
-
<View
|
|
272
|
-
style={{
|
|
273
|
-
width: tokens.avatarSizes.sm,
|
|
274
|
-
height: tokens.avatarSizes.sm,
|
|
275
|
-
borderRadius: tokens.avatarSizes.sm / 2,
|
|
276
|
-
backgroundColor: tokens.colors.surfaceVariant,
|
|
277
|
-
justifyContent: 'center',
|
|
278
|
-
alignItems: 'center',
|
|
279
|
-
marginLeft: -8,
|
|
280
|
-
borderWidth: 2,
|
|
281
|
-
borderColor: tokens.colors.backgroundPrimary,
|
|
282
|
-
}}
|
|
283
|
-
>
|
|
284
|
-
<AtomicText type="labelSmall">
|
|
285
|
-
+{remainingCount}
|
|
286
|
-
</AtomicText>
|
|
287
|
-
</View>
|
|
288
|
-
)}
|
|
185
|
+
// ✅ Overlapping avatars
|
|
186
|
+
<View style={{ flexDirection: 'row' }}>
|
|
187
|
+
{users.slice(0, 3).map((user, index) => (
|
|
188
|
+
<AtomicAvatar
|
|
189
|
+
key={user.id}
|
|
190
|
+
name={user.name}
|
|
191
|
+
size="sm"
|
|
192
|
+
style={{ marginLeft: index > 0 ? -8 : 0 }}
|
|
193
|
+
/>
|
|
194
|
+
))}
|
|
195
|
+
{users.length > 3 && (
|
|
196
|
+
<View style={{
|
|
197
|
+
width: 32,
|
|
198
|
+
height: 32,
|
|
199
|
+
borderRadius: 16,
|
|
200
|
+
backgroundColor: tokens.colors.surfaceVariant,
|
|
201
|
+
justifyContent: 'center',
|
|
202
|
+
alignItems: 'center',
|
|
203
|
+
marginLeft: -8,
|
|
204
|
+
}}>
|
|
205
|
+
<AtomicText type="labelSmall">+{users.length - 3}</AtomicText>
|
|
289
206
|
</View>
|
|
290
|
-
)
|
|
291
|
-
|
|
207
|
+
)}
|
|
208
|
+
</View>
|
|
292
209
|
```
|
|
293
210
|
|
|
294
|
-
###
|
|
211
|
+
### Status Indicators
|
|
295
212
|
|
|
213
|
+
✅ **DO**:
|
|
296
214
|
```tsx
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
</AtomicText>
|
|
315
|
-
</View>
|
|
316
|
-
|
|
317
|
-
<AtomicText type="bodyMedium">
|
|
318
|
-
{comment.text}
|
|
319
|
-
</AtomicText>
|
|
320
|
-
</View>
|
|
321
|
-
</View>
|
|
322
|
-
);
|
|
323
|
-
};
|
|
215
|
+
// ✅ Online status
|
|
216
|
+
<View style={{ position: 'relative' }}>
|
|
217
|
+
<AtomicAvatar name={user.name} size="lg" />
|
|
218
|
+
{user.isOnline && (
|
|
219
|
+
<View style={{
|
|
220
|
+
position: 'absolute',
|
|
221
|
+
bottom: 0,
|
|
222
|
+
right: 0,
|
|
223
|
+
width: 14,
|
|
224
|
+
height: 14,
|
|
225
|
+
borderRadius: 7,
|
|
226
|
+
backgroundColor: tokens.colors.success,
|
|
227
|
+
borderWidth: 2,
|
|
228
|
+
borderColor: tokens.colors.backgroundPrimary,
|
|
229
|
+
}} />
|
|
230
|
+
)}
|
|
231
|
+
</View>
|
|
324
232
|
```
|
|
325
233
|
|
|
326
|
-
|
|
327
|
-
|
|
234
|
+
## AI Coding Guidelines
|
|
235
|
+
|
|
236
|
+
### For AI Agents
|
|
237
|
+
|
|
238
|
+
When generating AtomicAvatar components, follow these rules:
|
|
239
|
+
|
|
240
|
+
1. **Always provide name fallback**:
|
|
241
|
+
```tsx
|
|
242
|
+
// ✅ Good
|
|
243
|
+
<AtomicAvatar
|
|
244
|
+
source={{ uri: user.avatar }}
|
|
245
|
+
name={user.name}
|
|
246
|
+
/>
|
|
247
|
+
|
|
248
|
+
// ❌ Bad
|
|
249
|
+
<AtomicAvatar source={{ uri: user.avatar }} />
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
2. **Always use appropriate size**:
|
|
253
|
+
```tsx
|
|
254
|
+
// ✅ Good - size matches context
|
|
255
|
+
<ListItem>
|
|
256
|
+
<AtomicAvatar name={user.name} size="sm" />
|
|
257
|
+
</ListItem>
|
|
258
|
+
<ProfileHeader>
|
|
259
|
+
<AtomicAvatar name={user.name} size="xxl" />
|
|
260
|
+
</ProfileHeader>
|
|
261
|
+
|
|
262
|
+
// ❌ Bad - wrong size
|
|
263
|
+
<ListItem>
|
|
264
|
+
<AtomicAvatar name={user.name} size="xxl" />
|
|
265
|
+
</ListItem>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
3. **Always handle missing data**:
|
|
269
|
+
```tsx
|
|
270
|
+
// ✅ Good - handles missing
|
|
271
|
+
<AtomicAvatar
|
|
272
|
+
name={user.name || 'Unknown'}
|
|
273
|
+
source={user.avatar ? { uri: user.avatar } : undefined}
|
|
274
|
+
/>
|
|
275
|
+
|
|
276
|
+
// ❌ Bad - doesn't handle missing
|
|
277
|
+
<AtomicAvatar name={user.name} source={{ uri: user.avatar }} />
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
4. **Never use for non-user images**:
|
|
281
|
+
```tsx
|
|
282
|
+
// ❌ Bad - non-user avatar
|
|
283
|
+
<AtomicAvatar
|
|
284
|
+
name="Product"
|
|
285
|
+
source={{ uri: productImage }}
|
|
286
|
+
/>
|
|
287
|
+
// Should use Image component instead
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Common Patterns
|
|
291
|
+
|
|
292
|
+
#### Basic Avatar
|
|
328
293
|
```tsx
|
|
329
|
-
|
|
330
|
-
return (
|
|
331
|
-
<Pressable
|
|
332
|
-
style={{ flexDirection: 'row', alignItems: 'center', padding: 16 }}
|
|
333
|
-
onPress={() => navigation.navigate('Profile', { userId: user.id })}
|
|
334
|
-
>
|
|
335
|
-
<AtomicAvatar
|
|
336
|
-
source={user.avatar ? { uri: user.avatar } : undefined}
|
|
337
|
-
name={user.name}
|
|
338
|
-
size="md"
|
|
339
|
-
/>
|
|
340
|
-
|
|
341
|
-
<View style={{ marginLeft: 12, flex: 1 }}>
|
|
342
|
-
<AtomicText type="bodyLarge" fontWeight="600">
|
|
343
|
-
{user.name}
|
|
344
|
-
</AtomicText>
|
|
345
|
-
<AtomicText type="bodySmall" color="textSecondary">
|
|
346
|
-
Profili görüntüle
|
|
347
|
-
</AtomicText>
|
|
348
|
-
</View>
|
|
349
|
-
|
|
350
|
-
<AtomicIcon name="chevron-forward" size="sm" />
|
|
351
|
-
</Pressable>
|
|
352
|
-
);
|
|
353
|
-
};
|
|
294
|
+
<AtomicAvatar name="John Doe" />
|
|
354
295
|
```
|
|
355
296
|
|
|
356
|
-
|
|
357
|
-
|
|
297
|
+
#### With Image
|
|
358
298
|
```tsx
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
source={user.avatar ? { uri: user.avatar } : undefined}
|
|
364
|
-
name={user.name}
|
|
365
|
-
size="lg"
|
|
366
|
-
/>
|
|
367
|
-
|
|
368
|
-
{isOnline && (
|
|
369
|
-
<View
|
|
370
|
-
style={{
|
|
371
|
-
position: 'absolute',
|
|
372
|
-
bottom: 0,
|
|
373
|
-
right: 0,
|
|
374
|
-
width: 16,
|
|
375
|
-
height: 16,
|
|
376
|
-
borderRadius: 8,
|
|
377
|
-
backgroundColor: tokens.colors.success,
|
|
378
|
-
borderWidth: 2,
|
|
379
|
-
borderColor: tokens.colors.backgroundPrimary,
|
|
380
|
-
}}
|
|
381
|
-
/>
|
|
382
|
-
)}
|
|
383
|
-
</View>
|
|
384
|
-
);
|
|
385
|
-
};
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
## Props
|
|
389
|
-
|
|
390
|
-
### AtomicAvatarProps
|
|
391
|
-
|
|
392
|
-
| Prop | Tip | Varsayılan | Açıklama |
|
|
393
|
-
|------|-----|------------|----------|
|
|
394
|
-
| `source` | `ImageSourcePropType` | - | Resim kaynağı |
|
|
395
|
-
| `name` | `string` | - | Kullanıcı ismi (baş harfler için) |
|
|
396
|
-
| `size` | `AvatarSize` | `'md'` | Avatar boyutu |
|
|
397
|
-
| `customSize` | `number` | - | Özel boyut (px) |
|
|
398
|
-
| `backgroundColor` | `string` | - | Arka plan rengi |
|
|
399
|
-
| `textColor` | `string` | - | Metin rengi |
|
|
400
|
-
| `borderRadius` | `number` | - | Köşe yarıçapı |
|
|
401
|
-
| `borderWidth` | `number` | `0` | Çerçeve kalınlığı |
|
|
402
|
-
| `borderColor` | `string` | - | Çerçeve rengi |
|
|
403
|
-
| `style` | `StyleProp<ViewStyle>` | - | Özel stil |
|
|
404
|
-
| `imageStyle` | `StyleProp<ImageStyle>` | - | Resim stili |
|
|
405
|
-
| `testID` | `string` | - | Test ID'si |
|
|
406
|
-
|
|
407
|
-
### AvatarSize
|
|
408
|
-
|
|
409
|
-
```typescript
|
|
410
|
-
type AvatarSize =
|
|
411
|
-
| 'xs' // Extra small
|
|
412
|
-
| 'sm' // Small
|
|
413
|
-
| 'md' // Medium (varsayılan)
|
|
414
|
-
| 'lg' // Large
|
|
415
|
-
| 'xl' // Extra large
|
|
416
|
-
| 'xxl'; // Extra extra large
|
|
299
|
+
<AtomicAvatar
|
|
300
|
+
source={{ uri: user.avatarUrl }}
|
|
301
|
+
name={user.name}
|
|
302
|
+
/>
|
|
417
303
|
```
|
|
418
304
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
### 1. Boyut Seçimi
|
|
422
|
-
|
|
305
|
+
#### List Avatar
|
|
423
306
|
```tsx
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
<AtomicAvatar size="sm" />
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
// Vurgu için
|
|
434
|
-
<AtomicAvatar size="lg" />
|
|
435
|
-
|
|
436
|
-
// Profil sayfası için
|
|
437
|
-
<AtomicAvatar size="xxl" />
|
|
307
|
+
<FlatList
|
|
308
|
+
data={users}
|
|
309
|
+
renderItem={({ item }) => (
|
|
310
|
+
<ListItem>
|
|
311
|
+
<AtomicAvatar name={item.name} size="sm" />
|
|
312
|
+
<AtomicText>{item.name}</AtomicText>
|
|
313
|
+
</ListItem>
|
|
314
|
+
)}
|
|
315
|
+
/>
|
|
438
316
|
```
|
|
439
317
|
|
|
440
|
-
|
|
441
|
-
|
|
318
|
+
#### Profile Header
|
|
442
319
|
```tsx
|
|
443
|
-
|
|
444
|
-
<AtomicAvatar
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
320
|
+
<View style={{ alignItems: 'center', padding: 24 }}>
|
|
321
|
+
<AtomicAvatar
|
|
322
|
+
source={{ uri: user.avatar }}
|
|
323
|
+
name={user.name}
|
|
324
|
+
size="xxl"
|
|
325
|
+
/>
|
|
326
|
+
<AtomicText type="headlineLarge" marginTop="md">
|
|
327
|
+
{user.name}
|
|
328
|
+
</AtomicText>
|
|
329
|
+
</View>
|
|
448
330
|
```
|
|
449
331
|
|
|
450
|
-
|
|
332
|
+
## Props Reference
|
|
451
333
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
334
|
+
| Prop | Type | Required | Default | Description |
|
|
335
|
+
|------|------|----------|---------|-------------|
|
|
336
|
+
| `source` | `ImageSourcePropType` | No | - | Image source |
|
|
337
|
+
| `name` | `string` | No* | - | User name (for initials) |
|
|
338
|
+
| `size` | `AvatarSize` | No | `'md'` | Avatar size |
|
|
339
|
+
| `customSize` | `number` | No | - | Custom size (px) |
|
|
340
|
+
| `backgroundColor` | `string` | No | - | Background color |
|
|
341
|
+
| `textColor` | `string` | No | - | Initials text color |
|
|
342
|
+
| `borderRadius` | `number` | No | - | Corner radius |
|
|
343
|
+
| `borderWidth` | `number` | No | `0` | Border width |
|
|
344
|
+
| `borderColor` | `string` | No | - | Border color |
|
|
459
345
|
|
|
460
|
-
|
|
346
|
+
*Either `source` or `name` should be provided
|
|
461
347
|
|
|
462
|
-
|
|
348
|
+
## Accessibility
|
|
463
349
|
|
|
464
|
-
- ✅ Screen reader
|
|
465
|
-
- ✅ Accessibility label
|
|
350
|
+
- ✅ Screen reader announces user name
|
|
351
|
+
- ✅ Accessibility label for image
|
|
466
352
|
- ✅ Semantic role (image)
|
|
467
|
-
- ✅ Test ID
|
|
353
|
+
- ✅ Test ID support
|
|
468
354
|
|
|
469
|
-
##
|
|
355
|
+
## Performance Tips
|
|
470
356
|
|
|
471
|
-
1. **Image
|
|
472
|
-
2. **Lazy
|
|
473
|
-
3. **Resize**:
|
|
357
|
+
1. **Image caching**: Cache avatar images
|
|
358
|
+
2. **Lazy loading**: In long lists
|
|
359
|
+
3. **Resize images**: Load appropriate size
|
|
360
|
+
4. **Memoization**: Memo avatar in lists
|
|
474
361
|
|
|
475
|
-
##
|
|
362
|
+
## Related Components
|
|
476
363
|
|
|
477
|
-
- [`
|
|
478
|
-
- [`
|
|
479
|
-
- [`
|
|
364
|
+
- [`AtomicText`](./AtomicText.README.md) - Text component
|
|
365
|
+
- [`AtomicIcon`](./AtomicIcon.README.md) - Icon component
|
|
366
|
+
- [`AtomicCard`](./AtomicCard.README.md) - Card component
|
|
480
367
|
|
|
481
|
-
##
|
|
368
|
+
## License
|
|
482
369
|
|
|
483
370
|
MIT
|