e4e995854d
- 新增忘记密码页面与重置密码确认流程(前端+后端) - 修复注册验证码页登录跳转路由 - 新增用户搜索API(按邮箱查询) - 简化infra脚本,统一为app.sh - 补充密码重置与用户API测试覆盖 - 更新runtime文档与AGENTS配置
4.2 KiB
4.2 KiB
Flutter Mobile Development Rules
This document defines Flutter mobile development constraints.
Design System
Design Tokens
All UI styling must use design tokens from apps/lib/core/theme/design_tokens.dart:
| Type | Usage |
|---|---|
| Colors | AppColors.primary, AppColors.slate500, AppColors.background |
| Spacing | AppSpacing.xs, AppSpacing.sm, AppSpacing.md |
| Radius | AppRadius.sm, AppRadius.md, AppRadius.lg |
NEVER hardcode colors, sizes, or spacing values.
Reuse Existing Components
Use pre-built components instead of creating custom ones:
- Buttons: Use
AppButtonwidget fromapps/lib/shared/widgets/app_button.dart - Input fields: Use standard Flutter
TextFieldwithInputDecoration - Loading states: Use built-in loading indicators
New Page Design Workflow
-
Analyze existing pages: Study login, register, home screens for:
- Layout structure (centered form, padding, spacing)
- Typography hierarchy (title 28px bold, label 13px, hint 14px)
- Component usage (AppButton, TextField style)
- Color and spacing tokens
-
Use frontend-design skill for mockups:
Use the `frontend-design` skill to create HTML/CSS mockups for review Match colors to `apps/lib/core/theme/design_tokens.dart` Match spacing to `AppSpacing` values Match radius to `AppRadius` values -
Verify design tokens:
- All colors from
AppColors - All spacing from
AppSpacing - All radius from
AppRadius - NO hardcoded values
- All colors from
-
Code review checklist:
- All colors/spacing/radius use design tokens
- Reuses existing components (AppButton)
- Consistent with existing page patterns
- No magic numbers
Layout Mapping Rules
Map design layout properties to Flutter explicitly:
- Always set
crossAxisAlignmentonRow/Column:alignItems: center->CrossAxisAlignment.centeralignItems: start->CrossAxisAlignment.startalignItems: stretch->CrossAxisAlignment.stretch
- Map full container chain: From root to leaf, ensure each
alignItemsandjustifyContenthas a Flutter equivalent. - Analyze before coding: Verify each container's alignment settings.
Centering and Visual Balance
- Centering must be evaluated inside
SafeAreabounds, not full-screen bounds. - Avoid relying on proportional
Spacervalues as the only centering mechanism for critical content. - For layouts with persistent top/bottom regions (e.g., headers or footers), center the primary content in the remaining available region.
- 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:
- Verify primary content remains centered relative to the usable viewport.
- Add at least one constrained viewport scenario (small height or large text scale).
Prohibitions
- DO NOT use colors not defined in design tokens
- DO NOT skip design container layers
- DO NOT start implementation before retrieving design variables
- DO NOT hardcode colors; use design variables
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
enum ToastType { info, success, warning, error }
Usage Examples
Global Toast (auto-dismiss):
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):
AppBanner(message: '邮箱或密码错误', type: ToastType.error)
AppBanner(message: '请检查输入', type: ToastType.warning)
Rules
- Use
Toastfor transient feedback that auto-dismisses - Use
AppBannerfor persistent inline messages (form errors) - DO NOT create custom SnackBar, Dialog, or Banner components
- DO NOT use raw
ScaffoldMessenger