create-catalog-item

作者: flutter

当用户要求基于JSON Schema定义在应用程序中创建新的CatalogItem、数据类和/或控件类时,使用此技能。

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

Create CatalogItem

Goal

To correctly implement a GenUI CatalogItem based on a provided json_schema_builder Schema, including its corresponding data class, CatalogItem instance, and Widget class. This ensures the AI model can properly generate and interact with the UI component.

Instructions

When tasked with creating a CatalogItem from a Schema, follow these steps:

  1. Create the Data Class:

    • Name it _<SchemaName>Data (e.g., if schema is myCardSchema, data class is _MyCardData).
    • Add final fields for each property defined in the schema.
    • Create a factory _<SchemaName>Data.fromJson(Map<String, Object?> json) method.
    • Use a try-catch block to parse the properties and return a new instance.
    • Cast each property from the json map to its expected type, e.g., title: json['title'] as String, or action: json['action'] as JsonMap?,.
    • Throw an Exception('Invalid JSON for _<SchemaName>Data') in the catch block if an error occurs.
  2. Create the CatalogItem Instance:

    • Name it identical to the schema name but without the "Schema" suffix (e.g., myCard for myCardSchema).
    • Declare as a final CatalogItem.
    • Set name to the capitalized version of the name (e.g., 'MyCard').
    • Set dataSchema to the provided schema.
    • Implement the widgetBuilder: (itemContext):
      • Cast itemContext.data to Map<String, Object?>.
      • Parse the data using the data class fromJson method: _<SchemaName>Data.fromJson(json).
      • Return the corresponding Widget class and pass the required data.
      • If the schema includes an action callback (like onCompleted), implement it here. You must parse the action context using resolveContext and dispatch an event using itemContext.dispatchEvent(...).
  3. Create the Widget Class:

    • Name it _<CapitalizedSchemaName> (e.g., _MyCard).
    • Inherit from StatelessWidget or StatefulWidget depending on state requirements.
    • Add the Data Class as a required property (e.g., final _<SchemaName>Data data;).
    • Add any required callback properties (e.g., final void Function(int) onCompleted;).
    • Implement the build method using Flutter Material components (e.g., Card, Column, Text). Make sure each data field in the data class is displayed, and that actions are represented by buttons or other interactive elements.

Examples

Input Schema

final basicCardSchema = S.object(
  properties: {
    'component': S.string(enumValues: ['BasicCard']),
    'title': S.string(),
    'description': 
    'action': A2uiSchemas.action(),
  },
  required: ['title'],
);

Expected Output

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,
      ),
    );
  }
}

Constraints

  • Ensure proper use of try-catch blocks and type casting when parsing JSON in fromJson.
  • Make sure action resolution accurately fetches variables via resolveContext and uses itemContext.dispatchEvent when actions are present in the Schema.

来自 flutter 的更多技能

dart-modern-features
flutter
为了找到现代化的候选方案:
flutter-fix-layout-issues
flutter
使用Dart和Flutter MCP工具修复Flutter布局错误(溢出、无界约束)。适用于处理“RenderFlex溢出”、“垂直…
adding-release-notes
flutter
在 DevTools 发布说明中添加面向用户的变更描述。用于在 NEXT_RELEASE_NOTES.md 文件中记录改进、修复或新功能。
reviewing-devtools-prs
flutter
DevTools 仓库专属的PR审查工作流程,执行DevTools风格指南和常见审查模式。在审查……中的拉取请求时使用。
dart-use-primary-constructors
flutter
帮助用户在Dart中编写语法和语义正确的主构造函数,并迁移/使用新的构造函数语法、空体分号语法等。
code-documentation
flutter
编写有效代码文档的指南,包括docstrings、JSDoc、dartdoc和实现注释。在编写新代码、添加…时使用此技能。
api-review
flutter
对照规范的API设计指南审查指定代码。当用户要求进行API审查或根据API设计规范检查代码时,请使用此技能…
flutter-accessibility
flutter
在Flutter应用中实现WCAG 2和EN 301 549无障碍标准及自适应布局。在移动端、网页端和桌面端强制实施语义标注、点击目标尺寸(最小48x48 dp)和文本对比度(小文本4.5:1,大文本3:1)。提供网页语义初始化、交互式组件包裹、基于屏幕尺寸的布局切换以及键盘/鼠标输入处理的决策逻辑。包含通过FocusTraversalGroup实现的焦点遍历管理,以及...