mcpField
C
create-catalog-item

create-catalog-item

github.com/flutter开发1.8k121 次安装2 周前更新
代码仓库

关于 create-catalog-item

指导根据 json_schema_builder Schema 实现 GenUI CatalogItem 的开发技能,涵盖数据类、JSON 解析、CatalogItem 连接及 Flutter Widget 行为,也包括 Schema 中定义的操作。

主要功能

  1. 01按 Schema 属性生成数据类
  2. 02使用类型字段解析 JSON 并处理错误
  3. 03连接由 Schema 定义的 CatalogItem
  4. 04构建展示字段的 Flutter Widget
  5. 05解析并分发 Schema 操作

适用场景

  1. 01根据 Schema 实现 GenUI CatalogItem
  2. 02为 Schema 组件添加操作处理

安装

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

$npx skills add https://github.com/flutter/genui --skill create-catalog-item

安装后在 Claude Code 中输入/create-catalog-item确认已加载。

详细介绍

创建 CatalogItem

目标

根据提供的 json_schema_builder Schema 正确实现 GenUI CatalogItem,包括对应的数据类、CatalogItem 实例和 Widget 类。这样可确保 AI 模型能够正确生成并与 UI 组件交互。

说明

需要根据 Schema 创建 CatalogItem 时,请按以下步骤操作:

  1. 创建数据类:

    • 将其命名为 _<SchemaName>Data(例如,如果 schema 是 myCardSchema,数据类就是 _MyCardData)。
    • 为 schema 中定义的每个属性添加 final 字段。
    • 创建一个 factory _<SchemaName>Data.fromJson(Map<String, Object?> json) 方法。
    • 使用 try-catch 块解析属性并返回一个新实例。
    • 将 json 映射中的每个属性转换为其预期类型,例如:title: json['title'] as String, 或 action: json['action'] as JsonMap?,。
    • 如果发生错误,在 catch 块中抛出 Exception('Invalid JSON for _<SchemaName>Data')。
  2. 创建 CatalogItem 实例:

    • 将其命名为与 schema 名称相同,但不带 "Schema" 后缀(例如,myCardSchema 对应 myCard)。
    • 声明为 final CatalogItem。
    • 将 name 设置为名称首字母大写后的形式(例如,'MyCard')。
    • 将 dataSchema 设置为提供的 schema。
    • 实现 widgetBuilder: (itemContext):
      • 将 itemContext.data 转换为 Map<String, Object?>。
      • 使用数据类的 fromJson 方法解析数据:_<SchemaName>Data.fromJson(json)。
      • 返回对应的 Widget 类,并传入所需数据。
      • 如果 schema 包含操作回调(例如 onCompleted),请在此处实现。必须使用 resolveContext 解析操作上下文,并通过 itemContext.dispatchEvent(...) 分发事件。
  3. 创建 Widget 类:

    • 将其命名为 _<CapitalizedSchemaName>(例如,_MyCard)。
    • 根据状态需求继承 StatelessWidget 或 StatefulWidget。
    • 将数据类添加为必需属性(例如,final _<SchemaName>Data data;)。
    • 添加任何必需的回调属性(例如,final void Function(int) onCompleted;)。
    • 使用 Flutter Material 组件(例如,Card、Column、Text)实现 build 方法。确保显示数据类中的每个数据字段,并通过按钮或其他交互元素呈现操作。

示例

输入 Schema
final basicCardSchema = S.object(
  properties: {
    'component': S.string(enumValues: ['BasicCard']),
    'title': S.string(),
    'description': 
    'action': A2uiSchemas.action(),
  },
  required: ['title'],
);
预期输出
class _BasicCardData {
  final String title;
  final JsonMap? action;

  _BasicCardData({required this.title, this.action});

  factory _BasicCardData.fromJson(Map<String, Object?> json) {
    try {
      return _BasicCardData(
        title: json['title'] as String,
        action: json['action'] as JsonMap?,
      );
    } catch (e) {
      throw Exception('Invalid JSON for _BasicCardData: $e');
    }
  }
}

final basicCard = CatalogItem(
  name: 'BasicCard',
  dataSchema: basicCardSchema,
  widgetBuilder: (itemContext) {
    final json = itemContext.data as Map<String, Object?>;
    final data = _BasicCardData.fromJson(json);

    return _BasicCard(
      data: data,
      onTap: () async {
        final action = data.action;
        if (action == null) return;
        final event = action['event'] as JsonMap?;
        final name = (event?['name'] as String?) ?? '';
        final JsonMap contextDefinition =
            (event?['context'] as JsonMap?) ?? <String, Object?>{};
        final JsonMap resolvedContext = await resolveContext(
          itemContext.dataContext,
          contextDefinition,
        );
        itemContext.dispatchEvent(
          UserActionEvent(
            name: name,
            sourceComponentId: itemContext.id,
            context: resolvedContext,
          ),
        );
      }
    );
  },
);

class _BasicCard extends StatelessWidget {
  final _BasicCardData data;
  final VoidCallback onTap;

  const _BasicCard({super.key, required this.data, required this.onTap});

  @override
  Widget build(BuildContext context) {
    return Card(
      child: ListTile(
        title: Text(data.title),
        onTap: onTap,
      ),
    );
  }
}

约束

  • 使用恰当的 try-catch 块和类型转换,在 fromJson 中解析 JSON。
  • 确保操作解析能够通过 resolveContext 准确获取变量,并在 Schema 中存在操作时使用 itemContext.dispatchEvent。

评论

支持 Markdown