packages/genui/skills/create-catalog-item/SKILL.md
Use this skill when the user asks to create a new CatalogItem, data class, and/or widget class based on a JSON Schema definition in an application that uses Flutter's `genui` package.
npx skillsauth add flutter/genui create-catalog-itemInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
When tasked with creating a CatalogItem from a Schema, follow these steps:
Create the Data Class:
_<SchemaName>Data (e.g., if schema is myCardSchema, data class is _MyCardData).factory _<SchemaName>Data.fromJson(Map<String, Object?> json) method.try-catch block to parse the properties and return a new instance.json map to its expected type, e.g., title: json['title'] as String, or action: json['action'] as JsonMap?,.Exception('Invalid JSON for _<SchemaName>Data') in the catch block if an error occurs.Create the CatalogItem Instance:
myCard for myCardSchema).final CatalogItem.name to the capitalized version of the name (e.g., 'MyCard').dataSchema to the provided schema.widgetBuilder: (itemContext):
itemContext.data to Map<String, Object?>.fromJson method: _<SchemaName>Data.fromJson(json).onCompleted), implement it here. You must parse the action context using resolveContext and dispatch an event using itemContext.dispatchEvent(...).Create the Widget Class:
_<CapitalizedSchemaName> (e.g., _MyCard).StatelessWidget or StatefulWidget depending on state requirements.final _<SchemaName>Data data;).final void Function(int) onCompleted;).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.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 blocks and type casting when parsing JSON in fromJson.resolveContext and uses itemContext.dispatchEvent when actions are present in the Schema.tools
Development helper for the GenUI repository. Use this skill when the user asks about GenUI workflows, running tests, creating components, finding A2UI or Dart references, or adhering to repository standards.
data-ai
Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some waiting on outside answers, and others rolling into a later summary.
data-ai
Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some waiting on outside answers, and others rolling into a later summary.
data-ai
OpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.