@umituz/react-native-design-system 2.6.88 → 2.6.89
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/molecules/FormField.README.md +424 -273
- package/src/molecules/List/README.md +568 -0
- package/src/molecules/StepProgress/README.md +522 -0
- package/src/molecules/emoji/README.md +580 -0
- package/src/molecules/splash/types/index.ts +5 -8
- package/src/molecules/swipe-actions/README.md +672 -0
- package/src/theme/core/colors/DarkColors.ts +0 -3
- package/src/theme/core/colors/LightColors.ts +0 -3
- package/src/theme/core/themes.ts +1 -8
- package/src/theme/infrastructure/providers/DesignSystemProvider.tsx +1 -1
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
# EmojiPicker
|
|
2
|
+
|
|
3
|
+
EmojiPicker, emoji seçimi için kullanılan bileşendir. `rn-emoji-keyboard` kütüphanesini wrapper'layarak temiz bir arayüz sunar. Kategori bazlı seçim, arama ve son kullanılan emoji'leri destekler.
|
|
4
|
+
|
|
5
|
+
## Özellikler
|
|
6
|
+
|
|
7
|
+
- 😀 **Emoji Seçimi**: Geniş emoji koleksiyonu
|
|
8
|
+
- 📁 **Kategoriler**: Kategori bazlı navigasyon
|
|
9
|
+
- 🔍 **Arama**: Emoji arama özelliği
|
|
10
|
+
- ⏰ **Son Kullanılanlar**: Son kullanılan emoji'ler
|
|
11
|
+
- 🌍 **Lokalizasyon**: Çoklu dil desteği
|
|
12
|
+
- 🎨 **Özelleştirilebilir**: Konfigürasyon seçenekleri
|
|
13
|
+
- ✨ **Animasyonlar**: Smooth animasyonlar
|
|
14
|
+
|
|
15
|
+
## Kurulum
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { EmojiPicker } from 'react-native-design-system';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Temel Kullanım
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import React, { useState } from 'react';
|
|
25
|
+
import { View, TouchableOpacity, Text } from 'react-native';
|
|
26
|
+
import { EmojiPicker } from 'react-native-design-system';
|
|
27
|
+
|
|
28
|
+
export const BasicExample = () => {
|
|
29
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
30
|
+
const [emoji, setEmoji] = useState('');
|
|
31
|
+
|
|
32
|
+
const handleEmojiSelect = (emojiObject) => {
|
|
33
|
+
setEmoji(emojiObject.emoji);
|
|
34
|
+
setIsOpen(false);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<View>
|
|
39
|
+
<TouchableOpacity onPress={() => setIsOpen(true)}>
|
|
40
|
+
<Text>{emoji || 'Emoji Seç'}</Text>
|
|
41
|
+
</TouchableOpacity>
|
|
42
|
+
|
|
43
|
+
<EmojiPicker
|
|
44
|
+
open={isOpen}
|
|
45
|
+
onClose={() => setIsOpen(false)}
|
|
46
|
+
onEmojiSelected={handleEmojiSelect}
|
|
47
|
+
/>
|
|
48
|
+
</View>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Basit Emoji Seçimi
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
export const SimpleEmojiPicker = () => {
|
|
57
|
+
const [open, setOpen] = useState(false);
|
|
58
|
+
const [selectedEmoji, setSelectedEmoji] = useState('');
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<View>
|
|
62
|
+
<Button
|
|
63
|
+
title={selectedEmoji || 'Emoji Seç'}
|
|
64
|
+
onPress={() => setOpen(true)}
|
|
65
|
+
/>
|
|
66
|
+
|
|
67
|
+
<EmojiPicker
|
|
68
|
+
open={open}
|
|
69
|
+
onClose={() => setOpen(false)}
|
|
70
|
+
onEmojiSelected={(emoji) => {
|
|
71
|
+
setSelectedEmoji(emoji.emoji);
|
|
72
|
+
setOpen(false);
|
|
73
|
+
}}
|
|
74
|
+
/>
|
|
75
|
+
</View>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Mesajlaşma
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
export const MessageComposer = () => {
|
|
84
|
+
const [message, setMessage] = useState('');
|
|
85
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
86
|
+
|
|
87
|
+
const handleEmojiSelect = (emojiObject) => {
|
|
88
|
+
setMessage(message + emojiObject.emoji);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<View>
|
|
93
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', padding: 16 }}>
|
|
94
|
+
<TouchableOpacity onPress={() => setEmojiPickerOpen(true)}>
|
|
95
|
+
<AtomicIcon name="happy-outline" size="lg" />
|
|
96
|
+
</TouchableOpacity>
|
|
97
|
+
|
|
98
|
+
<TextInput
|
|
99
|
+
style={{ flex: 1, marginLeft: 8 }}
|
|
100
|
+
value={message}
|
|
101
|
+
onChangeText={setMessage}
|
|
102
|
+
placeholder="Mesaj yazın..."
|
|
103
|
+
/>
|
|
104
|
+
|
|
105
|
+
<Button
|
|
106
|
+
title="Gönder"
|
|
107
|
+
onPress={() => sendMessage(message)}
|
|
108
|
+
/>
|
|
109
|
+
</View>
|
|
110
|
+
|
|
111
|
+
<EmojiPicker
|
|
112
|
+
open={emojiPickerOpen}
|
|
113
|
+
onClose={() => setEmojiPickerOpen(false)}
|
|
114
|
+
onEmojiSelected={handleEmojiSelect}
|
|
115
|
+
/>
|
|
116
|
+
</View>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Yorum Ekleme
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
export const CommentInput = () => {
|
|
125
|
+
const [comment, setComment] = useState('');
|
|
126
|
+
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
|
|
127
|
+
|
|
128
|
+
const insertEmoji = (emojiObject) => {
|
|
129
|
+
setComment(comment + emojiObject.emoji);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<View>
|
|
134
|
+
<View style={{ padding: 16 }}>
|
|
135
|
+
<View style={{ flexDirection: 'row', alignItems: 'flex-start' }}>
|
|
136
|
+
<Avatar
|
|
137
|
+
uri={currentUser.avatar}
|
|
138
|
+
name={currentUser.name}
|
|
139
|
+
size="sm"
|
|
140
|
+
/>
|
|
141
|
+
|
|
142
|
+
<View style={{ flex: 1, marginLeft: 12 }}>
|
|
143
|
+
<TextInput
|
|
144
|
+
style={{
|
|
145
|
+
borderWidth: 1,
|
|
146
|
+
borderColor: '#e0e0e0',
|
|
147
|
+
borderRadius: 8,
|
|
148
|
+
padding: 12,
|
|
149
|
+
minHeight: 80,
|
|
150
|
+
}}
|
|
151
|
+
value={comment}
|
|
152
|
+
onChangeText={setComment}
|
|
153
|
+
placeholder="Yorumunuzu yazın..."
|
|
154
|
+
multiline
|
|
155
|
+
/>
|
|
156
|
+
|
|
157
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 8 }}>
|
|
158
|
+
<TouchableOpacity onPress={() => setShowEmojiPicker(true)}>
|
|
159
|
+
<AtomicIcon name="happy-outline" size="md" />
|
|
160
|
+
</TouchableOpacity>
|
|
161
|
+
|
|
162
|
+
<Button
|
|
163
|
+
title="Yorum Yap"
|
|
164
|
+
onPress={() => postComment(comment)}
|
|
165
|
+
/>
|
|
166
|
+
</View>
|
|
167
|
+
</View>
|
|
168
|
+
</View>
|
|
169
|
+
</View>
|
|
170
|
+
|
|
171
|
+
<EmojiPicker
|
|
172
|
+
open={showEmojiPicker}
|
|
173
|
+
onClose={() => setShowEmojiPicker(false)}
|
|
174
|
+
onEmojiSelected={insertEmoji}
|
|
175
|
+
/>
|
|
176
|
+
</View>
|
|
177
|
+
);
|
|
178
|
+
};
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Profil Reaksiyonları
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
export const ProfileReactions = () => {
|
|
185
|
+
const [reactions, setReactions] = useState([]);
|
|
186
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
187
|
+
|
|
188
|
+
const addReaction = (emojiObject) => {
|
|
189
|
+
setReactions([...reactions, emojiObject.emoji]);
|
|
190
|
+
setEmojiPickerOpen(false);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
<View>
|
|
195
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', padding: 16 }}>
|
|
196
|
+
<Avatar
|
|
197
|
+
uri={user.avatar}
|
|
198
|
+
name={user.name}
|
|
199
|
+
size="lg"
|
|
200
|
+
/>
|
|
201
|
+
|
|
202
|
+
<View style={{ flex: 1, marginLeft: 12 }}>
|
|
203
|
+
<AtomicText type="titleMedium">{user.name}</AtomicText>
|
|
204
|
+
<AtomicText type="bodyMedium" color="secondary">
|
|
205
|
+
{user.bio}
|
|
206
|
+
</AtomicText>
|
|
207
|
+
</View>
|
|
208
|
+
|
|
209
|
+
<TouchableOpacity onPress={() => setEmojiPickerOpen(true)}>
|
|
210
|
+
<AtomicIcon name="heart-outline" size="lg" />
|
|
211
|
+
</TouchableOpacity>
|
|
212
|
+
</View>
|
|
213
|
+
|
|
214
|
+
{reactions.length > 0 && (
|
|
215
|
+
<View style={{ flexDirection: 'row', flexWrap: 'wrap', paddingHorizontal: 16, paddingBottom: 16 }}>
|
|
216
|
+
{reactions.map((emoji, index) => (
|
|
217
|
+
<View
|
|
218
|
+
key={index}
|
|
219
|
+
style={{
|
|
220
|
+
backgroundColor: '#f0f0f0',
|
|
221
|
+
paddingHorizontal: 12,
|
|
222
|
+
paddingVertical: 6,
|
|
223
|
+
borderRadius: 16,
|
|
224
|
+
marginRight: 8,
|
|
225
|
+
marginBottom: 8,
|
|
226
|
+
}}
|
|
227
|
+
>
|
|
228
|
+
<AtomicText style={{ fontSize: 18 }}>{emoji}</AtomicText>
|
|
229
|
+
</View>
|
|
230
|
+
))}
|
|
231
|
+
</View>
|
|
232
|
+
)}
|
|
233
|
+
|
|
234
|
+
<EmojiPicker
|
|
235
|
+
open={emojiPickerOpen}
|
|
236
|
+
onClose={() => setEmojiPickerOpen(false)}
|
|
237
|
+
onEmojiSelected={addReaction}
|
|
238
|
+
/>
|
|
239
|
+
</View>
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Post Oluşturma
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
export const PostCreator = () => {
|
|
248
|
+
const [content, setContent] = useState('');
|
|
249
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
250
|
+
|
|
251
|
+
const handleEmojiSelect = (emojiObject) => {
|
|
252
|
+
setContent(content + emojiObject.emoji);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const createPost = () => {
|
|
256
|
+
if (content.trim()) {
|
|
257
|
+
publishPost(content);
|
|
258
|
+
setContent('');
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
return (
|
|
263
|
+
<AtomicCard variant="outlined" style={{ margin: 16 }}>
|
|
264
|
+
<View style={{ padding: 16 }}>
|
|
265
|
+
<View style={{ flexDirection: 'row', alignItems: 'flex-start' }}>
|
|
266
|
+
<Avatar
|
|
267
|
+
uri={currentUser.avatar}
|
|
268
|
+
name={currentUser.name}
|
|
269
|
+
size="md"
|
|
270
|
+
/>
|
|
271
|
+
|
|
272
|
+
<View style={{ flex: 1, marginLeft: 12 }}>
|
|
273
|
+
<TextInput
|
|
274
|
+
style={{ minHeight: 100 }}
|
|
275
|
+
value={content}
|
|
276
|
+
onChangeText={setContent}
|
|
277
|
+
placeholder="Neler oluyor?"
|
|
278
|
+
multiline
|
|
279
|
+
/>
|
|
280
|
+
|
|
281
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 12 }}>
|
|
282
|
+
<View style={{ flexDirection: 'row', gap: 16 }}>
|
|
283
|
+
<TouchableOpacity onPress={() => setEmojiPickerOpen(true)}>
|
|
284
|
+
<AtomicIcon name="happy-outline" size="md" color="primary" />
|
|
285
|
+
</TouchableOpacity>
|
|
286
|
+
<TouchableOpacity>
|
|
287
|
+
<AtomicIcon name="image-outline" size="md" color="primary" />
|
|
288
|
+
</TouchableOpacity>
|
|
289
|
+
</View>
|
|
290
|
+
|
|
291
|
+
<Button
|
|
292
|
+
title="Paylaş"
|
|
293
|
+
onPress={createPost}
|
|
294
|
+
disabled={!content.trim()}
|
|
295
|
+
/>
|
|
296
|
+
</View>
|
|
297
|
+
</View>
|
|
298
|
+
</View>
|
|
299
|
+
</View>
|
|
300
|
+
|
|
301
|
+
<EmojiPicker
|
|
302
|
+
open={emojiPickerOpen}
|
|
303
|
+
onClose={() => setEmojiPickerOpen(false)}
|
|
304
|
+
onEmojiSelected={handleEmojiSelect}
|
|
305
|
+
/>
|
|
306
|
+
</AtomicCard>
|
|
307
|
+
);
|
|
308
|
+
};
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Grup İsmi
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
export const GroupNameEditor = () => {
|
|
315
|
+
const [groupName, setGroupName] = useState('');
|
|
316
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
317
|
+
|
|
318
|
+
return (
|
|
319
|
+
<View style={{ padding: 16 }}>
|
|
320
|
+
<AtomicText type="titleMedium" style={{ marginBottom: 8 }}>
|
|
321
|
+
Grup İsmi
|
|
322
|
+
</AtomicText>
|
|
323
|
+
|
|
324
|
+
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
325
|
+
<TouchableOpacity
|
|
326
|
+
style={{
|
|
327
|
+
width: 60,
|
|
328
|
+
height: 60,
|
|
329
|
+
borderRadius: 30,
|
|
330
|
+
backgroundColor: '#f0f0f0',
|
|
331
|
+
justifyContent: 'center',
|
|
332
|
+
alignItems: 'center',
|
|
333
|
+
}}
|
|
334
|
+
onPress={() => setEmojiPickerOpen(true)}
|
|
335
|
+
>
|
|
336
|
+
<AtomicText style={{ fontSize: 32 }}>
|
|
337
|
+
{groupName.slice(0, 1) || '📝'}
|
|
338
|
+
</AtomicText>
|
|
339
|
+
</TouchableOpacity>
|
|
340
|
+
|
|
341
|
+
<TextInput
|
|
342
|
+
style={{ flex: 1, marginLeft: 12 }}
|
|
343
|
+
value={groupName}
|
|
344
|
+
onChangeText={setGroupName}
|
|
345
|
+
placeholder="Grup adı..."
|
|
346
|
+
/>
|
|
347
|
+
</View>
|
|
348
|
+
|
|
349
|
+
<EmojiPicker
|
|
350
|
+
open={emojiPickerOpen}
|
|
351
|
+
onClose={() => setEmojiPickerOpen(false)}
|
|
352
|
+
onEmojiSelected={(emoji) => {
|
|
353
|
+
setGroupName(emoji.emoji + ' ' + groupName);
|
|
354
|
+
setEmojiPickerOpen(false);
|
|
355
|
+
}}
|
|
356
|
+
/>
|
|
357
|
+
</View>
|
|
358
|
+
);
|
|
359
|
+
};
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Emoji Reaksiyonları
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
export const MessageReactions = ({ message }) => {
|
|
366
|
+
const [reactions, setReactions] = useState(message.reactions || []);
|
|
367
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
368
|
+
|
|
369
|
+
const addReaction = (emojiObject) => {
|
|
370
|
+
const existing = reactions.find(r => r.emoji === emojiObject.emoji);
|
|
371
|
+
|
|
372
|
+
if (existing) {
|
|
373
|
+
// Remove reaction if already exists
|
|
374
|
+
setReactions(reactions.filter(r => r.emoji !== emojiObject.emoji));
|
|
375
|
+
} else {
|
|
376
|
+
// Add new reaction
|
|
377
|
+
setReactions([...reactions, {
|
|
378
|
+
emoji: emojiObject.emoji,
|
|
379
|
+
users: [currentUser.id],
|
|
380
|
+
count: 1,
|
|
381
|
+
}]);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
setEmojiPickerOpen(false);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
return (
|
|
388
|
+
<View>
|
|
389
|
+
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 4 }}>
|
|
390
|
+
{reactions.map((reaction, index) => (
|
|
391
|
+
<TouchableOpacity
|
|
392
|
+
key={index}
|
|
393
|
+
style={{
|
|
394
|
+
flexDirection: 'row',
|
|
395
|
+
alignItems: 'center',
|
|
396
|
+
backgroundColor: reaction.users.includes(currentUser.id)
|
|
397
|
+
? `${tokens.colors.primary}20`
|
|
398
|
+
: '#f0f0f0',
|
|
399
|
+
paddingHorizontal: 8,
|
|
400
|
+
paddingVertical: 4,
|
|
401
|
+
borderRadius: 16,
|
|
402
|
+
borderWidth: reaction.users.includes(currentUser.id) ? 1 : 0,
|
|
403
|
+
borderColor: tokens.colors.primary,
|
|
404
|
+
}}
|
|
405
|
+
onPress={() => addReaction({ emoji: reaction.emoji })}
|
|
406
|
+
>
|
|
407
|
+
<AtomicText style={{ fontSize: 16, marginRight: 4 }}>
|
|
408
|
+
{reaction.emoji}
|
|
409
|
+
</AtomicText>
|
|
410
|
+
<AtomicText type="labelSmall">
|
|
411
|
+
{reaction.count}
|
|
412
|
+
</AtomicText>
|
|
413
|
+
</TouchableOpacity>
|
|
414
|
+
))}
|
|
415
|
+
|
|
416
|
+
<TouchableOpacity
|
|
417
|
+
style={{
|
|
418
|
+
flexDirection: 'row',
|
|
419
|
+
alignItems: 'center',
|
|
420
|
+
backgroundColor: '#f0f0f0',
|
|
421
|
+
paddingHorizontal: 8,
|
|
422
|
+
paddingVertical: 4,
|
|
423
|
+
borderRadius: 16,
|
|
424
|
+
}}
|
|
425
|
+
onPress={() => setEmojiPickerOpen(true)}
|
|
426
|
+
>
|
|
427
|
+
<AtomicIcon name="add-outline" size="sm" />
|
|
428
|
+
</TouchableOpacity>
|
|
429
|
+
</View>
|
|
430
|
+
|
|
431
|
+
<EmojiPicker
|
|
432
|
+
open={emojiPickerOpen}
|
|
433
|
+
onClose={() => setEmojiPickerOpen(false)}
|
|
434
|
+
onEmojiSelected={addReaction}
|
|
435
|
+
/>
|
|
436
|
+
</View>
|
|
437
|
+
);
|
|
438
|
+
};
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Emoji Filtreleme
|
|
442
|
+
|
|
443
|
+
```tsx
|
|
444
|
+
export const EmojiFilter = () => {
|
|
445
|
+
const [selectedEmoji, setSelectedEmoji] = useState('');
|
|
446
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
447
|
+
const [filteredContent, setFilteredContent] = useState([]);
|
|
448
|
+
|
|
449
|
+
const handleEmojiSelect = (emojiObject) => {
|
|
450
|
+
setSelectedEmoji(emojiObject.emoji);
|
|
451
|
+
setEmojiPickerOpen(false);
|
|
452
|
+
|
|
453
|
+
// Filter content by emoji reaction
|
|
454
|
+
const filtered = content.filter(item =>
|
|
455
|
+
item.reactions?.some(r => r.emoji === emojiObject.emoji)
|
|
456
|
+
);
|
|
457
|
+
setFilteredContent(filtered);
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
return (
|
|
461
|
+
<View>
|
|
462
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', padding: 16, gap: 8 }}>
|
|
463
|
+
<TouchableOpacity onPress={() => {
|
|
464
|
+
setSelectedEmoji('');
|
|
465
|
+
setFilteredContent(content);
|
|
466
|
+
}}>
|
|
467
|
+
<AtomicText type="labelLarge">Tümü</AtomicText>
|
|
468
|
+
</TouchableOpacity>
|
|
469
|
+
|
|
470
|
+
<TouchableOpacity
|
|
471
|
+
style={{
|
|
472
|
+
paddingHorizontal: 12,
|
|
473
|
+
paddingVertical: 6,
|
|
474
|
+
backgroundColor: selectedEmoji ? `${tokens.colors.primary}20` : '#f0f0f0',
|
|
475
|
+
borderRadius: 16,
|
|
476
|
+
}}
|
|
477
|
+
onPress={() => setEmojiPickerOpen(true)}
|
|
478
|
+
>
|
|
479
|
+
<AtomicText style={{ fontSize: 18 }}>
|
|
480
|
+
{selectedEmoji || '😀'}
|
|
481
|
+
</AtomicText>
|
|
482
|
+
</TouchableOpacity>
|
|
483
|
+
</View>
|
|
484
|
+
|
|
485
|
+
<EmojiPicker
|
|
486
|
+
open={emojiPickerOpen}
|
|
487
|
+
onClose={() => setEmojiPickerOpen(false)}
|
|
488
|
+
onEmojiSelected={handleEmojiSelect}
|
|
489
|
+
/>
|
|
490
|
+
</View>
|
|
491
|
+
);
|
|
492
|
+
};
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## Props
|
|
496
|
+
|
|
497
|
+
### EmojiPickerProps
|
|
498
|
+
|
|
499
|
+
| Prop | Tip | Varsayılan | Açıklama |
|
|
500
|
+
|------|-----|------------|----------|
|
|
501
|
+
| `open` | `boolean` | - **(Zorunlu)** | Picker açık mı |
|
|
502
|
+
| `onClose` | `() => void` | - **(Zorunlu)** | Kapanma callback'i |
|
|
503
|
+
| `onEmojiSelected` | `(emoji) => void` | - **(Zorunlu)** | Emoji seçildiğinde |
|
|
504
|
+
| `config` | `EmojiPickerConfig` | `{}` | Konfigürasyon |
|
|
505
|
+
|
|
506
|
+
### EmojiPickerConfig
|
|
507
|
+
|
|
508
|
+
| Prop | Tip | Varsayılan | Açıklama |
|
|
509
|
+
|------|-----|------------|----------|
|
|
510
|
+
| `enableRecentlyUsed` | `boolean` | `true` | Son kullanılanlar |
|
|
511
|
+
| `enableSearch` | `boolean` | `true` | Arama çubuğu |
|
|
512
|
+
| `enableCategoryTabs` | `boolean` | `true` | Kategori sekmeleri |
|
|
513
|
+
| `categoryOrder` | `string[]` | - | Kategori sırası |
|
|
514
|
+
| `translation` | `object` | - | Lokalizasyon |
|
|
515
|
+
|
|
516
|
+
### EmojiObject
|
|
517
|
+
|
|
518
|
+
| Prop | Tip | Açıklama |
|
|
519
|
+
|------|-----|----------|
|
|
520
|
+
| `emoji` | `string` | Emoji karakteri |
|
|
521
|
+
| `name` | `string` | Emoji adı |
|
|
522
|
+
| `slug` | `string` | URL slug |
|
|
523
|
+
| `unicode_version` | `string` | Unicode versiyonu |
|
|
524
|
+
|
|
525
|
+
## Best Practices
|
|
526
|
+
|
|
527
|
+
### 1. Kullanıcı Deneyimi
|
|
528
|
+
|
|
529
|
+
```tsx
|
|
530
|
+
// ✅ İyi - Hemen kapanır
|
|
531
|
+
onEmojiSelected={(emoji) => {
|
|
532
|
+
onEmojiSelect(emoji);
|
|
533
|
+
onClose(); // Hemen kapat
|
|
534
|
+
}}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### 2. State Yönetimi
|
|
538
|
+
|
|
539
|
+
```tsx
|
|
540
|
+
// ✅ İyi - Ayrı state
|
|
541
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
|
542
|
+
const [selectedEmoji, setSelectedEmoji] = useState('');
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### 3. Trigger Butonu
|
|
546
|
+
|
|
547
|
+
```tsx
|
|
548
|
+
// ✅ İyi - İkonlu buton
|
|
549
|
+
<TouchableOpacity onPress={() => setEmojiPickerOpen(true)}>
|
|
550
|
+
<AtomicIcon name="happy-outline" size="lg" />
|
|
551
|
+
</TouchableOpacity>
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
## Erişilebilirlik
|
|
555
|
+
|
|
556
|
+
EmojiPicker, erişilebilirlik desteği sunar:
|
|
557
|
+
|
|
558
|
+
- ✅ Screen reader desteği
|
|
559
|
+
- ✅ Touch uygun boyut
|
|
560
|
+
- ✅ Semantic anlamlar
|
|
561
|
+
|
|
562
|
+
## Performans İpuçları
|
|
563
|
+
|
|
564
|
+
1. **Lazy Load**: Lazy loading kullanın
|
|
565
|
+
2. **Cache**: Emoji'leri cache'leyin
|
|
566
|
+
3. **Unmount**: Kullanılmadığında unmount edin
|
|
567
|
+
|
|
568
|
+
## İlgili Bileşenler
|
|
569
|
+
|
|
570
|
+
- [`AtomicIcon`](../../atoms/AtomicIcon/README.md) - İkon bileşeni
|
|
571
|
+
- [`FormField`](../FormField/README.md) - Form alanı
|
|
572
|
+
- [`BaseModal`](../BaseModal/README.md) - Modal bileşeni
|
|
573
|
+
|
|
574
|
+
## Bağımlılıklar
|
|
575
|
+
|
|
576
|
+
- `rn-emoji-keyboard` - Emoji picker UI library
|
|
577
|
+
|
|
578
|
+
## Lisans
|
|
579
|
+
|
|
580
|
+
MIT
|
|
@@ -11,7 +11,7 @@ import type { ReactNode } from "react";
|
|
|
11
11
|
* All colors should be provided by the main app via design tokens
|
|
12
12
|
*/
|
|
13
13
|
export interface SplashColors {
|
|
14
|
-
/** Background color
|
|
14
|
+
/** Background color */
|
|
15
15
|
background: string;
|
|
16
16
|
/** Text color for app name and tagline */
|
|
17
17
|
text: string;
|
|
@@ -25,7 +25,7 @@ export interface SplashColors {
|
|
|
25
25
|
export interface SplashCustomColors {
|
|
26
26
|
/** Text color for app name and tagline */
|
|
27
27
|
textColor: string;
|
|
28
|
-
/** Background color
|
|
28
|
+
/** Background color */
|
|
29
29
|
backgroundColor?: string;
|
|
30
30
|
/** Background color for icon placeholder circle */
|
|
31
31
|
iconPlaceholderColor?: string;
|
|
@@ -37,8 +37,7 @@ export interface SplashCustomColors {
|
|
|
37
37
|
export interface SplashThemeProviderProps {
|
|
38
38
|
/** Children components */
|
|
39
39
|
children: ReactNode;
|
|
40
|
-
|
|
41
|
-
gradientColors?: readonly [string, string, ...string[]];
|
|
40
|
+
|
|
42
41
|
/** Custom color configuration */
|
|
43
42
|
customColors?: SplashCustomColors;
|
|
44
43
|
}
|
|
@@ -49,8 +48,7 @@ export interface SplashThemeProviderProps {
|
|
|
49
48
|
export interface SplashThemeContextValue {
|
|
50
49
|
/** Resolved colors for splash screen */
|
|
51
50
|
colors: SplashColors;
|
|
52
|
-
|
|
53
|
-
gradientColors?: readonly [string, string, ...string[]];
|
|
51
|
+
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
/**
|
|
@@ -87,8 +85,7 @@ export interface SplashScreenProps {
|
|
|
87
85
|
*/
|
|
88
86
|
colors?: SplashColors;
|
|
89
87
|
|
|
90
|
-
|
|
91
|
-
gradientColors?: readonly [string, string, ...string[]];
|
|
88
|
+
|
|
92
89
|
|
|
93
90
|
/** Control visibility */
|
|
94
91
|
visible?: boolean;
|