Skip to content

Commit 72c315b

Browse files
authored
Initialize (#108)
1 parent 218c4a8 commit 72c315b

File tree

7 files changed

+206
-85
lines changed

7 files changed

+206
-85
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System.Threading.Tasks;
2+
using System.Timers;
3+
using Microsoft.AspNetCore.Components;
4+
using MudBlazor;
5+
6+
namespace MudExtensions
7+
{
8+
public abstract class MudDebouncedInputExtended<T> : MudBaseInputExtended<T>
9+
{
10+
private System.Timers.Timer _timer;
11+
private double _debounceInterval;
12+
13+
/// <summary>
14+
/// Interval to be awaited in milliseconds before changing the Text value
15+
/// </summary>
16+
[Parameter]
17+
[Category(CategoryTypes.FormComponent.Behavior)]
18+
public double DebounceInterval
19+
{
20+
get => _debounceInterval;
21+
set
22+
{
23+
if (NumericConverter<double>.AreEqual(_debounceInterval, value))
24+
return;
25+
_debounceInterval = value;
26+
if (_debounceInterval == 0)
27+
{
28+
// not debounced, dispose timer if any
29+
ClearTimer(suppressTick: false);
30+
return;
31+
}
32+
SetTimer();
33+
}
34+
}
35+
36+
/// <summary>
37+
/// callback to be called when the debounce interval has elapsed
38+
/// receives the Text as a parameter
39+
/// </summary>
40+
[Parameter] public EventCallback<string> OnDebounceIntervalElapsed { get; set; }
41+
42+
protected Task OnChange()
43+
{
44+
if (DebounceInterval > 0 && _timer != null)
45+
{
46+
_timer.Stop();
47+
return base.UpdateValuePropertyAsync(false);
48+
}
49+
50+
return Task.CompletedTask;
51+
}
52+
53+
protected override Task UpdateValuePropertyAsync(bool updateText)
54+
{
55+
// This method is called when Value property needs to be refreshed from the current Text property, so typically because Text property has changed.
56+
// We want to debounce only text-input, not a value being set, so the debouncing is only done when updateText==false (because that indicates the
57+
// change came from a Text setter)
58+
if (updateText)
59+
{
60+
// we have a change coming not from the Text setter, no debouncing is needed
61+
return base.UpdateValuePropertyAsync(updateText);
62+
}
63+
// if debounce interval is 0 we update immediately
64+
if (DebounceInterval <= 0 || _timer == null)
65+
return base.UpdateValuePropertyAsync(updateText);
66+
// If a debounce interval is defined, we want to delay the update of Value property.
67+
_timer.Stop();
68+
// restart the timer while user is typing
69+
_timer.Start();
70+
return Task.CompletedTask;
71+
}
72+
73+
protected override void OnParametersSet()
74+
{
75+
base.OnParametersSet();
76+
// if input is to be debounced, makes sense to bind the change of the text to oninput
77+
// so we set Immediate to true
78+
if (DebounceInterval > 0)
79+
Immediate = true;
80+
}
81+
82+
private void SetTimer()
83+
{
84+
if (_timer == null)
85+
{
86+
_timer = new System.Timers.Timer();
87+
_timer.Elapsed += OnTimerTick;
88+
_timer.AutoReset = false;
89+
}
90+
_timer.Interval = DebounceInterval;
91+
}
92+
93+
private void OnTimerTick(object sender, ElapsedEventArgs e)
94+
{
95+
InvokeAsync(OnTimerTickGuiThread).AndForget();
96+
}
97+
98+
private async Task OnTimerTickGuiThread()
99+
{
100+
await base.UpdateValuePropertyAsync(false);
101+
await OnDebounceIntervalElapsed.InvokeAsync(Text);
102+
}
103+
104+
private void ClearTimer(bool suppressTick = false)
105+
{
106+
if (_timer == null)
107+
return;
108+
var wasEnabled = _timer.Enabled;
109+
_timer.Stop();
110+
_timer.Elapsed -= OnTimerTick;
111+
_timer.Dispose();
112+
_timer = null;
113+
if (wasEnabled && !suppressTick)
114+
OnTimerTickGuiThread().AndForget();
115+
}
116+
117+
protected override void Dispose(bool disposing)
118+
{
119+
base.Dispose(disposing);
120+
ClearTimer(suppressTick: true);
121+
}
122+
}
123+
}

CodeBeam.MudExtensions/Components/InputExtended/MudInputCssHelperExtended.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ internal static class MudInputCssHelperExtended
1010
public static string GetClassname<T>(MudBaseInputExtended<T> baseInput, Func<bool> shrinkWhen) =>
1111
new CssBuilder("mud-input")
1212
.AddClass($"mud-input-{baseInput.Variant.ToDescriptionString()}")
13-
//.AddClass($"mud-input-adorned-start", baseInput.AdornmentStart != null)
14-
//.AddClass($"mud-input-adorned-end", baseInput.AdornmentEnd != null)
1513
.AddClass($"mud-input-margin-{baseInput.Margin.ToDescriptionString()}", when: () => baseInput.Margin != Margin.None)
1614
.AddClass("mud-input-underline", when: () => baseInput.DisableUnderLine == false && baseInput.Variant != Variant.Outlined)
1715
.AddClass("mud-shrink", when: shrinkWhen)
@@ -26,10 +24,8 @@ public static string GetInputClassname<T>(MudBaseInputExtended<T> baseInput) =>
2624
new CssBuilder("mud-input-slot")
2725
.AddClass("mud-input-root")
2826
.AddClass($"mud-input-root-{baseInput.Variant.ToDescriptionString()}")
29-
//.AddClass($"mud-input-root-adorned-start", baseInput.AdornmentStart != null)
30-
//.AddClass($"mud-input-root-adorned-end", baseInput.AdornmentEnd != null)
3127
.AddClass($"mud-input-root-margin-{baseInput.Margin.ToDescriptionString()}", when: () => baseInput.Margin != Margin.None)
32-
.AddClass("ms-4", baseInput.Variant == Variant.Text)
28+
.AddClass("ms-4", baseInput.AdornmentStart != null && baseInput.Variant == Variant.Text)
3329
.AddClass(baseInput.Class)
3430
.Build();
3531

CodeBeam.MudExtensions/Components/ListExtended/MudListExtended.razor.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,14 @@ protected internal async Task HandleKeyDown(KeyboardEventArgs obj)
796796
}
797797
}
798798
break;
799+
case "f":
800+
case "F":
801+
if (obj.CtrlKey == true && obj.ShiftKey == true)
802+
{
803+
SearchBox = !SearchBox;
804+
StateHasChanged();
805+
}
806+
break;
799807
}
800808
await OnKeyDown.InvokeAsync(obj);
801809
}

CodeBeam.MudExtensions/Components/SelectExtended/MudSelectItemExtended.razor.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Microsoft.AspNetCore.Components;
55
using MudBlazor;
66
using MudBlazor.Utilities;
7+
using MudExtensions.Extensions;
78

89
namespace MudExtensions
910
{
@@ -137,13 +138,17 @@ protected string DisplayString
137138
protected void HandleOnClick()
138139
{
139140
// Selection works on list. We arrange only popover state and some minor arrangements on click.
140-
MudSelectExtended?.SelectOption(Value).AndForget();
141+
MudSelectExtended?.SelectOption(Value).AndForgetExt();
141142
InvokeAsync(StateHasChanged);
142143
if (MultiSelection == false)
143144
{
144-
MudSelectExtended.CloseMenu().AndForget();
145+
MudSelectExtended.CloseMenu().AndForgetExt();
145146
}
146-
OnClick.InvokeAsync().AndForget();
147+
else
148+
{
149+
MudSelectExtended.FocusAsync().AndForgetExt();
150+
}
151+
OnClick.InvokeAsync().AndForgetExt();
147152
}
148153

149154
protected bool GetDisabledStatus()
Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,65 @@
11
@namespace MudExtensions
22
@typeparam T
3-
@inherits MudDebouncedInput<T>
3+
@inherits MudDebouncedInputExtended<T>
44

55
<CascadingValue Name="SubscribeToParentForm2" Value="@SubscribeToParentForm2" IsFixed="true">
6-
<MudInputControl Label="@Label"
7-
Variant="@Variant"
8-
HelperText="@HelperText"
9-
HelperTextOnFocus="@HelperTextOnFocus"
10-
CounterText="@GetCounterText()"
11-
FullWidth="@FullWidth"
12-
Class="@Classname"
13-
Error="@HasErrors"
14-
ErrorText="@GetErrorText()"
15-
ErrorId="@ErrorId"
16-
Disabled="@Disabled"
17-
Margin="@Margin"
18-
Required="@Required"
19-
ForId="@FieldId">
20-
<InputContent>
21-
<CascadingValue Name="SubscribeToParentForm2" Value="false" IsFixed="true">
22-
@if (_mask == null)
23-
{
24-
<MudInputExtended T="string"
25-
@ref="InputReference"
26-
@attributes="UserAttributes"
27-
InputType="@InputType"
28-
Lines="@Lines"
29-
Style="@Style"
30-
Variant="@Variant"
31-
TextUpdateSuppression="@TextUpdateSuppression"
32-
Value="@Text"
33-
ValueChanged="(s) => SetTextAsync(s)"
34-
Placeholder="@Placeholder"
35-
Disabled=@Disabled
36-
DisableUnderLine="@DisableUnderLine"
37-
ReadOnly="@ReadOnly"
38-
MaxLength="@MaxLength"
39-
IconSize="@IconSize"
40-
Error="@Error"
41-
ErrorId="@ErrorId"
42-
Immediate="@Immediate"
43-
Margin="@Margin"
44-
OnBlur="@OnBlurred"
45-
OnKeyDown="@InvokeKeyDown"
46-
OnInternalInputChanged="OnChange"
47-
OnKeyPress="@InvokeKeyPress"
48-
OnKeyUp="@InvokeKeyUp"
49-
KeyDownPreventDefault="KeyDownPreventDefault"
50-
KeyPressPreventDefault="KeyPressPreventDefault"
51-
KeyUpPreventDefault="KeyUpPreventDefault"
52-
HideSpinButtons="true"
53-
Clearable="@Clearable"
54-
OnClearButtonClick="@OnClearButtonClick"
55-
Pattern="@Pattern"
56-
AdornmentStart="@AdornmentStart"
57-
AdornmentEnd="@AdornmentEnd"
58-
AutoSize="AutoSize" />
59-
}
60-
else
61-
{
62-
<MudMask @ref="_maskReference"
6+
<MudInputControl Label="@Label"
7+
Variant="@Variant"
8+
HelperText="@HelperText"
9+
HelperTextOnFocus="@HelperTextOnFocus"
10+
CounterText="@GetCounterText()"
11+
FullWidth="@FullWidth"
12+
Class="@Classname"
13+
Error="@HasErrors"
14+
ErrorText="@GetErrorText()"
15+
ErrorId="@ErrorId"
16+
Disabled="@Disabled"
17+
Margin="@Margin"
18+
Required="@Required"
19+
ForId="@FieldId">
20+
<InputContent>
21+
<CascadingValue Name="SubscribeToParentForm2" Value="false" IsFixed="true">
22+
@if (_mask == null)
23+
{
24+
<MudInputExtended T="string"
25+
@ref="InputReference"
26+
@attributes="UserAttributes"
27+
InputType="@InputType"
28+
Lines="@Lines"
29+
Style="@Style"
30+
Variant="@Variant"
31+
TextUpdateSuppression="@TextUpdateSuppression"
32+
Value="@Text"
33+
ValueChanged="(s) => SetTextAsync(s)"
34+
Placeholder="@Placeholder"
35+
Disabled=@Disabled
36+
DisableUnderLine="@DisableUnderLine"
37+
ReadOnly="@ReadOnly"
38+
MaxLength="@MaxLength"
39+
IconSize="@IconSize"
40+
Error="@Error"
41+
ErrorId="@ErrorId"
42+
Immediate="@Immediate"
43+
Margin="@Margin"
44+
OnBlur="@OnBlurred"
45+
OnKeyDown="@InvokeKeyDown"
46+
OnInternalInputChanged="OnChange"
47+
OnKeyPress="@InvokeKeyPress"
48+
OnKeyUp="@InvokeKeyUp"
49+
KeyDownPreventDefault="KeyDownPreventDefault"
50+
KeyPressPreventDefault="KeyPressPreventDefault"
51+
KeyUpPreventDefault="KeyUpPreventDefault"
52+
HideSpinButtons="true"
53+
Clearable="@Clearable"
54+
OnClearButtonClick="@OnClearButtonClick"
55+
Pattern="@Pattern"
56+
AdornmentStart="@AdornmentStart"
57+
AdornmentEnd="@AdornmentEnd"
58+
AutoSize="AutoSize" />
59+
}
60+
else
61+
{
62+
<MudMask @ref="_maskReference"
6363
@attributes="UserAttributes"
6464
Mask="@_mask"
6565
InputType="@InputType"
@@ -80,10 +80,10 @@
8080
Margin="@Margin" OnBlur="@OnBlurred"
8181
Clearable="@Clearable"
8282
OnClearButtonClick="@OnClearButtonClick"
83-
AdornmentStart="@AdornmentStart"
84-
AdornmentEnd="@AdornmentEnd" />
85-
}
86-
</CascadingValue>
87-
</InputContent>
83+
AdornmentStart="@AdornmentStart"
84+
AdornmentEnd="@AdornmentEnd" />
85+
}
86+
</CascadingValue>
87+
</InputContent>
8888
</MudInputControl>
8989
</CascadingValue>

CodeBeam.MudExtensions/Components/TextFieldExtended/MudTextFieldExtended.razor.cs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace MudExtensions
99
{
10-
public partial class MudTextFieldExtended<T> : MudDebouncedInput<T>
10+
public partial class MudTextFieldExtended<T> : MudDebouncedInputExtended<T>
1111
{
1212
protected string Classname =>
1313
new CssBuilder("mud-input-input-control")
@@ -32,7 +32,7 @@ public partial class MudTextFieldExtended<T> : MudDebouncedInput<T>
3232
[Category(CategoryTypes.FormComponent.Behavior)]
3333
public InputType InputType { get; set; } = InputType.Text;
3434

35-
internal InputType GetInputType() => InputType;
35+
internal override InputType GetInputType() => InputType;
3636

3737
private string GetCounterText() => Counter == null ? string.Empty : (Counter == 0 ? (string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") : ((string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") + $" / {Counter}"));
3838

@@ -48,17 +48,6 @@ public partial class MudTextFieldExtended<T> : MudDebouncedInput<T>
4848
/// </summary>
4949
[Parameter] public EventCallback<MouseEventArgs> OnClearButtonClick { get; set; }
5050

51-
/// <summary>
52-
/// The adornment that placed start of the input.
53-
/// </summary>
54-
[Parameter] public RenderFragment AdornmentStart { get; set; }
55-
56-
/// <summary>
57-
/// The adornment that placed end of the input.
58-
/// </summary>
59-
[Parameter] public RenderFragment AdornmentEnd { get; set; }
60-
61-
6251
public override ValueTask FocusAsync()
6352
{
6453
if (_mask == null)

ComponentViewer.Docs/Pages/Components/SelectExtendedPage.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<SelectExtendedExample1 />
1111
</ExampleCard>
1212

13-
<ExampleCard ExampleName="SelectExtendedExample6" Title="SearchBox" Description="SearchBox can be added if items populated with ItemCollection parameter.">
13+
<ExampleCard ExampleName="SelectExtendedExample6" Title="SearchBox" Description="SearchBox can be added if items populated with ItemCollection parameter. Ctrl+Shift+F combination shows/hides the searchbox if the box not focused.">
1414
<SelectExtendedExample6 />
1515
</ExampleCard>
1616

0 commit comments

Comments
 (0)