颜色,基础组件重新封装,降低理解难度,分层更明显。入口更抽象
This commit is contained in:
@@ -3092,7 +3092,7 @@ flowchart TD
|
||||
│ └── socket_manager.dart # WebSocket 生命周期(连接/断开/重连编排)
|
||||
│
|
||||
└── ui/ # Core UI(设计系统 + 可复用组件)
|
||||
├── base/ # 设计 Token
|
||||
├── base/ # 设计基础(颜色 / 字体 / 间距 / 圆角 / 阴影)
|
||||
│ ├── assets.dart # 静态资源路径常量(AppAssets:logo / 占位图)
|
||||
│ ├── icons.dart # 图标常量(AppIcons:导航 / 操作 / 聊天 / 用户 / 状态)
|
||||
│ ├── app_theme.dart # ThemeData 组装(Light / Dark)
|
||||
@@ -3461,7 +3461,7 @@ flowchart TD
|
||||
|
||||
DesignSystem --> Colors[Colors 颜色]
|
||||
DesignSystem --> Typography[Typography 字体]
|
||||
DesignSystem --> Tokens[Design Tokens 基础定义]
|
||||
DesignSystem --> Tokens[间距 / 圆角 / 阴影]
|
||||
DesignSystem --> Theme[Theme 主题]
|
||||
|
||||
Foundation --> Atoms[Atoms 原子组件]
|
||||
@@ -3522,39 +3522,44 @@ flowchart TD
|
||||
|
||||
<p><strong>核心原则</strong>:与 Figma 设计稿完全对应,确保设计与实现一致。</p>
|
||||
|
||||
<h5>1.1 Colors(颜色)</h5>
|
||||
<h5>1.1 Colors(颜色)— 5 层架构</h5>
|
||||
|
||||
<pre><code class="language-dart">/// 颜色定义 - 与 Figma 设计稿对应
|
||||
class AppColors {
|
||||
// Primary Colors - 主色
|
||||
static const primary = Color(0xFF667EEA);
|
||||
static const primaryDark = Color(0xFF5568D3);
|
||||
static const primaryLight = Color(0xFF8B9FFF);
|
||||
<pre><code class="language-dart">/// Layer 1: 颜色常量,不带语义
|
||||
abstract class ColorBases {
|
||||
static const primary400 = Color(0xFF5BA3F5);
|
||||
static const primary500 = Color(0xFF2F80ED);
|
||||
static const primary700 = Color(0xFF1A6BD4);
|
||||
static const neutral0 = Color(0xFFFFFFFF);
|
||||
static const neutral50 = Color(0xFFF8F9FA);
|
||||
// ... neutral100~950, error500, success500, warning500
|
||||
}
|
||||
|
||||
// Secondary Colors - 辅助色
|
||||
static const secondary = Color(0xFF764BA2);
|
||||
static const secondaryDark = Color(0xFF5E3882);
|
||||
static const secondaryLight = Color(0xFF9B6FC4);
|
||||
/// Layer 2: 语义颜色接口
|
||||
abstract class AppColors {
|
||||
Color get bgPrimary; // Scaffold 底色
|
||||
Color get bgSecondary; // Card / Surface
|
||||
Color get textPrimary; // 主文本
|
||||
Color get textSecondary; // 辅助文本
|
||||
Color get brandPrimary; // 主品牌色
|
||||
Color get statusError; // 错误
|
||||
// ... 完整定义见 colors.dart
|
||||
}
|
||||
|
||||
// Neutral Colors - 中性色
|
||||
static const black = Color(0xFF000000);
|
||||
static const white = Color(0xFFFFFFFF);
|
||||
static const gray900 = Color(0xFF1A1A1A);
|
||||
static const gray800 = Color(0xFF2D2D2D);
|
||||
static const gray700 = Color(0xFF404040);
|
||||
static const gray600 = Color(0xFF5C5C5C);
|
||||
static const gray500 = Color(0xFF737373);
|
||||
static const gray400 = Color(0xFF999999);
|
||||
static const gray300 = Color(0xFFBFBFBF);
|
||||
static const gray200 = Color(0xFFE6E6E6);
|
||||
static const gray100 = Color(0xFFF5F5F5);
|
||||
static const gray50 = Color(0xFFFAFAFA);
|
||||
/// Layer 3: 亮暗实现
|
||||
class LightColors implements AppColors {
|
||||
const LightColors();
|
||||
@override Color get bgPrimary => ColorBases.neutral50;
|
||||
@override Color get textPrimary => ColorBases.neutral900;
|
||||
@override Color get brandPrimary => ColorBases.primary500;
|
||||
// ...
|
||||
}
|
||||
|
||||
// Semantic Colors - 语义色
|
||||
static const success = Color(0xFF10B981);
|
||||
static const warning = Color(0xFFF59E0B);
|
||||
static const error = Color(0xFFEF4444);
|
||||
static const info = Color(0xFF3B82F6);
|
||||
class DarkColors implements AppColors {
|
||||
const DarkColors();
|
||||
@override Color get bgPrimary => ColorBases.neutral900;
|
||||
@override Color get textPrimary => ColorBases.neutral0;
|
||||
@override Color get brandPrimary => ColorBases.primary400;
|
||||
// ...
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
@@ -3616,77 +3621,79 @@ class AppTypography {
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h5>1.3 Design Tokens(基础定义)</h5>
|
||||
<h5>1.3 间距 / 圆角 / 阴影</h5>
|
||||
|
||||
<pre><code class="language-dart">/// 基础定义 - 间距、圆角、阴影等
|
||||
class AppTokens {
|
||||
// Spacing - 间距(8pt 网格系统)
|
||||
static const spacing4 = 4.0;
|
||||
static const spacing8 = 8.0;
|
||||
static const spacing12 = 12.0;
|
||||
static const spacing16 = 16.0;
|
||||
static const spacing20 = 20.0;
|
||||
static const spacing24 = 24.0;
|
||||
static const spacing32 = 32.0;
|
||||
static const spacing40 = 40.0;
|
||||
static const spacing48 = 48.0;
|
||||
<pre><code class="language-dart">/// 间距常量 — spacing.dart
|
||||
class AppSpacing {
|
||||
static const double s4 = 4;
|
||||
static const double s8 = 8;
|
||||
static const double s12 = 12;
|
||||
static const double s16 = 16;
|
||||
static const double s24 = 24;
|
||||
static const double s32 = 32;
|
||||
}
|
||||
|
||||
// Border Radius - 圆角
|
||||
static const radiusSmall = 4.0;
|
||||
static const radiusMedium = 8.0;
|
||||
static const radiusLarge = 12.0;
|
||||
static const radiusXLarge = 16.0;
|
||||
static const radiusFull = 9999.0;
|
||||
/// 圆角常量 — radius.dart
|
||||
class AppRadius {
|
||||
// 基础 Radius
|
||||
static const Radius r4 = Radius.circular(4);
|
||||
static const Radius r8 = Radius.circular(8);
|
||||
static const Radius r12 = Radius.circular(12);
|
||||
static const Radius r16 = Radius.circular(16);
|
||||
|
||||
// Elevation - 阴影
|
||||
static const elevationNone = 0.0;
|
||||
static const elevationLow = 2.0;
|
||||
static const elevationMedium = 4.0;
|
||||
static const elevationHigh = 8.0;
|
||||
// 组件级圆角
|
||||
static const BorderRadius card = BorderRadius.all(r12);
|
||||
static const BorderRadius button = BorderRadius.all(r8);
|
||||
static const BorderRadius dialog = BorderRadius.all(r16);
|
||||
}
|
||||
|
||||
/// 阴影常量 — shadows.dart
|
||||
/// 颜色走 AppColors.shadow 自动适配亮暗模式
|
||||
class AppShadows {
|
||||
List<BoxShadow> get bs4; // Elevation 4 — 小卡片
|
||||
List<BoxShadow> get bs8; // Elevation 8 — Card
|
||||
List<BoxShadow> get bs12; // Elevation 12 — Dropdown
|
||||
List<BoxShadow> get bs16; // Elevation 16 — Dialog
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h5>1.4 Theme(主题 - 黑暗模式)</h5>
|
||||
<h5>1.4 Theme(主题组装)</h5>
|
||||
|
||||
<pre><code class="language-dart">/// 主题定义 - 支持亮色/暗色模式
|
||||
<pre><code class="language-dart">/// Layer 4: 主题组装 — 接收 AppColors 实例,零 isDark 分支
|
||||
class AppTheme {
|
||||
// Light Theme
|
||||
static ThemeData light = ThemeData(
|
||||
brightness: Brightness.light,
|
||||
primaryColor: AppColors.primary,
|
||||
scaffoldBackgroundColor: AppColors.white,
|
||||
colorScheme: const ColorScheme.light(
|
||||
primary: AppColors.primary,
|
||||
secondary: AppColors.secondary,
|
||||
error: AppColors.error,
|
||||
surface: AppColors.white,
|
||||
background: AppColors.gray50,
|
||||
),
|
||||
textTheme: TextTheme(
|
||||
displayLarge: AppTypography.displayLarge,
|
||||
headlineMedium: AppTypography.headlineMedium,
|
||||
bodyLarge: AppTypography.bodyLarge,
|
||||
),
|
||||
);
|
||||
AppTheme._();
|
||||
|
||||
// Dark Theme
|
||||
static ThemeData dark = ThemeData(
|
||||
brightness: Brightness.dark,
|
||||
primaryColor: AppColors.primary,
|
||||
scaffoldBackgroundColor: AppColors.gray900,
|
||||
colorScheme: const ColorScheme.dark(
|
||||
primary: AppColors.primary,
|
||||
secondary: AppColors.secondary,
|
||||
error: AppColors.error,
|
||||
surface: AppColors.gray800,
|
||||
background: AppColors.black,
|
||||
),
|
||||
textTheme: TextTheme(
|
||||
displayLarge: AppTypography.displayLarge.copyWith(color: AppColors.white),
|
||||
headlineMedium: AppTypography.headlineMedium.copyWith(color: AppColors.white),
|
||||
bodyLarge: AppTypography.bodyLarge.copyWith(color: AppColors.gray100),
|
||||
),
|
||||
);
|
||||
static ThemeData get theme => _build(const LightColors());
|
||||
static ThemeData get darkTheme => _build(const DarkColors());
|
||||
|
||||
static ThemeData _build(AppColors c) {
|
||||
final brightness = c is DarkColors ? Brightness.dark : Brightness.light;
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: brightness,
|
||||
scaffoldBackgroundColor: c.bgPrimary,
|
||||
colorScheme: ColorScheme(
|
||||
brightness: brightness,
|
||||
primary: c.brandPrimary,
|
||||
onPrimary: c.textOnPrimary,
|
||||
surface: c.bgSecondary,
|
||||
onSurface: c.textPrimary,
|
||||
error: c.statusError,
|
||||
onError: c.textOnPrimary,
|
||||
// ...
|
||||
),
|
||||
appBarTheme: AppBarTheme(backgroundColor: c.bgPrimary, foregroundColor: c.textPrimary),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(style: ElevatedButton.styleFrom(
|
||||
backgroundColor: c.brandPrimary, foregroundColor: c.textOnPrimary,
|
||||
)),
|
||||
inputDecorationTheme: InputDecorationTheme(fillColor: c.bgSecondary, filled: true),
|
||||
cardTheme: CardThemeData(color: c.bgSecondary),
|
||||
dividerTheme: DividerThemeData(color: c.divider),
|
||||
bottomNavigationBarTheme: BottomNavigationBarThemeData(
|
||||
backgroundColor: c.navBarBg, selectedItemColor: c.navBarSelected,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
@@ -3706,8 +3713,8 @@ class AppTheme {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>Primary/Main</code></td>
|
||||
<td><code>AppColors.primary</code></td>
|
||||
<td>主色</td>
|
||||
<td><code>context.colors.brandPrimary</code></td>
|
||||
<td>主品牌色</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Button/Primary</code></td>
|
||||
@@ -3716,18 +3723,18 @@ class AppTheme {
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Text/Headline/Large</code></td>
|
||||
<td><code>AppTypography.headlineLarge</code></td>
|
||||
<td><code>context.styles.headlineLarge</code></td>
|
||||
<td>大标题</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Spacing/16</code></td>
|
||||
<td><code>AppTokens.spacing16</code></td>
|
||||
<td><code>AppSpacing.s16</code></td>
|
||||
<td>16pt 间距</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Radius/Medium</code></td>
|
||||
<td><code>AppTokens.radiusMedium</code></td>
|
||||
<td>中等圆角</td>
|
||||
<td><code>Radius/Card</code></td>
|
||||
<td><code>AppRadius.card</code></td>
|
||||
<td>卡片圆角</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -3777,7 +3784,7 @@ class AppButton extends StatelessWidget {
|
||||
foregroundColor: _getForegroundColor(),
|
||||
padding: _getPadding(),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppTokens.radiusMedium),
|
||||
borderRadius: AppRadius.button,
|
||||
),
|
||||
),
|
||||
child: Text(text, style: _getTextStyle()),
|
||||
@@ -3806,7 +3813,7 @@ class AppTextField extends StatelessWidget {
|
||||
labelText: label,
|
||||
hintText: hint,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(AppTokens.radiusMedium),
|
||||
borderRadius: AppRadius.button,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -3831,11 +3838,11 @@ class SearchBar extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(AppTokens.spacing12),
|
||||
padding: EdgeInsets.all(AppSpacing.s12),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.search, color: AppColors.gray500),
|
||||
SizedBox(width: AppTokens.spacing8),
|
||||
Icon(Icons.search, color: context.colors.textSecondary),
|
||||
SizedBox(width: AppSpacing.s8),
|
||||
Expanded(
|
||||
child: AppTextField(
|
||||
hint: hint,
|
||||
@@ -3902,18 +3909,18 @@ class MessageBubble extends ConsumerWidget {
|
||||
alignment: isSender ? Alignment.centerRight : Alignment.centerLeft,
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: AppTokens.spacing16,
|
||||
vertical: AppTokens.spacing8,
|
||||
horizontal: AppSpacing.s16,
|
||||
vertical: AppSpacing.s8,
|
||||
),
|
||||
padding: EdgeInsets.all(AppTokens.spacing12),
|
||||
padding: EdgeInsets.all(AppSpacing.s12),
|
||||
decoration: BoxDecoration(
|
||||
color: isSender ? AppColors.primary : AppColors.gray200,
|
||||
borderRadius: BorderRadius.circular(AppTokens.radiusLarge),
|
||||
color: isSender ? context.colors.brandPrimary : context.colors.bgTertiary,
|
||||
borderRadius: AppRadius.card,
|
||||
),
|
||||
child: Text(
|
||||
message.content,
|
||||
style: AppTypography.bodyMedium.copyWith(
|
||||
color: isSender ? AppColors.white : AppColors.black,
|
||||
style: context.styles.bodyMedium?.copyWith(
|
||||
color: isSender ? context.colors.textOnPrimary : context.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -4143,7 +4150,7 @@ class PlatformButton extends StatelessWidget {
|
||||
if (PlatformAdapter.isIOS) {
|
||||
return CupertinoButton(
|
||||
onPressed: onPressed,
|
||||
color: AppColors.primary,
|
||||
color: context.colors.brandPrimary,
|
||||
child: Text(text),
|
||||
);
|
||||
}
|
||||
@@ -6879,10 +6886,13 @@ final user = await db.selectFirst(appDb.users, (t) => t.uid.equals(uid));
|
||||
<p>最底层的视觉规范定义,<strong>不含任何 Widget</strong>,只输出颜色/字体常量和 ThemeData:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>colors.dart</code>(已实现):颜色体系 —— 品牌色、语义色(success / warning / error)、中性灰阶</li>
|
||||
<li><code>colors.dart</code>(已实现):5 层颜色体系 —— ColorBases(颜色常量)+ AppColors(语义接口)+ LightColors / DarkColors(亮暗实现)</li>
|
||||
<li><code>font.dart</code>(已实现):字体 —— TextStyle 定义 + <code>textTheme(brightness)</code>(统一字族/字号/行高)</li>
|
||||
<li><code>app_theme.dart</code>(已实现):主题组装 —— 将以上令牌组合为 Light / Dark ThemeData</li>
|
||||
<li>spacing / radius / shadows 等(待开发,按需添加)</li>
|
||||
<li><code>shadows.dart</code>(已实现):阴影常量 —— bs4 / bs8 / bs12 / bs16,颜色走 AppColors.shadow 自动适配亮暗</li>
|
||||
<li><code>spacing.dart</code>(已实现):间距常量 —— s4 / s8 / s12 / s16 / s24 / s32</li>
|
||||
<li><code>radius.dart</code>(已实现):圆角常量 —— 基础 r4~r20 + 组件级 card / button / dialog</li>
|
||||
<li><code>app_theme.dart</code>(已实现):主题组装 —— <code>_build(AppColors c)</code> 零 isDark 分支</li>
|
||||
<li><code>context_theme_ext.dart</code>(已实现):统一 context 扩展 —— context.colors + context.styles + context.shadows</li>
|
||||
</ul>
|
||||
|
||||
<h4>第二层:基础组件(core/ui/components/)</h4>
|
||||
@@ -9855,37 +9865,74 @@ flowchart TD
|
||||
|
||||
<h3 id="8-1-颜色体系">8.1 颜色体系</h3>
|
||||
|
||||
<p>所有颜色通过抽象名称引用。抽象名在亮色 / 暗色两套主题下对应不同色值,修改主题只需改映射表,不需逐个找组件。</p>
|
||||
<p>颜色采用 5 层架构:<strong>ColorBases(颜色常量)→ AppColors(语义接口)→ LightColors/DarkColors(亮暗实现)→ AppTheme._build(AppColors c)(主题组装)→ context.colors(Widget 消费)</strong>。AppTheme 内部零 isDark 分支,亮暗差异完全由实现类决定。</p>
|
||||
|
||||
<h4>语义色(随主题变化)</h4>
|
||||
<h4>Layer 1: ColorBases — 颜色常量</h4>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>抽象名</th><th>Figma 名</th><th>亮色</th><th>暗色</th><th>用途</th></tr>
|
||||
</thead>
|
||||
<thead><tr><th>色相</th><th>常量名</th><th>色值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>primary</code></td><td>Primary</td><td>#2F80ED</td><td>#5BA3F5</td><td>主操作、链接、选中态</td></tr>
|
||||
<tr><td><code>background</code></td><td>Background</td><td>#F8F9FA</td><td>#202124</td><td>页面底色</td></tr>
|
||||
<tr><td><code>surface</code></td><td>Surface</td><td>#FFFFFF</td><td>#3C4043</td><td>卡片、弹框、输入框</td></tr>
|
||||
<tr><td><code>onSurface</code></td><td>On Surface</td><td>#202124</td><td>#FFFFFF</td><td>surface 上的文字</td></tr>
|
||||
<tr><td><code>error</code></td><td>Error</td><td colspan="2">#EB5757</td><td>错误状态</td></tr>
|
||||
<tr><td><code>success</code></td><td>Success</td><td colspan="2">#27AE60</td><td>成功状态</td></tr>
|
||||
<tr><td><code>warning</code></td><td>Warning</td><td colspan="2">#F2C94C</td><td>警告状态</td></tr>
|
||||
<tr><td rowspan="3">Brand</td><td>primary400</td><td>#5BA3F5</td></tr>
|
||||
<tr><td>primary500</td><td>#2F80ED</td></tr>
|
||||
<tr><td>primary700</td><td>#1A6BD4</td></tr>
|
||||
<tr><td rowspan="10">Neutral</td><td>neutral0</td><td>#FFFFFF</td></tr>
|
||||
<tr><td>neutral50</td><td>#F8F9FA</td></tr>
|
||||
<tr><td>neutral100</td><td>#F1F3F4</td></tr>
|
||||
<tr><td>neutral200</td><td>#E8EAED</td></tr>
|
||||
<tr><td>neutral400</td><td>#BDC1C6</td></tr>
|
||||
<tr><td>neutral600</td><td>#80868B</td></tr>
|
||||
<tr><td>neutral800</td><td>#3C4043</td></tr>
|
||||
<tr><td>neutral850</td><td>#2C2C2E</td></tr>
|
||||
<tr><td>neutral900</td><td>#202124</td></tr>
|
||||
<tr><td>neutral950</td><td>#000000</td></tr>
|
||||
<tr><td rowspan="2">Neutral Alpha</td><td>black12</td><td>12% 透明度黑色</td></tr>
|
||||
<tr><td>black60</td><td>60% 透明度黑色</td></tr>
|
||||
<tr><td rowspan="3">Status</td><td>error500</td><td>#EB5757</td></tr>
|
||||
<tr><td>success500</td><td>#27AE60</td></tr>
|
||||
<tr><td>warning500</td><td>#F2C94C</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h4>灰阶(固定值,不随主题变化)</h4>
|
||||
<h4>Layer 2-3: AppColors — 语义接口 + 亮暗实现</h4>
|
||||
|
||||
<table>
|
||||
<thead><tr><th>名称</th><th>色值</th><th>名称</th><th>色值</th><th>名称</th><th>色值</th></tr></thead>
|
||||
<thead><tr><th>语义名</th><th>用途</th><th>亮色</th><th>暗色</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>white</td><td>#FFFFFF</td><td>gray50</td><td>#F8F9FA</td><td>gray100</td><td>#F1F3F4</td></tr>
|
||||
<tr><td>gray200</td><td>#E8EAED</td><td>gray400</td><td>#BDC1C6</td><td>gray600</td><td>#80868B</td></tr>
|
||||
<tr><td>gray800</td><td>#3C4043</td><td>gray900</td><td>#202124</td><td>black</td><td>#000000</td></tr>
|
||||
<tr><td><code>bgPrimary</code></td><td>Scaffold 底色</td><td>neutral50</td><td>neutral900</td></tr>
|
||||
<tr><td><code>bgSecondary</code></td><td>Card / Surface</td><td>neutral0</td><td>neutral800</td></tr>
|
||||
<tr><td><code>bgTertiary</code></td><td>次要区块</td><td>neutral100</td><td>neutral850</td></tr>
|
||||
<tr><td><code>textPrimary</code></td><td>主文本</td><td>neutral900</td><td>neutral0</td></tr>
|
||||
<tr><td><code>textSecondary</code></td><td>辅助文本</td><td>neutral600</td><td>neutral400</td></tr>
|
||||
<tr><td><code>textDisabled</code></td><td>禁用态</td><td>neutral400</td><td>neutral600</td></tr>
|
||||
<tr><td><code>textOnPrimary</code></td><td>品牌色上的文字</td><td colspan="2">neutral0</td></tr>
|
||||
<tr><td><code>borderDefault</code></td><td>默认边框</td><td>neutral200</td><td>neutral800</td></tr>
|
||||
<tr><td><code>borderFocused</code></td><td>聚焦边框</td><td>primary500</td><td>primary400</td></tr>
|
||||
<tr><td><code>brandPrimary</code></td><td>主品牌色</td><td>primary500</td><td>primary400</td></tr>
|
||||
<tr><td><code>brandPrimaryHover</code></td><td>Hover 态</td><td>primary700</td><td>primary500</td></tr>
|
||||
<tr><td><code>statusError</code></td><td>错误</td><td colspan="2">error500</td></tr>
|
||||
<tr><td><code>statusSuccess</code></td><td>成功</td><td colspan="2">success500</td></tr>
|
||||
<tr><td><code>statusWarning</code></td><td>警告</td><td colspan="2">warning500</td></tr>
|
||||
<tr><td><code>navBarBg</code></td><td>底部导航背景</td><td>neutral0</td><td>neutral900</td></tr>
|
||||
<tr><td><code>navBarSelected</code></td><td>导航选中色</td><td>primary500</td><td>primary400</td></tr>
|
||||
<tr><td><code>divider</code></td><td>分割线</td><td>neutral100</td><td>neutral800</td></tr>
|
||||
<tr><td><code>shadow</code></td><td>阴影颜色</td><td>black12</td><td>black60</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p><strong>使用原则</strong>:需随主题切换 → 用语义色(<code>primary</code>、<code>surface</code>);亮暗保持不变 → 用灰阶固定值。</p>
|
||||
<h4>Widget 侧使用(双入口)</h4>
|
||||
|
||||
<p>三个 context 扩展:<strong><code>context.colors</code></strong> — 语义颜色;<strong><code>context.styles</code></strong> — 字体 + 预组合样式;<strong><code>context.shadows</code></strong> — 阴影常量。</p>
|
||||
<pre><code>final c = context.colors;
|
||||
final s = context.styles;
|
||||
|
||||
Container(color: c.bgSecondary) // 语义颜色
|
||||
Text('标题', style: s.headlineMedium) // 字体
|
||||
Text('分组', style: s.sectionLabel) // 预组合:字体 + 品牌色
|
||||
Icon(Icons.check, color: c.brandPrimary) // 图标颜色
|
||||
Container(decoration: BoxDecoration(boxShadow: context.shadows.bs8)) // 阴影
|
||||
</code></pre>
|
||||
|
||||
<p><strong>使用原则</strong>:颜色一律用 <code>context.colors.xxx</code>,禁止写 <code>Color(0xFF...)</code> 或 <code>Theme.of(context).colorScheme.xxx</code>。新增语义色先在 <code>AppColors</code> 加 getter,再在 LightColors / DarkColors 各实现一遍。</p>
|
||||
|
||||
<h3 id="8-2-字体体系">8.2 字体体系</h3>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user