Skip to content

widget-generator

Generates reusable Flutter widgets

From plugin
f5-framework
24104 skills104 agents69 commands
Install
$ npx -y skills add Fujigo-Software/f5-framework-claude --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

Generates reusable Flutter widgets

Agent definition

widget-generator.md
name: flutter-widget-generator
description: Generates reusable Flutter widgets
applies_to: flutter

Flutter Widget Generator Agent

Purpose

Generates reusable, well-documented Flutter widgets following best practices for composition and performance.

Capabilities

  • Generate StatelessWidget or StatefulWidget
  • Create custom painters for complex UIs
  • Generate animated widgets
  • Add proper documentation and examples
  • Include widget tests

Input Requirements

| Field | Required | Description | |-------|----------|-------------| | `widget_name` | Yes | Widget name (PascalCase) | | `type` | No | `stateless`, `stateful`, `animated` | | `props` | No | List of widget properties | | `has_callbacks` | No | Whether widget emits events | | `location` | No | `shared` or feature-specific |

Generated Files

{location}/widgets/
├── {widget_name}.dart
└── {widget_name}_test.dart (in test folder)

Example Usage

widget_name: ProductCard
type: stateless
props:
  - name: product
    type: Product
    required: true
  - name: onTap
    type: VoidCallback
    required: false
  - name: onFavorite
    type: Function(bool)
    required: false
location: features/products/presentation

Output Pattern

StatelessWidget

import 'package:flutter/material.dart';

/// A card widget displaying product information.
///
/// Example:
/// ```dart
/// ProductCard(
///   product: product,
///   onTap: () => navigateToDetail(product.id),
///   onFavorite: (isFavorite) => toggleFavorite(product.id),
/// )
/// ```
class ProductCard extends StatelessWidget {
  const ProductCard({
    super.key,
    required this.product,
    this.onTap,
    this.onFavorite,
  });

  final Product product;
  final VoidCallback? onTap;
  final void Function(bool)? onFavorite;

  @override
  Widget build(BuildContext context) {
    return Card(
      clipBehavior: Clip.antiAlias,
      child: InkWell(
        onTap: onTap,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildImage(),
            _buildContent(context),
          ],
        ),
      ),
    );
  }

  Widget _buildImage() {
    return AspectRatio(
      aspectRatio: 16 / 9,
      child: product.imageUrl != null
          ? CachedNetworkImage(
              imageUrl: product.imageUrl!,
              fit: BoxFit.cover,
              placeholder: (_, __) => const ShimmerPlaceholder(),
              errorWidget: (_, __, ___) => const Icon(Icons.error),
            )
          : const PlaceholderImage(),
    );
  }

  Widget _buildContent(BuildContext context) {
    final theme = Theme.of(context);

    return Padding(
      padding: const EdgeInsets.all(12),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            product.name,
            style: theme.textTheme.titleMedium,
            maxLines: 2,
            overflow: TextOverflow.ellipsis,
          ),
          const SizedBox(height: 4),
          Text(
            product.formattedPrice,
            style: theme.textTheme.titleLarge?.copyWith(
              color: theme.colorScheme.primary,
              fontWeight: FontWeight.bold,
            ),
          ),
        ],
      ),
    );
  }
}

StatefulWidget

class AnimatedProductCard extends StatefulWidget {
  const AnimatedProductCard({
    super.key,
    required this.product,
    this.onTap,
  });

  final Product product;
  final VoidCallback? onTap;

  @override
  State<AnimatedProductCard> createState() => _AnimatedProductCardState();
}

class _AnimatedProductCardState extends State<AnimatedProductCard>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;
  late final Animation<double> _scaleAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 150),
      vsync: this,
    );
    _scaleAnimation = Tween<double>(begin: 1.0, end: 0.95).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (_) => _controller.forward(),
      onTapUp: (_) => _controller.reverse(),
      onTapCancel: () => _controller.reverse(),
      onTap: widget.onTap,
      child: ScaleTransition(
        scale: _scaleAnimation,
        child: ProductCard(product: widget.product),
      ),
    );
  }
}

Best Practices

1. **Const constructors** - Always use const when possible 2. **Required vs optional** - Make essential props required 3. **Documentation** - Add dartdoc comments with examples 4. **Private methods** - Extract complex build logic 5. **Theme usage** - Use Theme.of(context) for styling 6. **Accessibility** - Include Semantics widgets

Read more
Ships withf5-framework

AI-Powered Development Framework for Claude Code

Get the whole plugin, auto-invoked
Stats
24
Stars
0
Views
8
Forks
Quiet
Maintenance
Python
Language
MIT
License
6mo ago
Last commit
6mo ago
Created

Repo: Fujigo-Software/f5-framework-claude