← API | 列表 | component_issues
提示信息
# 组件问题审查报告

> 覆盖范围:4 批共 22 个组件  
> 问题分类:**[字体]** / **[颜色]** / **[规范]** / **[逻辑]**

---

## 第一批

### app_action_sheet.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 标题区用 `bodySm`(14px 正文体),用于 UI 标题语义不符 | 改为 `labelStyle(fontSize: 13, fontWeight: w500)` |
| 2 | **[字体]** | 操作项用 `bodyMd`(16px 正文体),按钮/操作文字不应用正文体 | 改为 `labelStyle(fontSize: 15, fontWeight: w500)` |
| 3 | **[字体]** | 取消按钮用 `bodyMd`,应与操作项统一字体族 | 改为 `labelStyle(fontSize: 15, fontWeight: w600)` |
| 4 | **[字体]** | `AppDialog.showSheet` 的 Sheet 标题用了 `h3`(22px 衬线体),底部弹层标题过大且不符合场景 | 改为 `labelStyle(fontSize: 15, fontWeight: w700)`(无衬线,与 ActionSheet 统一)|
| 5 | **[规范]** | 使用原生 `Padding`、`Column`、`Container`、`Row`、`SizedBox` | 全部改为 VelocityX 链式写法 |

---

### app_badge.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 徽章数字裸写 `TextStyle(fontSize: 9, fontWeight: w700)` | 改为 `AppTextStyles.labelStyle(fontSize: 9, fontWeight: FontWeight.w700)` |
| 2 | **[颜色]** | 徽章边框颜色用 `AppColors.white`,深色模式下白边在深色背景上变灰 | 改为 `context.themeBackground` |
| 3 | **[规范]** | 使用原生 `Container`、`Stack` | 改为 VelocityX |

---

### app_capsule_button.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 文字用 `bodySm`(14px 宋体正文体),胶囊按钮标签不应用正文字体族 | 改为 `labelStyle(fontSize: 13, fontWeight: w500)` |
| 2 | **[字体]** | 垂直内边距 `xs + 2 = 6dp` 过紧 | 改为 `AppSpacing.sm`(8dp)|
| 3 | **[规范]** | 使用原生 `Container`、`GestureDetector` | `GestureDetector` 改为 `.onTap()`,容器改为 VelocityX |

---

### app_cell.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | Title 用 `bodyMd`(16px),列表密集时偏大 | 改为 `bodyStyle(fontSize: 15)` |
| 2 | **[字体]** | Subtitle 用 `caption`(10px),列表中过小 | 改为 `labelStyle(fontSize: 12)` |
| 3 | **[字体]** | Value 用 `bodySm`(14px),与 title 层次区分不足 | 改为 `labelStyle(fontSize: 13, color: muted)` |
| 4 | **[字体]** | `AppCellGroup` 分组标题用 `caption`(10px),Editorial 分组标签太小 | 改为 `labelStyle(fontSize: 11, letterSpacing: 1.0)` |
| 5 | **[规范]** | 大量原生 `Column`、`Row`、`Container`、`Padding`、`SizedBox`、`Material` | 改为 VelocityX |

---

### app_checkbox.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[规范]** | 使用原生 `AnimatedContainer`、`GestureDetector`、`Opacity`(动画组件可豁免,须加注释)| 非动画部分改为 VelocityX,动画部分加注释豁免 |
| 2 | **[规范]** | 圆角用 `AppRadius.sm`,与按钮胶囊规则有歧义 | ai_rules 已明确 Checkbox 豁免为 `AppRadius.sm`,无需修改 ✅ |

---

### app_dialog.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | Dialog 标题用了 `h3`(22px 衬线体),弹窗内标题不应使用 Serif 大标题,视觉过重 | 改为 `labelStyle(fontSize: 17, fontWeight: w700)`(无衬线,紧凑) |
| 2 | **[字体]** | ActionSheet/Sheet 标题用了 `h3`(22px 衬线体),底部弹层标题同样过大 | 改为 `labelStyle(fontSize: 15, fontWeight: w700)` |
| 3 | **[字体]** | 正文用 `bodySm`(14px),对话框正文偏小 | 改为 `bodyStyle(fontSize: 14)` |
| 4 | **[规范]** | `_ConfirmDialog` 使用原生 `Column`、`Row`、`Padding`、`SizedBox` | 改为 VelocityX |
| 5 | **[规范]** | `_ConfirmDialog`(原生)与 `_AppSheetWrapper`(VelocityX)风格不统一 | 统一为 VelocityX |

---

## 第二批

### app_empty_state.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 标题用 `bodyMd`(16px 正文体),空状态标题应有更强视觉重量 | 改为 `headingStyle(fontSize: 18)` 或 `labelStyle(fontSize: 15, fontWeight: w600)` |
| 2 | **[字体]** | 副标题 `height: 1.5`,与设计系统 `bodyStyle` 默认 `1.6` 不一致 | 改为 `height: 1.6` |
| 3 | **[颜色]** | 图标颜色用 `Theme.of(context).colorScheme.primary`,绕过设计系统 | 改为 `context.themePrimary` |
| 4 | **[规范]** | 使用原生 `Column`、`Container`、`Center`、`SizedBox` | 改为 VelocityX,`.px24()` 已正确使用 ✅ |

---

### app_input.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[逻辑]** | `enabledBorder` 的颜色 `context.themeDivider.withValues(alpha: 0.1)` 二次叠加透明度,边框几乎不可见 | 直接改为 `context.themeDivider` |
| 2 | **[逻辑]** | 圆角用 `AppRadius.lg`(16dp),与 `app_theme.dart` 全局 `inputDecorationTheme` 中定义的 `AppRadius.xs`(4dp)不一致 | 统一为 `AppRadius.lg`(组件优先,需同步修改全局主题)|

---

### app_list_view.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[逻辑]** | `MaterialHeader/Footer` 的 `backgroundColor` 和 `valueColor` 逻辑互换,深色模式下刷新头背景黑、指示器白,视觉突兀 | `backgroundColor` 改为 `context.themeBackground`,`valueColor` 改为 `context.themePrimary` |

---

### app_loading.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[颜色]** | spinner 颜色用 `Theme.of(context).colorScheme.primary`,绕过设计系统 | 改为 `context.themePrimary` |
| 2 | **[颜色]** | 卡片背景用 `Theme.of(context).cardColor`,绕过设计系统 | 改为 `context.themeSurface` |
| 3 | **[颜色]** | 蒙层用 `AppColors.black.withValues(alpha: 0.4)`,`black` 映射 `ink`(暖黑),语义不明确 | 暂用 `AppColors.ink.withValues(alpha: 0.4)`,后续在 `AppColors` 补充 `scrim` 色 |
| 4 | **[规范]** | 使用原生 `Material`、`Center`、`Container`、`SizedBox` | 改为 VelocityX |

---

### app_radio.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[颜色]** | 选中内圆点用 `AppColors.white`,深色模式下 `themePrimary = paper`,内圆与背景同色导致不可见 | 改为 `context.themeBackground` |
| 2 | **[规范]** | 使用原生 `GestureDetector`、`AnimatedContainer`、`Container`、`SizedBox`、`Opacity`(动画部分可豁免)| 非动画部分改为 VelocityX,动画部分加注释 |

---

### app_skeleton.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[颜色]** | `ShimmerEffect` 的 `highlightColor` 用 `AppColors.bgSecondary`(纯白),深色模式下不切换,shimmer 闪烁异常亮 | 改为 `context.themeSurface` |
| 2 | **[规范]** | `listTile`、`card`、`page` 中混用 VelocityX 和原生 `Container`、`Expanded`、`ListView.builder` | 原生部分改为 VelocityX |

---

## 第三批

### app_swipe_cell.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 操作按钮标签用 `caption`(10px),滑动操作区文字极小 | 改为 `labelStyle(fontSize: 12, fontWeight: w500)` |
| 2 | **[颜色]** | 文字/图标用 `AppColors.white`,若调用方传入浅色背景,对比度不足 | 可改为参数化,默认 `AppColors.paper`,由调用方按需覆盖 |
| 3 | **[颜色]** | 主内容背景用 `AppColors.surface(context)`(静态方法),风格不统一 | 改为 `context.themeSurface` |
| 4 | **[规范]** | 大量原生 `GestureDetector`、`Stack`、`Row`、`Column`、`Container`、`SizedBox` | 改为 VelocityX |

---

### app_tab_bar.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[颜色]** | `labelColor` 硬编码 `AppColors.ink`,深色模式下不可见 | 改为 `context.themeTextPrimary` |
| 2 | **[颜色]** | `unselectedLabelColor` 硬编码 `AppColors.muted`,深色模式下不切换 | 改为 `context.themeTextSecondary` |
| 3 | **[颜色]** | `indicator` 的 `BorderSide` 硬编码 `AppColors.ink`,深色模式失效 | 改为 `context.themeTextPrimary` |
| 4 | **[颜色]** | `dividerColor` 硬编码 `AppColors.line`(浅色专用色),深色模式下分割线消失 | 改为 `context.themeDivider` |

---

### app_toast.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | `letterSpacing: 0.2` 偏离 `labelStyle` 默认值(1.2),字间距不统一 | 改为 `letterSpacing: 0.5` 或走默认值 |
| 2 | **[颜色]** | `info` 类型图标颜色用 `AppColors.primary`(映射 ink,近黑),辨识度低 | 暂用 `AppColors.muted`,后续补充 `info` 语义色 |
| 3 | **[规范]** | 使用原生 `Row`、`Container`、`Material`、`SizedBox`(涉及 Overlay 动画,可酌情豁免,须加注释)| 非动画/非特效部分改为 VelocityX |

---

### custom_avatar.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 首字母裸写 `TextStyle(fontSize: size.fontSize, fontWeight: w700)` | 改为 `AppTextStyles.labelStyle(fontSize: size.fontSize, fontWeight: FontWeight.w700)` |
| 2 | **[颜色]** | 渐变颜色用 `Theme.of(context).colorScheme.primary`,绕过设计系统 | 改为 `context.themePrimary` |
| 3 | **[颜色]** | 首字母颜色用 `AppColors.white`,深色模式下头像背景为 `paper`(暖白),白字不可见 | 改为 `context.themeBackground` |
| 4 | **[规范]** | 使用原生 `Container`、`ClipRRect` | 改为 VelocityX |

---

### editorial_widgets.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[颜色]** | `EditorialDivider` 的 label 用 `AppTextStyles.labelStyle()` 无参调用,默认 `color: AppColors.muted`,深色模式下颜色过浅 | 改为 `labelStyle(color: context.themeTextSecondary)` |
| 2 | **[字体]** | `EditorialDivider` 间距裸写 `SizedBox(height: 4)` | 改为 `AppSpacing.xs` |
| 3 | **[规范]** | `EditorialDivider` 使用原生 `Column`、`SizedBox` | 改为 VelocityX |

---

### primary_action_button.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[颜色]** | Loading 状态 spinner 颜色硬编码 `AppColors.white`,secondary 按钮(浅色背景)时 spinner 不可见 | 改为与 `textColor` 一致,即 `AlwaysStoppedAnimation(textColor)` |
| 2 | **[规范]** | `import '../shared.dart'` 使用相对路径 | 改为 `import 'package:tongban_app/shared.dart'` |
| 3 | **[规范]** | 使用原生 `Opacity`、`AnimatedContainer`、`Material`、`InkWell`、`Center`、`Padding`、`SizedBox`(涉及动画和涟漪效果,可酌情豁免,须加注释)| 非动画部分改为 VelocityX,动画/涟漪部分加注释 |

---

## 第四批

### app_bottom_nav_bar.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | Badge 文字裸写 `TextStyle(fontSize: 9, fontWeight: bold)` | 改为 `AppTextStyles.labelStyle(fontSize: 9, fontWeight: FontWeight.bold)` |
| 2 | **[颜色]** | 使用 Flutter 原生 `Badge` 组件,样式与 `AppBadge` 不一致 | 替换为 `AppBadge` |
| 3 | **[颜色]** | 毛玻璃背景和边框颜色手动 `isDark` 分支硬编码,脆弱 | 改为 `context.themeBackground.withValues(alpha: 0.85)` 和 `context.themeDivider` |
| 4 | **[颜色]** | `isDark` 用 `Theme.of(context).brightness`,`primary` 用 `Theme.of(context).colorScheme.primary` | 分别改为 `context.isDark`、`context.themePrimary` |
| 5 | **[规范]** | 使用原生 `Container`、`Row`、`GestureDetector`、`Center`、`Expanded` | 改为 VelocityX |

---

### app_chat_nav_bar.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 用户名用 VelocityX `.bold.base`(14px),聊天导航栏对方名字偏小 | 改为 `.textStyle(AppTextStyles.bodyStyle(fontSize: 16)).bold` |
| 2 | **[字体]** | 在线状态用 `.xs`(12px),未走 `AppTextStyles`,字间距缺失 | 改为 `AppTextStyles.labelStyle(fontSize: 11)` |

---

### app_nav_bar.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[颜色]** | 底部分割线 `context.themeDivider.withValues(alpha: 0.2)` 二次叠加透明度,分割线几乎不可见 | 直接改为 `context.themeDivider` |
| 2 | **[颜色]** | 使用 `Colors.transparent`,违反原生 Colors 禁令 | 改为 `AppColors.transparent` |
| 3 | **[规范]** | 大量原生 `Container`、`SafeArea`、`SizedBox`、`Stack`、`Center`、`Padding`、`Positioned`、`Row`、`GestureDetector` | 改为 VelocityX |

---

### app_search_nav_bar.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 搜索框 hint 用 `bodySm`(14px 宋体),胶囊输入框内用宋体字感偏重 | 改为 `labelStyle(fontSize: 14, letterSpacing: 0)` |
| 2 | **[字体]** | `TextField` 未设置 `style` 参数,输入内容 fallback 到系统字体 | 补充 `style: AppTextStyles.bodyStyle(fontSize: 15, color: context.themeTextPrimary)` |

---

### app_transparent_nav_bar.dart

| # | 分类 | 问题描述 | 修改建议 |
|---|---|---|---|
| 1 | **[字体]** | 标题用 `AppTextStyles.h3`(22px),与 `AppNavBar` 的 `navTitle`(18px)不一致,同为导航栏标题字号偏大 | 改为 `AppTextStyles.navTitle(context)` |
| 2 | **[颜色]** | 返回按钮遮罩用 `AppColors.black.withValues(alpha: 0.26)`,`black` 映射 `ink`(暖黑),语义不明确 | 暂用 `AppColors.ink.withValues(alpha: 0.3)`,后续补充 `AppColors.scrim` |
| 3 | **[颜色]** | 使用 `Colors.transparent`,违反原生 Colors 禁令 | 改为 `AppColors.transparent` |

---

## 全局共性问题汇总

| 问题类型 | 涉及组件 |
|---|---|
| 按钮/操作文字用正文字体(`bodyMd`/`bodySm`)而非 `labelStyle` | ActionSheet、CapsuleButton、SwipeCell |
| 列表辅助文字用 `caption`(10px)过小 | Cell、ActionSheet、CellGroup |
| 裸写 `TextStyle` 未走 `AppTextStyles` | Badge、Avatar、BottomNavBar |
| 导航栏标题字号不统一(`h3 22px` vs `navTitle 18px`)| TransparentNavBar |
| 搜索框缺少输入内容 `style` 参数 | SearchNavBar |
| `Theme.of(context).colorScheme.primary` 绕过设计系统 | EmptyState、Loading、Avatar、BottomNavBar |
| 深色模式下 `AppColors.white`/`paper` 反色失效 | Badge、Radio、Avatar、PrimaryButton |
| `context.themeDivider` 二次叠加透明度导致边框不可见 | Input、NavBar |
| `Colors.transparent` 未替换为 `AppColors.transparent` | NavBar、TransparentNavBar |
| `import '../shared.dart'` 相对路径违规 | Avatar、PrimaryButton |
| Flutter 原生 `Badge` 组件未替换为 `AppBadge` | BottomNavBar |
| `ShimmerEffect` 高亮色深色模式不切换 | Skeleton |
| 刷新头颜色逻辑互换 | ListView |
| Loading spinner 颜色在 secondary 按钮上不可见 | PrimaryButton |
| `AppColors` 缺少 `scrim`(蒙层)和 `info`(信息蓝)语义色 | Loading、Toast、TransparentNavBar |
| 原生布局组件未 VelocityX 化 | 全部组件均有不同程度违反 |

---

## Showcase HTML 视觉问题修复记录

> 本节记录 HTML 预览文件中发现的视觉/规范问题,已在新版本中全部修复。

| # | 问题描述 | 修复方案 |
|---|---|---|
| 1 | Dialog 标题用 `.h3`(22px 衬线体),弹窗内标题视觉过重 | 改为 `Sans 17px w700`,Dialog 场景不用 Serif |
| 2 | ActionSheet 标题用 `.h3`(22px),底部弹层标题过大 | 改为 `Sans 15px w700` |
| 3 | `.grid2` / `.grid3` 在手机宽度下两列挤压 | 添加 `@media(max-width:540px)` 响应式断点,单列降级 |
| 4 | `.code` 标签 `white-space:nowrap` 导致移动端横向溢出 | 添加 `max-width:100%; overflow:hidden; text-overflow:ellipsis` |
| 5 | SwipeCell 操作按钮 `transform:translateX(-144px)` 写死,窄屏下遮挡内容正常 | 保留 demo 效果,加说明注释 |
| 6 | Loading spinner 的轨道用 `var(--div)` 深色模式下几乎不可见 | 保留 `var(--div)` 但加粗到 2.5px,可接受 |
| 7 | Empty State 图标容器 88px 但图标 `font-size:40px`,比例协调问题 | 容器改为 80px,图标改为 36px,比例更紧凑 |
| 8 | Toast `align-items:flex-start` 导致各行宽度不统一,视觉凌乱 | 改为 `width:fit-content;max-width:100%`,每条独立宽度 |
| 9 | 字体排版区 `type-row` 在小屏下 code 标签错行 | 改为 `flex-wrap:wrap`,code 标签可换行显示 |
| 10 | 字体图标 RemixIcon CDN 链接已正确引入 `remixicon@4.8.0` | 确认引入,图标全部正常渲染 ✅ |