@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,201 +1,255 @@
|
|
|
1
1
|
# AtomicPicker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Powerful and customizable selection/dropdown component with modal interface for React Native applications.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Import & Usage
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- 📱 **Modal Display**: Full-screen modal (mobile)
|
|
11
|
-
- 🎭 **İkon Desteği**: Seçenekler için ikonlar
|
|
12
|
-
- ✅ **Clearable**: Seçimi temizleme
|
|
13
|
-
- ♿ **Erişilebilir**: Tam erişilebilirlik desteği
|
|
14
|
-
- 📝 **Form Ready**: react-hook-form entegrasyonu hazır
|
|
7
|
+
```typescript
|
|
8
|
+
import { AtomicPicker } from 'react-native-design-system/src/atoms/picker';
|
|
9
|
+
```
|
|
15
10
|
|
|
16
|
-
|
|
11
|
+
**Location:** `src/atoms/picker/AtomicPicker.tsx`
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
17
14
|
|
|
18
15
|
```tsx
|
|
19
|
-
|
|
16
|
+
<AtomicPicker
|
|
17
|
+
value={selectedValue}
|
|
18
|
+
onChange={setSelectedValue}
|
|
19
|
+
options={[
|
|
20
|
+
{ label: 'Option 1', value: '1' },
|
|
21
|
+
{ label: 'Option 2', value: '2' },
|
|
22
|
+
]}
|
|
23
|
+
label="Select an option"
|
|
24
|
+
placeholder="Choose..."
|
|
25
|
+
/>
|
|
20
26
|
```
|
|
21
27
|
|
|
22
|
-
##
|
|
28
|
+
## Strategy
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
30
|
+
**Purpose**: Provide consistent, accessible, and performant selection interface with mobile-first modal display.
|
|
31
|
+
|
|
32
|
+
**When to Use**:
|
|
33
|
+
- Selecting from options (single or multiple)
|
|
34
|
+
- Form fields with predefined choices
|
|
35
|
+
- Filtering and sorting options
|
|
36
|
+
- User role/category selection
|
|
37
|
+
- Country/city selection
|
|
38
|
+
|
|
39
|
+
**When NOT to Use**:
|
|
40
|
+
- For boolean choices - use Switch or Checkbox
|
|
41
|
+
- For date/time selection - use DateTimePicker
|
|
42
|
+
- For very long lists (>100 items) - consider search-first approach
|
|
43
|
+
- For custom selections - build custom modal
|
|
44
|
+
|
|
45
|
+
## Rules
|
|
46
|
+
|
|
47
|
+
### Required
|
|
48
|
+
|
|
49
|
+
1. **ALWAYS** provide `value`, `onChange`, and `options` props
|
|
50
|
+
2. **MUST** have proper `label` for accessibility
|
|
51
|
+
3. **NEVER** use empty options array
|
|
52
|
+
4. **ALWAYS** provide meaningful option labels
|
|
53
|
+
5. **MUST** provide `placeholder` for unselected state
|
|
54
|
+
|
|
55
|
+
### Options Structure
|
|
49
56
|
|
|
50
|
-
|
|
57
|
+
1. **MUST** have unique `value` for each option
|
|
58
|
+
2. **ALWAYS** provide human-readable `label`
|
|
59
|
+
3. **SHOULD** include `icon` for better UX
|
|
60
|
+
4. **MUST** keep labels short and clear
|
|
61
|
+
|
|
62
|
+
### Single vs Multi-Select
|
|
63
|
+
|
|
64
|
+
1. **Single**: Use for mutually exclusive choices
|
|
65
|
+
2. **Multi**: Use for multiple selections
|
|
66
|
+
3. **MUST** set `multiple` prop for multi-select
|
|
67
|
+
4. **SHOULD** use `autoClose={false}` for multi-select
|
|
68
|
+
|
|
69
|
+
### Searchable
|
|
70
|
+
|
|
71
|
+
1. **MUST** use `searchable` for lists with 20+ options
|
|
72
|
+
2. **ALWAYS** provide `searchPlaceholder`
|
|
73
|
+
3. **SHOULD** provide `emptyMessage` for no results
|
|
74
|
+
|
|
75
|
+
## Forbidden
|
|
76
|
+
|
|
77
|
+
❌ **NEVER** do these:
|
|
51
78
|
|
|
52
79
|
```tsx
|
|
53
|
-
|
|
80
|
+
// ❌ Missing required props
|
|
81
|
+
<AtomicPicker />
|
|
82
|
+
<AtomicPicker options={options} />
|
|
83
|
+
<AtomicPicker value={value} onChange={onChange} />
|
|
84
|
+
|
|
85
|
+
// ❌ Empty options array
|
|
86
|
+
<AtomicPicker
|
|
87
|
+
value={value}
|
|
88
|
+
onChange={setValue}
|
|
89
|
+
options={[]}
|
|
90
|
+
/>
|
|
54
91
|
|
|
92
|
+
// ❌ Options without labels
|
|
55
93
|
<AtomicPicker
|
|
56
|
-
value={partyType}
|
|
57
|
-
onChange={setPartyType}
|
|
58
94
|
options={[
|
|
59
|
-
{
|
|
60
|
-
{
|
|
61
|
-
{ label: 'Kurumsal Etkinlik', value: 'corporate', icon: 'briefcase' },
|
|
95
|
+
{ value: '1' }, // ❌ Missing label
|
|
96
|
+
{ value: '2' },
|
|
62
97
|
]}
|
|
63
|
-
label="Parti Türü"
|
|
64
|
-
placeholder="Parti türünü seçin"
|
|
65
98
|
/>
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Multi Select
|
|
69
99
|
|
|
70
|
-
|
|
71
|
-
|
|
100
|
+
// ❌ Duplicate values
|
|
101
|
+
<AtomicPicker
|
|
102
|
+
options={[
|
|
103
|
+
{ label: 'Option 1', value: '1' },
|
|
104
|
+
{ label: 'Option 2', value: '1' }, // ❌ Duplicate value
|
|
105
|
+
]}
|
|
106
|
+
/>
|
|
72
107
|
|
|
108
|
+
// ❌ Hardcoded labels (use i18n)
|
|
73
109
|
<AtomicPicker
|
|
74
|
-
value={guests}
|
|
75
|
-
onChange={setGuests}
|
|
76
|
-
multiple
|
|
77
110
|
options={[
|
|
78
|
-
{ label: '
|
|
79
|
-
{ label: 'Ayşe Demir', value: 'ayse' },
|
|
80
|
-
{ label: 'Mehmet Kaya', value: 'mehmet' },
|
|
111
|
+
{ label: 'Select', value: 'select' }, // ❌ Use t()
|
|
81
112
|
]}
|
|
82
|
-
label="Davetliler"
|
|
83
|
-
placeholder="Davetli seçin"
|
|
84
|
-
modalTitle="Davetli Seçin"
|
|
85
113
|
/>
|
|
86
|
-
```
|
|
87
114
|
|
|
88
|
-
|
|
115
|
+
// ❌ Multi-select without multiple prop
|
|
116
|
+
<AtomicPicker
|
|
117
|
+
value={[1, 2, 3]} // ❌ Array value but no multiple prop
|
|
118
|
+
onChange={setValue}
|
|
119
|
+
options={options}
|
|
120
|
+
/>
|
|
89
121
|
|
|
90
|
-
|
|
122
|
+
// ❌ Long lists without searchable
|
|
91
123
|
<AtomicPicker
|
|
92
|
-
|
|
93
|
-
onChange={setSelectedCountry}
|
|
94
|
-
options={countries} // Uzun liste
|
|
95
|
-
label="Ülke"
|
|
96
|
-
placeholder="Ülke seçin"
|
|
97
|
-
searchable
|
|
98
|
-
searchPlaceholder="Ülke ara..."
|
|
124
|
+
options={hundredOptions} // ❌ Add searchable prop
|
|
99
125
|
/>
|
|
100
126
|
```
|
|
101
127
|
|
|
102
|
-
##
|
|
128
|
+
## Best Practices
|
|
129
|
+
|
|
130
|
+
### Option Structure
|
|
103
131
|
|
|
132
|
+
✅ **DO**:
|
|
104
133
|
```tsx
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
label
|
|
110
|
-
|
|
111
|
-
clearable
|
|
112
|
-
/>
|
|
134
|
+
// With icons for better UX
|
|
135
|
+
const roleOptions = [
|
|
136
|
+
{ label: t('roles.admin'), value: 'admin', icon: 'shield-checkmark' },
|
|
137
|
+
{ label: t('roles.moderator'), value: 'moderator', icon: 'person' },
|
|
138
|
+
{ label: t('roles.user'), value: 'user', icon: 'person-outline' },
|
|
139
|
+
];
|
|
113
140
|
```
|
|
114
141
|
|
|
115
|
-
|
|
116
|
-
|
|
142
|
+
❌ **DON'T**:
|
|
117
143
|
```tsx
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
placeholder="Kategori seçin"
|
|
124
|
-
error="Bu alan zorunludur"
|
|
125
|
-
/>
|
|
144
|
+
// Don't use long labels
|
|
145
|
+
{ label: 'This is a very long label that breaks the UI', value: '1' }
|
|
146
|
+
|
|
147
|
+
// Don't use technical labels
|
|
148
|
+
{ label: 'USR_ROLE_ADMIN', value: 'admin' }
|
|
126
149
|
```
|
|
127
150
|
|
|
128
|
-
|
|
151
|
+
### Searchable Usage
|
|
129
152
|
|
|
153
|
+
✅ **DO**:
|
|
130
154
|
```tsx
|
|
131
155
|
<AtomicPicker
|
|
132
|
-
value={
|
|
133
|
-
onChange={
|
|
134
|
-
options={
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
156
|
+
value={country}
|
|
157
|
+
onChange={setCountry}
|
|
158
|
+
options={countries} // 50+ options
|
|
159
|
+
searchable
|
|
160
|
+
searchPlaceholder={t('search.country')}
|
|
161
|
+
emptyMessage={t('search.noResults')}
|
|
138
162
|
/>
|
|
139
163
|
```
|
|
140
164
|
|
|
141
|
-
|
|
142
|
-
|
|
165
|
+
❌ **DON'T**:
|
|
143
166
|
```tsx
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
onChange={setValue}
|
|
150
|
-
options={options}
|
|
151
|
-
label="Small"
|
|
152
|
-
/>
|
|
153
|
-
|
|
154
|
-
{/* Medium (Varsayılan) */}
|
|
155
|
-
<AtomicPicker
|
|
156
|
-
size="md"
|
|
157
|
-
value={value}
|
|
158
|
-
onChange={setValue}
|
|
159
|
-
options={options}
|
|
160
|
-
label="Medium"
|
|
161
|
-
/>
|
|
162
|
-
|
|
163
|
-
{/* Large */}
|
|
164
|
-
<AtomicPicker
|
|
165
|
-
size="lg"
|
|
166
|
-
value={value}
|
|
167
|
-
onChange={setValue}
|
|
168
|
-
options={options}
|
|
169
|
-
label="Large"
|
|
170
|
-
/>
|
|
171
|
-
</View>
|
|
167
|
+
// Don't make searchable lists short
|
|
168
|
+
<AtomicPicker
|
|
169
|
+
options={[{ label: 'Yes', value: 'yes' }]}
|
|
170
|
+
searchable // ❌ Unnecessary for 1 option
|
|
171
|
+
/>
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
### Multi-Select
|
|
175
175
|
|
|
176
|
+
✅ **DO**:
|
|
176
177
|
```tsx
|
|
177
|
-
// Single select için otomatik kapanma
|
|
178
178
|
<AtomicPicker
|
|
179
|
-
value={
|
|
180
|
-
onChange={
|
|
181
|
-
options={
|
|
182
|
-
|
|
179
|
+
value={selectedCategories}
|
|
180
|
+
onChange={setSelectedCategories}
|
|
181
|
+
options={categories}
|
|
182
|
+
multiple
|
|
183
|
+
autoClose={false} // Keep open for multiple selections
|
|
184
|
+
modalTitle={t('picker.selectCategories')}
|
|
183
185
|
/>
|
|
186
|
+
```
|
|
184
187
|
|
|
185
|
-
|
|
188
|
+
❌ **DON'T**:
|
|
189
|
+
```tsx
|
|
190
|
+
// Don't use autoClose with multi-select
|
|
186
191
|
<AtomicPicker
|
|
187
|
-
value={multiValue}
|
|
188
|
-
onChange={setMultiValue}
|
|
189
|
-
options={options}
|
|
190
192
|
multiple
|
|
191
|
-
autoClose
|
|
193
|
+
autoClose // ❌ Closes after each selection
|
|
192
194
|
/>
|
|
193
195
|
```
|
|
194
196
|
|
|
195
|
-
##
|
|
196
|
-
|
|
197
|
-
###
|
|
198
|
-
|
|
197
|
+
## AI Coding Guidelines
|
|
198
|
+
|
|
199
|
+
### For AI Agents
|
|
200
|
+
|
|
201
|
+
When generating AtomicPicker components, follow these rules:
|
|
202
|
+
|
|
203
|
+
1. **Always import from correct path**:
|
|
204
|
+
```typescript
|
|
205
|
+
import { AtomicPicker } from 'react-native-design-system/src/atoms/picker';
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
2. **Always provide all required props**:
|
|
209
|
+
```tsx
|
|
210
|
+
<AtomicPicker
|
|
211
|
+
value="选定的值"
|
|
212
|
+
onChange="处理函数"
|
|
213
|
+
options="选项数组"
|
|
214
|
+
label="清晰的标签"
|
|
215
|
+
placeholder="适当的占位符"
|
|
216
|
+
/>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
3. **Always use i18n for labels**:
|
|
220
|
+
```tsx
|
|
221
|
+
<AtomicPicker
|
|
222
|
+
label={t('form.country')}
|
|
223
|
+
placeholder={t('form.selectCountry')}
|
|
224
|
+
options={[
|
|
225
|
+
{ label: t('countries.turkey'), value: 'tr' },
|
|
226
|
+
{ label: t('countries.usa'), value: 'us' },
|
|
227
|
+
]}
|
|
228
|
+
/>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
4. **Always enable searchable for long lists**:
|
|
232
|
+
```tsx
|
|
233
|
+
<AtomicPicker
|
|
234
|
+
options={longOptionsList} // 20+ options
|
|
235
|
+
searchable
|
|
236
|
+
searchPlaceholder={t('search.placeholder')}
|
|
237
|
+
emptyMessage={t('search.noResults')}
|
|
238
|
+
/>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
5. **Always use autoClose={false} for multi-select**:
|
|
242
|
+
```tsx
|
|
243
|
+
<AtomicPicker
|
|
244
|
+
multiple
|
|
245
|
+
autoClose={false}
|
|
246
|
+
modalTitle={t('picker.selectMultiple')}
|
|
247
|
+
/>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Common Patterns
|
|
251
|
+
|
|
252
|
+
#### Single Select
|
|
199
253
|
```tsx
|
|
200
254
|
const [role, setRole] = useState('user');
|
|
201
255
|
|
|
@@ -203,18 +257,16 @@ const [role, setRole] = useState('user');
|
|
|
203
257
|
value={role}
|
|
204
258
|
onChange={setRole}
|
|
205
259
|
options={[
|
|
206
|
-
{ label: '
|
|
207
|
-
{ label: '
|
|
208
|
-
{ label: '
|
|
260
|
+
{ label: t('roles.admin'), value: 'admin', icon: 'shield-checkmark' },
|
|
261
|
+
{ label: t('roles.moderator'), value: 'moderator', icon: 'person' },
|
|
262
|
+
{ label: t('roles.user'), value: 'user', icon: 'person-outline' },
|
|
209
263
|
]}
|
|
210
|
-
label=
|
|
211
|
-
placeholder=
|
|
212
|
-
searchable={false}
|
|
264
|
+
label={t('form.role')}
|
|
265
|
+
placeholder={t('form.selectRole')}
|
|
213
266
|
/>
|
|
214
267
|
```
|
|
215
268
|
|
|
216
|
-
|
|
217
|
-
|
|
269
|
+
#### Multi Select
|
|
218
270
|
```tsx
|
|
219
271
|
const [categories, setCategories] = useState<string[]>([]);
|
|
220
272
|
|
|
@@ -222,35 +274,45 @@ const [categories, setCategories] = useState<string[]>([]);
|
|
|
222
274
|
value={categories}
|
|
223
275
|
onChange={setCategories}
|
|
224
276
|
multiple
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
277
|
+
autoClose={false}
|
|
278
|
+
options={categoryOptions}
|
|
279
|
+
label={t('form.categories')}
|
|
280
|
+
placeholder={t('form.selectCategories')}
|
|
281
|
+
modalTitle={t('picker.selectCategories')}
|
|
229
282
|
searchable
|
|
230
|
-
searchPlaceholder="Kategori ara..."
|
|
231
|
-
emptyMessage="Kategori bulunamadı"
|
|
232
283
|
/>
|
|
233
284
|
```
|
|
234
285
|
|
|
235
|
-
|
|
236
|
-
|
|
286
|
+
#### Searchable Picker
|
|
237
287
|
```tsx
|
|
238
288
|
const [city, setCity] = useState('');
|
|
239
289
|
|
|
240
290
|
<AtomicPicker
|
|
241
291
|
value={city}
|
|
242
292
|
onChange={setCity}
|
|
243
|
-
options={
|
|
244
|
-
label=
|
|
245
|
-
placeholder=
|
|
293
|
+
options={cities}
|
|
294
|
+
label={t('form.city')}
|
|
295
|
+
placeholder={t('form.selectCity')}
|
|
246
296
|
searchable
|
|
247
|
-
searchPlaceholder=
|
|
297
|
+
searchPlaceholder={t('search.searchCity')}
|
|
298
|
+
emptyMessage={t('search.noCityFound')}
|
|
248
299
|
clearable
|
|
249
300
|
/>
|
|
250
301
|
```
|
|
251
302
|
|
|
252
|
-
|
|
303
|
+
#### With Error State
|
|
304
|
+
```tsx
|
|
305
|
+
<AtomicPicker
|
|
306
|
+
value={country}
|
|
307
|
+
onChange={setCountry}
|
|
308
|
+
options={countries}
|
|
309
|
+
label={t('form.country')}
|
|
310
|
+
placeholder={t('form.selectCountry')}
|
|
311
|
+
error={errors.country}
|
|
312
|
+
/>
|
|
313
|
+
```
|
|
253
314
|
|
|
315
|
+
#### Priority Select
|
|
254
316
|
```tsx
|
|
255
317
|
const [priority, setPriority] = useState('medium');
|
|
256
318
|
|
|
@@ -258,155 +320,62 @@ const [priority, setPriority] = useState('medium');
|
|
|
258
320
|
value={priority}
|
|
259
321
|
onChange={setPriority}
|
|
260
322
|
options={[
|
|
261
|
-
{ label: '
|
|
262
|
-
{ label: '
|
|
263
|
-
{ label: '
|
|
264
|
-
{ label: '
|
|
323
|
+
{ label: t('priority.low'), value: 'low', icon: 'arrow-down' },
|
|
324
|
+
{ label: t('priority.medium'), value: 'medium', icon: 'remove' },
|
|
325
|
+
{ label: t('priority.high'), value: 'high', icon: 'arrow-up' },
|
|
326
|
+
{ label: t('priority.urgent'), value: 'urgent', icon: 'warning' },
|
|
265
327
|
]}
|
|
266
|
-
label=
|
|
267
|
-
placeholder="Öncelik seçin"
|
|
328
|
+
label={t('form.priority')}
|
|
268
329
|
/>
|
|
269
330
|
```
|
|
270
331
|
|
|
271
|
-
## Props
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
|
276
|
-
|
|
277
|
-
| `
|
|
278
|
-
| `
|
|
279
|
-
| `
|
|
280
|
-
| `
|
|
281
|
-
| `
|
|
282
|
-
| `
|
|
283
|
-
| `
|
|
284
|
-
| `
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
289
|
-
| `
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
function MyForm() {
|
|
320
|
-
const { control, handleSubmit } = useForm({
|
|
321
|
-
defaultValues: {
|
|
322
|
-
country: 'turkey',
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
const onSubmit = (data) => {
|
|
327
|
-
console.log(data);
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
return (
|
|
331
|
-
<Controller
|
|
332
|
-
control={control}
|
|
333
|
-
name="country"
|
|
334
|
-
render={({ field: { onChange, value }, fieldState: { error } }) => (
|
|
335
|
-
<AtomicPicker
|
|
336
|
-
value={value}
|
|
337
|
-
onChange={onChange}
|
|
338
|
-
options={countries}
|
|
339
|
-
label="Ülke"
|
|
340
|
-
placeholder="Ülke seçin"
|
|
341
|
-
error={error?.message}
|
|
342
|
-
/>
|
|
343
|
-
)}
|
|
344
|
-
/>
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
## Best Practices
|
|
350
|
-
|
|
351
|
-
### 1. Option Yapısı
|
|
352
|
-
|
|
353
|
-
```tsx
|
|
354
|
-
// İyi - İkonlu seçenekler
|
|
355
|
-
const options = [
|
|
356
|
-
{ label: 'Admin', value: 'admin', icon: 'shield' },
|
|
357
|
-
{ label: 'User', value: 'user', icon: 'person' },
|
|
358
|
-
];
|
|
359
|
-
|
|
360
|
-
// İyi - Basit seçenekler
|
|
361
|
-
const options = [
|
|
362
|
-
{ label: 'Evet', value: 'yes' },
|
|
363
|
-
{ label: 'Hayır', value: 'no' },
|
|
364
|
-
];
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### 2. Multi-Select Kullanımı
|
|
368
|
-
|
|
369
|
-
```tsx
|
|
370
|
-
// AutoClose false - birden fazla seçim yapılabilir
|
|
371
|
-
<AtomicPicker
|
|
372
|
-
multiple
|
|
373
|
-
autoClose={false}
|
|
374
|
-
// ...
|
|
375
|
-
/>
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
### 3. Searchable Kullanımı
|
|
379
|
-
|
|
380
|
-
```tsx
|
|
381
|
-
// Uzun listelerde searchable kullanın
|
|
382
|
-
<AtomicPicker
|
|
383
|
-
options={longList} // 50+ seçenek
|
|
384
|
-
searchable
|
|
385
|
-
// ...
|
|
386
|
-
/>
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
## Erişilebilirlik
|
|
390
|
-
|
|
391
|
-
AtomicPicker, tam erişilebilirlik desteği sunar:
|
|
392
|
-
|
|
393
|
-
- ✅ Screen reader desteği
|
|
394
|
-
- ✅ Keyboard navigation
|
|
395
|
-
- ✅ Accessibility label desteği
|
|
396
|
-
- ✅ Test ID desteği
|
|
397
|
-
|
|
398
|
-
## Performans İpuçları
|
|
399
|
-
|
|
400
|
-
1. **Uzun Listeler**: `searchable` özelliğini kullanın
|
|
401
|
-
2. **Multi-Select**: `autoClose={false}` kullanarak UX'i iyileştirin
|
|
402
|
-
3. **Re-renders**: `onChange` callback'ini stabilize edin
|
|
403
|
-
|
|
404
|
-
## İlgili Bileşenler
|
|
405
|
-
|
|
406
|
-
- [`FormField`](../../molecules/FormField/README.md) - Form alanı
|
|
407
|
-
- [`AtomicInput`](../input/README.md) - Input bileşeni
|
|
408
|
-
- [`AtomicChip`](../chip/README.md) - Chip bileşeni (seçili değerleri göstermek için)
|
|
409
|
-
|
|
410
|
-
## Lisans
|
|
332
|
+
## Props Reference
|
|
333
|
+
|
|
334
|
+
| Prop | Type | Required | Default | Description |
|
|
335
|
+
|------|------|----------|---------|-------------|
|
|
336
|
+
| `value` | `string \| string[]` | Yes | - | Selected value(s) |
|
|
337
|
+
| `onChange` | `(value: any) => void` | Yes | - | Change handler |
|
|
338
|
+
| `options` | `PickerOption[]` | Yes | - | Options array |
|
|
339
|
+
| `label` | `string` | No | - | Field label |
|
|
340
|
+
| `placeholder` | `string` | No | - | Placeholder text |
|
|
341
|
+
| `multiple` | `boolean` | No | `false` | Enable multi-select |
|
|
342
|
+
| `searchable` | `boolean` | No | `false` | Enable search |
|
|
343
|
+
| `clearable` | `boolean` | No | `false` | Show clear button |
|
|
344
|
+
| `autoClose` | `boolean` | No | `true` | Auto-close on select |
|
|
345
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | No | `'md'` | Picker size |
|
|
346
|
+
| `error` | `string` | No | - | Error message |
|
|
347
|
+
| `disabled` | `boolean` | No | `false` | Disabled state |
|
|
348
|
+
| `modalTitle` | `string` | No | - | Modal title |
|
|
349
|
+
| `searchPlaceholder` | `string` | No | - | Search placeholder |
|
|
350
|
+
| `emptyMessage` | `string` | No | - | Empty results message |
|
|
351
|
+
|
|
352
|
+
## Accessibility
|
|
353
|
+
|
|
354
|
+
- ✅ Screen reader announces label and selection
|
|
355
|
+
- ✅ Modal is fully accessible
|
|
356
|
+
- ✅ Keyboard navigation support
|
|
357
|
+
- ✅ Error state announced to screen readers
|
|
358
|
+
- ✅ Test ID support for testing
|
|
359
|
+
|
|
360
|
+
## Performance Tips
|
|
361
|
+
|
|
362
|
+
1. **Limit options**: Keep under 100 options, use search for more
|
|
363
|
+
2. **Memo options**: Don't recreate options array on every render
|
|
364
|
+
3. **Stable onChange**: Use `useCallback` for onChange handler
|
|
365
|
+
4. **Lazy loading**: For very large lists, consider pagination
|
|
366
|
+
|
|
367
|
+
## Related Components
|
|
368
|
+
|
|
369
|
+
- [`AtomicChip`](./chip/README.md) - Display selected items as chips
|
|
370
|
+
- [`FormField`](../../molecules/FormField/README.md) - Form field wrapper
|
|
371
|
+
- [`AtomicInput`](./input/README.md) - Text input component
|
|
372
|
+
|
|
373
|
+
## Version History
|
|
374
|
+
|
|
375
|
+
- **2.6.0**: Added searchable and multi-select support
|
|
376
|
+
- **2.5.0**: Added modal interface
|
|
377
|
+
- **2.0.0**: Initial release
|
|
378
|
+
|
|
379
|
+
## License
|
|
411
380
|
|
|
412
381
|
MIT
|