diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PhoneInput/BitPhoneInput.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PhoneInput/BitPhoneInput.razor.cs index baa5dc51a6..73913c22c7 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PhoneInput/BitPhoneInput.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PhoneInput/BitPhoneInput.razor.cs @@ -8,14 +8,14 @@ namespace Bit.BlazorUI; /// public partial class BitPhoneInput : BitInputBase { + private readonly BitInputRateLimiter _rateLimiter = new(); + private bool _isOpen; private bool _hasFocus; + private string? _searchText; private int _activeIndex = -1; private int _lastScrolledIndex = -1; - private string? _searchText; - private List _viewItems = []; - private List _allItems = []; - private ICollection? _lastCountries; + private string _labelId = string.Empty; private string _inputId = string.Empty; private string _searchId = string.Empty; @@ -24,9 +24,13 @@ public partial class BitPhoneInput : BitInputBase private string _dropdownId = string.Empty; private string _fieldGroupId = string.Empty; private string _scrollContainerId = string.Empty; - private DotNetObjectReference? _dotnetObj; + + private List _allItems = []; + private List _viewItems = []; private ElementReference _searchInputRef; private ElementReference _dropdownButtonRef; + private ICollection? _lastCountries; + private DotNetObjectReference? _dotnetObj; // Keys whose default browser behavior must be suppressed. These are applied through a // deterministic JS keydown listener (see BitExtrasSetPreventKeys) so the suppression @@ -64,6 +68,12 @@ public partial class BitPhoneInput : BitInputBase [Parameter, TwoWayBound] public BitCountry? Country { get; set; } + /// + /// The debounce time in milliseconds for the number input (applied when Immediate is enabled). + /// When both DebounceTime and ThrottleTime are greater than zero, debounce takes precedence and throttle is ignored. + /// + [Parameter] public int DebounceTime { get; set; } + /// /// The default selected country to be initially used when the Country parameter is not set. /// @@ -141,6 +151,12 @@ public partial class BitPhoneInput : BitInputBase /// [Parameter] public BitPhoneInputClassStyles? Styles { get; set; } + /// + /// The throttle time in milliseconds for the number input (applied when Immediate is enabled). + /// Throttle is ignored when both DebounceTime and ThrottleTime are set, as debounce takes precedence. + /// + [Parameter] public int ThrottleTime { get; set; } + /// @@ -478,7 +494,8 @@ private async Task HandleOnNumberInput(ChangeEventArgs e) if (Immediate is false) return; - await SetCurrentValueAsStringAsync(e.Value?.ToString()); + await _rateLimiter.Run(e, DebounceTime, ThrottleTime, async args => + await InvokeAsync(async () => await HandleOnNumberChange(args))); } private void HandleOnInputFocusIn() @@ -507,6 +524,8 @@ protected override async ValueTask DisposeAsync(bool disposing) _dotnetObj?.Dispose(); + _rateLimiter.Reset(); + try { await _js.BitExtrasDisposePreventKeys(_dropdownButtonRef); diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/PhoneInput/BitPhoneInputDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/PhoneInput/BitPhoneInputDemo.razor index b38363e8c4..f848ef0423 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/PhoneInput/BitPhoneInputDemo.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/PhoneInput/BitPhoneInputDemo.razor @@ -72,7 +72,39 @@ - + +
+ By default the value updates on the change event (when the input loses focus). Enable the + Immediate parameter to update the value on every keystroke (the 'oninput' event). To + rate-limit how often the value updates while typing, combine it with DebounceTime (waits + until typing pauses) or ThrottleTime (updates at most once per interval). +
+
+
Immediate:
+ +
Value: [@immediateNumber]
+
+
Immediate + DebounceTime (500ms):
+ +
Value: [@debouncedNumber]
+
+
Immediate + ThrottleTime (500ms):
+ +
Value: [@throttledNumber]
+
+ +
Disabled:

@@ -82,7 +114,7 @@
- +
Use the OnCountryChange callback to react to the selected country changes.

Selected country: @changedCountry?.Name
- +
Customize the appearance of the BitPhoneInput using Style, Class, Styles, and Classes.

- +
Use BitPhoneInput in right-to-left (RTL).

diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/PhoneInput/BitPhoneInputDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/PhoneInput/BitPhoneInputDemo.razor.cs index d9810c3c8a..42f16954fd 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/PhoneInput/BitPhoneInputDemo.razor.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/PhoneInput/BitPhoneInputDemo.razor.cs @@ -50,6 +50,13 @@ public partial class BitPhoneInputDemo Href = "#country", }, new() + { + Name = "DebounceTime", + Type = "int", + DefaultValue = "0", + Description = "The debounce time in milliseconds for the number input (applied when Immediate is enabled).", + }, + new() { Name = "DropDirection", Type = "BitDropDirection", @@ -149,6 +156,13 @@ public partial class BitPhoneInputDemo LinkType = LinkType.Link, Href = "#class-styles", }, + new() + { + Name = "ThrottleTime", + Type = "int", + DefaultValue = "0", + Description = "The throttle time in milliseconds for the number input (applied when Immediate is enabled).", + }, ]; private readonly List componentSubClasses = @@ -214,6 +228,9 @@ public partial class BitPhoneInputDemo private string? bindingNumber; private BitCountry? bindingCountry; private BitCountry? changedCountry; + private string? immediateNumber; + private string? debouncedNumber; + private string? throttledNumber; private readonly List customCountries = [ BitCountries.UnitedStates, @@ -267,30 +284,55 @@ public partial class BitPhoneInputDemo "; private readonly string example7RazorCode = @" + +
Value: [@immediateNumber]
+ + +
Value: [@debouncedNumber]
+ + +
Value: [@throttledNumber]
"; + private readonly string example7CsharpCode = @" +private string? immediateNumber; +private string? debouncedNumber; +private string? throttledNumber;"; + + private readonly string example8RazorCode = @" "; - private readonly string example7CsharpCode = @""; + private readonly string example8CsharpCode = @""; - private readonly string example8RazorCode = @" + private readonly string example9RazorCode = @" changedCountry = c"" Placeholder=""Enter your number"" />
Selected country: @changedCountry?.Name
"; - private readonly string example8CsharpCode = @" + private readonly string example9CsharpCode = @" private BitCountry? changedCountry;"; - private readonly string example9RazorCode = @" + private readonly string example10RazorCode = @" "; - private readonly string example9CsharpCode = @""; + private readonly string example10CsharpCode = @""; - private readonly string example10RazorCode = @" + private readonly string example11RazorCode = @"
";