MudFormComponent: Preserve consumer-managed Error when no validation source#13415
Conversation
…source ValidateValue's non-EditContext branch unconditionally wrote ErrorState and ErrorText from its own (usually empty) error list, so any validate pass - blur, submit, value change - wiped an Error/ErrorText the consumer set manually (MudBlazor#12732, MudBlazor#11244, MudBlazor#4593). Since Error/ErrorText became ParameterState-backed, that write clobbers rather than no-ops as the stale comment claimed. Only publish an assessment when the component has a validation source of its own (Validation, Required, For attributes, or a conversion error), or while it still needs to clear an error it previously published - tracked by _hasInternalError so a resolved conversion error still clears. Otherwise the consumer's Error/ErrorText stay intact. Adds regression tests for the text-field and select surfaces plus the conversion-error clear path.
|
Reproduced live on Before. A
Same on the Root cause. The non-EditContext branch of After. Same steps → Edge case guarded against. Gating purely on "has a validation source" would strand a conversion error: it sets Tests. 3 new regression tests (text field, select, conversion-clear). Full unit suite: 5424 passed / 2 skipped / 0 failed. The 1,254 form-component tests (Select / TextField / NumericField / Autocomplete / pickers / boolean inputs / Form) pass unchanged, since configured fields still hit the exact same write path. Note: |
Addresses review: _validationAttrsFor is non-null but empty when the For-targeted property has no ValidationAttribute, so `is not null` still counted it as a validation source and could wipe a consumer-managed Error. Require an actual attribute via Any(). Adds a regression test.
MudFormComponent.ValidateValue(the non-EditContext branch) unconditionally wroteErrorState/ErrorTextfrom its own error list on every validate pass. When a component has no validation source of its own, that list is empty, so a blur, submit, or value change wiped anyError/ErrorTextthe consumer had set manually.The stale comment claimed "setting them here will have no effect" — that was true before
Error/ErrorTextbecameParameterState-backed, but the internal write now wins over the parameter, so it clobbers.We now publish an internal assessment only when the component actually has a validation source:
Validation,Required,Forattributes, or a conversion error. A small_hasInternalErrorflag keeps us writing long enough to clear an error the component previously published (e.g. a resolved conversion error) even after its source goes away. Otherwise the consumer'sError/ErrorTextare left intact — the aria error-id, form update, and render still run so a consumer-managed error stays wired up.Fixes #12732
Fixes #11244
Fixes #4593
Likely also relevant to #7518 and #11503 (same clobber); left open for separate confirmation.