Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

status:needs-investigationNeeds additional investigationv5For the next major version

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions