@umituz/react-native-settings 4.20.57 → 4.20.59
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/.github/ISSUE_TEMPLATE/bug_report.md +51 -0
- package/.github/ISSUE_TEMPLATE/documentation.md +52 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +63 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +84 -0
- package/AI_AGENT_GUIDELINES.md +367 -0
- package/ARCHITECTURE.md +246 -0
- package/CHANGELOG.md +67 -0
- package/CODE_OF_CONDUCT.md +75 -0
- package/CONTRIBUTING.md +107 -0
- package/DOCUMENTATION_MIGRATION.md +319 -0
- package/DOCUMENTATION_TEMPLATE.md +155 -0
- package/LICENSE +21 -0
- package/README.md +321 -498
- package/SECURITY.md +98 -0
- package/SETTINGS_SCREEN_GUIDE.md +185 -0
- package/TESTING.md +358 -0
- package/package.json +13 -2
- package/src/__tests__/setup.ts +1 -4
- package/src/application/README.md +85 -271
- package/src/domains/about/README.md +85 -440
- package/src/domains/about/presentation/hooks/README.md +93 -348
- package/src/domains/appearance/README.md +95 -584
- package/src/domains/appearance/hooks/README.md +95 -303
- package/src/domains/appearance/infrastructure/services/README.md +83 -397
- package/src/domains/appearance/presentation/components/README.md +99 -0
- package/src/domains/cloud-sync/README.md +73 -439
- package/src/domains/cloud-sync/presentation/components/README.md +95 -493
- package/src/domains/dev/README.md +71 -457
- package/src/domains/disclaimer/README.md +77 -411
- package/src/domains/disclaimer/presentation/components/README.md +95 -392
- package/src/domains/faqs/README.md +86 -574
- package/src/domains/feedback/README.md +79 -553
- package/src/domains/feedback/presentation/hooks/README.md +93 -426
- package/src/domains/legal/README.md +88 -537
- package/src/domains/rating/README.md +73 -440
- package/src/domains/rating/presentation/components/README.md +95 -475
- package/src/domains/video-tutorials/README.md +77 -470
- package/src/domains/video-tutorials/presentation/components/README.md +95 -431
- package/src/infrastructure/README.md +78 -425
- package/src/infrastructure/repositories/README.md +88 -420
- package/src/infrastructure/services/README.md +74 -460
- package/src/presentation/components/README.md +97 -480
- package/src/presentation/components/SettingsErrorBoundary/README.md +48 -442
- package/src/presentation/components/SettingsFooter/README.md +48 -427
- package/src/presentation/components/SettingsItemCard/README.md +153 -392
- package/src/presentation/components/SettingsItemCard/STRATEGY.md +164 -0
- package/src/presentation/components/SettingsSection/README.md +47 -401
- package/src/presentation/hooks/README.md +95 -389
- package/src/presentation/hooks/mutations/README.md +99 -376
- package/src/presentation/hooks/queries/README.md +111 -353
- package/src/presentation/navigation/README.md +70 -502
- package/src/presentation/navigation/components/README.md +70 -295
- package/src/presentation/navigation/hooks/README.md +75 -367
- package/src/presentation/navigation/utils/README.md +100 -380
- package/src/presentation/screens/README.md +53 -504
- package/src/presentation/screens/components/SettingsContent/README.md +53 -382
- package/src/presentation/screens/components/SettingsHeader/README.md +48 -303
- package/src/presentation/screens/components/sections/CustomSettingsList/README.md +47 -359
- package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +81 -176
- package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +40 -297
- package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +47 -451
- package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +45 -361
- package/src/presentation/screens/hooks/README.md +64 -354
- package/src/presentation/screens/types/README.md +79 -409
- package/src/presentation/screens/utils/README.md +65 -255
|
@@ -1,445 +1,78 @@
|
|
|
1
1
|
# Rating Domain
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
**Custom Colors:**
|
|
79
|
-
|
|
80
|
-
```tsx
|
|
81
|
-
function CustomColoredRating() {
|
|
82
|
-
return (
|
|
83
|
-
<StarRating
|
|
84
|
-
rating={4}
|
|
85
|
-
activeColor="#FF6B6B"
|
|
86
|
-
inactiveColor="#E0E0E0"
|
|
87
|
-
size={32}
|
|
88
|
-
/>
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Read-Only Display:**
|
|
94
|
-
|
|
95
|
-
```tsx
|
|
96
|
-
function ReadOnlyRating() {
|
|
97
|
-
return (
|
|
98
|
-
<StarRating
|
|
99
|
-
rating={4.5}
|
|
100
|
-
disabled={true}
|
|
101
|
-
activeColor="#FFD700"
|
|
102
|
-
/>
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**10-Star Rating:**
|
|
108
|
-
|
|
109
|
-
```tsx
|
|
110
|
-
function TenStarRating() {
|
|
111
|
-
const [rating, setRating] = useState(7);
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<StarRating
|
|
115
|
-
rating={rating}
|
|
116
|
-
maxRating={10}
|
|
117
|
-
onRatingChange={setRating}
|
|
118
|
-
size={20}
|
|
119
|
-
/>
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**Large Stars:**
|
|
125
|
-
|
|
126
|
-
```tsx
|
|
127
|
-
function LargeStarRating() {
|
|
128
|
-
return (
|
|
129
|
-
<StarRating
|
|
130
|
-
rating={5}
|
|
131
|
-
size={48}
|
|
132
|
-
activeColor="#FFA500"
|
|
133
|
-
/>
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
**With Custom Style:**
|
|
139
|
-
|
|
140
|
-
```tsx
|
|
141
|
-
function StyledRating() {
|
|
142
|
-
return (
|
|
143
|
-
<StarRating
|
|
144
|
-
rating={4}
|
|
145
|
-
style={{
|
|
146
|
-
backgroundColor: '#F5F5F5',
|
|
147
|
-
padding: 16,
|
|
148
|
-
borderRadius: 8,
|
|
149
|
-
}}
|
|
150
|
-
/>
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## Types
|
|
156
|
-
|
|
157
|
-
### RatingValue
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
type RatingValue = 0 | 1 | 2 | 3 | 4 | 5;
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Rating
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
interface Rating {
|
|
167
|
-
id: string;
|
|
168
|
-
userId: string;
|
|
169
|
-
entityId: string;
|
|
170
|
-
entityType: string;
|
|
171
|
-
value: RatingValue;
|
|
172
|
-
createdAt: string;
|
|
173
|
-
updatedAt: string;
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### RatingStats
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
interface RatingStats {
|
|
181
|
-
average: number;
|
|
182
|
-
count: number;
|
|
183
|
-
distribution: Record<RatingValue, number>;
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
## Examples
|
|
188
|
-
|
|
189
|
-
### Product Rating
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
import { StarRating } from '@umituz/react-native-settings';
|
|
193
|
-
|
|
194
|
-
function ProductRating({ product }) {
|
|
195
|
-
const [userRating, setUserRating] = useState(0);
|
|
196
|
-
|
|
197
|
-
return (
|
|
198
|
-
<View>
|
|
199
|
-
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
200
|
-
<Text style={{ fontSize: 24, fontWeight: 'bold' }}>
|
|
201
|
-
{product.averageRating.toFixed(1)}
|
|
202
|
-
</Text>
|
|
203
|
-
<StarRating
|
|
204
|
-
rating={product.averageRating}
|
|
205
|
-
disabled={true}
|
|
206
|
-
size={20}
|
|
207
|
-
style={{ marginLeft: 8 }}
|
|
208
|
-
/>
|
|
209
|
-
<Text style={{ marginLeft: 8, color: '#666' }}>
|
|
210
|
-
({product.ratingCount} reviews)
|
|
211
|
-
</Text>
|
|
212
|
-
</View>
|
|
213
|
-
|
|
214
|
-
<View style={{ marginTop: 16 }}>
|
|
215
|
-
<Text>Rate this product:</Text>
|
|
216
|
-
<StarRating
|
|
217
|
-
rating={userRating}
|
|
218
|
-
onRatingChange={setUserRating}
|
|
219
|
-
/>
|
|
220
|
-
</View>
|
|
221
|
-
</View>
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Rating Distribution
|
|
227
|
-
|
|
228
|
-
```tsx
|
|
229
|
-
function RatingDistribution({ stats }) {
|
|
230
|
-
return (
|
|
231
|
-
<View>
|
|
232
|
-
<Text style={{ fontSize: 18, fontWeight: 'bold', marginBottom: 16 }}>
|
|
233
|
-
Rating Distribution
|
|
234
|
-
</Text>
|
|
235
|
-
|
|
236
|
-
{[5, 4, 3, 2, 1].map((star) => {
|
|
237
|
-
const count = stats.distribution[star] || 0;
|
|
238
|
-
const percentage = (count / stats.count) * 100;
|
|
239
|
-
|
|
240
|
-
return (
|
|
241
|
-
<View key={star} style={{ flexDirection: 'row', marginBottom: 8 }}>
|
|
242
|
-
<Text style={{ width: 40 }}>{star} star</Text>
|
|
243
|
-
<View style={{ flex: 1, height: 8, backgroundColor: '#E0E0E0' }}>
|
|
244
|
-
<View
|
|
245
|
-
style={{
|
|
246
|
-
width: `${percentage}%`,
|
|
247
|
-
height: '100%',
|
|
248
|
-
backgroundColor: '#FFD700',
|
|
249
|
-
}}
|
|
250
|
-
/>
|
|
251
|
-
</View>
|
|
252
|
-
<Text style={{ marginLeft: 8, width: 40 }}>{count}</Text>
|
|
253
|
-
</View>
|
|
254
|
-
);
|
|
255
|
-
})}
|
|
256
|
-
</View>
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### Review with Rating
|
|
262
|
-
|
|
263
|
-
```tsx
|
|
264
|
-
function ReviewCard({ review }) {
|
|
265
|
-
return (
|
|
266
|
-
<View style={{ padding: 16, backgroundColor: '#FFF', marginBottom: 8 }}>
|
|
267
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 8 }}>
|
|
268
|
-
<StarRating
|
|
269
|
-
rating={review.rating}
|
|
270
|
-
disabled={true}
|
|
271
|
-
size={16}
|
|
272
|
-
/>
|
|
273
|
-
<Text style={{ marginLeft: 8, fontWeight: 'bold' }}>
|
|
274
|
-
{review.userName}
|
|
275
|
-
</Text>
|
|
276
|
-
</View>
|
|
277
|
-
|
|
278
|
-
<Text style={{ color: '#666', marginBottom: 8 }}>
|
|
279
|
-
{review.date}
|
|
280
|
-
</Text>
|
|
281
|
-
|
|
282
|
-
<Text>{review.comment}</Text>
|
|
283
|
-
</View>
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
### Feedback Rating
|
|
289
|
-
|
|
290
|
-
```tsx
|
|
291
|
-
function FeedbackRating() {
|
|
292
|
-
const [rating, setRating] = useState(0);
|
|
293
|
-
const [submitted, setSubmitted] = useState(false);
|
|
294
|
-
|
|
295
|
-
const handleSubmit = async () => {
|
|
296
|
-
await api.submitFeedbackRating(rating);
|
|
297
|
-
setSubmitted(true);
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
if (submitted) {
|
|
301
|
-
return (
|
|
302
|
-
<View style={{ padding: 20, alignItems: 'center' }}>
|
|
303
|
-
<Text>Thanks for your feedback!</Text>
|
|
304
|
-
</View>
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return (
|
|
309
|
-
<View style={{ padding: 20 }}>
|
|
310
|
-
<Text style={{ fontSize: 18, marginBottom: 16 }}>
|
|
311
|
-
How would you rate your experience?
|
|
312
|
-
</Text>
|
|
313
|
-
|
|
314
|
-
<StarRating
|
|
315
|
-
rating={rating}
|
|
316
|
-
onRatingChange={setRating}
|
|
317
|
-
size={40}
|
|
318
|
-
/>
|
|
319
|
-
|
|
320
|
-
{rating > 0 && (
|
|
321
|
-
<Button
|
|
322
|
-
title="Submit Rating"
|
|
323
|
-
onPress={handleSubmit}
|
|
324
|
-
style={{ marginTop: 16 }}
|
|
325
|
-
/>
|
|
326
|
-
)}
|
|
327
|
-
</View>
|
|
328
|
-
);
|
|
329
|
-
}
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### Animated Rating
|
|
333
|
-
|
|
334
|
-
```tsx
|
|
335
|
-
import { Animated } from 'react-native';
|
|
336
|
-
|
|
337
|
-
function AnimatedStarRating() {
|
|
338
|
-
const [rating, setRating] = useState(0);
|
|
339
|
-
const scaleAnim = useRef(new Animated.Value(1)).current;
|
|
340
|
-
|
|
341
|
-
const handleRatingChange = (newRating) => {
|
|
342
|
-
// Animate scale
|
|
343
|
-
Animated.sequence([
|
|
344
|
-
Animated.timing(scaleAnim, {
|
|
345
|
-
toValue: 1.2,
|
|
346
|
-
duration: 100,
|
|
347
|
-
useNativeDriver: true,
|
|
348
|
-
}),
|
|
349
|
-
Animated.timing(scaleAnim, {
|
|
350
|
-
toValue: 1,
|
|
351
|
-
duration: 100,
|
|
352
|
-
useNativeDriver: true,
|
|
353
|
-
}),
|
|
354
|
-
]).start();
|
|
355
|
-
|
|
356
|
-
setRating(newRating);
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
return (
|
|
360
|
-
<Animated.View style={{ transform: [{ scale: scaleAnim }] }}>
|
|
361
|
-
<StarRating
|
|
362
|
-
rating={rating}
|
|
363
|
-
onRatingChange={handleRatingChange}
|
|
364
|
-
size={32}
|
|
365
|
-
/>
|
|
366
|
-
</Animated.View>
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
## Architecture
|
|
372
|
-
|
|
373
|
-
```
|
|
374
|
-
src/domains/rating/
|
|
375
|
-
├── domain/
|
|
376
|
-
│ └── entities/
|
|
377
|
-
│ └── Rating.ts # Rating types and interfaces
|
|
378
|
-
└── presentation/
|
|
379
|
-
└── components/
|
|
380
|
-
└── StarRating.tsx # Star rating component
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
## Best Practices
|
|
384
|
-
|
|
385
|
-
1. **Clear Purpose**: Always explain what users are rating
|
|
386
|
-
2. **Immediate Feedback**: Show selected rating immediately
|
|
387
|
-
3. **Allow Changes**: Let users change their rating before submitting
|
|
388
|
-
4. **Visual Hierarchy**: Make ratings prominent but not overwhelming
|
|
389
|
-
5. **Accessible**: Use proper accessibility labels for screen readers
|
|
390
|
-
6. **Consistent Sizing**: Use consistent star sizes across your app
|
|
391
|
-
7. **Color Coding**: Use standard colors (gold/yellow for filled stars)
|
|
392
|
-
|
|
393
|
-
## Testing
|
|
394
|
-
|
|
395
|
-
```tsx
|
|
396
|
-
import { render, fireEvent } from '@testing-library/react-native';
|
|
397
|
-
import { StarRating } from '@umituz/react-native-settings';
|
|
398
|
-
|
|
399
|
-
describe('StarRating', () => {
|
|
400
|
-
it('renders correct number of stars', () => {
|
|
401
|
-
const { getAllByTestId } = render(
|
|
402
|
-
<StarRating rating={3} maxRating={5} />
|
|
403
|
-
);
|
|
404
|
-
|
|
405
|
-
expect(getAllByTestId(/star/)).toHaveLength(5);
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
it('displays filled and empty stars correctly', () => {
|
|
409
|
-
const { getAllByTestId } = render(
|
|
410
|
-
<StarRating rating={3} maxRating={5} />
|
|
411
|
-
);
|
|
412
|
-
|
|
413
|
-
const stars = getAllByTestId(/star/);
|
|
414
|
-
// First 3 should be filled, last 2 empty
|
|
415
|
-
// (implementation-specific assertions)
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
it('calls onRatingChange when star is pressed', () => {
|
|
419
|
-
const mockOnChange = jest.fn();
|
|
420
|
-
const { getAllByTestId } = render(
|
|
421
|
-
<StarRating rating={0} onRatingChange={mockOnChange} maxRating={5} />
|
|
422
|
-
);
|
|
423
|
-
|
|
424
|
-
const stars = getAllByTestId(/star/);
|
|
425
|
-
fireEvent.press(stars[3]);
|
|
426
|
-
|
|
427
|
-
expect(mockOnChange).toHaveBeenCalledWith(4);
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
it('does not respond to presses when disabled', () => {
|
|
431
|
-
const mockOnChange = jest.fn();
|
|
432
|
-
const { getAllByTestId } = render(
|
|
433
|
-
<StarRating rating={3} onRatingChange={mockOnChange} disabled={true} />
|
|
434
|
-
);
|
|
435
|
-
|
|
436
|
-
const stars = getAllByTestId(/star/);
|
|
437
|
-
fireEvent.press(stars[0]);
|
|
438
|
-
|
|
439
|
-
expect(mockOnChange).not.toHaveBeenCalled();
|
|
440
|
-
});
|
|
441
|
-
});
|
|
442
|
-
```
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Provides star rating component and rating management utilities for collecting and displaying user ratings with customizable appearance.
|
|
6
|
+
|
|
7
|
+
## File Paths
|
|
8
|
+
|
|
9
|
+
**Components:**
|
|
10
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/rating/presentation/components/StarRating.tsx`
|
|
11
|
+
|
|
12
|
+
**Entities:**
|
|
13
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/rating/domain/entities/Rating.ts`
|
|
14
|
+
|
|
15
|
+
**Index:**
|
|
16
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/rating/index.ts`
|
|
17
|
+
|
|
18
|
+
## Strategy
|
|
19
|
+
|
|
20
|
+
1. **Interactive Feedback**: Provide immediate visual feedback when users interact with rating stars
|
|
21
|
+
2. **Read-Only Support**: Support both interactive and read-only display modes
|
|
22
|
+
3. **Customization**: Allow customization of colors, sizes, and star count
|
|
23
|
+
4. **Accessibility**: Ensure proper accessibility labels for screen readers
|
|
24
|
+
5. **Type Safety**: Use TypeScript types for rating values (0-5)
|
|
25
|
+
|
|
26
|
+
## Restrictions (Forbidden)
|
|
27
|
+
|
|
28
|
+
### DO NOT
|
|
29
|
+
- ❌ DO NOT use StarRating without providing rating prop
|
|
30
|
+
- ❌ DO NOT bypass the rating prop validation
|
|
31
|
+
- ❌ DO NOT use non-standard rating values outside the 0-5 range
|
|
32
|
+
- ❌ DO NOT mix rating display logic with business logic
|
|
33
|
+
|
|
34
|
+
### NEVER
|
|
35
|
+
- ❌ NEVER use StarRating for non-rating purposes (e.g., progress indicators)
|
|
36
|
+
- ❌ NEVER allow ratings without explaining what users are rating
|
|
37
|
+
- ❌ NEVER use inappropriate colors for filled stars (use standard gold/yellow)
|
|
38
|
+
- ❌ NEVER implement custom rating components when StarRating can be configured
|
|
39
|
+
|
|
40
|
+
### AVOID
|
|
41
|
+
- ❌ AVOID creating custom rating UI when StarRating provides everything needed
|
|
42
|
+
- ❌ AVOID using different star sizes across the app inconsistently
|
|
43
|
+
- ❌ AVOID using rating components without proper accessibility labels
|
|
44
|
+
- ❌ AVOID mixing interactive and read-only modes without clear distinction
|
|
45
|
+
|
|
46
|
+
## Rules
|
|
47
|
+
|
|
48
|
+
### ALWAYS
|
|
49
|
+
- ✅ ALWAYS provide rating prop to StarRating (required)
|
|
50
|
+
- ✅ ALWAYS provide onRatingChange handler for interactive ratings
|
|
51
|
+
- ✅ ALWAYS use standard colors (gold/yellow) for filled stars
|
|
52
|
+
- ✅ ALWAYS include proper accessibility labels for screen readers
|
|
53
|
+
- ✅ ALWAYS explain what users are rating before displaying the component
|
|
54
|
+
|
|
55
|
+
### MUST
|
|
56
|
+
- ✅ MUST keep rating values within 0-5 range
|
|
57
|
+
- ✅ MUST use disabled prop for read-only display
|
|
58
|
+
- ✅ MUST ensure proper contrast ratios for accessibility
|
|
59
|
+
- ✅ MUST use consistent star sizes across the app
|
|
60
|
+
- ✅ MUST handle rating changes properly with validation
|
|
61
|
+
|
|
62
|
+
### SHOULD
|
|
63
|
+
- ✅ SHOULD allow users to change their rating before submitting
|
|
64
|
+
- ✅ SHOULD show selected rating immediately
|
|
65
|
+
- ✅ SHOULD make ratings prominent but not overwhelming
|
|
66
|
+
- ✅ SHOULD use RatingValue type for type safety
|
|
67
|
+
- ✅ SHOULD provide visual feedback on rating selection
|
|
68
|
+
|
|
69
|
+
## AI Agent Guidelines
|
|
70
|
+
|
|
71
|
+
1. **Component Usage**: Always use StarRating for all rating displays - never create custom rating components
|
|
72
|
+
2. **Mode Selection**: Use interactive mode (with onRatingChange) for collecting ratings, disabled mode for display
|
|
73
|
+
3. **Customization**: Use activeColor and inactiveColor props for customization - never modify component directly
|
|
74
|
+
4. **Accessibility**: Always ensure proper accessibility labels and contrast ratios
|
|
75
|
+
5. **Type Safety**: Always use RatingValue type for rating values - never use loose number types
|
|
443
76
|
|
|
444
77
|
## Related
|
|
445
78
|
|