@neyugn/agent-kits 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 +514 -0
- package/README.vi.md +410 -0
- package/README.zh.md +410 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +422 -0
- package/kits/coder/ARCHITECTURE.md +289 -0
- package/kits/coder/agents/ai-engineer.md +344 -0
- package/kits/coder/agents/backend-specialist.md +270 -0
- package/kits/coder/agents/cloud-architect.md +363 -0
- package/kits/coder/agents/code-reviewer.md +284 -0
- package/kits/coder/agents/data-engineer.md +401 -0
- package/kits/coder/agents/database-specialist.md +251 -0
- package/kits/coder/agents/debugger.md +209 -0
- package/kits/coder/agents/devops-engineer.md +281 -0
- package/kits/coder/agents/documentation-writer.md +296 -0
- package/kits/coder/agents/frontend-specialist.md +298 -0
- package/kits/coder/agents/i18n-specialist.md +348 -0
- package/kits/coder/agents/integration-specialist.md +314 -0
- package/kits/coder/agents/mobile-developer.md +271 -0
- package/kits/coder/agents/multi-tenant-architect.md +281 -0
- package/kits/coder/agents/orchestrator.md +263 -0
- package/kits/coder/agents/performance-analyst.md +327 -0
- package/kits/coder/agents/project-planner.md +277 -0
- package/kits/coder/agents/queue-specialist.md +282 -0
- package/kits/coder/agents/realtime-specialist.md +267 -0
- package/kits/coder/agents/security-auditor.md +253 -0
- package/kits/coder/agents/test-engineer.md +315 -0
- package/kits/coder/agents/ux-researcher.md +388 -0
- package/kits/coder/rules/.cursorrules +287 -0
- package/kits/coder/rules/CLAUDE.md +287 -0
- package/kits/coder/rules/CODEX.md +287 -0
- package/kits/coder/rules/GEMINI.md +287 -0
- package/kits/coder/scripts/checklist.py +318 -0
- package/kits/coder/scripts/kit_status.py +292 -0
- package/kits/coder/scripts/skills_manager.py +243 -0
- package/kits/coder/scripts/verify_all.py +391 -0
- package/kits/coder/skills/accessibility-patterns/SKILL.md +372 -0
- package/kits/coder/skills/accessibility-patterns/scripts/a11y_checker.py +211 -0
- package/kits/coder/skills/ai-rag-patterns/SKILL.md +444 -0
- package/kits/coder/skills/api-patterns/SKILL.md +316 -0
- package/kits/coder/skills/api-patterns/assets/.gitkeep +1 -0
- package/kits/coder/skills/api-patterns/references/deep-dive.md +21 -0
- package/kits/coder/skills/api-patterns/scripts/api_validator.py +253 -0
- package/kits/coder/skills/api-patterns/scripts/validate.py +56 -0
- package/kits/coder/skills/auth-patterns/SKILL.md +267 -0
- package/kits/coder/skills/aws-patterns/SKILL.md +576 -0
- package/kits/coder/skills/brainstorming/SKILL.md +370 -0
- package/kits/coder/skills/brainstorming/assets/.gitkeep +1 -0
- package/kits/coder/skills/brainstorming/references/deep-dive.md +21 -0
- package/kits/coder/skills/brainstorming/scripts/validate.py +56 -0
- package/kits/coder/skills/clean-code/SKILL.md +240 -0
- package/kits/coder/skills/clean-code/assets/.gitkeep +1 -0
- package/kits/coder/skills/clean-code/references/deep-dive.md +21 -0
- package/kits/coder/skills/clean-code/scripts/lint_runner.py +186 -0
- package/kits/coder/skills/clean-code/scripts/validate.py +56 -0
- package/kits/coder/skills/database-design/SKILL.md +255 -0
- package/kits/coder/skills/database-design/assets/.gitkeep +1 -0
- package/kits/coder/skills/database-design/references/deep-dive.md +21 -0
- package/kits/coder/skills/database-design/scripts/schema_validator.py +272 -0
- package/kits/coder/skills/database-design/scripts/validate.py +56 -0
- package/kits/coder/skills/docker-patterns/SKILL.md +240 -0
- package/kits/coder/skills/documentation-templates/SKILL.md +441 -0
- package/kits/coder/skills/e2e-testing/SKILL.md +457 -0
- package/kits/coder/skills/flutter-patterns/SKILL.md +330 -0
- package/kits/coder/skills/frontend-design/SKILL.md +127 -0
- package/kits/coder/skills/github-actions/SKILL.md +349 -0
- package/kits/coder/skills/gitlab-ci-patterns/SKILL.md +466 -0
- package/kits/coder/skills/graphql-patterns/SKILL.md +558 -0
- package/kits/coder/skills/i18n-localization/SKILL.md +345 -0
- package/kits/coder/skills/i18n-localization/scripts/i18n_checker.py +267 -0
- package/kits/coder/skills/kubernetes-patterns/SKILL.md +357 -0
- package/kits/coder/skills/mermaid-diagrams/SKILL.md +351 -0
- package/kits/coder/skills/mobile-design/SKILL.md +305 -0
- package/kits/coder/skills/monitoring-observability/SKILL.md +458 -0
- package/kits/coder/skills/multi-tenancy/SKILL.md +317 -0
- package/kits/coder/skills/multi-tenancy/assets/.gitkeep +1 -0
- package/kits/coder/skills/multi-tenancy/references/deep-dive.md +21 -0
- package/kits/coder/skills/multi-tenancy/scripts/validate.py +56 -0
- package/kits/coder/skills/nodejs-best-practices/SKILL.md +220 -0
- package/kits/coder/skills/performance-profiling/SKILL.md +333 -0
- package/kits/coder/skills/performance-profiling/assets/.gitkeep +1 -0
- package/kits/coder/skills/performance-profiling/references/deep-dive.md +21 -0
- package/kits/coder/skills/performance-profiling/scripts/validate.py +56 -0
- package/kits/coder/skills/plan-writing/SKILL.md +360 -0
- package/kits/coder/skills/plan-writing/assets/.gitkeep +1 -0
- package/kits/coder/skills/plan-writing/references/deep-dive.md +21 -0
- package/kits/coder/skills/plan-writing/scripts/validate.py +56 -0
- package/kits/coder/skills/postgres-patterns/SKILL.md +361 -0
- package/kits/coder/skills/prompt-engineering/SKILL.md +277 -0
- package/kits/coder/skills/queue-patterns/SKILL.md +359 -0
- package/kits/coder/skills/queue-patterns/assets/.gitkeep +1 -0
- package/kits/coder/skills/queue-patterns/references/deep-dive.md +21 -0
- package/kits/coder/skills/queue-patterns/scripts/validate.py +56 -0
- package/kits/coder/skills/react-native-patterns/SKILL.md +393 -0
- package/kits/coder/skills/react-patterns/SKILL.md +319 -0
- package/kits/coder/skills/realtime-patterns/SKILL.md +506 -0
- package/kits/coder/skills/realtime-patterns/assets/.gitkeep +1 -0
- package/kits/coder/skills/realtime-patterns/references/deep-dive.md +21 -0
- package/kits/coder/skills/realtime-patterns/scripts/validate.py +56 -0
- package/kits/coder/skills/redis-patterns/SKILL.md +484 -0
- package/kits/coder/skills/security-fundamentals/SKILL.md +363 -0
- package/kits/coder/skills/security-fundamentals/assets/.gitkeep +1 -0
- package/kits/coder/skills/security-fundamentals/references/deep-dive.md +21 -0
- package/kits/coder/skills/security-fundamentals/scripts/security_scan.py +326 -0
- package/kits/coder/skills/security-fundamentals/scripts/validate.py +56 -0
- package/kits/coder/skills/seo-patterns/SKILL.md +262 -0
- package/kits/coder/skills/seo-patterns/scripts/seo_checker.py +211 -0
- package/kits/coder/skills/systematic-debugging/SKILL.md +478 -0
- package/kits/coder/skills/systematic-debugging/assets/.gitkeep +1 -0
- package/kits/coder/skills/systematic-debugging/references/deep-dive.md +21 -0
- package/kits/coder/skills/systematic-debugging/scripts/validate.py +56 -0
- package/kits/coder/skills/tailwind-patterns/SKILL.md +395 -0
- package/kits/coder/skills/terraform-patterns/SKILL.md +470 -0
- package/kits/coder/skills/testing-patterns/SKILL.md +285 -0
- package/kits/coder/skills/testing-patterns/assets/.gitkeep +1 -0
- package/kits/coder/skills/testing-patterns/references/deep-dive.md +21 -0
- package/kits/coder/skills/testing-patterns/scripts/test_runner.py +219 -0
- package/kits/coder/skills/testing-patterns/scripts/validate.py +56 -0
- package/kits/coder/skills/typescript-patterns/SKILL.md +417 -0
- package/kits/coder/skills/ui-ux-pro-max/SKILL.md +364 -0
- package/kits/coder/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/kits/coder/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/kits/coder/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/kits/coder/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/kits/coder/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/kits/coder/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/kits/coder/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/kits/coder/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/kits/coder/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/kits/coder/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/kits/coder/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/kits/coder/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-314.pyc +0 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-314.pyc +0 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/core.py +257 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/design_system.py +488 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/search.py +76 -0
- package/kits/coder/workflows/.gitkeep +20 -0
- package/kits/coder/workflows/create.md +152 -0
- package/kits/coder/workflows/debug.md +223 -0
- package/kits/coder/workflows/deploy.md +283 -0
- package/kits/coder/workflows/orchestrate.md +243 -0
- package/kits/coder/workflows/plan.md +134 -0
- package/kits/coder/workflows/test.md +237 -0
- package/kits/coder/workflows/ui-ux-pro-max.md +109 -0
- package/package.json +49 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flutter-patterns
|
|
3
|
+
description: Flutter development with Dart 3, widget composition, state management, and multi-platform deployment. Use when building mobile, web, desktop apps with Flutter. Covers Riverpod, Bloc, performance, and testing.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash
|
|
5
|
+
version: 1.0
|
|
6
|
+
priority: MEDIUM
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Flutter Patterns - Cross-Platform Development Excellence
|
|
10
|
+
|
|
11
|
+
> **Philosophy:** Build once, run anywhere with native performance. Widget composition over inheritance, const constructors everywhere.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 🎯 Core Principles
|
|
16
|
+
|
|
17
|
+
| Principle | Rule |
|
|
18
|
+
| ------------------ | ------------------------------------------------ |
|
|
19
|
+
| **Composition** | Compose widgets, don't inherit |
|
|
20
|
+
| **Immutability** | Use `const` constructors for optimal performance |
|
|
21
|
+
| **Null Safety** | Dart 3 null safety is mandatory |
|
|
22
|
+
| **Platform Aware** | One codebase, platform-specific polish |
|
|
23
|
+
| **Test First** | Widget tests, integration tests, golden tests |
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
❌ WRONG: Create God widgets with everything
|
|
27
|
+
✅ CORRECT: Small, focused, reusable widget compositions
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 📁 Project Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
lib/
|
|
36
|
+
├── app/ # App configuration
|
|
37
|
+
│ ├── router.dart # GoRouter configuration
|
|
38
|
+
│ └── theme.dart # Theme tokens
|
|
39
|
+
├── features/ # Feature modules
|
|
40
|
+
│ ├── auth/
|
|
41
|
+
│ │ ├── data/ # Repositories, data sources
|
|
42
|
+
│ │ ├── domain/ # Entities, use cases
|
|
43
|
+
│ │ └── presentation/ # Widgets, pages, state
|
|
44
|
+
│ └── home/
|
|
45
|
+
├── shared/ # Shared components
|
|
46
|
+
│ ├── widgets/ # Reusable UI components
|
|
47
|
+
│ ├── utils/ # Utilities
|
|
48
|
+
│ └── extensions/ # Dart extensions
|
|
49
|
+
└── main.dart # App entry point
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 🏗️ State Management Selection
|
|
55
|
+
|
|
56
|
+
| Solution | Best For | Complexity |
|
|
57
|
+
| ----------------- | --------------------------------- | ----------- |
|
|
58
|
+
| **Riverpod** | Medium-large apps, compile safety | Medium-High |
|
|
59
|
+
| **Bloc/Cubit** | Event-driven, testable flows | Medium |
|
|
60
|
+
| **Provider** | Simple apps, shared state | Low |
|
|
61
|
+
| **GetX** | Rapid prototyping | Low |
|
|
62
|
+
| **Flutter Hooks** | Simple local state | Low |
|
|
63
|
+
|
|
64
|
+
### Decision Tree
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
Need complex business logic?
|
|
68
|
+
├── Yes → Need event-driven architecture?
|
|
69
|
+
│ ├── Yes → Bloc
|
|
70
|
+
│ └── No → Riverpod
|
|
71
|
+
└── No → Simple state sharing?
|
|
72
|
+
├── Yes → Provider or Riverpod
|
|
73
|
+
└── No → setState or Hooks
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 📦 Riverpod Pattern (Recommended)
|
|
79
|
+
|
|
80
|
+
```dart
|
|
81
|
+
// providers/auth_provider.dart
|
|
82
|
+
@riverpod
|
|
83
|
+
class Auth extends _$Auth {
|
|
84
|
+
@override
|
|
85
|
+
AuthState build() => const AuthState.unauthenticated();
|
|
86
|
+
|
|
87
|
+
Future<void> signIn(String email, String password) async {
|
|
88
|
+
state = const AuthState.loading();
|
|
89
|
+
try {
|
|
90
|
+
final user = await ref.read(authRepositoryProvider).signIn(email, password);
|
|
91
|
+
state = AuthState.authenticated(user);
|
|
92
|
+
} catch (e) {
|
|
93
|
+
state = AuthState.error(e.toString());
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
Future<void> signOut() async {
|
|
98
|
+
await ref.read(authRepositoryProvider).signOut();
|
|
99
|
+
state = const AuthState.unauthenticated();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Usage in widget
|
|
104
|
+
class LoginPage extends ConsumerWidget {
|
|
105
|
+
@override
|
|
106
|
+
Widget build(BuildContext context, WidgetRef ref) {
|
|
107
|
+
final authState = ref.watch(authProvider);
|
|
108
|
+
|
|
109
|
+
return authState.when(
|
|
110
|
+
authenticated: (user) => HomePage(user: user),
|
|
111
|
+
unauthenticated: () => LoginForm(),
|
|
112
|
+
loading: () => const LoadingIndicator(),
|
|
113
|
+
error: (message) => ErrorDisplay(message: message),
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 🎨 Widget Patterns
|
|
122
|
+
|
|
123
|
+
### Const Constructor Rule
|
|
124
|
+
|
|
125
|
+
```dart
|
|
126
|
+
// ✅ GOOD - Const constructor
|
|
127
|
+
class ActionButton extends StatelessWidget {
|
|
128
|
+
const ActionButton({
|
|
129
|
+
super.key,
|
|
130
|
+
required this.label,
|
|
131
|
+
required this.onPressed,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
final String label;
|
|
135
|
+
final VoidCallback onPressed;
|
|
136
|
+
|
|
137
|
+
@override
|
|
138
|
+
Widget build(BuildContext context) {
|
|
139
|
+
return ElevatedButton(
|
|
140
|
+
onPressed: onPressed,
|
|
141
|
+
child: Text(label),
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ❌ BAD - No const constructor
|
|
147
|
+
class ActionButton extends StatelessWidget {
|
|
148
|
+
ActionButton({required this.label, required this.onPressed});
|
|
149
|
+
// ...
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Widget Keys
|
|
154
|
+
|
|
155
|
+
| Scenario | Key Type |
|
|
156
|
+
| -------------------------- | ----------------- |
|
|
157
|
+
| List items with unique IDs | `ValueKey(id)` |
|
|
158
|
+
| Animated list items | `ObjectKey(item)` |
|
|
159
|
+
| Form fields | `GlobalKey` |
|
|
160
|
+
| Never needs identity | No key |
|
|
161
|
+
|
|
162
|
+
```dart
|
|
163
|
+
ListView.builder(
|
|
164
|
+
itemBuilder: (context, index) {
|
|
165
|
+
final item = items[index];
|
|
166
|
+
return ProductCard(
|
|
167
|
+
key: ValueKey(item.id), // Stable identity
|
|
168
|
+
product: item,
|
|
169
|
+
);
|
|
170
|
+
},
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 🚀 Performance Optimization
|
|
177
|
+
|
|
178
|
+
### Widget Rebuild Prevention
|
|
179
|
+
|
|
180
|
+
| Technique | When to Use |
|
|
181
|
+
| -------------------- | ---------------------------------- |
|
|
182
|
+
| `const` constructors | Always when possible |
|
|
183
|
+
| `Consumer` widgets | Scope Riverpod rebuilds |
|
|
184
|
+
| `select` in Riverpod | Watch only needed parts |
|
|
185
|
+
| `RepaintBoundary` | Isolate expensive paint operations |
|
|
186
|
+
| `ListView.builder` | Large lists (virtualized) |
|
|
187
|
+
|
|
188
|
+
### Image Optimization
|
|
189
|
+
|
|
190
|
+
```dart
|
|
191
|
+
// Use cached_network_image
|
|
192
|
+
CachedNetworkImage(
|
|
193
|
+
imageUrl: url,
|
|
194
|
+
placeholder: (context, url) => const Shimmer(),
|
|
195
|
+
errorWidget: (context, url, error) => const Icon(Icons.error),
|
|
196
|
+
memCacheWidth: 300, // Limit memory cache size
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
// For assets, use appropriate resolution
|
|
200
|
+
Image.asset(
|
|
201
|
+
'assets/images/logo.png',
|
|
202
|
+
width: 100,
|
|
203
|
+
height: 100,
|
|
204
|
+
cacheWidth: 200, // 2x for retina
|
|
205
|
+
)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Isolates for Heavy Work
|
|
209
|
+
|
|
210
|
+
```dart
|
|
211
|
+
// Run CPU-intensive work in isolate
|
|
212
|
+
final result = await compute(heavyComputation, data);
|
|
213
|
+
|
|
214
|
+
// Or use Isolate.spawn for more control
|
|
215
|
+
Future<void> processLargeData(List<Data> data) async {
|
|
216
|
+
final receivePort = ReceivePort();
|
|
217
|
+
await Isolate.spawn(
|
|
218
|
+
_processInIsolate,
|
|
219
|
+
(data, receivePort.sendPort),
|
|
220
|
+
);
|
|
221
|
+
return await receivePort.first;
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 🧪 Testing Patterns
|
|
228
|
+
|
|
229
|
+
### Widget Tests
|
|
230
|
+
|
|
231
|
+
```dart
|
|
232
|
+
testWidgets('LoginForm submits credentials', (tester) async {
|
|
233
|
+
await tester.pumpWidget(
|
|
234
|
+
const ProviderScope(
|
|
235
|
+
child: MaterialApp(home: LoginForm()),
|
|
236
|
+
),
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
await tester.enterText(find.byKey(const Key('email')), 'test@email.com');
|
|
240
|
+
await tester.enterText(find.byKey(const Key('password')), 'password');
|
|
241
|
+
await tester.tap(find.text('Sign In'));
|
|
242
|
+
await tester.pump();
|
|
243
|
+
|
|
244
|
+
expect(find.byType(CircularProgressIndicator), findsOneWidget);
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Golden Tests
|
|
249
|
+
|
|
250
|
+
```dart
|
|
251
|
+
testWidgets('ProductCard matches golden', (tester) async {
|
|
252
|
+
await tester.pumpWidget(
|
|
253
|
+
const MaterialApp(
|
|
254
|
+
home: ProductCard(product: mockProduct),
|
|
255
|
+
),
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
await expectLater(
|
|
259
|
+
find.byType(ProductCard),
|
|
260
|
+
matchesGoldenFile('goldens/product_card.png'),
|
|
261
|
+
);
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 📱 Platform-Specific Code
|
|
268
|
+
|
|
269
|
+
```dart
|
|
270
|
+
// Use Platform for runtime checks
|
|
271
|
+
if (Platform.isIOS) {
|
|
272
|
+
// iOS-specific code
|
|
273
|
+
} else if (Platform.isAndroid) {
|
|
274
|
+
// Android-specific code
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Or use kIsWeb for web detection
|
|
278
|
+
if (kIsWeb) {
|
|
279
|
+
// Web-specific code
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Use .ios.dart / .android.dart for file-based separation
|
|
283
|
+
// lib/widgets/button.dart -> Default
|
|
284
|
+
// lib/widgets/button.ios.dart -> iOS override
|
|
285
|
+
// lib/widgets/button.android.dart -> Android override
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 🚨 Anti-Patterns
|
|
291
|
+
|
|
292
|
+
| ❌ Don't | ✅ Do |
|
|
293
|
+
| -------------------------------- | ------------------------------------- |
|
|
294
|
+
| Inherit from StatelessWidget/ful | Compose widgets |
|
|
295
|
+
| Skip `const` constructors | Add `const` everywhere possible |
|
|
296
|
+
| setState in large widgets | Use state management solution |
|
|
297
|
+
| Fetch data in build() | Use FutureBuilder or state management |
|
|
298
|
+
| Large build() methods | Extract smaller widget functions |
|
|
299
|
+
| Hardcode colors/sizes | Use Theme and design tokens |
|
|
300
|
+
| Skip null safety | Embrace Dart 3 null safety |
|
|
301
|
+
| Test only happy paths | Test edge cases and errors |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## ✅ Self-Check Before Completing
|
|
306
|
+
|
|
307
|
+
| Check | Question |
|
|
308
|
+
| ------------------- | --------------------------------------- |
|
|
309
|
+
| ✅ **Const?** | Are const constructors used everywhere? |
|
|
310
|
+
| ✅ **Keys?** | Do list items have stable keys? |
|
|
311
|
+
| ✅ **State?** | Is state management properly scoped? |
|
|
312
|
+
| ✅ **Null safe?** | Is null safety properly handled? |
|
|
313
|
+
| ✅ **Tested?** | Are widgets and logic tested? |
|
|
314
|
+
| ✅ **Platform?** | Tested on both iOS and Android? |
|
|
315
|
+
| ✅ **Performance?** | No jank, smooth scrolling? |
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## 🔗 Related Skills
|
|
320
|
+
|
|
321
|
+
| Need | Skill |
|
|
322
|
+
| ----------------------- | ----------------------- |
|
|
323
|
+
| React Native comparison | `react-native-patterns` |
|
|
324
|
+
| Mobile design | `mobile-design` |
|
|
325
|
+
| Testing patterns | `testing-patterns` |
|
|
326
|
+
| Performance profiling | `performance-profiling` |
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
> **Remember:** Flutter's power is in composition. Small, focused widgets that compose together create maintainable, testable, and performant apps.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-design
|
|
3
|
+
description: Design thinking for web UI. Color theory, typography, spacing, layouts, micro-interactions.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Frontend Design Patterns
|
|
8
|
+
|
|
9
|
+
> Design is how it works.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Core Principles
|
|
14
|
+
|
|
15
|
+
1. **Hierarchy matters** - Guide the eye with visual weight
|
|
16
|
+
2. **Consistency builds trust** - Same patterns, same meanings
|
|
17
|
+
3. **Space is content** - Whitespace is intentional
|
|
18
|
+
4. **Motion has meaning** - Animate purposefully
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🎨 Color System
|
|
23
|
+
|
|
24
|
+
### Palette Structure
|
|
25
|
+
|
|
26
|
+
| Role | Use Case |
|
|
27
|
+
| --------- | --------------------------- |
|
|
28
|
+
| Primary | CTAs, links, brand elements |
|
|
29
|
+
| Secondary | Supporting elements |
|
|
30
|
+
| Neutral | Text, borders, backgrounds |
|
|
31
|
+
| Success | Confirmations, completed |
|
|
32
|
+
| Warning | Caution, pending |
|
|
33
|
+
| Error | Errors, destructive actions |
|
|
34
|
+
|
|
35
|
+
### Contrast (WCAG)
|
|
36
|
+
|
|
37
|
+
| Level | Normal Text | Large Text |
|
|
38
|
+
| ----- | ----------- | ---------- |
|
|
39
|
+
| AA | 4.5:1 | 3:1 |
|
|
40
|
+
| AAA | 7:1 | 4.5:1 |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 📝 Typography
|
|
45
|
+
|
|
46
|
+
### Type Scale
|
|
47
|
+
|
|
48
|
+
| Name | Size | Line Height | Use Case |
|
|
49
|
+
| ---- | -------- | ----------- | --------------- |
|
|
50
|
+
| xs | 0.75rem | 1.5 | Labels |
|
|
51
|
+
| sm | 0.875rem | 1.5 | Secondary text |
|
|
52
|
+
| base | 1rem | 1.6 | Body text |
|
|
53
|
+
| lg | 1.125rem | 1.5 | Lead paragraphs |
|
|
54
|
+
| xl | 1.25rem | 1.4 | Card titles |
|
|
55
|
+
| 2xl | 1.5rem | 1.3 | Section headers |
|
|
56
|
+
| 3xl | 1.875rem | 1.2 | Page titles |
|
|
57
|
+
|
|
58
|
+
### Rules
|
|
59
|
+
|
|
60
|
+
- Body line length: 60-75 characters
|
|
61
|
+
- Body line height: 1.5-1.7
|
|
62
|
+
- Max 2 font families
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 📐 Spacing (8pt Grid)
|
|
67
|
+
|
|
68
|
+
| Token | Value | Use Case |
|
|
69
|
+
| ----- | ----- | ---------------- |
|
|
70
|
+
| 1 | 4px | Tight grouping |
|
|
71
|
+
| 2 | 8px | Related items |
|
|
72
|
+
| 4 | 16px | Standard spacing |
|
|
73
|
+
| 6 | 24px | Section gaps |
|
|
74
|
+
| 8 | 32px | Major sections |
|
|
75
|
+
| 12 | 48px | Page sections |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 📊 Layout Patterns
|
|
80
|
+
|
|
81
|
+
| Pattern | Description |
|
|
82
|
+
| ---------- | ----------------------------- |
|
|
83
|
+
| Holy Grail | Header, footer, 3-col middle |
|
|
84
|
+
| Sidebar | Fixed sidebar + fluid content |
|
|
85
|
+
| Dashboard | Sidebar nav + header + grid |
|
|
86
|
+
| Cards | Auto-filling responsive grid |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## ✨ Micro-Interactions
|
|
91
|
+
|
|
92
|
+
| Principle | Implementation |
|
|
93
|
+
| --------- | -------------------------------- |
|
|
94
|
+
| Duration | 150-300ms for interactions |
|
|
95
|
+
| Easing | ease-out for enter, ease-in exit |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 🧩 Button Hierarchy
|
|
100
|
+
|
|
101
|
+
| Type | Use Case | Style |
|
|
102
|
+
| ----------- | -------------- | ----------------- |
|
|
103
|
+
| Primary | Main action | Filled, brand |
|
|
104
|
+
| Secondary | Supporting | Outlined |
|
|
105
|
+
| Tertiary | Less important | Text only |
|
|
106
|
+
| Destructive | Delete | Red, with confirm |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## ❌ Anti-Patterns
|
|
111
|
+
|
|
112
|
+
| Don't | Do |
|
|
113
|
+
| ------------------------ | -------------------- |
|
|
114
|
+
| Low contrast text | WCAG AA minimum |
|
|
115
|
+
| More than 3 fonts | 1-2 fonts |
|
|
116
|
+
| Inconsistent spacing | Use spacing tokens |
|
|
117
|
+
| Animation for decoration | Animate purposefully |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 🔗 Related Skills
|
|
122
|
+
|
|
123
|
+
- `ui-ux-pro-max` - Design system generator (search + recommend)
|
|
124
|
+
- `react-patterns` - React components
|
|
125
|
+
- `tailwind-patterns` - Tailwind CSS
|
|
126
|
+
- `accessibility-patterns` - Accessibility
|
|
127
|
+
- `mobile-design` - Mobile design
|