[WIP] epic: rewrite forms around ChangeNotifier - #52
Draft
mateusz-pietras wants to merge 61 commits into
Draft
Conversation
KamilSztandur
force-pushed
the
refactor/forms-rework
branch
from
August 14, 2026 07:43
a4cbe41 to
af26daa
Compare
…nagement Migrated from Cubit (Bloc) to value notifier. Removed dependencies: flutter_bloc, rx_dart, equatable, Changes are reflected on examples Changes are reflected on tests
Removed unnecessary //ignore commands Reverted version change on leancode_lint in example project Added debugLabel
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Examples modified FormGroupState is renamed into FormState
Examples and tests modified accordingly
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Added FocusNode support in AdvancedTextFieldController * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
extract common code like copyWith methods; apply leancode architecture standards (field ordering, codestyle); remove maintainer docs from public-facing api
clean up code; fix issue where if async validator thrown an error, the error wouldnt be reported until caught in zone, while the form field got stuck in `validating` status
add isDisposed flag in field controller; resolve debounce issues in async validator
mateusz-pietras
force-pushed
the
refactor/forms-rework
branch
from
August 14, 2026 10:18
af26daa to
56b8112
Compare
Every validation pass now belongs to the value it was started for. `setValue`, `setError`, `clearErrors`, `reset`, `markReadOnly`, `setValidationEnabled(false)` and `dispose` all abort the pending or in-flight round, which can then never write state, notify, or report. That closes a family of bugs where a stale result resurrected an earlier value or undid a just-applied change. A round settles exactly once, so nothing can await a result that never arrives, and a validator that throws before its first `await` takes the same path as a rejected future instead of wedging the field on `validating`. A settled answer is reused while it still describes the value, so a second submit on an unchanged form makes no network calls. `validate()` is now `Future<bool>` on both controllers and runs the async validators; calling it again before the first call finishes gives the same result. Form aggregates — `validating`, `canSubmit`, `hasFailedValidation`, `validationErrors` — are derived from the fields on read, so they cannot outlive the child that justified them. Adds `AsyncValidation.timeout` and `failureToError`, `FieldStatus.failedValidation` and `AdvancedFieldController.lastFailure`. Splits `AdvancedFieldState` and `AsyncValidation` into their own files, and replaces `CancelableFuture` with `CoalescingCall`. BREAKING CHANGE: `validate()` returns `Future<bool>`; `AsyncValidation.onError` is now `onFailure`; `autovalidate` gates the async validator too; `reset()` keeps `autovalidate` and `readOnly`; `setError(null)` clears the error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141bii9YkhiH3V77uRiabsU
Covers round ownership and every abort point, terminal states for a validator that throws or times out, verdict reuse, `validate()` sharing one pass across concurrent calls, the `failedValidation` status and `lastFailure`, the derived form aggregates, and the text controller reconciling after a rejected write. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141bii9YkhiH3V77uRiabsU
Describes the validation model in the README, the upgrade path in MIGRATION.md and the API delta in the changelog, and moves the recipes in EXAMPLES.md to the async `validate()` and the `AsyncValidation` object. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141bii9YkhiH3V77uRiabsU
Updates every screen to the controller API and the async `validate()`, and adds an optimized-rendering screen that demonstrates the builder's `child` parameter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141bii9YkhiH3V77uRiabsU
throw when calling controller methods when disposed
Written and hardened over 5 test-verify-refine iterations: 15 agent builds from the skill alone (all flutter-analyze clean), every claim adjudicated against package source, disputed semantics locked by executed tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Fix the false claim that super-parameters cannot combine with an explicit super(...) call; the PhoneFieldController example now uses super.validator. - Async validation is available on every field controller, selects included — drop the "text and boolean only" restriction. - Soften "one ErrorTranslator per error enum": the same error code often needs different wording per field. - Spell out the "at least one traveler" cross-field example. - Drop the dispose() override snippet for detached subforms; state the ownership rule in prose instead. - Realign with the rebased base: the validate() gate sweep no longer consults validationEnabled in that order, and subscribeToFields / registerFields throw on disposed controllers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(validation): refine validation pipeline; fix validation issues
docs: add AI agent skill for building forms with leancode_forms
feat(form): add addRelation for cross-field value dependencies
Full quality pass over the tracked markdown docs: README, CHANGELOG, MIGRATION, and example/README, run as an iterative analyze -> verify -> implement loop, followed by a two-axis review (standards + spec) and a PR review pass (#56). - README: added title, badges, license footer, API-reference link; fixed false claims (dependency list vs pubspec, asyncValidation support on select controllers); quickstart compiles as shown; Validation section trimmed to the happy path; renamed "validation round" to "validation pass" throughout. - CHANGELOG: 0.2.0 regrouped into Breaking / Added / Changed / Fixed / Deprecated; rename bullets kept as a sublist; missing entries added (Flutter SDK floor raise, revalidateSync); reworded imprecise wording. - MIGRATION: before-code no longer shows an API that never existed in 0.1.x; every behavior change has its own linkable heading; undefined refreshFor() replaced with the real revalidateSync(). - example/README: replaced the flutter create placeholder with run instructions and a screen guide table, pointing at README anchors. - Removed EXAMPLES.md (introduced during drafting, decided against in review — example/, README and the SKILL cover the same ground) and every reference to it across the other docs. - Removed DOCS_SPEC.md, the working spec used to drive this pass (process artifact, not shipped documentation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
docs: overhaul package documentation against a written spec
- Cross-field logic: replace the raw addListener + setValue pattern with AdvancedFormController.addRelation (select/onChange, ==-compared, cleaned up in dispose, no call at registration, StateError on disposed). - Document validateWithAutovalidate() next to validateAll, and state that validateAll is that same primitive run on every value change. - Point 0.1.x migration tasks at MIGRATION.md / CHANGELOG.md instead of this skill. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
docs(skill): sync leancode-forms skill with refactor/forms-rework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.