CtrlK
BlogDocsLog inGet started
Tessl Logo

g14wxz/flutter-micro-ui

Atomic Design micro-UI architecture

90

Quality

90%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/generate-micro-ui/

name:
generate-micro-ui
description:
Generates micro Flutter/Dart UI components (atoms/molecules) following Atomic Design patterns. Uses StatelessWidget for atoms and HookConsumerWidget for molecules, including form validation classes and auto-generated widget tests with mocktail mocks. Use when the user asks to create small Flutter UI components such as buttons, text fields, inputs, cards, or reusable widgets following Atomic Design principles, or when they need a Flutter atom, molecule, or micro-UI component with Riverpod integration.

Skill: Generate Micro-UI Component

Pre-Conditions

HALT on any missing prerequisite — instruct the user to resolve it before continuing.

  1. hooks_riverpod and flutter_hooks present in pubspec.yaml.
  2. mocktail present in dev_dependencies.
  3. Target feature directory exists (if feature-scoped) or lib/shared/widgets/ exists (if shared).
  4. Component name, purpose, and input fields/props have been provided.

Path Template

All paths follow this convention (substitute {scope} and {type}):

ScopeWidget sourceTest
Sharedlib/shared/widgets/{type}/{component_name}.darttest/shared/widgets/{type}/{component_name}_test.dart
Featurelib/features/{feature}/presentation/widgets/{type}/{component_name}.darttest/features/{feature}/presentation/widgets/{type}/{component_name}_test.dart

{type} = atoms or molecules. Validator lives in the same directory as the molecule: {component_name}_validator.dart.

Shared Constraints (apply to ALL generated widget files)

  • MUST use const constructor
  • MUST use package:storestorm/... imports — NEVER relative imports
  • MUST include a dartdoc comment explaining the component's purpose
  • MUST NOT contain business logic (API calls, data transformation, domain operations, repository access, BLoC event dispatch)

Phase 1 — Classify Component

MUST classify the component before writing any code.

ConditionClassificationWidget Type
All data from constructor, no controllers, no refAtomStatelessWidget
Needs useTextEditingController, useFocusNode, useState, or ref.watch/ref.readMoleculeHookConsumerWidget

If classification is ambiguous, default to Atom. Escalate to Molecule ONLY when a concrete controller or Riverpod access is required.

If the user requests StatefulWidget, HALT — explain the architecture mandates HookConsumerWidget for stateful micro-UI.

Phase 2 — Generate Atom (StatelessWidget)

Step 2.1 — Create widget file

Use the Path Template with {type} = atoms.

Atom-specific requirements (in addition to Shared Constraints):

  • All data as final constructor parameters
  • MUST NOT import hooks_riverpod, flutter_hooks, flutter_bloc, or provider
  • MUST NOT exceed 80 lines

Step 2.2 — Skip to Phase 6 (Post-Validation)

Atoms do NOT require a Validator or mandatory widget tests (unless conditional rendering exists).

Phase 3 — Generate Molecule (HookConsumerWidget)

Step 3.1 — Create widget file

Use the Path Template with {type} = molecules.

Molecule-specific requirements (in addition to Shared Constraints):

  • MUST extend HookConsumerWidget
  • MUST use hooks for all local state: useTextEditingController(), useFocusNode(), useState()
  • MUST NOT use setState() — NEVER
  • MUST delegate user actions to Riverpod providers via ref.read(provider.notifier).method()
  • MUST NOT exceed 120 lines — if larger, decompose into smaller atoms + molecule

Step 3.2 — Wire Form validation (if component has input fields)

  • Wrap input fields in a Form widget with a GlobalKey<FormState>
  • Wire each TextFormField.validator to the Validator class (generated in Phase 4)
  • Call formKey.currentState!.validate() before any submission action

Phase 4 — Generate Validator

Execute for every Molecule that has user input fields.

Step 4.1 — Create validator file

Path: same directory as the molecule — {component_name}_validator.dart.

Requirements:

  • Class with a private constructor (ClassName._())
  • Expose static String? validate(String? value) for each validated field — return null for valid, a user-facing error string for invalid
  • Pure — no dependencies on BuildContext, ref, or any external service
  • Handle: null/empty check, format validation (regex if applicable), length bounds
  • Include dartdoc on each method explaining accepted format

Step 4.2 — Wire validator to molecule

  • Import the validator in the molecule file
  • Assign validator: {ValidatorClass}.validate on each TextFormField

Phase 5 — Generate Widget Test

Mandatory for EVERY Molecule.

Step 5.1 — Create test file

Use the Path Template with {type} = molecules.

Step 5.2 — Test structure

import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mocktail/mocktail.dart';
// Import the widget and its dependencies

class Mock{X}Notifier extends Mock implements {X}Notifier {}

void main() {
  group('{ComponentName}', () {
    Widget createTestWidget({List<Override> overrides = const []}) =>
      ProviderScope(
        overrides: overrides,
        child: const MaterialApp(home: Scaffold(body: Form(child: {ComponentName}()))),
      );

    testWidgets('renders initial state correctly', (tester) async { /* assert key UI elements present */ });
    testWidgets('displays validation error for invalid input', (tester) async { /* enter invalid data, trigger validate, assert error text */ });
    testWidgets('passes validation for valid input', (tester) async { /* enter valid data, trigger validate, assert no error text */ });
    testWidgets('dispatches to provider on valid submission', (tester) async { /* submit, verify(() => mockNotifier.method(any())).called(1) */ });
  });
}

Mock setup rules:

  • Override providers in ProviderScope(overrides: [...]) — NEVER use real providers in tests
  • Register fallback values for any custom types used in verify or when calls

Phase 6 — Post-Execution Validation

After generating all files, verify each of the following. Fix any violation before reporting completion.

  1. Imports: All imports use package:storestorm/... — no relative imports anywhere.
  2. Classification: Atom files contain zero hooks/riverpod imports. Molecule files extend HookConsumerWidget.
  3. Validator (molecules with input): Validator file exists, is wired to the molecule, all validate methods return String?.
  4. Tests (molecules): Test file exists, uses ProviderScope with overrides, has minimum 4 test cases.
  5. Line counts: Atoms ≤ 80 lines, Molecules ≤ 120 lines.
  6. No business logic: Neither atoms nor molecules contain API calls, repository access, BLoC event dispatch, or data transformation.

Output Summary

After execution, report:

  • Component type: Atom or Molecule
  • Files created: list all file paths
  • Validator: created / not needed
  • Tests: created with N test cases
  • Validation: all checks passed / list violations fixed

skills

generate-micro-ui

tile.json