2026-02-05 15:13:06 +08:00
|
|
|
## Mobile Rules
|
|
|
|
|
|
2026-02-24 18:18:42 +08:00
|
|
|
- Flutter mobile rules are maintained here.
|
|
|
|
|
- If no more specific rule is defined here, follow the root `AGENTS.md`.
|
|
|
|
|
|
|
|
|
|
## Flutter Design-to-Code Workflow
|
|
|
|
|
|
|
|
|
|
Before writing any Flutter UI code, follow this sequence:
|
|
|
|
|
|
|
|
|
|
1. **Get editor state**: Use `pencil_get_editor_state` to confirm the active design.
|
|
|
|
|
2. **Get structure**: Use `pencil_batch_get` to inspect node hierarchy and layout.
|
|
|
|
|
3. **Get variables**: Use `pencil_get_variables` to fetch colors, typography, and tokens.
|
|
|
|
|
4. **Implement**: Match design values and container hierarchy exactly.
|
|
|
|
|
|
|
|
|
|
## Layout Mapping Rules
|
|
|
|
|
|
|
|
|
|
Map design layout properties to Flutter explicitly:
|
|
|
|
|
|
|
|
|
|
1. **Always set `crossAxisAlignment` on `Row`/`Column`**:
|
|
|
|
|
- `alignItems: center` -> `CrossAxisAlignment.center`
|
|
|
|
|
- `alignItems: start` -> `CrossAxisAlignment.start`
|
|
|
|
|
- `alignItems: stretch` -> `CrossAxisAlignment.stretch`
|
|
|
|
|
2. **Map full container chain**: From root to leaf, ensure each `alignItems` and `justifyContent` has a Flutter equivalent.
|
|
|
|
|
3. **Analyze before coding**: Use `pencil_snapshot_layout` or `pencil_batch_get` to verify each container's alignment settings.
|
|
|
|
|
|
|
|
|
|
## Centering and Visual Balance
|
|
|
|
|
|
|
|
|
|
Apply these rules on any screen that relies on centered composition:
|
|
|
|
|
|
|
|
|
|
1. Centering must be evaluated inside **`SafeArea` bounds**, not full-screen bounds.
|
|
|
|
|
2. Avoid relying on proportional `Spacer` values as the only centering mechanism for critical content.
|
|
|
|
|
3. For layouts with persistent top/bottom regions (for example headers or footers), center the primary content in the remaining available region.
|
|
|
|
|
4. Distinguish geometric centering from visual centering; validate final visual balance with screenshot review.
|
|
|
|
|
|
|
|
|
|
## Quality Gate
|
|
|
|
|
|
|
|
|
|
For important screens, add widget tests that reduce layout-regression risk:
|
|
|
|
|
|
|
|
|
|
1. Verify primary content remains centered relative to the usable viewport.
|
|
|
|
|
2. Add at least one constrained viewport scenario (small height or large text scale).
|
|
|
|
|
|
|
|
|
|
## Prohibitions
|
|
|
|
|
|
|
|
|
|
- Do not use colors or themes not defined in the design.
|
|
|
|
|
- Do not skip design container layers.
|
|
|
|
|
- Do not start implementation before retrieving design variables.
|
|
|
|
|
- Do not hardcode colors; use design variables.
|
2026-02-25 18:00:02 +08:00
|
|
|
|
|
|
|
|
## UI Feedback System
|
|
|
|
|
|
|
|
|
|
**MUST use the Toast system for all user feedback messages.**
|
|
|
|
|
|
|
|
|
|
### Components
|
|
|
|
|
|
|
|
|
|
| Component | Use Case | Example |
|
|
|
|
|
|-----------|----------|---------|
|
|
|
|
|
| `Toast.show()` | Global temporary notifications | Success/error feedback after action |
|
|
|
|
|
| `AppBanner` | Inline form validation errors | Login form error message |
|
|
|
|
|
|
|
|
|
|
### Toast Types
|
|
|
|
|
|
|
|
|
|
```dart
|
|
|
|
|
enum ToastType { info, success, warning, error }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Usage Examples
|
|
|
|
|
|
|
|
|
|
**Global Toast (auto-dismiss):**
|
|
|
|
|
```dart
|
|
|
|
|
Toast.show(context, '保存成功', type: ToastType.success);
|
|
|
|
|
Toast.show(context, '网络错误', type: ToastType.error);
|
|
|
|
|
Toast.show(context, '正在加载...', type: ToastType.info, duration: Duration(seconds: 3));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Inline Banner (persistent):**
|
|
|
|
|
```dart
|
|
|
|
|
AppBanner(message: '邮箱或密码错误', type: ToastType.error)
|
|
|
|
|
AppBanner(message: '请检查输入', type: ToastType.warning)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Rules
|
|
|
|
|
|
|
|
|
|
- Use `Toast` for transient feedback that auto-dismisses
|
|
|
|
|
- Use `AppBanner` for persistent inline messages (form errors)
|
|
|
|
|
- Do NOT create custom SnackBar, Dialog, or Banner components
|
|
|
|
|
- Do NOT use raw `ScaffoldMessenger`
|