Merge pull request 'feat(Core UI): common 常量' (#7) from dk/dev-0307 into dev
Reviewed-on: https://gitea.winwayinfo.com/CUS-IM/customer-im-client/pulls/7
This commit is contained in:
7
apps/im_app/lib/core/ui/base/app_theme_ext.dart
Normal file
7
apps/im_app/lib/core/ui/base/app_theme_ext.dart
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:im_app/core/ui/base/shadows.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension AppThemeExt on BuildContext {
|
||||||
|
AppShadows get shadows => AppShadows(this);
|
||||||
|
}
|
||||||
@@ -37,4 +37,8 @@ class AppColors {
|
|||||||
static const gray800 = Color(0xFF3C4043);
|
static const gray800 = Color(0xFF3C4043);
|
||||||
static const gray900 = Color(0xFF202124);
|
static const gray900 = Color(0xFF202124);
|
||||||
static const black = Color(0xFF000000);
|
static const black = Color(0xFF000000);
|
||||||
|
|
||||||
|
// ── Neutral black Scale ─────────────────────────────────────────────────────
|
||||||
|
static const black12 = Color(0x1F000000); // 12% opacity
|
||||||
|
static const black60 = Color(0x99000000); // 60% opacity
|
||||||
}
|
}
|
||||||
|
|||||||
131
apps/im_app/lib/core/ui/base/radius.dart
Normal file
131
apps/im_app/lib/core/ui/base/radius.dart
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
/// 圆角设计 Token
|
||||||
|
///
|
||||||
|
/// 统一管理项目中的圆角规范,避免在业务代码中直接写
|
||||||
|
/// `Radius.circular()` 或 `BorderRadius.circular()`
|
||||||
|
///
|
||||||
|
/// 使用方式:
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// Container(
|
||||||
|
/// decoration: BoxDecoration(
|
||||||
|
/// borderRadius: AppRadius.card,
|
||||||
|
/// ),
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// 设计规范来源:
|
||||||
|
/// 通常来自 UI 设计系统,例如
|
||||||
|
/// 4 / 8 / 12 / 16 / 20
|
||||||
|
class AppRadius {
|
||||||
|
/// 私有构造函数,防止被实例化
|
||||||
|
AppRadius._();
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 基础 Radius Token
|
||||||
|
// ================================
|
||||||
|
// 用于组合 BorderRadius
|
||||||
|
|
||||||
|
/// 4px 圆角
|
||||||
|
static const Radius r4 = Radius.circular(4);
|
||||||
|
|
||||||
|
/// 6px 圆角
|
||||||
|
static const Radius r6 = Radius.circular(6);
|
||||||
|
|
||||||
|
/// 8px 圆角(常用于按钮)
|
||||||
|
static const Radius r8 = Radius.circular(8);
|
||||||
|
|
||||||
|
/// 10px 圆角
|
||||||
|
static const Radius r10 = Radius.circular(10);
|
||||||
|
|
||||||
|
/// 12px 圆角(常用于卡片)
|
||||||
|
static const Radius r12 = Radius.circular(12);
|
||||||
|
|
||||||
|
/// 14px 圆角
|
||||||
|
static const Radius r14 = Radius.circular(14);
|
||||||
|
|
||||||
|
/// 16px 圆角(常用于弹窗)
|
||||||
|
static const Radius r16 = Radius.circular(16);
|
||||||
|
|
||||||
|
/// 18px 圆角
|
||||||
|
static const Radius r18 = Radius.circular(18);
|
||||||
|
|
||||||
|
/// 20px 圆角
|
||||||
|
static const Radius r20 = Radius.circular(20);
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 组件级设计 Token
|
||||||
|
// ================================
|
||||||
|
// 推荐优先使用这些,而不是直接使用 brXX
|
||||||
|
|
||||||
|
/// 卡片圆角
|
||||||
|
///
|
||||||
|
/// 示例:Card / 商品卡片 / 信息卡片
|
||||||
|
static const BorderRadius card = BorderRadius.all(r12);
|
||||||
|
|
||||||
|
/// 按钮圆角
|
||||||
|
///
|
||||||
|
/// 示例:PrimaryButton / SecondaryButton
|
||||||
|
static const BorderRadius button = BorderRadius.all(r8);
|
||||||
|
|
||||||
|
/// 弹窗圆角
|
||||||
|
///
|
||||||
|
/// 示例:Dialog / Modal
|
||||||
|
static const BorderRadius dialog = BorderRadius.all(r16);
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 通用 BorderRadius
|
||||||
|
// ================================
|
||||||
|
// 当组件 Token 不满足需求时使用
|
||||||
|
|
||||||
|
static const BorderRadius br4 = BorderRadius.all(r4);
|
||||||
|
|
||||||
|
static const BorderRadius br6 = BorderRadius.all(r6);
|
||||||
|
|
||||||
|
static const BorderRadius br8 = BorderRadius.all(r8);
|
||||||
|
|
||||||
|
static const BorderRadius br10 = BorderRadius.all(r10);
|
||||||
|
|
||||||
|
static const BorderRadius br12 = BorderRadius.all(r12);
|
||||||
|
|
||||||
|
static const BorderRadius br14 = BorderRadius.all(r14);
|
||||||
|
|
||||||
|
static const BorderRadius br16 = BorderRadius.all(r16);
|
||||||
|
|
||||||
|
static const BorderRadius br18 = BorderRadius.all(r18);
|
||||||
|
|
||||||
|
static const BorderRadius br20 = BorderRadius.all(r20);
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 辅助方法
|
||||||
|
// ================================
|
||||||
|
// 用于生成顶部或底部圆角
|
||||||
|
|
||||||
|
/// 生成顶部圆角
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - BottomSheet
|
||||||
|
/// - 底部弹窗
|
||||||
|
/// - 半屏弹层
|
||||||
|
///
|
||||||
|
/// 示例:
|
||||||
|
/// ```dart
|
||||||
|
/// borderRadius: AppRadius.top(AppRadius.r16)
|
||||||
|
/// ```
|
||||||
|
static BorderRadius top(Radius r) =>
|
||||||
|
BorderRadius.vertical(top: r);
|
||||||
|
|
||||||
|
/// 生成底部圆角
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - Header
|
||||||
|
/// - 顶部卡片
|
||||||
|
///
|
||||||
|
/// 示例:
|
||||||
|
/// ```dart
|
||||||
|
/// borderRadius: AppRadius.bottom(AppRadius.r16)
|
||||||
|
/// ```
|
||||||
|
static BorderRadius bottom(Radius r) =>
|
||||||
|
BorderRadius.vertical(bottom: r);
|
||||||
|
}
|
||||||
129
apps/im_app/lib/core/ui/base/shadows.dart
Normal file
129
apps/im_app/lib/core/ui/base/shadows.dart
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'colors.dart';
|
||||||
|
|
||||||
|
/// 阴影 Design Token
|
||||||
|
///
|
||||||
|
/// 统一管理项目中的阴影规范,避免在业务代码中直接书写 `BoxShadow`。
|
||||||
|
/// 所有阴影通过 Design Token 提供,保证:
|
||||||
|
///
|
||||||
|
/// - UI 风格统一
|
||||||
|
/// - 支持 Dark / Light Mode
|
||||||
|
/// - 与设计稿(Figma)保持一致
|
||||||
|
///
|
||||||
|
/// ## 数据流位置
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// AppColors(颜色常量)
|
||||||
|
/// → AppShadows(阴影 Token)
|
||||||
|
/// → Context Extension(context.shadows)
|
||||||
|
/// → View 层消费
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## 使用示例
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// Container(
|
||||||
|
/// decoration: BoxDecoration(
|
||||||
|
/// color: Colors.white,
|
||||||
|
/// boxShadow: context.shadows.bs8,
|
||||||
|
/// ),
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Elevation 体系
|
||||||
|
///
|
||||||
|
/// 阴影遵循常见 UI 设计系统的层级规范:
|
||||||
|
///
|
||||||
|
/// - **4** : 小卡片 / List Item
|
||||||
|
/// - **8** : Card / 商品卡片
|
||||||
|
/// - **12** : Dropdown / Popover
|
||||||
|
/// - **16** : Dialog / Modal / 悬浮面板
|
||||||
|
class AppShadows {
|
||||||
|
/// 构造函数,通过 BuildContext 获取当前主题
|
||||||
|
AppShadows(this.context);
|
||||||
|
|
||||||
|
/// 当前 Widget 的 BuildContext
|
||||||
|
///
|
||||||
|
/// 用于根据 Theme 判断 Light / Dark Mode,
|
||||||
|
/// 从而动态获取阴影颜色。
|
||||||
|
final BuildContext context;
|
||||||
|
|
||||||
|
/// 内部统一阴影生成方法
|
||||||
|
///
|
||||||
|
/// 避免重复创建 `BoxShadow` 逻辑,
|
||||||
|
/// 所有阴影 Token 都通过该方法生成。
|
||||||
|
List<BoxShadow> _shadow({
|
||||||
|
required double blur,
|
||||||
|
required double dy,
|
||||||
|
}) {
|
||||||
|
return [
|
||||||
|
BoxShadow(
|
||||||
|
|
||||||
|
/// 阴影颜色来自 Design Token
|
||||||
|
color: _shadowColor,
|
||||||
|
|
||||||
|
/// 模糊半径(影响阴影扩散范围)
|
||||||
|
blurRadius: blur,
|
||||||
|
|
||||||
|
/// 阴影偏移
|
||||||
|
offset: Offset(0, dy),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Elevation 4
|
||||||
|
///
|
||||||
|
/// 适用场景:
|
||||||
|
/// - List Item
|
||||||
|
/// - 小卡片
|
||||||
|
List<BoxShadow> get bs4 =>
|
||||||
|
_shadow(
|
||||||
|
blur: 4,
|
||||||
|
dy: 2,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Elevation 8
|
||||||
|
///
|
||||||
|
/// 适用场景:
|
||||||
|
/// - Card
|
||||||
|
/// - 商品卡片
|
||||||
|
List<BoxShadow> get bs8 =>
|
||||||
|
_shadow(
|
||||||
|
blur: 8,
|
||||||
|
dy: 4,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Elevation 12
|
||||||
|
///
|
||||||
|
/// 适用场景:
|
||||||
|
/// - Dropdown
|
||||||
|
/// - Popover
|
||||||
|
List<BoxShadow> get bs12 =>
|
||||||
|
_shadow(
|
||||||
|
blur: 12,
|
||||||
|
dy: 8,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Elevation 16
|
||||||
|
///
|
||||||
|
/// 适用场景:
|
||||||
|
/// - Dialog
|
||||||
|
/// - Modal
|
||||||
|
/// - Floating Panel
|
||||||
|
List<BoxShadow> get bs16 =>
|
||||||
|
_shadow(
|
||||||
|
blur: 16,
|
||||||
|
dy: 8,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// 阴影颜色 Token
|
||||||
|
Color get _shadowColor {
|
||||||
|
final brightness = Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness;
|
||||||
|
|
||||||
|
return brightness == Brightness.dark
|
||||||
|
? AppColors.black60
|
||||||
|
: AppColors.black12;
|
||||||
|
}
|
||||||
|
}
|
||||||
72
apps/im_app/lib/core/ui/base/spacing.dart
Normal file
72
apps/im_app/lib/core/ui/base/spacing.dart
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/// 间距设计 Token
|
||||||
|
///
|
||||||
|
/// 统一管理项目中的间距规范,避免在业务代码中直接写 magic number,例如:
|
||||||
|
///
|
||||||
|
/// ❌ 不推荐
|
||||||
|
/// ```dart
|
||||||
|
/// Padding(padding: EdgeInsets.all(16))
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ✅ 推荐
|
||||||
|
/// ```dart
|
||||||
|
/// Padding(padding: EdgeInsets.all(AppSpacing.s16))
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - Padding
|
||||||
|
/// - Margin
|
||||||
|
/// - SizedBox
|
||||||
|
/// - Sliver 间距
|
||||||
|
///
|
||||||
|
/// 设计规范通常来源于 UI 设计系统,例如:
|
||||||
|
/// 4 / 8 / 12 / 16 / 24 / 32
|
||||||
|
class AppSpacing {
|
||||||
|
/// 私有构造函数,防止实例化
|
||||||
|
AppSpacing._();
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// 基础间距 Token
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
/// 4px 间距(最小间距)
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - icon 与文字之间
|
||||||
|
/// - 紧凑布局
|
||||||
|
static const double s4 = 4;
|
||||||
|
|
||||||
|
/// 8px 间距(小间距)
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - 列表 item 内间距
|
||||||
|
/// - 小组件之间
|
||||||
|
static const double s8 = 8;
|
||||||
|
|
||||||
|
/// 12px 间距(中小间距)
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - 表单组件
|
||||||
|
/// - 信息块之间
|
||||||
|
static const double s12 = 12;
|
||||||
|
|
||||||
|
/// 16px 间距(标准间距)
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - 页面 Padding
|
||||||
|
/// - Card 内边距
|
||||||
|
static const double s16 = 16;
|
||||||
|
|
||||||
|
/// 24px 间距(大间距)
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - 模块之间
|
||||||
|
/// - Section 分隔
|
||||||
|
static const double s24 = 24;
|
||||||
|
|
||||||
|
/// 32px 间距(超大间距)
|
||||||
|
///
|
||||||
|
/// 常用于:
|
||||||
|
/// - 页面大区块
|
||||||
|
/// - 顶部/底部留白
|
||||||
|
static const double s32 = 32;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user