Skip to content

MudInput: Avoid duplicate blur interop during normal focus changes - #13049

Merged
danielchalmers merged 2 commits into
MudBlazor:devfrom
danielchalmers:likely-whale
Apr 19, 2026
Merged

danielchalmers merged 2 commits into
MudBlazor:devfrom
danielchalmers:likely-whale

Conversation

@danielchalmers

@danielchalmers danielchalmers commented Apr 15, 2026 •

Copy link
Copy Markdown
Member

This fixes #13011, a MudTextField / MudButton race where clicking a button immediately after editing a non-Immediate text field could execute the button OnClick before the field value was committed.

Root cause: MudInput had two independent blur paths:

  • the normal Blazor @onblur handler
  • a JS blur bridge added in #10842 that called back into .NET separately

That extra JS interop path could bypass Blazor’s normal ordered change -> blur -> click processing and create intermittent stale model values, especially on Blazor Server.

What changed:

  • keep native Blazor blur as the primary path
  • treat the JS blur bridge as a fallback only
  • skip the JS callback when focus moves normally to another element
  • dedupe native blur and JS fallback so the same blur is only processed once
  • add regression coverage for duplicate blur delivery

This keeps the fix platform-agnostic instead of relying on an iOS-only device check (closes #13047), while still preserving a fallback for cases where focus is dismissed without Blazor observing a native blur.

Checklist:

  • I've read the contribution guidelines
  • My code follows the style of this project
  • I've added or updated relevant unit tests

…ck cases

This fixes a `MudTextField` / `MudButton` race where clicking a button immediately after editing a non-`Immediate` text field could execute the button `OnClick` before the field value was committed.

Root cause:
`MudInput` had two independent blur paths:
- the normal Blazor `@onblur` handler
- a JS blur bridge added in `MudBlazor#10842` that called back into `.NET` separately

That extra JS interop path could bypass Blazor’s normal ordered `change -> blur -> click` processing and create intermittent stale model values, especially on Blazor Server.

What changed:
- keep native Blazor blur as the primary path
- treat the JS blur bridge as a fallback only
- skip the JS callback when focus moves normally to another element
- dedupe native blur and JS fallback so the same blur is only processed once
- add regression coverage for duplicate blur delivery

This keeps the fix platform-agnostic instead of relying on an iOS-only device check, while still preserving a fallback for cases where focus is dismissed without Blazor observing a native blur.
@mudbot mudbot Bot added the bug Unexpected behavior or functionality not working as intended label Apr 15, 2026
@danielchalmers danielchalmers changed the title MudInput: keep native blur/click ordering and limit JS blur to fallback cases MudInput: Avoid duplicate blur interop during normal focus changes Apr 15, 2026
@danielchalmers
danielchalmers requested a review from versile2 April 15, 2026 21:35
@danielchalmers
danielchalmers requested a review from meenzen April 19, 2026 13:06
@danielchalmers
danielchalmers merged commit 2c36649 into MudBlazor:dev Apr 19, 2026
11 checks passed
@danielchalmers
danielchalmers deleted the likely-whale branch April 19, 2026 23:29
This was referenced Apr 22, 2026
vantaflow added a commit to vantaflow/MudBlazor that referenced this pull request Nov 1, 2026
MudMask re-applies the caret after every render while _isFocused is true,
and the JS selectRange helper always calls element.focus(). When the native
blur is not delivered (e.g. Hybrid hosts losing window focus), _isFocused
stays true and each render steals focus back from other inputs.

Add the JS blur fallback bridge that MudInput already uses (MudBlazor#10842, MudBlazor#13049)
so the focus state is cleared even without the native blur event.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Unexpected behavior or functionality not working as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MudTextField without Immediate: ValueChanged not guaranteed to fire before button OnClick when clicking Save while field has focus

1 participant