@if (string.IsNullOrWhiteSpace(Label) == false) { } @code { [Parameter] public required string Label { get; set; } [Parameter] public string? Value { get; set; } [Parameter] public EventCallback ValueChanged { get; set; } [Parameter] public bool Immediate { get; set; } [Parameter] public int DebounceInterval { get; set; } = 300; /// If true, also emit immediately on blur/Enter (in addition to debounced typing). [Parameter] public bool EmitOnCommit { get; set; } = false; private string? currentValue; private CancellationTokenSource? cancellationTokenSource; protected override void OnParametersSet() { currentValue = Value; } private void OnInnerValueChanged(string? newValue) { currentValue = newValue; _ = DebounceEmitAsync(); //Task.Run(DebounceEmitAsync); } private async Task DebounceEmitAsync() { cancellationTokenSource?.Cancel(); cancellationTokenSource?.Dispose(); cancellationTokenSource = new(); try { await Task.Delay(DebounceInterval, cancellationTokenSource.Token); await ValueChanged.InvokeAsync(currentValue); } catch (TaskCanceledException) { } } private async Task OnInnerChange(object? _) { if (EmitOnCommit) { cancellationTokenSource?.Cancel(); await ValueChanged.InvokeAsync(currentValue); } } public void Dispose() { cancellationTokenSource?.Cancel(); cancellationTokenSource?.Dispose(); } }