flutter-pro-max-cli 2.3.0 → 2.3.2

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.
Files changed (38) hide show
  1. package/assets/templates/base/rules/01_skill_usage.md +22 -0
  2. package/assets/templates/base/rules/02_code_quality.md +50 -0
  3. package/assets/templates/base/rules/03_interaction_flow.md +21 -0
  4. package/assets/templates/base/rules/04_app_consistency.md +58 -0
  5. package/assets/templates/base/rules/05_error_handling.md +43 -0
  6. package/assets/templates/base/rules/06_testing.md +48 -0
  7. package/assets/templates/base/rules/07_performance.md +47 -0
  8. package/assets/templates/base/rules/08_security.md +41 -0
  9. package/assets/templates/base/rules/09_state_management.md +54 -0
  10. package/assets/templates/base/rules/10_naming_conventions.md +70 -0
  11. package/assets/templates/base/rules/11_accessibility.md +56 -0
  12. package/assets/templates/base/skill-content-10k.md +40 -206
  13. package/assets/templates/base/skill-content-4k.md +9 -95
  14. package/assets/templates/base/skill-content.md +33 -371
  15. package/assets/templates/platforms/agent.json +6 -2
  16. package/assets/templates/platforms/claude.json +5 -1
  17. package/assets/templates/platforms/codebuddy.json +6 -2
  18. package/assets/templates/platforms/codex.json +6 -2
  19. package/assets/templates/platforms/continue.json +6 -2
  20. package/assets/templates/platforms/copilot.json +6 -2
  21. package/assets/templates/platforms/cursor.json +6 -2
  22. package/assets/templates/platforms/gemini.json +6 -2
  23. package/assets/templates/platforms/junie.json +6 -2
  24. package/assets/templates/platforms/kiro.json +6 -2
  25. package/assets/templates/platforms/opencode.json +6 -2
  26. package/assets/templates/platforms/qoder.json +6 -2
  27. package/assets/templates/platforms/roocode.json +6 -2
  28. package/assets/templates/platforms/trae.json +6 -2
  29. package/assets/templates/platforms/vscode.json +6 -2
  30. package/assets/templates/platforms/windsurf.json +6 -2
  31. package/dist/types/index.d.ts +4 -0
  32. package/dist/utils/extract.d.ts +8 -2
  33. package/dist/utils/extract.js +125 -0
  34. package/dist/utils/template.js +50 -1
  35. package/package.json +1 -1
  36. package/LICENSE +0 -21
  37. package/assets/scripts/__pycache__/core.cpython-312.pyc +0 -0
  38. package/assets/scripts/__pycache__/design_system.cpython-312.pyc +0 -0
@@ -0,0 +1,22 @@
1
+ # Rule: Tự động sử dụng Skill
2
+
3
+ > Kích hoạt: Khi làm việc với Flutter/Dart files
4
+
5
+ **TRƯỚC KHI viết code Flutter**, bạn PHẢI tự động sử dụng skill để lấy knowledge phù hợp. Không được bỏ qua bước này.
6
+
7
+ | Tình huống | Domains cần search |
8
+ |------------|-------------------|
9
+ | Tạo UI/Screen mới | `style`, `pattern`, `color`, `typography`, `landing` |
10
+ | Chọn package/thư viện | `package` (kèm `--stack` filter nếu có) |
11
+ | Thiết kế kiến trúc | `architect`, `pattern` |
12
+ | Tối ưu performance | `performance` |
13
+ | Accessibility | `accessibility` |
14
+ | Không chắc UI style | Dùng `--design-system` để generate design system |
15
+
16
+ **Workflow bắt buộc:**
17
+
18
+ ```
19
+ User request → Search skill (≥2 domains) → Đọc kết quả → Áp dụng vào code
20
+ ```
21
+
22
+ > ⚠️ Viết code Flutter mà không tham khảo skill trước = thiếu context = code chất lượng thấp.
@@ -0,0 +1,50 @@
1
+ # Rule: Code Quality & Hard Constraints
2
+
3
+ > Kích hoạt: Khi tạo/chỉnh sửa files `.dart`
4
+
5
+ ## Think-Before-Code Protocol
6
+
7
+ **TRƯỚC KHI tạo file mới hoặc viết widget**, bạn PHẢI trả lời 5 câu hỏi:
8
+
9
+ 1. **File này có vượt 300 dòng không?** → Nếu có khả năng, TÁCH ngay từ đầu
10
+ 2. **Widget/Component này đã tồn tại chưa?** → Search codebase trước, REUSE nếu có
11
+ 3. **Widget này có thể reuse cho nơi khác không?** → Nếu có, đặt vào `core/widgets/` hoặc shared folder
12
+ 4. **Logic này thuộc layer nào?** → UI / Domain / Data — KHÔNG được trộn layers
13
+ 5. **Có widget/hàm nào đang lặp logic tương tự không?** → Nếu có, REFACTOR thành shared component
14
+
15
+ ## Hard Constraints (Vùng Cấm)
16
+
17
+ ### 🚫 NO GOD CLASSES
18
+
19
+ | Indicator | Threshold | Action |
20
+ |-----------|-----------|--------|
21
+ | Public methods | > 10 methods | 🔴 **REFACTOR** |
22
+ | Lines of logic | > 200 lines | 🔴 **REFACTOR** |
23
+ | Mixed concerns | Logic + UI + DB | 🔴 **TÁCH NGAY** |
24
+
25
+ ### 🚫 NO GOD FILES
26
+
27
+ | Rule | Limit |
28
+ |------|-------|
29
+ | **File size** | ≤ 300 dòng (tối đa 500) |
30
+ | **Classes per file** | 1 Class chính duy nhất |
31
+
32
+ ### 🚫 NO LOGIC LEAKAGE
33
+
34
+ | Violation | Correct Layer |
35
+ |-----------|---------------|
36
+ | Business Logic trong Widget | ➜ Move to `UseCase` / `Service` |
37
+ | SQL/Query trong Controller | ➜ Move to `Repository` |
38
+ | API calls trong UI | ➜ Move to `DataSource` |
39
+
40
+ ## Nguyên tắc cứng
41
+
42
+ | ❌ Sai | ✅ Đúng |
43
+ |--------|---------|
44
+ | Tạo `UserCard` mới khi đã có `ProfileCard` tương tự | Mở rộng `ProfileCard` hoặc extract shared `BaseCard` |
45
+ | Screen 500+ dòng | Tách thành `_HeaderSection`, `_ContentBody`, `_ActionBar` |
46
+ | 3 screens cùng copy-paste search bar | Tạo `SearchableScaffold` dùng chung |
47
+ | Hardcode colors, padding, font sizes | Dùng `Theme.of(context)`, design tokens, constants |
48
+ | Business logic trong Widget `build()` | Tách vào UseCase / Service / Provider |
49
+
50
+ > 🔴 **REUSE > CREATE.** Không bao giờ tạo file mới mà không kiểm tra codebase hiện tại trước.
@@ -0,0 +1,21 @@
1
+ # Rule: Interaction Flow (ABCR)
2
+
3
+ > Kích hoạt: Khi review, refactor, hoặc fix bugs
4
+
5
+ Khi nhận request liên quan đến code hiện tại, luôn tuân thủ quy trình:
6
+
7
+ 1. **AUDIT** - Quét code smells, kiểm tra God Class/File
8
+ 2. **BLOCK** - Cảnh báo nếu vi phạm, giải thích Technical Debt
9
+ 3. **REFACTOR** - Sửa kiến trúc trước khi fix bug
10
+ 4. **EXPLAIN** - Giải thích lý do tách/refactor
11
+
12
+ ### Khi nào áp dụng ABCR?
13
+
14
+ | Tình huống | Áp dụng? |
15
+ |------------|----------|
16
+ | User yêu cầu fix bug | ✅ AUDIT trước, refactor nếu có code smell |
17
+ | User yêu cầu thêm feature | ✅ AUDIT file đích trước khi thêm code |
18
+ | User yêu cầu tạo file mới | ⚠️ Chỉ AUDIT các file liên quan |
19
+ | User hỏi kiến thức chung | ❌ Không cần ABCR |
20
+
21
+ > 💡 **Mục đích:** Không bao giờ thêm code rác lên code rác. Fix nền tảng trước.
@@ -0,0 +1,58 @@
1
+ # Rule: App Consistency
2
+
3
+ > Kích hoạt: Khi tạo UI, thêm screen, hoặc chỉnh sửa widget
4
+
5
+ ## Nguyên tắc: Mọi thứ phải nhất quán
6
+
7
+ **TRƯỚC KHI viết UI code**, bạn PHẢI kiểm tra các pattern hiện có trong project để đảm bảo consistency.
8
+
9
+ ## 1. Design Tokens — Dùng chung, không hardcode
10
+
11
+ | ❌ Sai | ✅ Đúng |
12
+ |--------|---------|
13
+ | `Color(0xFF1A73E8)` | `Theme.of(context).colorScheme.primary` |
14
+ | `EdgeInsets.all(16)` | `EdgeInsets.all(AppSpacing.md)` hoặc constant |
15
+ | `TextStyle(fontSize: 14)` | `Theme.of(context).textTheme.bodyMedium` |
16
+ | `BorderRadius.circular(8)` | `BorderRadius.circular(AppRadius.sm)` |
17
+ | `Duration(milliseconds: 300)` | `AppDurations.normal` |
18
+
19
+ ## 2. Widget Patterns — Copy style từ existing screens
20
+
21
+ **TRƯỚC KHI tạo screen mới:**
22
+
23
+ 1. Tìm screen tương tự trong codebase (list, detail, form, dashboard)
24
+ 2. Sao chép cấu trúc, spacing, và layout pattern
25
+ 3. Dùng cùng widget wrappers (Scaffold, AppBar style, padding)
26
+
27
+ | Element | Quy tắc |
28
+ |---------|---------|
29
+ | **AppBar** | Dùng chung 1 style/component cho toàn app |
30
+ | **Empty States** | Dùng chung widget, không tạo mới mỗi screen |
31
+ | **Loading States** | Dùng chung shimmer/skeleton, không mỗi chỗ 1 kiểu |
32
+ | **Error States** | Dùng chung error widget với retry action |
33
+ | **List Items** | Cùng padding, divider style, tap behavior |
34
+ | **Forms** | Cùng validation style, field spacing, button placement |
35
+ | **Dialogs** | Cùng shape, padding, button alignment |
36
+
37
+ ## 3. Navigation & Transitions
38
+
39
+ - Dùng chung transition animations (không mỗi screen 1 kiểu)
40
+ - Consistent back button behavior
41
+ - Cùng pattern cho bottom sheets, modals, popups
42
+
43
+ ## 4. Spacing System
44
+
45
+ Định nghĩa và tuân thủ spacing scale:
46
+
47
+ ```dart
48
+ // ✅ Dùng constants
49
+ abstract class AppSpacing {
50
+ static const double xs = 4;
51
+ static const double sm = 8;
52
+ static const double md = 16;
53
+ static const double lg = 24;
54
+ static const double xl = 32;
55
+ }
56
+ ```
57
+
58
+ > 🔴 **Khi có nghi ngờ:** Mở screen hiện tại có cùng chức năng → copy exact spacing và layout pattern. **Không sáng tạo riêng.**
@@ -0,0 +1,43 @@
1
+ # Rule: Error Handling
2
+
3
+ > Kích hoạt: Khi viết logic xử lý dữ liệu, API calls, hoặc async operations
4
+
5
+ ## Nguyên tắc: Không bao giờ fail im lặng
6
+
7
+ ### Bắt buộc
8
+
9
+ | Tình huống | Cách xử lý |
10
+ |------------|------------|
11
+ | API call | Luôn wrap trong `try-catch`, log lỗi, hiển thị message cho user |
12
+ | Parse JSON/data | Dùng `tryParse` hoặc `try-catch`, KHÔNG để crash |
13
+ | File I/O | Handle `FileSystemException` cụ thể |
14
+ | Navigation args | Validate params trước khi dùng |
15
+
16
+ ### Pattern chuẩn
17
+
18
+ ```dart
19
+ // ✅ Structured error handling
20
+ Future<Result<User>> fetchUser(String id) async {
21
+ try {
22
+ final response = await api.getUser(id);
23
+ return Result.success(User.fromJson(response));
24
+ } on DioException catch (e) {
25
+ developer.log('API failed', name: 'user.fetch', error: e);
26
+ return Result.failure(e.toAppError());
27
+ } catch (e, s) {
28
+ developer.log('Unexpected', name: 'user.fetch', error: e, stackTrace: s);
29
+ return Result.failure(AppError.unexpected(e));
30
+ }
31
+ }
32
+ ```
33
+
34
+ ### Cấm
35
+
36
+ | ❌ Sai | Lý do |
37
+ |--------|-------|
38
+ | `catch (e) {}` (empty catch) | Nuốt lỗi, debug nightmare |
39
+ | `print(e)` | Dùng `developer.log()` thay vì print |
40
+ | Throw generic `Exception('Error')` | Tạo custom exceptions có context |
41
+ | Ignore `StackTrace` | Luôn log cả `stackTrace` để debug |
42
+
43
+ > 🔴 **Mỗi `try` phải có `catch` có ý nghĩa.** Log + User message + Recovery action.
@@ -0,0 +1,48 @@
1
+ # Rule: Testing
2
+
3
+ > Kích hoạt: Khi tạo feature mới, fix bug, hoặc refactor logic
4
+
5
+ ## Nguyên tắc: Không có test = Không hoàn thành
6
+
7
+ ### Khi nào PHẢI viết test
8
+
9
+ | Loại code | Test bắt buộc | Ví dụ |
10
+ |-----------|---------------|-------|
11
+ | Business logic | Unit test | UseCase, Service, Validator |
12
+ | Repository/DataSource | Unit test với mock | API calls, DB queries |
13
+ | Widget có logic | Widget test | Form validation, state changes |
14
+ | User flow quan trọng | Integration test | Login, checkout, onboarding |
15
+
16
+ ### Khi nào KHÔNG cần test
17
+
18
+ - Pure UI widget không có logic (chỉ layout/styling)
19
+ - Generated code (`.g.dart`, `.freezed.dart`)
20
+ - Constants, enums đơn giản
21
+
22
+ ### Pattern chuẩn
23
+
24
+ ```dart
25
+ // ✅ Test structure: Arrange → Act → Assert
26
+ test('should return user when API succeeds', () async {
27
+ // Arrange
28
+ when(mockApi.getUser('123')).thenAnswer(
29
+ (_) async => {'name': 'John'},
30
+ );
31
+
32
+ // Act
33
+ final result = await useCase.execute('123');
34
+
35
+ // Assert
36
+ expect(result, isA<Success<User>>());
37
+ expect(result.data.name, equals('John'));
38
+ });
39
+ ```
40
+
41
+ ### Quy tắc
42
+
43
+ - File test đặt cùng tên: `user_service.dart` → `user_service_test.dart`
44
+ - Dùng `package:mocktail` hoặc `package:mockito` cho mocking
45
+ - Mỗi test case chỉ test 1 behavior
46
+ - Tên test mô tả behavior: `should [expected] when [condition]`
47
+
48
+ > 🔴 **Fix bug?** Viết test reproduce bug TRƯỚC, rồi mới fix.
@@ -0,0 +1,47 @@
1
+ # Rule: Performance
2
+
3
+ > Kích hoạt: Khi viết widget, xử lý danh sách, hoặc async operations
4
+
5
+ ## Nguyên tắc: Performance là requirement, không phải nice-to-have
6
+
7
+ ### Widget Performance
8
+
9
+ | ❌ Sai | ✅ Đúng | Impact |
10
+ |--------|---------|--------|
11
+ | `Container()` cho spacing | `const SizedBox(height: 16)` | Giảm rebuild |
12
+ | `ListView(children: [...])` | `ListView.builder(itemBuilder:)` | Lazy loading |
13
+ | Widget không có `const` | `const MyWidget()` | Prevent rebuild |
14
+ | Inline function trong `build()` | Extract method hoặc cached | Tránh tạo closure mỗi frame |
15
+ | Rebuild toàn tree | `ValueListenableBuilder` scoped | Chỉ rebuild phần thay đổi |
16
+
17
+ ### Async & Computation
18
+
19
+ | Quy tắc | Lý do |
20
+ |----------|-------|
21
+ | KHÔNG gọi API/async trong `build()` | Block UI thread |
22
+ | Heavy JSON parsing → dùng `compute()` | Chạy trên isolate riêng |
23
+ | Image caching → dùng `CachedNetworkImage` | Tránh download lại |
24
+ | Debounce search input (300-500ms) | Giảm API calls |
25
+
26
+ ### State Management Performance
27
+
28
+ ```dart
29
+ // ❌ Toàn widget tree rebuild
30
+ setState(() => _counter++);
31
+
32
+ // ✅ Chỉ rebuild phần cần thiết
33
+ ValueListenableBuilder<int>(
34
+ valueListenable: _counter,
35
+ builder: (_, value, child) => Text('$value'),
36
+ child: const ExpensiveWidget(), // Không bị rebuild
37
+ );
38
+ ```
39
+
40
+ ### Checklist trước ship
41
+
42
+ - [ ] Tất cả widget có `const` constructor nếu có thể
43
+ - [ ] ListView/GridView dùng `.builder` hoặc `.separated`
44
+ - [ ] Không có `print()` còn sót (dùng `developer.log`)
45
+ - [ ] Images có loading/error builders
46
+
47
+ > 🔴 **Nếu list > 20 items → BẮT BUỘC dùng `.builder`.** Không exceptions.
@@ -0,0 +1,41 @@
1
+ # Rule: Security
2
+
3
+ > Kích hoạt: Khi xử lý authentication, API keys, user data, hoặc storage
4
+
5
+ ## Nguyên tắc: Bảo mật không phải optional
6
+
7
+ ### API Keys & Secrets
8
+
9
+ | ❌ KHÔNG BAO GIỜ | ✅ Thay bằng |
10
+ |-------------------|-------------|
11
+ | Hardcode API key trong source | Dùng `--dart-define` hoặc `.env` |
12
+ | Commit `.env` file | Thêm vào `.gitignore` |
13
+ | Log sensitive data | Mask/redact trước khi log |
14
+ | Lưu token trong `SharedPreferences` | Dùng `flutter_secure_storage` |
15
+
16
+ ### Authentication
17
+
18
+ | Quy tắc | Chi tiết |
19
+ |----------|----------|
20
+ | Token storage | `flutter_secure_storage` (encrypted) |
21
+ | Token refresh | Interceptor tự động refresh khi 401 |
22
+ | Logout | Clear ALL tokens + secure storage |
23
+ | Deep link auth | Validate state parameter |
24
+
25
+ ### Data Protection
26
+
27
+ | Tình huống | Xử lý |
28
+ |------------|-------|
29
+ | User input | Sanitize trước khi gửi API |
30
+ | Hiển thị PII (email, phone) | Mask một phần: `john***@gmail.com` |
31
+ | Cache sensitive data | Encrypt hoặc không cache |
32
+ | Screenshot prevention | `FLAG_SECURE` cho screens nhạy cảm |
33
+
34
+ ### Network Security
35
+
36
+ - HTTPS only (không HTTP)
37
+ - Certificate pinning cho apps quan trọng
38
+ - Timeout cho mọi API call (30s max)
39
+ - Không trust user input từ deep links
40
+
41
+ > 🔴 **Mỗi lần thêm API key hay xử lý auth**, kiểm tra checklist trên.
@@ -0,0 +1,54 @@
1
+ # Rule: State Management
2
+
3
+ > Kích hoạt: Khi quản lý state trong widget, screen, hoặc app-level
4
+
5
+ ## Nguyên tắc: Native-First, Escalate khi cần
6
+
7
+ ### Hierarchy (Ưu tiên từ trên xuống)
8
+
9
+ | Level | Giải pháp | Khi nào dùng |
10
+ |-------|-----------|-------------|
11
+ | 1️⃣ | `StatelessWidget` | UI tĩnh, không có state |
12
+ | 2️⃣ | `ValueNotifier` + `ValueListenableBuilder` | State đơn giản (counter, toggle, loading) |
13
+ | 3️⃣ | `ChangeNotifier` + `ListenableBuilder` | State phức tạp có nhiều fields (form, cart) |
14
+ | 4️⃣ | `InheritedWidget` / `Provider` | Shared state giữa nhiều widgets |
15
+ | 5️⃣ | Riverpod / Bloc | **CHỈ KHI user yêu cầu rõ ràng** |
16
+
17
+ ### Quy tắc cứng
18
+
19
+ | ❌ Sai | ✅ Đúng |
20
+ |--------|---------|
21
+ | Dùng Riverpod cho counter đơn giản | `ValueNotifier<int>` |
22
+ | `setState` rebuild toàn screen | `ValueListenableBuilder` scoped |
23
+ | Global state cho state chỉ 1 screen dùng | Local state trong widget |
24
+ | Mutable state trực tiếp | Immutable state + `copyWith` |
25
+
26
+ ### Pattern chuẩn
27
+
28
+ ```dart
29
+ // ✅ Simple: ValueNotifier
30
+ class CounterWidget extends StatelessWidget {
31
+ final _count = ValueNotifier<int>(0);
32
+
33
+ @override
34
+ Widget build(BuildContext context) {
35
+ return ValueListenableBuilder<int>(
36
+ valueListenable: _count,
37
+ builder: (_, value, __) => Text('$value'),
38
+ );
39
+ }
40
+ }
41
+
42
+ // ✅ Complex: ChangeNotifier
43
+ class CartNotifier extends ChangeNotifier {
44
+ final List<Item> _items = [];
45
+ List<Item> get items => List.unmodifiable(_items);
46
+
47
+ void add(Item item) {
48
+ _items.add(item);
49
+ notifyListeners();
50
+ }
51
+ }
52
+ ```
53
+
54
+ > ⚠️ **KHÔNG tự ý thêm Riverpod/Bloc/GetX.** Hỏi user trước nếu cần escalate.
@@ -0,0 +1,70 @@
1
+ # Rule: Naming & Conventions
2
+
3
+ > Kích hoạt: Khi tạo files, classes, functions, hoặc variables
4
+
5
+ ## Nguyên tắc: Tên phải tự giải thích, cấu trúc phải nhất quán
6
+
7
+ ### Naming Convention
8
+
9
+ | Element | Convention | Ví dụ |
10
+ |---------|-----------|-------|
11
+ | Files | `snake_case` | `user_profile_page.dart` |
12
+ | Classes | `PascalCase` | `UserProfilePage` |
13
+ | Functions/Methods | `camelCase` | `fetchUserProfile()` |
14
+ | Variables | `camelCase` | `userName`, `isLoading` |
15
+ | Constants | `camelCase` hoặc `SCREAMING_SNAKE` | `maxRetryCount`, `API_BASE_URL` |
16
+ | Private | Prefix `_` | `_buildHeader()`, `_items` |
17
+ | Enums | `PascalCase` values | `UserRole.admin` |
18
+
19
+ ### File Naming theo Layer
20
+
21
+ | Layer | Pattern | Ví dụ |
22
+ |-------|---------|-------|
23
+ | Page/Screen | `*_page.dart` | `login_page.dart` |
24
+ | Widget | `*_widget.dart` hoặc tên mô tả | `user_avatar.dart` |
25
+ | Model | `*_model.dart` | `user_model.dart` |
26
+ | Repository | `*_repository.dart` | `auth_repository.dart` |
27
+ | Service/UseCase | `*_service.dart` / `*_use_case.dart` | `auth_service.dart` |
28
+ | Provider/Notifier | `*_provider.dart` / `*_notifier.dart` | `cart_notifier.dart` |
29
+ | Extension | `*_extension.dart` | `string_extension.dart` |
30
+
31
+ ### Folder Structure
32
+
33
+ ```
34
+ lib/
35
+ ├── core/ # Shared: theme, utils, widgets, constants
36
+ │ ├── theme/
37
+ │ ├── widgets/ # Reusable widgets
38
+ │ ├── utils/
39
+ │ └── constants/
40
+ ├── features/ # Feature-first organization
41
+ │ ├── auth/
42
+ │ │ ├── data/ # Repository implementations, models
43
+ │ │ ├── domain/ # Entities, use cases, repo interfaces
44
+ │ │ └── presentation/ # Pages, widgets, notifiers
45
+ │ └── home/
46
+ └── main.dart
47
+ ```
48
+
49
+ ### Git Commit Convention
50
+
51
+ ```
52
+ <type>(<scope>): <description>
53
+
54
+ feat(auth): add biometric login support
55
+ fix(cart): resolve item count not updating
56
+ refactor(core): extract shared AppBar widget
57
+ docs(readme): update installation guide
58
+ test(auth): add login use case unit tests
59
+ ```
60
+
61
+ | Type | Khi nào |
62
+ |------|---------|
63
+ | `feat` | Feature mới |
64
+ | `fix` | Sửa bug |
65
+ | `refactor` | Restructure code, không đổi behavior |
66
+ | `docs` | Documentation only |
67
+ | `test` | Thêm/sửa tests |
68
+ | `chore` | Config, dependencies, tooling |
69
+
70
+ > 🔴 **Đặt tên file/class sai convention?** Rename ngay, không để nợ.
@@ -0,0 +1,56 @@
1
+ # Rule: Accessibility
2
+
3
+ > Kích hoạt: Khi tạo UI, interactive elements, hoặc form inputs
4
+
5
+ ## Nguyên tắc: App phải dùng được cho MỌI NGƯỜI
6
+
7
+ ### Bắt buộc cho mọi widget
8
+
9
+ | Requirement | Standard | Cách check |
10
+ |-------------|----------|------------|
11
+ | **Contrast** | Minimum 4.5:1 cho text | Dùng contrast checker tool |
12
+ | **Large Text** | Minimum 3:1 (18pt hoặc 14pt bold) | Visual check |
13
+ | **Touch Target** | Minimum 48x48dp | `SizedBox` wrapper nếu cần |
14
+ | **Semantics** | Label tất cả interactive elements | `Semantics()` widget |
15
+ | **Dynamic Scaling** | Hỗ trợ lên đến 200% font size | Test với `textScaleFactor` |
16
+
17
+ ### Code Patterns
18
+
19
+ ```dart
20
+ // ✅ Semantics cho interactive elements
21
+ Semantics(
22
+ label: 'Xóa sản phẩm khỏi giỏ hàng',
23
+ button: true,
24
+ child: IconButton(
25
+ icon: const Icon(Icons.delete),
26
+ onPressed: onDelete,
27
+ ),
28
+ );
29
+
30
+ // ✅ Form field accessible
31
+ TextFormField(
32
+ decoration: const InputDecoration(
33
+ labelText: 'Email', // Screen reader đọc được
34
+ hintText: 'example@email.com',
35
+ ),
36
+ );
37
+
38
+ // ✅ Image có description
39
+ Image.network(
40
+ url,
41
+ semanticLabel: 'Ảnh đại diện của người dùng',
42
+ );
43
+ ```
44
+
45
+ ### Checklist
46
+
47
+ | Element | Kiểm tra |
48
+ |---------|----------|
49
+ | Buttons/Icons | Có `tooltip` hoặc `Semantics.label` |
50
+ | Images | Có `semanticLabel` |
51
+ | Forms | Có `labelText`, không chỉ `hintText` |
52
+ | Alerts/Dialogs | Có title mô tả rõ |
53
+ | Navigation | Focus order hợp lý |
54
+ | Colors | Không dùng màu là cách duy nhất truyền thông tin |
55
+
56
+ > 🔴 **Mỗi `IconButton` PHẢI có `tooltip`.** Mỗi `Image` PHẢI có `semanticLabel`.