@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,433 +1,400 @@
|
|
|
1
1
|
# AtomicSpinner
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A versatile loading indicator component for React Native. Wrapper around ActivityIndicator with extensive customization options.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Import & Usage
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- 🖼️ **Overlay**: Tam ekran overlay desteği
|
|
11
|
-
- 📦 **Full Container**: Parent container'ı doldurma
|
|
12
|
-
- ♿ **Erişilebilir**: Tam erişilebilirlik desteği
|
|
7
|
+
```typescript
|
|
8
|
+
import { AtomicSpinner } from 'react-native-design-system/src/atoms/AtomicSpinner';
|
|
9
|
+
```
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
**Location:** `src/atoms/AtomicSpinner.tsx`
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
15
14
|
|
|
16
15
|
```tsx
|
|
17
|
-
|
|
16
|
+
<AtomicSpinner />
|
|
18
17
|
```
|
|
19
18
|
|
|
20
|
-
##
|
|
19
|
+
## Strategy
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
import React from 'react';
|
|
24
|
-
import { View } from 'react-native';
|
|
25
|
-
import { AtomicSpinner } from 'react-native-design-system';
|
|
26
|
-
|
|
27
|
-
export const BasicExample = () => {
|
|
28
|
-
return (
|
|
29
|
-
<View style={{ padding: 16 }}>
|
|
30
|
-
<AtomicSpinner />
|
|
31
|
-
</View>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
```
|
|
21
|
+
**Purpose**: Provide a consistent, accessible loading indicator for async operations and content loading states.
|
|
35
22
|
|
|
36
|
-
|
|
23
|
+
**When to Use**:
|
|
24
|
+
- During data fetching (API calls, database queries)
|
|
25
|
+
- For content loading states (images, videos, lists)
|
|
26
|
+
- In forms during submission
|
|
27
|
+
- For page transitions
|
|
28
|
+
- During async operations (file uploads, processing)
|
|
37
29
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
**When NOT to Use**:
|
|
31
|
+
- For determinate progress (use AtomicProgress instead)
|
|
32
|
+
- When progress percentage is known (use progress bar)
|
|
33
|
+
- For static content that doesn't need loading indication
|
|
34
|
+
- As a decorative element without loading context
|
|
42
35
|
|
|
43
|
-
|
|
44
|
-
<AtomicSpinner size="md" />
|
|
36
|
+
## Rules
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
<AtomicSpinner size="lg" />
|
|
38
|
+
### Required
|
|
48
39
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
40
|
+
1. **MUST** provide accessible loading state to screen readers
|
|
41
|
+
2. **ALWAYS** show spinner during actual async operations
|
|
42
|
+
3. **MUST** hide spinner when loading completes
|
|
43
|
+
4. **SHOULD** provide context with `text` prop for longer operations
|
|
44
|
+
5. **ALWAYS** use appropriate size for the context
|
|
45
|
+
6. **MUST** not block user interaction unnecessarily (unless overlay)
|
|
46
|
+
7. **SHOULD** use `fullContainer` for centered loading states
|
|
53
47
|
|
|
54
|
-
|
|
48
|
+
### Usage Guidelines
|
|
55
49
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<AtomicSpinner color="warning" />
|
|
62
|
-
<AtomicSpinner color="error" />
|
|
63
|
-
<AtomicSpinner color="white" />
|
|
64
|
-
</View>
|
|
65
|
-
```
|
|
50
|
+
1. **Size selection**: Match size to context (sm for buttons, md-lg for content)
|
|
51
|
+
2. **Text context**: Always provide text for operations taking > 3 seconds
|
|
52
|
+
3. **Overlay use**: Only use overlay for blocking operations
|
|
53
|
+
4. **Color semantics**: Use semantic colors (primary, success, error) when meaningful
|
|
54
|
+
5. **Positioning**: Use `fullContainer` for centering, or handle positioning manually
|
|
66
55
|
|
|
67
|
-
|
|
56
|
+
### Performance
|
|
68
57
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
58
|
+
1. **Don't over-render**: Only show when actually loading
|
|
59
|
+
2. **Avoid nested spinners**: One spinner per loading context
|
|
60
|
+
3. **Clean up**: Always remove spinner when complete
|
|
61
|
+
|
|
62
|
+
## Forbidden
|
|
73
63
|
|
|
74
|
-
|
|
64
|
+
❌ **NEVER** do these:
|
|
75
65
|
|
|
76
66
|
```tsx
|
|
77
|
-
|
|
67
|
+
// ❌ Spinner without loading state
|
|
68
|
+
<View>
|
|
69
|
+
<AtomicSpinner /> {/* ❌ Always visible, no loading state */}
|
|
70
|
+
<Content />
|
|
71
|
+
</View>
|
|
72
|
+
|
|
73
|
+
// ❌ Generic text without context
|
|
78
74
|
<AtomicSpinner
|
|
79
|
-
text="
|
|
80
|
-
textPosition="bottom"
|
|
75
|
+
text="Loading" {/* ❌ What is loading? */}
|
|
81
76
|
/>
|
|
82
77
|
|
|
83
|
-
|
|
78
|
+
// ❌ Wrong size for button
|
|
79
|
+
<Button onPress={handleAction}>
|
|
80
|
+
{loading && <AtomicSpinner size="xl" />}
|
|
81
|
+
{/* ❌ Too large for button */}
|
|
82
|
+
</Button>
|
|
83
|
+
|
|
84
|
+
// ❌ Overlay for non-blocking operation
|
|
84
85
|
<AtomicSpinner
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
overlay {/* ❌ Blocks UI for simple fetch */}
|
|
87
|
+
text="Fetching data"
|
|
87
88
|
/>
|
|
88
|
-
```
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
// ❌ Never removes spinner
|
|
91
|
+
const [loading, setLoading] = useState(true);
|
|
92
|
+
// ❌ Never sets to false
|
|
91
93
|
|
|
92
|
-
|
|
93
|
-
<View
|
|
94
|
-
<AtomicSpinner
|
|
94
|
+
// ❌ Spinner in static content
|
|
95
|
+
<View>
|
|
96
|
+
<AtomicSpinner /> {/* ❌ Static content, not loading */}
|
|
97
|
+
<Text>Welcome</Text>
|
|
95
98
|
</View>
|
|
96
99
|
```
|
|
97
100
|
|
|
98
|
-
##
|
|
99
|
-
|
|
100
|
-
```tsx
|
|
101
|
-
<View style={{ height: 200 }}>
|
|
102
|
-
{/* Overlay varsayılan renk */}
|
|
103
|
-
<AtomicSpinner overlay text="Yükleniyor..." />
|
|
104
|
-
|
|
105
|
-
{/* Custom overlay rengi */}
|
|
106
|
-
<AtomicSpinner
|
|
107
|
-
overlay
|
|
108
|
-
overlayColor="rgba(0, 0, 0, 0.7)"
|
|
109
|
-
text="Lütfen bekleyin..."
|
|
110
|
-
color="white"
|
|
111
|
-
/>
|
|
112
|
-
</View>
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Custom Size
|
|
116
|
-
|
|
117
|
-
```tsx
|
|
118
|
-
<AtomicSpinner size={32} />
|
|
119
|
-
<AtomicSpinner size={48} />
|
|
120
|
-
<AtomicSpinner size={64} />
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Örnek Kullanımlar
|
|
101
|
+
## Best Practices
|
|
124
102
|
|
|
125
|
-
###
|
|
103
|
+
### Loading States
|
|
126
104
|
|
|
105
|
+
✅ **DO**:
|
|
127
106
|
```tsx
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
);
|
|
107
|
+
const [loading, setLoading] = useState(false);
|
|
108
|
+
|
|
109
|
+
const fetchData = async () => {
|
|
110
|
+
setLoading(true);
|
|
111
|
+
try {
|
|
112
|
+
await apiCall();
|
|
113
|
+
} finally {
|
|
114
|
+
setLoading(false); // ✅ Always completes
|
|
115
|
+
}
|
|
138
116
|
};
|
|
139
|
-
```
|
|
140
117
|
|
|
141
|
-
|
|
118
|
+
{loading ? (
|
|
119
|
+
<AtomicSpinner fullContainer text="Loading data..." />
|
|
120
|
+
) : (
|
|
121
|
+
<DataContent />
|
|
122
|
+
)}
|
|
123
|
+
```
|
|
142
124
|
|
|
125
|
+
❌ **DON'T**:
|
|
143
126
|
```tsx
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
<>
|
|
150
|
-
<AtomicSpinner size="sm" color="white" />
|
|
151
|
-
<AtomicText style={{ marginLeft: 8 }}>Yükleniyor...</AtomicText>
|
|
152
|
-
</>
|
|
153
|
-
) : (
|
|
154
|
-
children
|
|
155
|
-
)}
|
|
156
|
-
</View>
|
|
157
|
-
</Pressable>
|
|
158
|
-
);
|
|
127
|
+
// ❌ No cleanup
|
|
128
|
+
const fetchData = async () => {
|
|
129
|
+
setLoading(true);
|
|
130
|
+
await apiCall();
|
|
131
|
+
// Forgot setLoading(false)
|
|
159
132
|
};
|
|
133
|
+
|
|
134
|
+
// ❌ Loading state not managed
|
|
135
|
+
<AtomicSpinner /> {/* Always visible */}
|
|
160
136
|
```
|
|
161
137
|
|
|
162
|
-
###
|
|
138
|
+
### Context with Text
|
|
163
139
|
|
|
140
|
+
✅ **DO**:
|
|
164
141
|
```tsx
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
size="lg"
|
|
171
|
-
text="Veriler çekiliyor..."
|
|
172
|
-
/>
|
|
173
|
-
</View>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
142
|
+
// ✅ Specific context
|
|
143
|
+
<AtomicSpinner
|
|
144
|
+
text="Uploading photo..."
|
|
145
|
+
size="md"
|
|
146
|
+
/>
|
|
176
147
|
|
|
177
|
-
|
|
178
|
-
|
|
148
|
+
// ✅ Progress indication
|
|
149
|
+
<AtomicSpinner
|
|
150
|
+
text="Processing step 1 of 3..."
|
|
151
|
+
textPosition="bottom"
|
|
152
|
+
/>
|
|
179
153
|
```
|
|
180
154
|
|
|
181
|
-
|
|
182
|
-
|
|
155
|
+
❌ **DON'T**:
|
|
183
156
|
```tsx
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
{isSubmitting ? (
|
|
188
|
-
<View style={{ alignItems: 'center' }}>
|
|
189
|
-
<AtomicSpinner
|
|
190
|
-
size="md"
|
|
191
|
-
text="Form gönderiliyor..."
|
|
192
|
-
textPosition="bottom"
|
|
193
|
-
/>
|
|
194
|
-
</View>
|
|
195
|
-
) : (
|
|
196
|
-
<AtomicText>Form hazır</AtomicText>
|
|
197
|
-
)}
|
|
198
|
-
</View>
|
|
199
|
-
);
|
|
200
|
-
};
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### İçerik Yenileme
|
|
157
|
+
// ❌ Generic text
|
|
158
|
+
<AtomicSpinner text="Loading" />
|
|
159
|
+
<AtomicSpinner text="Please wait" />
|
|
204
160
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
return (
|
|
208
|
-
<View style={{ padding: 16, alignItems: 'center' }}>
|
|
209
|
-
{isRefreshing && (
|
|
210
|
-
<AtomicSpinner
|
|
211
|
-
size="sm"
|
|
212
|
-
text="Yenileniyor..."
|
|
213
|
-
textPosition="right"
|
|
214
|
-
/>
|
|
215
|
-
)}
|
|
216
|
-
</View>
|
|
217
|
-
);
|
|
218
|
-
};
|
|
161
|
+
// ❌ Unnecessary text for quick operation
|
|
162
|
+
<AtomicSpinner text="Loading..." /> {/* < 1 second */}
|
|
219
163
|
```
|
|
220
164
|
|
|
221
|
-
###
|
|
165
|
+
### Size Selection
|
|
222
166
|
|
|
167
|
+
✅ **DO**:
|
|
223
168
|
```tsx
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
overlay
|
|
229
|
-
overlayColor="rgba(0, 0, 0, 0.7)"
|
|
230
|
-
size="lg"
|
|
231
|
-
text="Lütfen bekleyin..."
|
|
232
|
-
color="white"
|
|
233
|
-
/>
|
|
234
|
-
</Modal>
|
|
235
|
-
);
|
|
236
|
-
};
|
|
237
|
-
```
|
|
169
|
+
// ✅ Button inline
|
|
170
|
+
<Button>
|
|
171
|
+
{loading && <AtomicSpinner size="sm" color="white" />}
|
|
172
|
+
</Button>
|
|
238
173
|
|
|
239
|
-
|
|
174
|
+
// ✅ Content loading
|
|
175
|
+
<AtomicSpinner size="md" fullContainer />
|
|
240
176
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
return (
|
|
244
|
-
<View style={{ padding: 24 }}>
|
|
245
|
-
<AtomicSpinner
|
|
246
|
-
size="md"
|
|
247
|
-
text="Öğeler yükleniyor..."
|
|
248
|
-
/>
|
|
249
|
-
</View>
|
|
250
|
-
);
|
|
251
|
-
};
|
|
177
|
+
// ✅ Page loading
|
|
178
|
+
<AtomicSpinner size="lg" fullContainer text="Loading page..." />
|
|
252
179
|
```
|
|
253
180
|
|
|
254
|
-
|
|
255
|
-
|
|
181
|
+
❌ **DON'T**:
|
|
256
182
|
```tsx
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
<AtomicSpinner
|
|
262
|
-
fullContainer
|
|
263
|
-
text="Görsel yükleniyor..."
|
|
264
|
-
color="primary"
|
|
265
|
-
/>
|
|
266
|
-
) : (
|
|
267
|
-
children
|
|
268
|
-
)}
|
|
269
|
-
</View>
|
|
270
|
-
);
|
|
271
|
-
};
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### Async Operasyon
|
|
183
|
+
// ❌ Too large for button
|
|
184
|
+
<Button>
|
|
185
|
+
<AtomicSpinner size="xl" />
|
|
186
|
+
</Button>
|
|
275
187
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const [isProcessing, setIsProcessing] = useState(false);
|
|
279
|
-
|
|
280
|
-
const handleProcess = async () => {
|
|
281
|
-
setIsProcessing(true);
|
|
282
|
-
try {
|
|
283
|
-
await performAsyncOperation();
|
|
284
|
-
} finally {
|
|
285
|
-
setIsProcessing(false);
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
return (
|
|
290
|
-
<View>
|
|
291
|
-
{isProcessing ? (
|
|
292
|
-
<AtomicSpinner
|
|
293
|
-
size="md"
|
|
294
|
-
text="İşleniyor..."
|
|
295
|
-
textPosition="right"
|
|
296
|
-
/>
|
|
297
|
-
) : (
|
|
298
|
-
<Button title="İşle" onPress={handleProcess} />
|
|
299
|
-
)}
|
|
300
|
-
</View>
|
|
301
|
-
);
|
|
302
|
-
};
|
|
188
|
+
// ❌ Too small for page
|
|
189
|
+
<AtomicSpinner size="xs" fullContainer />
|
|
303
190
|
```
|
|
304
191
|
|
|
305
|
-
###
|
|
192
|
+
### Overlay Usage
|
|
306
193
|
|
|
194
|
+
✅ **DO**:
|
|
307
195
|
```tsx
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
size="sm"
|
|
315
|
-
text="Daha fazla yükleniyor..."
|
|
316
|
-
textPosition="right"
|
|
317
|
-
/>
|
|
318
|
-
</View>
|
|
319
|
-
);
|
|
320
|
-
};
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
## Props
|
|
324
|
-
|
|
325
|
-
### AtomicSpinnerProps
|
|
326
|
-
|
|
327
|
-
| Prop | Tip | Varsayılan | Açıklama |
|
|
328
|
-
|------|-----|------------|----------|
|
|
329
|
-
| `size` | `SpinnerSize \| number` | `'md'` | Spinner boyutu |
|
|
330
|
-
| `color` | `SpinnerColor \| string` | `'primary'` | Spinner rengi |
|
|
331
|
-
| `text` | `string` | - | Yükleme metni |
|
|
332
|
-
| `textPosition` | `'bottom' \| 'right'` | `'bottom'` | Metin konumu |
|
|
333
|
-
| `fullContainer` | `boolean` | `false` | Container'ı doldur |
|
|
334
|
-
| `overlay` | `boolean` | `false` | Overlay göster |
|
|
335
|
-
| `overlayColor` | `string` | `'rgba(0, 0, 0, 0.5)'` | Overlay rengi |
|
|
336
|
-
| `style` | `ViewStyle \| ViewStyle[]` | - | Özel stil |
|
|
337
|
-
| `testID` | `string` | - | Test ID'si |
|
|
338
|
-
|
|
339
|
-
### SpinnerSize
|
|
196
|
+
// ✅ Blocking operation
|
|
197
|
+
<AtomicSpinner
|
|
198
|
+
overlay
|
|
199
|
+
text="Processing payment..."
|
|
200
|
+
color="white"
|
|
201
|
+
/>
|
|
340
202
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
| 'lg' // Large (36px)
|
|
346
|
-
| 'xl'; // Extra Large (48px)
|
|
203
|
+
// ✅ Modal loading
|
|
204
|
+
<Modal visible={loading}>
|
|
205
|
+
<AtomicSpinner overlay />
|
|
206
|
+
</Modal>
|
|
347
207
|
```
|
|
348
208
|
|
|
349
|
-
|
|
209
|
+
❌ **DON'T**:
|
|
210
|
+
```tsx
|
|
211
|
+
// ❌ Overlay for non-blocking
|
|
212
|
+
<AtomicSpinner
|
|
213
|
+
overlay {/* ❌ Blocks UI unnecessarily */}
|
|
214
|
+
text="Fetching list"
|
|
215
|
+
/>
|
|
350
216
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
| 'warning' // Uyarı rengi
|
|
358
|
-
| 'white'; // Beyaz
|
|
217
|
+
// ❌ Missing color for dark overlay
|
|
218
|
+
<AtomicSpinner
|
|
219
|
+
overlay
|
|
220
|
+
overlayColor="rgba(0, 0, 0, 0.7)"
|
|
221
|
+
color="primary" {/* ❌ Hard to see on dark */}
|
|
222
|
+
/>
|
|
359
223
|
```
|
|
360
224
|
|
|
361
|
-
##
|
|
362
|
-
|
|
363
|
-
###
|
|
364
|
-
|
|
225
|
+
## AI Coding Guidelines
|
|
226
|
+
|
|
227
|
+
### For AI Agents
|
|
228
|
+
|
|
229
|
+
When generating AtomicSpinner components, follow these rules:
|
|
230
|
+
|
|
231
|
+
1. **Always import from correct path**:
|
|
232
|
+
```typescript
|
|
233
|
+
import { AtomicSpinner } from 'react-native-design-system/src/atoms/AtomicSpinner';
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
2. **Always manage loading state properly**:
|
|
237
|
+
```tsx
|
|
238
|
+
// ✅ Good - proper state management
|
|
239
|
+
const [loading, setLoading] = useState(false);
|
|
240
|
+
const handleAction = async () => {
|
|
241
|
+
setLoading(true);
|
|
242
|
+
try {
|
|
243
|
+
await doSomething();
|
|
244
|
+
} finally {
|
|
245
|
+
setLoading(false);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// ❌ Bad - no cleanup
|
|
250
|
+
const [loading, setLoading] = useState(false);
|
|
251
|
+
const handleAction = async () => {
|
|
252
|
+
setLoading(true);
|
|
253
|
+
await doSomething();
|
|
254
|
+
// Forgot setLoading(false)
|
|
255
|
+
};
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
3. **Always provide context for long operations**:
|
|
259
|
+
```tsx
|
|
260
|
+
// ✅ Good - specific context
|
|
261
|
+
<AtomicSpinner
|
|
262
|
+
text="Uploading profile photo..."
|
|
263
|
+
fullContainer
|
|
264
|
+
/>
|
|
265
|
+
|
|
266
|
+
// ❌ Bad - generic text
|
|
267
|
+
<AtomicSpinner text="Loading..." />
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
4. **Always use appropriate sizes**:
|
|
271
|
+
```tsx
|
|
272
|
+
// ✅ Good - size matches context
|
|
273
|
+
<Button>
|
|
274
|
+
{loading && <AtomicSpinner size="sm" color="white" />}
|
|
275
|
+
</Button>
|
|
276
|
+
<AtomicSpinner size="lg" fullContainer />
|
|
277
|
+
|
|
278
|
+
// ❌ Bad - wrong sizes
|
|
279
|
+
<Button>
|
|
280
|
+
<AtomicSpinner size="xl" /> {/* Too large */}
|
|
281
|
+
</Button>
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
5. **Always clean up spinner**:
|
|
285
|
+
```tsx
|
|
286
|
+
// ✅ Good - always completes
|
|
287
|
+
try {
|
|
288
|
+
setLoading(true);
|
|
289
|
+
await operation();
|
|
290
|
+
} finally {
|
|
291
|
+
setLoading(false);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// ❌ Bad - doesn't complete on error
|
|
295
|
+
setLoading(true);
|
|
296
|
+
await operation(); // If this throws, spinner stays
|
|
297
|
+
setLoading(false);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Common Patterns
|
|
301
|
+
|
|
302
|
+
#### Basic Loading State
|
|
365
303
|
```tsx
|
|
366
|
-
|
|
367
|
-
<AtomicSpinner size="sm" />
|
|
368
|
-
|
|
369
|
-
// Normal kullanım
|
|
370
|
-
<AtomicSpinner size="md" />
|
|
371
|
-
|
|
372
|
-
// Vurgu için
|
|
373
|
-
<AtomicSpinner size="lg" />
|
|
374
|
-
|
|
375
|
-
// Tam ekran
|
|
376
|
-
<AtomicSpinner size="xl" fullContainer />
|
|
304
|
+
{loading && <AtomicSpinner />}
|
|
377
305
|
```
|
|
378
306
|
|
|
379
|
-
|
|
307
|
+
#### Full Container Loading
|
|
308
|
+
```tsx
|
|
309
|
+
{loading ? (
|
|
310
|
+
<AtomicSpinner fullContainer text="Loading..." />
|
|
311
|
+
) : (
|
|
312
|
+
<Content />
|
|
313
|
+
)}
|
|
314
|
+
```
|
|
380
315
|
|
|
316
|
+
#### Button Loading
|
|
381
317
|
```tsx
|
|
382
|
-
|
|
383
|
-
|
|
318
|
+
<Button onPress={handleSubmit} disabled={loading}>
|
|
319
|
+
{loading ? (
|
|
320
|
+
<AtomicSpinner size="sm" color="white" />
|
|
321
|
+
) : (
|
|
322
|
+
"Submit"
|
|
323
|
+
)}
|
|
324
|
+
</Button>
|
|
325
|
+
```
|
|
384
326
|
|
|
385
|
-
|
|
327
|
+
#### Overlay Loading
|
|
328
|
+
```tsx
|
|
386
329
|
<AtomicSpinner
|
|
387
330
|
overlay
|
|
388
|
-
overlayColor="rgba(
|
|
389
|
-
|
|
331
|
+
overlayColor="rgba(0, 0, 0, 0.7)"
|
|
332
|
+
text="Processing..."
|
|
333
|
+
color="white"
|
|
390
334
|
/>
|
|
391
335
|
```
|
|
392
336
|
|
|
393
|
-
|
|
394
|
-
|
|
337
|
+
#### With Text Position
|
|
395
338
|
```tsx
|
|
396
|
-
// Açıklayıcı metin
|
|
397
|
-
<AtomicSpinner text="Veriler yükleniyor..." />
|
|
398
|
-
|
|
399
|
-
// Kısa metin
|
|
400
|
-
<AtomicSpinner text="Yükleniyor..." />
|
|
401
|
-
|
|
402
|
-
// Sağda metin (horizontal layout)
|
|
403
339
|
<AtomicSpinner
|
|
404
|
-
text="
|
|
340
|
+
text="Uploading..."
|
|
405
341
|
textPosition="right"
|
|
342
|
+
size="sm"
|
|
406
343
|
/>
|
|
407
344
|
```
|
|
408
345
|
|
|
409
|
-
|
|
346
|
+
#### Custom Size
|
|
347
|
+
```tsx
|
|
348
|
+
<AtomicSpinner size={32} />
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Props Reference
|
|
352
|
+
|
|
353
|
+
| Prop | Type | Required | Default | Description |
|
|
354
|
+
|------|------|----------|---------|-------------|
|
|
355
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| 'xl' \| number` | No | `'md'` | Spinner size |
|
|
356
|
+
| `color` | `SpinnerColor \| string` | No | `'primary'` | Spinner color |
|
|
357
|
+
| `text` | `string` | No | - | Loading text |
|
|
358
|
+
| `textPosition` | `'bottom' \| 'right'` | No | `'bottom'` | Text position |
|
|
359
|
+
| `fullContainer` | `boolean` | No | `false` | Fill and center in container |
|
|
360
|
+
| `overlay` | `boolean` | No | `false` | Show overlay background |
|
|
361
|
+
| `overlayColor` | `string` | No | `'rgba(0, 0, 0, 0.5)'` | Overlay background color |
|
|
362
|
+
| `style` | `ViewStyle \| ViewStyle[]` | No | - | Custom style |
|
|
363
|
+
| `testID` | `string` | No | - | Test identifier |
|
|
364
|
+
|
|
365
|
+
### SpinnerColor
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
type SpinnerColor =
|
|
369
|
+
| 'primary' // Main theme color
|
|
370
|
+
| 'secondary' // Secondary theme color
|
|
371
|
+
| 'success' // Success color
|
|
372
|
+
| 'error' // Error color
|
|
373
|
+
| 'warning' // Warning color
|
|
374
|
+
| 'white'; // White
|
|
375
|
+
```
|
|
410
376
|
|
|
411
|
-
|
|
377
|
+
## Accessibility
|
|
412
378
|
|
|
413
|
-
- ✅ Screen reader
|
|
414
|
-
- ✅ Accessibility label
|
|
379
|
+
- ✅ Screen reader announces loading state
|
|
380
|
+
- ✅ Accessibility label for context
|
|
415
381
|
- ✅ Progress bar role
|
|
416
|
-
- ✅ Live region
|
|
417
|
-
- ✅ Test ID
|
|
382
|
+
- ✅ Live region announcements
|
|
383
|
+
- ✅ Test ID support for testing
|
|
418
384
|
|
|
419
|
-
##
|
|
385
|
+
## Performance Tips
|
|
420
386
|
|
|
421
|
-
1. **Conditional
|
|
422
|
-
2. **Size
|
|
423
|
-
3. **Avoid
|
|
387
|
+
1. **Conditional rendering**: Only render when loading
|
|
388
|
+
2. **Size selection**: Use appropriate size for context
|
|
389
|
+
3. **Avoid re-renders**: Stabilize spinner props
|
|
390
|
+
4. **Clean up**: Always remove spinner when complete
|
|
424
391
|
|
|
425
|
-
##
|
|
392
|
+
## Related Components
|
|
426
393
|
|
|
427
|
-
- [`AtomicProgress`](./AtomicProgress
|
|
428
|
-
- [`AtomicSkeleton`](./skeleton/AtomicSkeleton
|
|
429
|
-
- [`EmptyState`](./EmptyState
|
|
394
|
+
- [`AtomicProgress`](./AtomicProgress.README.md) - Determinate progress bar
|
|
395
|
+
- [`AtomicSkeleton`](./skeleton/AtomicSkeleton.README.md) - Skeleton placeholder
|
|
396
|
+
- [`EmptyState`](./EmptyState.README.md) - Empty state component
|
|
430
397
|
|
|
431
|
-
##
|
|
398
|
+
## License
|
|
432
399
|
|
|
433
400
|
MIT
|