关于 create-catalog-item
指导根据 json_schema_builder Schema 实现 GenUI CatalogItem 的开发技能,涵盖数据类、JSON 解析、CatalogItem 连接及 Flutter Widget 行为,也包括 Schema 中定义的操作。
主要功能
- 01按 Schema 属性生成数据类
- 02使用类型字段解析 JSON 并处理错误
- 03连接由 Schema 定义的 CatalogItem
- 04构建展示字段的 Flutter Widget
- 05解析并分发 Schema 操作
适用场景
- 01根据 Schema 实现 GenUI CatalogItem
- 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 时,请按以下步骤操作:
-
创建数据类:
- 将其命名为
_<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')。
- 将其命名为
-
创建 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(...)分发事件。
- 将
- 将其命名为与 schema 名称相同,但不带 "Schema" 后缀(例如,
-
创建 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