ux-toolkit 0.1.0
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/LICENSE +21 -0
- package/README.md +137 -0
- package/agents/accessibility-auditor.md +39 -0
- package/agents/accessibility-engineer.md +43 -0
- package/agents/interaction-reviewer.md +47 -0
- package/agents/ux-auditor.md +52 -0
- package/agents/ux-engineer.md +40 -0
- package/agents/visual-reviewer.md +41 -0
- package/commands/a11y-check.md +14 -0
- package/commands/design-review.md +14 -0
- package/commands/screenshot-review.md +15 -0
- package/commands/ux-audit.md +15 -0
- package/dist/cli.js +295 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +254 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +88 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.js +220 -0
- package/dist/index.js.map +1 -0
- package/package.json +71 -0
- package/skills/interaction-patterns/SKILL.md +258 -0
- package/skills/mobile-responsive-ux/SKILL.md +260 -0
- package/skills/react-ux-patterns/SKILL.md +335 -0
- package/skills/ux-heuristics/SKILL.md +150 -0
- package/skills/visual-design-system/SKILL.md +208 -0
- package/skills/wcag-accessibility/SKILL.md +178 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: interaction-patterns
|
|
3
|
+
description: Micro-interaction patterns, loading states, feedback mechanisms, and animation guidelines
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Interaction Design Patterns
|
|
8
|
+
|
|
9
|
+
## Micro-interaction Anatomy
|
|
10
|
+
|
|
11
|
+
Every micro-interaction has four parts:
|
|
12
|
+
|
|
13
|
+
1. **Trigger** - What initiates it (user action or system event)
|
|
14
|
+
2. **Rules** - What happens in response
|
|
15
|
+
3. **Feedback** - Visual/audio response to the user
|
|
16
|
+
4. **Loops/Modes** - What happens on repeat or over time
|
|
17
|
+
|
|
18
|
+
## Feedback Timing
|
|
19
|
+
|
|
20
|
+
| Response Time | User Perception | Guidance |
|
|
21
|
+
|---------------|-----------------|----------|
|
|
22
|
+
| <100ms | Instant | No indicator needed |
|
|
23
|
+
| 100-300ms | Slight delay | Optional subtle feedback |
|
|
24
|
+
| 300-1000ms | Noticeable | Show loading indicator |
|
|
25
|
+
| 1-5s | Waiting | Show progress or skeleton |
|
|
26
|
+
| >5s | Long wait | Show progress + estimated time |
|
|
27
|
+
|
|
28
|
+
## Loading State Patterns
|
|
29
|
+
|
|
30
|
+
### Skeleton Screens (Preferred)
|
|
31
|
+
Best for: Content with predictable layout
|
|
32
|
+
|
|
33
|
+
```css
|
|
34
|
+
.skeleton {
|
|
35
|
+
background: linear-gradient(
|
|
36
|
+
90deg,
|
|
37
|
+
#f0f0f0 25%,
|
|
38
|
+
#e0e0e0 50%,
|
|
39
|
+
#f0f0f0 75%
|
|
40
|
+
);
|
|
41
|
+
background-size: 200% 100%;
|
|
42
|
+
animation: shimmer 1.5s infinite;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@keyframes shimmer {
|
|
46
|
+
0% { background-position: 200% 0; }
|
|
47
|
+
100% { background-position: -200% 0; }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@media (prefers-reduced-motion: reduce) {
|
|
51
|
+
.skeleton {
|
|
52
|
+
animation: none;
|
|
53
|
+
background: #e0e0e0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Spinner
|
|
59
|
+
Best for: Short operations, unknown duration
|
|
60
|
+
|
|
61
|
+
- Use for actions <3 seconds
|
|
62
|
+
- Center within the loading area
|
|
63
|
+
- Include text for longer waits ("Loading...")
|
|
64
|
+
|
|
65
|
+
### Progress Bar
|
|
66
|
+
Best for: Determinate operations
|
|
67
|
+
|
|
68
|
+
- Show percentage or steps completed
|
|
69
|
+
- Move smoothly, never backwards
|
|
70
|
+
- Include text description of current step
|
|
71
|
+
|
|
72
|
+
### Optimistic UI
|
|
73
|
+
Best for: High-confidence operations
|
|
74
|
+
|
|
75
|
+
- Update UI immediately before server confirms
|
|
76
|
+
- Show subtle pending indicator
|
|
77
|
+
- Revert gracefully on failure
|
|
78
|
+
|
|
79
|
+
## Button States
|
|
80
|
+
|
|
81
|
+
| State | Visual Treatment | Timing |
|
|
82
|
+
|-------|------------------|--------|
|
|
83
|
+
| Default | Base style | - |
|
|
84
|
+
| Hover | Subtle highlight (5-10% lighter/darker) | Immediate |
|
|
85
|
+
| Focus | Visible ring/outline (2px+) | Immediate |
|
|
86
|
+
| Active | Pressed appearance (slight scale/shadow) | Immediate |
|
|
87
|
+
| Loading | Spinner replaces or joins text | During operation |
|
|
88
|
+
| Disabled | Reduced opacity (50-60%), no pointer | - |
|
|
89
|
+
| Success | Brief green flash (optional) | 1-2s then reset |
|
|
90
|
+
|
|
91
|
+
### Button Loading Pattern
|
|
92
|
+
```tsx
|
|
93
|
+
<button disabled={isLoading}>
|
|
94
|
+
{isLoading ? (
|
|
95
|
+
<>
|
|
96
|
+
<Spinner className="mr-2" />
|
|
97
|
+
Saving...
|
|
98
|
+
</>
|
|
99
|
+
) : (
|
|
100
|
+
'Save'
|
|
101
|
+
)}
|
|
102
|
+
</button>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Form Interactions
|
|
106
|
+
|
|
107
|
+
### Validation Timing
|
|
108
|
+
| Approach | When | Best For |
|
|
109
|
+
|----------|------|----------|
|
|
110
|
+
| On change (debounced) | As user types | Real-time feedback, username availability |
|
|
111
|
+
| On blur | When leaving field | Most form fields |
|
|
112
|
+
| On submit | Form submission | Final validation |
|
|
113
|
+
|
|
114
|
+
### Input States
|
|
115
|
+
- **Default**: Ready for input
|
|
116
|
+
- **Focused**: Active, ready for input
|
|
117
|
+
- **Filled**: Has value, not focused
|
|
118
|
+
- **Error**: Invalid value, show message
|
|
119
|
+
- **Success**: Valid value (optional)
|
|
120
|
+
- **Disabled**: Not editable
|
|
121
|
+
|
|
122
|
+
### Error Message Pattern
|
|
123
|
+
```html
|
|
124
|
+
<div class="form-field">
|
|
125
|
+
<label for="email">Email</label>
|
|
126
|
+
<input
|
|
127
|
+
id="email"
|
|
128
|
+
type="email"
|
|
129
|
+
aria-invalid="true"
|
|
130
|
+
aria-describedby="email-error"
|
|
131
|
+
/>
|
|
132
|
+
<span id="email-error" class="error" role="alert">
|
|
133
|
+
Please enter a valid email address
|
|
134
|
+
</span>
|
|
135
|
+
</div>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Animation Guidelines
|
|
139
|
+
|
|
140
|
+
### Principles
|
|
141
|
+
1. **Purposeful** - Guides attention, communicates meaning
|
|
142
|
+
2. **Subtle** - Enhances, doesn't distract
|
|
143
|
+
3. **Fast** - 150-300ms for micro-interactions
|
|
144
|
+
4. **Smooth** - 60fps, no jank
|
|
145
|
+
5. **Respectful** - Honors `prefers-reduced-motion`
|
|
146
|
+
|
|
147
|
+
### Easing Functions
|
|
148
|
+
| Easing | Use Case |
|
|
149
|
+
|--------|----------|
|
|
150
|
+
| ease-out | Elements entering (fast start, slow end) |
|
|
151
|
+
| ease-in | Elements exiting (slow start, fast end) |
|
|
152
|
+
| ease-in-out | Elements moving within view |
|
|
153
|
+
| linear | Progress indicators, loading |
|
|
154
|
+
|
|
155
|
+
### Duration Guidelines
|
|
156
|
+
| Animation Type | Duration |
|
|
157
|
+
|----------------|----------|
|
|
158
|
+
| Micro-interaction | 100-200ms |
|
|
159
|
+
| State change | 150-300ms |
|
|
160
|
+
| Page transition | 300-500ms |
|
|
161
|
+
| Complex animation | 500-1000ms |
|
|
162
|
+
|
|
163
|
+
### Reduced Motion
|
|
164
|
+
```css
|
|
165
|
+
@media (prefers-reduced-motion: reduce) {
|
|
166
|
+
*,
|
|
167
|
+
*::before,
|
|
168
|
+
*::after {
|
|
169
|
+
animation-duration: 0.01ms !important;
|
|
170
|
+
animation-iteration-count: 1 !important;
|
|
171
|
+
transition-duration: 0.01ms !important;
|
|
172
|
+
scroll-behavior: auto !important;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Error Handling UX
|
|
178
|
+
|
|
179
|
+
### Principles
|
|
180
|
+
1. **Prevent first** - Validate before errors occur
|
|
181
|
+
2. **Be specific** - What exactly went wrong
|
|
182
|
+
3. **Be helpful** - How to fix it
|
|
183
|
+
4. **Be kind** - Don't blame the user
|
|
184
|
+
5. **Preserve work** - Never lose user input
|
|
185
|
+
|
|
186
|
+
### Error Message Components
|
|
187
|
+
1. **What happened** - Clear description of the problem
|
|
188
|
+
2. **Why it happened** - Context if helpful
|
|
189
|
+
3. **What to do** - Specific recovery action
|
|
190
|
+
|
|
191
|
+
### Error Display Patterns
|
|
192
|
+
|
|
193
|
+
**Inline (field-level)**
|
|
194
|
+
- Show next to the problematic field
|
|
195
|
+
- Use for form validation
|
|
196
|
+
- Red border + error message below
|
|
197
|
+
|
|
198
|
+
**Toast (transient)**
|
|
199
|
+
- Auto-dismiss after 5-10 seconds
|
|
200
|
+
- Use for non-critical errors
|
|
201
|
+
- Include dismiss button
|
|
202
|
+
|
|
203
|
+
**Banner (persistent)**
|
|
204
|
+
- Show at top of page/section
|
|
205
|
+
- Use for page-level issues
|
|
206
|
+
- Stays until resolved
|
|
207
|
+
|
|
208
|
+
**Modal (blocking)**
|
|
209
|
+
- Use sparingly for critical errors
|
|
210
|
+
- Require acknowledgment
|
|
211
|
+
- Provide clear action path
|
|
212
|
+
|
|
213
|
+
## Optimistic UI Pattern
|
|
214
|
+
|
|
215
|
+
### When to Use
|
|
216
|
+
- Toggle states (like, bookmark)
|
|
217
|
+
- Simple text edits
|
|
218
|
+
- Reordering items
|
|
219
|
+
- Adding to lists
|
|
220
|
+
|
|
221
|
+
### When to Avoid
|
|
222
|
+
- Financial transactions
|
|
223
|
+
- Irreversible actions
|
|
224
|
+
- Complex server validation
|
|
225
|
+
- Multi-step processes
|
|
226
|
+
|
|
227
|
+
### Implementation
|
|
228
|
+
```typescript
|
|
229
|
+
async function toggleLike(itemId: string) {
|
|
230
|
+
// 1. Optimistically update UI
|
|
231
|
+
setLiked(true);
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
// 2. Send to server
|
|
235
|
+
await api.like(itemId);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
// 3. Revert on failure
|
|
238
|
+
setLiked(false);
|
|
239
|
+
showError('Failed to save');
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Notification Patterns
|
|
245
|
+
|
|
246
|
+
### Types
|
|
247
|
+
| Type | Duration | Dismissible | Use |
|
|
248
|
+
|------|----------|-------------|-----|
|
|
249
|
+
| Success | 3-5s | Yes | Confirmation of action |
|
|
250
|
+
| Info | 5-10s | Yes | Neutral information |
|
|
251
|
+
| Warning | Persistent | Yes | Requires attention |
|
|
252
|
+
| Error | Persistent | Yes | Problem occurred |
|
|
253
|
+
|
|
254
|
+
### Placement
|
|
255
|
+
- **Top right** - Most common, notifications
|
|
256
|
+
- **Top center** - Important alerts
|
|
257
|
+
- **Bottom center** - Mobile, snackbars
|
|
258
|
+
- **Inline** - Context-specific feedback
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mobile-responsive-ux
|
|
3
|
+
description: Mobile UX patterns including touch targets, gestures, responsive design, and mobile-specific considerations
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Mobile & Responsive UX
|
|
8
|
+
|
|
9
|
+
## Touch Target Sizes
|
|
10
|
+
|
|
11
|
+
| Standard | Size | Notes |
|
|
12
|
+
|----------|------|-------|
|
|
13
|
+
| WCAG 2.2 AA | 24×24px | Absolute minimum |
|
|
14
|
+
| Apple HIG | 44×44px | Recommended minimum |
|
|
15
|
+
| Material Design | 48×48px | Recommended minimum |
|
|
16
|
+
| Comfortable | 48×48px+ | Best for accessibility |
|
|
17
|
+
|
|
18
|
+
### Spacing Between Targets
|
|
19
|
+
- Minimum: 8px between touch targets
|
|
20
|
+
- Recommended: 16px for comfortable tapping
|
|
21
|
+
- Critical actions: Extra spacing to prevent mis-taps
|
|
22
|
+
|
|
23
|
+
## Mobile Navigation Patterns
|
|
24
|
+
|
|
25
|
+
### Bottom Navigation (Recommended)
|
|
26
|
+
Best for: 3-5 primary destinations
|
|
27
|
+
|
|
28
|
+
**Guidelines:**
|
|
29
|
+
- Maximum 5 items
|
|
30
|
+
- Icon + text label for each
|
|
31
|
+
- Highlight active state clearly
|
|
32
|
+
- Most important items in thumb-reach zone
|
|
33
|
+
|
|
34
|
+
**Thumb Zone (Right-handed)**
|
|
35
|
+
```
|
|
36
|
+
┌─────────────────┐
|
|
37
|
+
│ Hard to reach │
|
|
38
|
+
│ │
|
|
39
|
+
│ Comfortable │
|
|
40
|
+
│ │
|
|
41
|
+
│ Easy to reach │
|
|
42
|
+
└─────────────────┘
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Hamburger Menu
|
|
46
|
+
Best for: Secondary navigation, settings
|
|
47
|
+
|
|
48
|
+
**Guidelines:**
|
|
49
|
+
- Use clear ☰ icon or "Menu" label
|
|
50
|
+
- Full-screen overlay on mobile
|
|
51
|
+
- Easy close (X button + tap outside)
|
|
52
|
+
- Remember scroll position
|
|
53
|
+
|
|
54
|
+
### Tab Bar
|
|
55
|
+
Best for: Parallel content sections
|
|
56
|
+
|
|
57
|
+
**Guidelines:**
|
|
58
|
+
- Maximum 5 tabs
|
|
59
|
+
- Scrollable if more needed
|
|
60
|
+
- Clear active state
|
|
61
|
+
- Consider icons + text
|
|
62
|
+
|
|
63
|
+
## Gesture Patterns
|
|
64
|
+
|
|
65
|
+
| Gesture | Common Use | Consider |
|
|
66
|
+
|---------|------------|----------|
|
|
67
|
+
| Tap | Select, activate | Primary interaction |
|
|
68
|
+
| Long press | Context menu, select mode | Discoverable alternative needed |
|
|
69
|
+
| Swipe horizontal | Delete, archive, navigation | Provide visual hint |
|
|
70
|
+
| Swipe vertical | Refresh, dismiss, scroll | Pull-to-refresh standard |
|
|
71
|
+
| Pinch | Zoom in/out | Images, maps |
|
|
72
|
+
| Double tap | Zoom, like | Secondary action |
|
|
73
|
+
| Drag | Reorder, move | Provide handle affordance |
|
|
74
|
+
|
|
75
|
+
### Gesture Best Practices
|
|
76
|
+
- Always provide button alternative for gestures
|
|
77
|
+
- Add visual hints for available gestures
|
|
78
|
+
- Use standard platform conventions
|
|
79
|
+
- Provide haptic feedback when appropriate
|
|
80
|
+
|
|
81
|
+
## Responsive Design Checklist
|
|
82
|
+
|
|
83
|
+
### Content
|
|
84
|
+
- [ ] Text readable without zooming (16px+ base)
|
|
85
|
+
- [ ] Images scale appropriately
|
|
86
|
+
- [ ] No horizontal scrolling required
|
|
87
|
+
- [ ] Tables adapt or scroll horizontally
|
|
88
|
+
- [ ] Long words break appropriately
|
|
89
|
+
|
|
90
|
+
### Interaction
|
|
91
|
+
- [ ] Touch targets ≥44px
|
|
92
|
+
- [ ] Adequate spacing between targets
|
|
93
|
+
- [ ] Forms usable with on-screen keyboard
|
|
94
|
+
- [ ] Dropdowns have mobile-friendly alternatives
|
|
95
|
+
- [ ] Date pickers use native when possible
|
|
96
|
+
|
|
97
|
+
### Layout
|
|
98
|
+
- [ ] Single column on mobile
|
|
99
|
+
- [ ] Critical content above fold
|
|
100
|
+
- [ ] Navigation accessible
|
|
101
|
+
- [ ] Fixed headers not too tall
|
|
102
|
+
- [ ] Bottom nav in thumb zone
|
|
103
|
+
|
|
104
|
+
## Mobile-First CSS
|
|
105
|
+
|
|
106
|
+
```css
|
|
107
|
+
/* Base: Mobile styles */
|
|
108
|
+
.container {
|
|
109
|
+
padding: 16px;
|
|
110
|
+
font-size: 16px;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.grid {
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-direction: column;
|
|
116
|
+
gap: 16px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Tablet: 768px+ */
|
|
120
|
+
@media (min-width: 768px) {
|
|
121
|
+
.container {
|
|
122
|
+
padding: 24px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.grid {
|
|
126
|
+
flex-direction: row;
|
|
127
|
+
flex-wrap: wrap;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.grid-item {
|
|
131
|
+
flex: 0 0 calc(50% - 8px);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Desktop: 1024px+ */
|
|
136
|
+
@media (min-width: 1024px) {
|
|
137
|
+
.container {
|
|
138
|
+
padding: 32px;
|
|
139
|
+
max-width: 1200px;
|
|
140
|
+
margin: 0 auto;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.grid-item {
|
|
144
|
+
flex: 0 0 calc(33.333% - 11px);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Mobile Form UX
|
|
150
|
+
|
|
151
|
+
### Input Types
|
|
152
|
+
| Data | Input Type | Keyboard |
|
|
153
|
+
|------|------------|----------|
|
|
154
|
+
| Email | `type="email"` | @ and .com keys |
|
|
155
|
+
| Phone | `type="tel"` | Number pad |
|
|
156
|
+
| Number | `type="number"` | Number pad |
|
|
157
|
+
| URL | `type="url"` | .com and / keys |
|
|
158
|
+
| Search | `type="search"` | Search button |
|
|
159
|
+
| Date | `type="date"` | Date picker |
|
|
160
|
+
|
|
161
|
+
### Form Best Practices
|
|
162
|
+
- Use large touch targets for inputs
|
|
163
|
+
- Show inline validation
|
|
164
|
+
- Enable autocomplete (`autocomplete` attribute)
|
|
165
|
+
- Use appropriate `inputmode` for custom keyboards
|
|
166
|
+
- Avoid dropdowns when possible (use segmented controls)
|
|
167
|
+
- Group related fields
|
|
168
|
+
- Show keyboard-appropriate labels
|
|
169
|
+
|
|
170
|
+
### Keyboard Handling
|
|
171
|
+
```html
|
|
172
|
+
<input
|
|
173
|
+
type="text"
|
|
174
|
+
inputmode="numeric"
|
|
175
|
+
pattern="[0-9]*"
|
|
176
|
+
autocomplete="cc-number"
|
|
177
|
+
enterkeyhint="next"
|
|
178
|
+
/>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Safe Areas
|
|
182
|
+
|
|
183
|
+
Handle notches, home indicators, and rounded corners:
|
|
184
|
+
|
|
185
|
+
```css
|
|
186
|
+
.app-container {
|
|
187
|
+
padding-top: env(safe-area-inset-top);
|
|
188
|
+
padding-right: env(safe-area-inset-right);
|
|
189
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
190
|
+
padding-left: env(safe-area-inset-left);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* For fixed bottom navigation */
|
|
194
|
+
.bottom-nav {
|
|
195
|
+
padding-bottom: calc(16px + env(safe-area-inset-bottom));
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Mobile Performance UX
|
|
200
|
+
|
|
201
|
+
### Image Optimization
|
|
202
|
+
```html
|
|
203
|
+
<img
|
|
204
|
+
src="image-800.jpg"
|
|
205
|
+
srcset="
|
|
206
|
+
image-400.jpg 400w,
|
|
207
|
+
image-800.jpg 800w,
|
|
208
|
+
image-1200.jpg 1200w
|
|
209
|
+
"
|
|
210
|
+
sizes="(max-width: 600px) 100vw, 50vw"
|
|
211
|
+
loading="lazy"
|
|
212
|
+
alt="Description"
|
|
213
|
+
/>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Lazy Loading
|
|
217
|
+
- Images below fold: `loading="lazy"`
|
|
218
|
+
- Iframes: `loading="lazy"`
|
|
219
|
+
- Heavy components: Dynamic import with Suspense
|
|
220
|
+
|
|
221
|
+
### Perceived Performance
|
|
222
|
+
- Show skeleton screens immediately
|
|
223
|
+
- Progressive image loading (blur-up)
|
|
224
|
+
- Optimistic UI for common actions
|
|
225
|
+
- Prefetch likely next pages
|
|
226
|
+
|
|
227
|
+
## Offline & Slow Network
|
|
228
|
+
|
|
229
|
+
### Offline States
|
|
230
|
+
- Clear "offline" indicator
|
|
231
|
+
- Cache critical content
|
|
232
|
+
- Queue actions for sync
|
|
233
|
+
- Show last updated timestamp
|
|
234
|
+
|
|
235
|
+
### Slow Network Handling
|
|
236
|
+
- Skeleton screens
|
|
237
|
+
- Lower quality images first
|
|
238
|
+
- Retry failed requests
|
|
239
|
+
- Show progress for large uploads
|
|
240
|
+
|
|
241
|
+
## Mobile Testing Checklist
|
|
242
|
+
|
|
243
|
+
### Device Testing
|
|
244
|
+
- [ ] Test on actual devices (not just emulators)
|
|
245
|
+
- [ ] Test on different screen sizes
|
|
246
|
+
- [ ] Test in portrait and landscape
|
|
247
|
+
- [ ] Test with different text sizes (accessibility)
|
|
248
|
+
- [ ] Test with one-handed use
|
|
249
|
+
|
|
250
|
+
### Network Testing
|
|
251
|
+
- [ ] Test on slow 3G
|
|
252
|
+
- [ ] Test offline mode
|
|
253
|
+
- [ ] Test intermittent connection
|
|
254
|
+
- [ ] Test large file uploads
|
|
255
|
+
|
|
256
|
+
### Input Testing
|
|
257
|
+
- [ ] Test with on-screen keyboard
|
|
258
|
+
- [ ] Test keyboard dismissal
|
|
259
|
+
- [ ] Test with voice input
|
|
260
|
+
- [ ] Test copy/paste
|