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

flutter-micro-ui-rules.mdrules/

RULES: Flutter Micro-UI (Atomic Design)

Atom Rules (StatelessWidget)

  • You MUST ALWAYS use StatelessWidget for atoms — components that receive ALL data via constructor parameters and render it without any local state, controllers, or Riverpod access.
  • You MUST NEVER use HookConsumerWidget, ConsumerWidget, StatefulWidget, or HookWidget for atoms. If the component needs no controllers, no ref, and no mutable state, it MUST be a StatelessWidget.
  • You MUST ALWAYS make atom constructor parameters final and use const constructors when possible.
  • You MUST NEVER place business logic, API calls, navigation, or side effects inside an atom.

Molecule Rules (HookConsumerWidget)

  • You MUST ALWAYS use HookConsumerWidget from hooks_riverpod for molecules — interactive components that require local controllers (e.g., useTextEditingController, useFocusNode, useAnimationController) OR need to read/watch Riverpod providers.
  • You MUST NEVER place business logic (API calls, data transformation, domain operations, BLoC event dispatching) inside a HookConsumerWidget. Business logic MUST stay in Riverpod providers or BLoCs.
  • A HookConsumerWidget MUST ONLY handle:
    • Ephemeral UI state (text controllers, focus nodes, animation controllers, scroll controllers)
    • Input validation via a Validator class or mixin (see Validator Rule below)
    • Reading/watching Riverpod providers for display data
    • Dispatching user intent to providers (e.g., ref.read(provider.notifier).submit(value))
  • You MUST NEVER use setState() in any micro-UI component. Use hooks for local state (useState, useTextEditingController) and Riverpod for shared state.

Validator Rules

  • You MUST ALWAYS extract input validation logic into a dedicated Validator class or mixin per molecule. The validator MUST NOT live inline inside the build() method.
  • The Validator MUST expose a String? validate(String? value) method (or equivalent typed signature) for each field.
  • You MUST ALWAYS wire the Validator's validate method to TextFormField.validator (or equivalent) so error states render automatically via Flutter's Form widget.
  • You MUST ALWAYS use a GlobalKey<FormState> to trigger formKey.currentState!.validate() before submitting.
  • You MUST NEVER perform validation by manually checking controller text inside button callbacks — ALWAYS use the Form + Validator pattern.

Decision Tree Rule

  • Before creating any micro-UI component, you MUST classify it:
    • Atom (StatelessWidget): The component ONLY displays data passed via constructor. No controllers, no ref, no mutable state. Examples: labels, icons, badges, static cards, display-only list items.
    • Molecule (HookConsumerWidget): The component has interactive elements (text fields, toggles, sliders), needs local controllers (useTextEditingController, useFocusNode), or must access Riverpod state (ref.watch). Examples: search bars, form fields, toggle switches with state, filter chips with selection.
  • You MUST NEVER default to HookConsumerWidget when StatelessWidget suffices. Start with atom; escalate to molecule ONLY when required.

Testing Rules

  • You MUST ALWAYS generate a widget test file for every HookConsumerWidget molecule.
  • You MUST ALWAYS wrap the widget under test in a ProviderScope with overrides: to mock all Riverpod dependencies.
  • You MUST ALWAYS test: (1) initial render state, (2) user interaction triggers correct provider calls, (3) validation error states display correctly for invalid input, (4) validation passes for valid input.
  • You MUST use mocktail for mocking providers and dependencies — NEVER mockito.
  • Atom (StatelessWidget) tests are optional but MUST be written if the atom has conditional rendering logic (e.g., null checks, theme variations).

File Placement Rules

  • Atoms MUST be placed in lib/shared/widgets/atoms/ or lib/features/{feature}/presentation/widgets/atoms/.
  • Molecules MUST be placed in lib/shared/widgets/molecules/ or lib/features/{feature}/presentation/widgets/molecules/.
  • Validators MUST be placed alongside their molecule: {molecule_name}_validator.dart in the same directory.
  • Test files MUST mirror source paths: test/shared/widgets/molecules/ or test/features/{feature}/presentation/widgets/molecules/.

tile.json