mcpField
U
ui-package

ui-package

github.com/verygoodopensource开发17564 次安装今天更新
代码仓库

关于 ui-package

面向 Flutter 开发者的可复用 UI 包构建指南,围绕 Material 组件、ThemeExtension 主题令牌和一致的组件 API 组织设计。还规定包结构、公共导出、组件测试及 Widgetbook 目录等实践。

主要功能

  1. 01基于 Material 组件组合 UI
  2. 02使用 ThemeExtension 扩展主题令牌
  3. 03通过单一 barrel 文件导出公共 API
  4. 04每个组件配套行为测试
  5. 05包含 pumpApp 与 Widgetbook 脚手架

适用场景

  1. 01创建可复用的 Flutter UI 包
  2. 02为应用定义间距和自定义颜色令牌
  3. 03实现遵循 Material 的共享组件
  4. 04为组件编写交互测试并整理目录

MCP 相关

指南要求使用 Very Good CLI MCP 的 `create` 工具,并将 `subcommand` 设为 `app_ui_package` 来生成 UI 包。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/verygoodopensource/vgv-ai-flutter-plugin --skill ui-package

安装后在 Claude Code 中输入/ui-package确认已加载。

附带文件agents/openai.yamlreference.md

详细介绍

UI 包

创建 Flutter UI 包的最佳实践——一个可复用的 widget 库,构建于 package:flutter/material.dart 之上,通过特定于应用的组件、使用 ThemeExtension 定义的自定义设计令牌,以及一致的 API 表面来扩展它。

主题基础: 本技能侧重于 UI 包结构、widget API 和测试。有关 Material 3 主题的基础知识(ColorScheme、TextTheme、组件主题、间距常量、浅色/深色模式),请参阅 Material Theming 技能(/material-theming)。这两项技能互为补充——Material Theming 介绍如何设置和使用 ThemeData;本技能介绍如何使用 ThemeExtension 扩展它,并围绕它封装可复用的 widget。

核心标准

所有 UI 包工作都应遵循以下标准:

  • 从 app_ui_package 模板搭建——使用 Very Good CLI MCP 工具创建包,subcommand: 'app_ui_package'。绝不要使用 flutter_package、dart_package 或 flutter create --template=package;它们生成的是精简包,不包含下文所述的主题、导出文件、测试辅助工具或 Widgetbook 脚手架
  • 基于 Material 构建——依赖 flutter/material.dart 并组合使用 Material widget;不要重新构建 Material 已提供的基础组件
  • 每个文件对应一个 widget——每个公开 widget 都放在单独的文件中,文件名使用该 widget 名称的 snake_case 形式(例如,app_button.dart)
  • 通过导出文件公开 API——通过单一导出文件(例如,lib/my_ui.dart)公开所有公开 widget 和主题类;该文件还应重新导出 material.dart,这样使用方只需一次导入,就能同时使用 Material 的 widget 和包自身的 widget,无需再导入 Material
  • lib/src/ 是私有目录——使用方只导入导出文件,不导入其他文件;逐个导入文件(例如 package:my_ui/src/widgets/app_button.dart)会访问私有实现,并且任何内部重命名都会导致导入失效。Tree shaking 会自动移除未使用的 widget,因此导出文件不会带来任何开销
  • 使用 ThemeExtension 扩展主题——以 Material 的 ThemeData、ColorScheme 和 TextTheme 为基础(参见 Material Theming 技能);通过 ThemeExtension<T> 添加特定于应用的令牌(间距、自定义颜色),将每个令牌都注册到 ThemeData.extensions 中,并通过 BuildContext 扩展读取它们(context.appColors、context.appSpacing)
  • 每个 widget 都有对应的 widget 测试——行为测试需验证交互、回调和状态变化,并通过包的 pumpApp 辅助工具进行泵测,而不是内联使用 MaterialApp
  • 用可运行的代码纠正反模式——当请求涉及反模式表中的内容时,说明其错误之处,并在同一回复中提供修正后的实现。不要只提出异议,也不要询问是否可以按文档所述的方式实现
  • 为所有公开类添加前缀——使用一致的前缀(例如 App、Vg),避免与 Material widget 发生命名冲突
  • 尽可能在所有地方使用 const 构造函数——所有 widget 构造函数都应在可行时声明为 const
  • 为每个公开成员编写文档——每个公开类、构造函数参数和方法都必须有 dartdoc 注释

包结构

my_ui/
├── lib/
│   ├── my_ui.dart              # Barrel file — re-exports material.dart + all public API
│   └── src/
│       ├── theme/
│       │   ├── app_theme.dart        # AppTheme class with light/dark ThemeData builders
│       │   ├── app_colors.dart       # AppColors ThemeExtension for custom color tokens
│       │   ├── app_spacing.dart      # AppSpacing ThemeExtension for spacing tokens
│       │   └── app_text_styles.dart  # Optional: extra text styles beyond Material's TextTheme
│       ├── widgets/
│       │   ├── app_button.dart
│       │   ├── app_text_field.dart
│       │   ├── app_card.dart
│       │   └── ...
│       └── extensions/
│           └── build_context_extensions.dart  # context.appColors, context.appSpacing shortcuts
├── test/
│   ├── src/
│   │   ├── theme/
│   │   │   └── app_theme_test.dart
│   │   └── widgets/
│   │       ├── app_button_test.dart
│   │       └── ...
│   └── helpers/
│       └── pump_app.dart         # Test helper wrapping widgets in MaterialApp + theme
├── widgetbook/                   # Widgetbook catalog submodule (sandbox + showcase)
│   └── ...
└── pubspec.yaml

构建 Widget

Widget API 指南
  • 组合使用 Material widget——将 FilledButton、OutlinedButton、TextField、Card 等用作构建模块
  • 只接受必需的最少参数——避免“厨房水槽式”构造函数
  • 除 key 和 child/children 外,所有参数都使用命名参数
  • 未提供参数时,根据主题提供合理的默认值
  • 使用 ValueChanged<T> 或 VoidCallback 暴露回调——不要使用原始 Function
  • 使用 Widget? 实现可选的插槽式组合(前置、后置图标等)

反模式

反模式正确做法
重建 Material 已提供的组件(例如,用 GestureDetector + DecoratedBox 自定义按钮)组合使用 Material 组件(FilledButton、OutlinedButton)并为其设置样式
使用自定义 InheritedWidget 创建平行的主题系统以 Material 的 ThemeData 为基础,并使用 ThemeExtension 定义自定义令牌
在组件代码中硬编码 Color(0xFF...)标准颜色使用 Theme.of(context).colorScheme,自定义令牌使用 context.appColors
在自定义类中重复定义 Material 的 ColorScheme 角色仅为 Material 未涵盖的值创建 ThemeExtension 令牌(例如 success、warning、info)
将 dynamic 或 Object 用作回调类型使用 VoidCallback、ValueChanged<T> 或特定的函数 typedef
直接公开内部实现文件使用 barrel 文件;将 src/ 下的所有文件设为私有

创建软件包

使用 Very Good CLI MCP create 工具搭建框架:

参数值
subcommandapp_ui_package — 所有 UI 软件包始终使用此值
name采用 snake_case 的软件包名称(例如,storefront_ui)
output_directory存放共享软件包的 monorepo 目录(例如,packages/)

app_ui_package 是随附 lib/src/theme 扩展、barrel 文件、pumpApp 助手和 Widgetbook 目录的模板。flutter_package 则提供一个空软件包,需要你手动重新构建。

跨环境备用方案。 如果主机没有此插件的 Bash hooks,也未连接 Very Good CLI MCP 服务,请直接运行等效命令 very_good create app_ui_package <package_name> --output-directory <dir>。

参阅 reference.md,了解 ThemeExtension 类表(AppColors、AppSpacing、AppTheme、BuildContext 扩展)、pumpApp 测试助手、barrel 文件示例、Widgetbook 目录概念和 build_runner 命令,以及添加组件或自定义令牌的分步工作流。

评论

支持 Markdown