microsoft / microsoft/fluentui-blazor

fix: v5 debounced inputs can submit stale values before ImmediateDelay expires

Open
#5,250 4 comments 0 reactions 1 assignee View on GitHub

@dvoituron is already working on this.

Since Sep 8, 2026.

status:needs-investigation v5
Dominant language
C#
Stars
4.8k
Forks
483
Avg merge
14h 41m
Merged PRs (30d)
68

Description

Bug Report

On dev-v5, pending Immediate input is not flushed when the user commits/submits before ImmediateDelay expires. This leaves gaps in two paths:

  • FluentCombobox: type custom text and immediately click Submit. Its native input emits change, but the Blazor combobox does not handle that event to commit ImmediateText.
  • FluentTextInput: type and immediately press Enter. In Chromium, the Fluent text input's form submit event can precede its forwarded change event.

Text inputs are different from comboboxes on the usual click-to-submit path: FluentTextInput handles change, and the browser emits it before the button click submits. That commits the value independently of the debounce. It does not mean the pending timer itself was flushed or cancelled, and it does not cover the Enter ordering below.

Repro or Code Sample

Add this page to a Fluent UI Blazor v5 app configured for Interactive Server. The longer delay makes the ordering easy to exercise; the default 200 ms leaves the same, smaller window.

@page "/pending-input-repro"
@rendermode InteractiveServer
@using Microsoft.FluentUI.AspNetCore.Components

<form @onsubmit="Submit" @onsubmit:preventDefault>
    <FluentTextInput Label="Text"
                     @bind-Value="_text"
                     Immediate="true"
                     ImmediateDelay="2000" />

    <FluentCombobox TOption="string" TValue="string"
                    Label="Custom value"
                    Items="_options"
                    @bind-Value="_selected"
                    @bind-ImmediateText="_comboText"
                    Immediate="true"
                    ImmediateDelay="2000">
        <FreeOption>
            <FreeOptionOutput />
        </FreeOption>
    </FluentCombobox>

    <button type="submit">Submit</button>
</form>

<p>Submitted text: @_submittedText</p>
<p>Submitted custom value: @_submittedComboText</p>

@code {
    private readonly string[] _options = ["previous", "another"];
    private string? _text = "previous";
    private string? _selected = "previous";
    private string? _comboText = "previous";
    private string? _submittedText;
    private string? _submittedComboText;

    private void Submit()
    {
        _submittedText = _text;
        _submittedComboText = _comboText;
    }
}
  1. Reload between scenarios.
  2. Combobox: replace previous with unmatched custom text and click Submit before two seconds pass. The submit handler can observe the old ImmediateText.
  3. Text input: replace previous and press Enter before two seconds pass. The submit handler can run before either the delayed input event or the forwarded change.
  4. Compare with typing in the text input and clicking Submit: its change arrives before submission.

Expected Behavior

Committing an edit/submitting should make the latest native input text available to binding and validation before the submit handler runs. Debouncing while typing should not require the user to pause before submitting.

Current Behavior and Verification

A browser probe using the web components and TextInput.attachImmediateEvent from the installed package, with real Playwright input and click/Enter actions and a 2000 ms delay, recorded:

FluentTextInput + click:
  input(new) -> change(new) -> focusout -> submit

FluentTextInput + Enter:
  input(new) -> submit -> change(new)

FluentCombobox + click:
  input(new) -> change(new) -> focusout -> submit
  (no immediate event before submit; no Blazor change binding on combobox)

The pending immediate event is only delivered later by the timer. Verification so far is at the native-control/event layer plus review of the dev-v5 Blazor implementation; the Razor sample above has not been run as a standalone connected Blazor reproduction.

Relevant implementation:

  • TextInput.ts: InputImmediate listens only for input; the timer is not flushed on change, focus loss, or submission.
  • FluentTextInput.razor: handles @onchange and @ontextimmediate, explaining the working click path but not the Enter ordering.
  • FluentSelect.razor: combobox markup handles dropdown selection, focus, and delayed text, but not the native input's change.
  • FluentCombobox.cs: FocusOutHandlerAsync synchronizes ImmediateText from the selected option, not the browser's pending text.

Possible Solution

Add a commit/flush path that delivers pending text before binding validation/submission, and cancels the corresponding timer to avoid replaying it later. Comboboxes need to preserve the distinction between typed text and the selected option's value/key. Enter-triggered submission also needs coverage; only handling blur would leave the text-input case open.

ImmediateDelay="0" is a workaround for the debounce window, but removes debouncing entirely.

Please add browser regression coverage for typing followed immediately by a submit click and Enter. Tests that directly dispatch ontextimmediate before submit bypass the problematic ordering.

Context

Found while migrating Aspire Dashboard interaction and filter dialogs to v5. Related to #5173, but this is specifically about committing pending input before the delay elapses, not missing Immediate support or the freeform-value contract in #5199.

Environment

  • Source branch: dev-v5
  • Package: Microsoft.FluentUI.AspNetCore.Components 5.0.0-rc.6.26241.1
  • Windows, Chromium 148 / Electron 42 (VS Code integrated browser)
  • Downstream: Aspire Dashboard, Blazor Server targeting .NET 8

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.