新增:档案页共享组件三件 + TagPill 深变体映射(DEBT-1 偿还)
- PetAvatar 四尺寸档(96/64/44/32)收敛头像重复实现:3px 白描边 + 轻投影,编辑徽标底改 primaryStrong(白图标 4.49:1 达非文字 3:1), M2 无上传(ADR-010),url 缺省渲染本地占位形态 - RecordTypeDot 三尺寸档 + 五类记录类型的图标/三色映射唯一出口 (05 号规范 §2 表,供 T2-13/14 时间线复用) - EmptyStateIllustration 空态插画区(112 圆 + 标题 + 说明 + 可选 CTA) - TagPill 增可选 inkColor,缺省按 color 查深变体映射 (primary→primaryDark 8.74:1 / success→successInk 7.39:1 / accent→accentDark 7.07:1 / error→errorDark 5.78:1 / 未命中→ink), 既有调用零参数回归 - AppColors 新增 errorDark #B02C25、inkSoft #6B5A4A(05 号规范 D8) flutter test 141/141 全绿;analyze 0 问题(T2-12 第一部分) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patbond_flutter/core/theme/app_theme.dart';
|
||||
|
||||
/// 空态插画区(05 号规范 §3.4):承载引导动作的空态,向上兼容现有
|
||||
/// `EmptyState`(42 图标 + 一行 bodySmall 的纯提示版继续留用)。
|
||||
///
|
||||
/// 布局:112 圆形插画区(`surfaceTint` 底 + 56 `primary` 图标,大面积
|
||||
/// 装饰用法)→ 标题 → 说明(12 `inkSoft` ≤2 行居中)→ 可选 CTA。
|
||||
/// v1 插画用 Material 图标,正式素材待品牌侧供给后原位替换。
|
||||
class EmptyStateIllustration extends StatelessWidget {
|
||||
const EmptyStateIllustration({
|
||||
required this.icon,
|
||||
required this.title,
|
||||
super.key,
|
||||
this.description,
|
||||
this.ctaLabel,
|
||||
this.onCtaPressed,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final String title;
|
||||
final String? description;
|
||||
|
||||
/// CTA 文案;null 则不渲染按钮(如筛选后空态)。
|
||||
final String? ctaLabel;
|
||||
final VoidCallback? onCtaPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 48, horizontal: 16),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 112,
|
||||
height: 112,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: AppColors.surfaceTint,
|
||||
),
|
||||
child: Icon(icon, size: 56, color: AppColors.primary),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
if (description != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
description!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
color: AppColors.inkSoft,
|
||||
fontSize: 12,
|
||||
height: 1.4,
|
||||
),
|
||||
),
|
||||
],
|
||||
if (ctaLabel != null) ...[
|
||||
const SizedBox(height: 24),
|
||||
FilledButton(
|
||||
style: FilledButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
),
|
||||
onPressed: onCtaPressed,
|
||||
child: Text(ctaLabel!),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user