Progress
This commit is contained in:
parent
9f1214fd9f
commit
a04a0f07e2
@ -143,7 +143,7 @@ public abstract class FormComponent<T, U> : UIComponent, IFormComponent, IDispos
|
|||||||
/// Return the validation error text or the conversion error message.
|
/// Return the validation error text or the conversion error message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Error text/message</returns>
|
/// <returns>Error text/message</returns>
|
||||||
public string? GetErrorText()
|
public string? GetErrorText(bool test = false)
|
||||||
{
|
{
|
||||||
// ErrorText is either set from outside or the first validation error
|
// ErrorText is either set from outside or the first validation error
|
||||||
if (!IsNullOrWhiteSpace(ErrorText))
|
if (!IsNullOrWhiteSpace(ErrorText))
|
||||||
@ -152,6 +152,8 @@ public abstract class FormComponent<T, U> : UIComponent, IFormComponent, IDispos
|
|||||||
if (!IsNullOrWhiteSpace(ConversionErrorMessage))
|
if (!IsNullOrWhiteSpace(ConversionErrorMessage))
|
||||||
return ConversionErrorMessage;
|
return ConversionErrorMessage;
|
||||||
|
|
||||||
|
if (test) return "Error: test";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Connected.Annotations;
|
using Connected.Annotations;
|
||||||
using Connected.Utilities.BindingConverters;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace Connected.Components;
|
namespace Connected.Components;
|
||||||
|
@ -3,6 +3,23 @@
|
|||||||
@inherits InputBase<T>
|
@inherits InputBase<T>
|
||||||
|
|
||||||
<div class="@Classname">
|
<div class="@Classname">
|
||||||
|
<InputControl Label="@Label"
|
||||||
|
Variant="@Variant"
|
||||||
|
HelperText="@HelperText"
|
||||||
|
HelperTextOnFocus="@HelperTextOnFocus"
|
||||||
|
CounterText="@GetCounterText()"
|
||||||
|
FullWidth="@FullWidth"
|
||||||
|
Class="@Classname"
|
||||||
|
Error="@HasErrors"
|
||||||
|
ErrorText="@ErrorText"
|
||||||
|
ErrorId="@ErrorId"
|
||||||
|
Disabled="@Disabled"
|
||||||
|
Margin="@Margin"
|
||||||
|
Required="@Required"
|
||||||
|
ForId="@FieldId">
|
||||||
|
<CascadingValue Name="SubscribeToParentForm" Value="@base.SubscribeToParentForm" IsFixed="true">
|
||||||
|
|
||||||
|
|
||||||
@if (Adornment == Adornment.Start)
|
@if (Adornment == Adornment.Start)
|
||||||
{
|
{
|
||||||
<InputAdornment Class="@AdornmentClassname"
|
<InputAdornment Class="@AdornmentClassname"
|
||||||
@ -15,7 +32,7 @@
|
|||||||
AriaLabel="@AdornmentAriaLabel"
|
AriaLabel="@AdornmentAriaLabel"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
<InputContent>
|
||||||
@if (Lines > 1)
|
@if (Lines > 1)
|
||||||
{
|
{
|
||||||
<textarea class="@InputClassname"
|
<textarea class="@InputClassname"
|
||||||
@ -46,6 +63,7 @@
|
|||||||
>
|
>
|
||||||
@Text
|
@Text
|
||||||
</textarea>
|
</textarea>
|
||||||
|
|
||||||
@*Note: double mouse wheel handlers needed for Firefox because it doesn't know onmousewheel*@
|
@*Note: double mouse wheel handlers needed for Firefox because it doesn't know onmousewheel*@
|
||||||
@*note: the value="@_internalText" is absolutely essential here. the inner html @Text is needed by tests checking it*@
|
@*note: the value="@_internalText" is absolutely essential here. the inner html @Text is needed by tests checking it*@
|
||||||
}
|
}
|
||||||
@ -104,15 +122,10 @@
|
|||||||
|
|
||||||
@if (_showClearable && !Disabled)
|
@if (_showClearable && !Disabled)
|
||||||
{
|
{
|
||||||
<IconButton Class="@ClearButtonClassname"
|
|
||||||
Color="@ThemeColor.Default"
|
|
||||||
Icon="@ClearIcon"
|
|
||||||
Size="@Size.Small"
|
|
||||||
OnClick="@ClearButtonClickHandlerAsync"
|
|
||||||
tabindex="-1"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@if (Adornment == Adornment.End)
|
@if (Adornment == Adornment.End)
|
||||||
{
|
{
|
||||||
<InputAdornment Class="@AdornmentClassname"
|
<InputAdornment Class="@AdornmentClassname"
|
||||||
@ -142,4 +155,12 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
</InputContent>
|
||||||
|
|
||||||
|
</CascadingValue>
|
||||||
|
|
||||||
|
</InputControl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,11 +2,191 @@
|
|||||||
using Connected.Utilities;
|
using Connected.Utilities;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.Components.Web;
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
namespace Connected.Components;
|
namespace Connected.Components;
|
||||||
|
|
||||||
public partial class Input<T> : InputBase<T>
|
public partial class Input<T> : InputBase<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debounce
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current character counter, displayed below the text field.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter] public string CounterText { get; set; }
|
||||||
|
|
||||||
|
private System.Timers.Timer _timer;
|
||||||
|
private double _debounceInterval;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interval to be awaited in MILLISECONDS before changing the Text value
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public double TextChangeDelay
|
||||||
|
{
|
||||||
|
get => _debounceInterval;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (NumericConverter<double>.AreEqual(_debounceInterval, value))
|
||||||
|
return;
|
||||||
|
_debounceInterval = value;
|
||||||
|
if (_debounceInterval == 0)
|
||||||
|
{
|
||||||
|
// not debounced, dispose timer if any
|
||||||
|
ClearTimer(suppressTick: false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// callback to be called when the debounce interval has elapsed
|
||||||
|
/// receives the Text as a parameter
|
||||||
|
/// </summary>
|
||||||
|
[Parameter] public EventCallback<string> OnDebounceIntervalElapsed { get; set; }
|
||||||
|
|
||||||
|
protected Task OnDebounceChange()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (TextChangeDelay > 0 && _timer != null)
|
||||||
|
{
|
||||||
|
_timer.Stop();
|
||||||
|
return base.UpdateValuePropertyAsync(false);
|
||||||
|
}
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Task UpdateValuePropertyAsync(bool updateText)
|
||||||
|
{
|
||||||
|
// This method is called when Value property needs to be refreshed from the current Text property, so typically because Text property has changed.
|
||||||
|
// 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
|
||||||
|
// change came from a Text setter)
|
||||||
|
if (updateText)
|
||||||
|
{
|
||||||
|
// we have a change coming not from the Text setter, no debouncing is needed
|
||||||
|
return base.UpdateValuePropertyAsync(updateText);
|
||||||
|
}
|
||||||
|
// if debounce interval is 0 we update immediately
|
||||||
|
if (TextChangeDelay <= 0 || _timer == null)
|
||||||
|
return base.UpdateValuePropertyAsync(updateText);
|
||||||
|
// If a debounce interval is defined, we want to delay the update of Value property.
|
||||||
|
_timer.Stop();
|
||||||
|
// restart the timer while user is typing
|
||||||
|
_timer.Start();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnParametersSet()
|
||||||
|
{
|
||||||
|
base.OnParametersSet();
|
||||||
|
// if input is to be debounced, makes sense to bind the change of the text to oninput
|
||||||
|
// so we set Immediate to true
|
||||||
|
if (TextChangeDelay > 0)
|
||||||
|
Immediate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetTimer()
|
||||||
|
{
|
||||||
|
if (_timer == null)
|
||||||
|
{
|
||||||
|
_timer = new System.Timers.Timer();
|
||||||
|
_timer.Elapsed += OnTimerTick;
|
||||||
|
_timer.AutoReset = false;
|
||||||
|
}
|
||||||
|
_timer.Interval = TextChangeDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTimerTick(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
InvokeAsync(OnTimerTickGuiThread).AndForget();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnTimerTickGuiThread()
|
||||||
|
{
|
||||||
|
await base.UpdateValuePropertyAsync(false);
|
||||||
|
await OnDebounceIntervalElapsed.InvokeAsync(Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearTimer(bool suppressTick = false)
|
||||||
|
{
|
||||||
|
if (_timer == null)
|
||||||
|
return;
|
||||||
|
var wasEnabled = _timer.Enabled;
|
||||||
|
_timer.Stop();
|
||||||
|
_timer.Elapsed -= OnTimerTick;
|
||||||
|
_timer.Dispose();
|
||||||
|
_timer = null;
|
||||||
|
if (wasEnabled && !suppressTick)
|
||||||
|
OnTimerTickGuiThread().AndForget();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debounce end
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected CssBuilder CompiledHelperContainerClassList
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new CssBuilder("input-control-helper-container")
|
||||||
|
.AddClass($"px-1", Variant == Variant.Filled)
|
||||||
|
.AddClass($"px-2", Variant == Variant.Outlined)
|
||||||
|
.AddClass($"px-1", Variant == Variant.Text)
|
||||||
|
.AddClass(HelperContainerClassList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A space separated list of class names, added on top of the default helper container class list.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string? HelperContainerClassList { get; set; }
|
||||||
|
|
||||||
|
protected CssBuilder CompiledHelperClassList
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new CssBuilder("input-helper-text")
|
||||||
|
.AddClass("input-helper-onfocus", HelperTextOnFocus)
|
||||||
|
.AddClass(HelperClassList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A space separated list of class names, added on top of the default helper class list.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string? HelperClassList { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*protected string HelperContainer =>
|
||||||
|
new CssBuilder("input-control-helper-container")
|
||||||
|
.AddClass($"px-1", Variant == Variant.Filled)
|
||||||
|
.AddClass($"px-2", Variant == Variant.Outlined)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
|
protected string HelperClass =>
|
||||||
|
new CssBuilder("input-helper-text")
|
||||||
|
.AddClass("input-helper-onfocus", HelperTextOnFocus)
|
||||||
|
.Build();*/
|
||||||
|
|
||||||
|
private string GetCounterText()
|
||||||
|
{
|
||||||
|
string result = Text.Length.ToString();
|
||||||
|
if (string.IsNullOrEmpty(Text)) result = "0";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
protected string Classname => InputCssHelper.GetClassname(this,
|
protected string Classname => InputCssHelper.GetClassname(this,
|
||||||
() => HasNativeHtmlPlaceholder() || !string.IsNullOrEmpty(Text) || Adornment == Adornment.Start || !string.IsNullOrWhiteSpace(Placeholder));
|
() => HasNativeHtmlPlaceholder() || !string.IsNullOrEmpty(Text) || Adornment == Adornment.Start || !string.IsNullOrWhiteSpace(Placeholder));
|
||||||
|
|
||||||
@ -31,15 +211,79 @@ public partial class Input<T> : InputBase<T>
|
|||||||
|
|
||||||
protected string InputTypeString => InputType.ToDescription();
|
protected string InputTypeString => InputType.ToDescription();
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
private bool IsDecimalNumber(string type)
|
||||||
|
{
|
||||||
|
switch (type.ToLower())
|
||||||
|
{
|
||||||
|
case "double":
|
||||||
|
case "float":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsNumber(string s)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
result= double.TryParse(s, out d);
|
||||||
|
} catch
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ValidateInput(string value)
|
||||||
|
{
|
||||||
|
string result = value;
|
||||||
|
if (value is not null)
|
||||||
|
{
|
||||||
|
var expectedType = typeof(T).Name;
|
||||||
|
if (IsNumericType(expectedType))
|
||||||
|
{
|
||||||
|
if (IsNumber(value.ToString()))
|
||||||
|
{
|
||||||
|
result = value.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IsDecimalNumber(value.ToString()))
|
||||||
|
result = Regex.Replace(value.ToString(), "[^0-9.]", "");
|
||||||
|
else result = Regex.Replace(value.ToString(), "[^0-9]", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
protected Task OnInput(ChangeEventArgs args)
|
protected Task OnInput(ChangeEventArgs args)
|
||||||
{
|
{
|
||||||
if (!Immediate)
|
if (!Immediate)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
_isFocused = true;
|
_isFocused = true;
|
||||||
return SetTextAsync(args?.Value as string);
|
return SetTextAsync(args?.Value as string);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task OnChange(ChangeEventArgs args)
|
protected async Task OnChange(ChangeEventArgs args)
|
||||||
|
{
|
||||||
|
if (TextChangeDelay > 0 && _timer != null)
|
||||||
|
{
|
||||||
|
_timer.Stop();
|
||||||
|
await UpdateValuePropertyAsync(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_internalText = args?.Value as string;
|
_internalText = args?.Value as string;
|
||||||
await OnInternalInputChanged.InvokeAsync(args);
|
await OnInternalInputChanged.InvokeAsync(args);
|
||||||
@ -49,6 +293,8 @@ public partial class Input<T> : InputBase<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Paste hook for descendants.
|
/// Paste hook for descendants.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -164,12 +410,12 @@ public partial class Input<T> : InputBase<T>
|
|||||||
UpdateClearable(Text);
|
UpdateClearable(Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task UpdateValuePropertyAsync(bool updateText)
|
/*protected override async Task UpdateValuePropertyAsync(bool updateText)
|
||||||
{
|
{
|
||||||
await base.UpdateValuePropertyAsync(updateText);
|
await base.UpdateValuePropertyAsync(updateText);
|
||||||
if (Clearable)
|
if (Clearable)
|
||||||
UpdateClearable(Value);
|
UpdateClearable(Value);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
protected virtual async Task ClearButtonClickHandlerAsync(MouseEventArgs e)
|
protected virtual async Task ClearButtonClickHandlerAsync(MouseEventArgs e)
|
||||||
{
|
{
|
||||||
@ -196,6 +442,33 @@ public partial class Input<T> : InputBase<T>
|
|||||||
{
|
{
|
||||||
// in WASM (or in BSS with TextUpdateSuppression==false) we always update
|
// in WASM (or in BSS with TextUpdateSuppression==false) we always update
|
||||||
_internalText = Text;
|
_internalText = Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
string baseTypeName = typeof(T).Name;
|
||||||
|
if (IsNumericType(baseTypeName))
|
||||||
|
{
|
||||||
|
InputType = InputType.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsNumericType(string type)
|
||||||
|
{
|
||||||
|
switch (type.ToLower())
|
||||||
|
{
|
||||||
|
case "uint16":
|
||||||
|
case "uint32":
|
||||||
|
case "uint64":
|
||||||
|
case "int16":
|
||||||
|
case "int32":
|
||||||
|
case "int64":
|
||||||
|
case "int":
|
||||||
|
case "double":
|
||||||
|
case "decimal":
|
||||||
|
case "float":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +220,7 @@ public abstract class InputBase<T> : FormComponent<T, string>
|
|||||||
await UpdateValuePropertyAsync(false);
|
await UpdateValuePropertyAsync(false);
|
||||||
await TextChanged.InvokeAsync(Text);
|
await TextChanged.InvokeAsync(Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -329,7 +330,11 @@ public abstract class InputBase<T> : FormComponent<T, string>
|
|||||||
/// Fired when the Value property changes.
|
/// Fired when the Value property changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<T> ValueChanged { get; set; }
|
public EventCallback<T> ValueChanged
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value of this input element.
|
/// The value of this input element.
|
||||||
|
@ -387,7 +387,7 @@ public partial class Picker<T> : FormComponent<T, string>
|
|||||||
|
|
||||||
protected override void ResetValue()
|
protected override void ResetValue()
|
||||||
{
|
{
|
||||||
_inputReference?.Reset();
|
_inputReference?.InputReference.Reset();
|
||||||
base.ResetValue();
|
base.ResetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
@namespace Connected.Components
|
@namespace Connected.Components
|
||||||
@typeparam T
|
@typeparam T
|
||||||
@inherits DebouncedInput<T>
|
@inherits InputBase<T>
|
||||||
|
|
||||||
<CascadingValue Name="SubscribeToParentForm" Value="@SubscribeToParentForm" IsFixed="true">
|
<CascadingValue Name="SubscribeToParentForm" Value="@base.SubscribeToParentForm" IsFixed="true">
|
||||||
<InputControl Label="@Label"
|
<InputControl Label="@Label"
|
||||||
Variant="@Variant"
|
Variant="@Variant"
|
||||||
HelperText="@HelperText"
|
HelperText="@HelperText"
|
||||||
HelperTextOnFocus="@HelperTextOnFocus"
|
HelperTextOnFocus="@HelperTextOnFocus"
|
||||||
CounterText="@GetCounterText()"
|
CounterText="@GetCounterText()"
|
||||||
FullWidth="@FullWidth"
|
FullWidth="@FullWidth"
|
||||||
Class="@ClassList"
|
class="@ClassList"
|
||||||
Error="@HasErrors"
|
Error="@HasErrors"
|
||||||
ErrorText="@GetErrorText()"
|
ErrorText="@GetErrorText()"
|
||||||
ErrorId="@ErrorId"
|
ErrorId="@ErrorId"
|
||||||
@ -48,7 +48,6 @@
|
|||||||
Margin="@Margin"
|
Margin="@Margin"
|
||||||
OnBlur="@OnBlurred"
|
OnBlur="@OnBlurred"
|
||||||
OnKeyDown="@InvokeKeyDown"
|
OnKeyDown="@InvokeKeyDown"
|
||||||
OnInternalInputChanged="OnChange"
|
|
||||||
OnKeyPress="@InvokeKeyPress"
|
OnKeyPress="@InvokeKeyPress"
|
||||||
OnKeyUp="@InvokeKeyUp"
|
OnKeyUp="@InvokeKeyUp"
|
||||||
KeyDownPreventDefault="KeyDownPreventDefault"
|
KeyDownPreventDefault="KeyDownPreventDefault"
|
||||||
@ -57,6 +56,7 @@
|
|||||||
HideSpinButtons="true"
|
HideSpinButtons="true"
|
||||||
Clearable="@Clearable"
|
Clearable="@Clearable"
|
||||||
OnClearButtonClick="@OnClearButtonClick"
|
OnClearButtonClick="@OnClearButtonClick"
|
||||||
|
Class="@CompiledClassList.Build()"
|
||||||
Pattern="@Pattern"/>
|
Pattern="@Pattern"/>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -83,8 +83,10 @@
|
|||||||
OnAdornmentClick="@OnAdornmentClick"
|
OnAdornmentClick="@OnAdornmentClick"
|
||||||
Error="@HasError"
|
Error="@HasError"
|
||||||
Immediate="@Immediate"
|
Immediate="@Immediate"
|
||||||
Margin="@Margin" OnBlur="@OnBlurred"
|
Margin="@Margin"
|
||||||
|
OnBlur="@OnBlurred"
|
||||||
Clearable="@Clearable"
|
Clearable="@Clearable"
|
||||||
|
Class="@CompiledClassList.Build()"
|
||||||
OnClearButtonClick="@OnClearButtonClick"/>
|
OnClearButtonClick="@OnClearButtonClick"/>
|
||||||
}
|
}
|
||||||
</CascadingValue>
|
</CascadingValue>
|
||||||
|
@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components.Web;
|
|||||||
|
|
||||||
namespace Connected.Components;
|
namespace Connected.Components;
|
||||||
|
|
||||||
public partial class TextField<T> : DebouncedInput<T>
|
public partial class TextField<T> : InputBase<T>
|
||||||
{
|
{
|
||||||
private Mask? _maskReference;
|
private Mask? _maskReference;
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ public partial class TextField<T> : DebouncedInput<T>
|
|||||||
|
|
||||||
internal override InputType GetInputType() => InputType;
|
internal override InputType GetInputType() => InputType;
|
||||||
|
|
||||||
private string GetCounterText() => Counter == null ? string.Empty : (Counter == 0 ? (string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") : ((string.IsNullOrEmpty(Text) ? "0" : $"{Text.Length}") + $" / {Counter}"));
|
private string GetCounterText() => base.Counter == null ? string.Empty : (base.Counter == 0 ? (string.IsNullOrEmpty(base.Text) ? "0" : $"{base.Text.Length}") : ((string.IsNullOrEmpty(base.Text) ? "0" : $"{base.Text.Length}") + $" / {base.Counter}"));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show clear button.
|
/// Show clear button.
|
||||||
@ -32,10 +32,25 @@ public partial class TextField<T> : DebouncedInput<T>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter] public EventCallback<MouseEventArgs> OnClearButtonClick { get; set; }
|
[Parameter] public EventCallback<MouseEventArgs> OnClearButtonClick { get; set; }
|
||||||
|
|
||||||
protected string ClassList =>
|
/*protected string ClassList =>
|
||||||
new CssBuilder("input-input-control")
|
new CssBuilder("input-input-control")
|
||||||
.AddClass(base.AdditionalClassList)
|
.AddClass(base.AdditionalClassList)
|
||||||
.Build();
|
.Build();*/
|
||||||
|
|
||||||
|
protected virtual CssBuilder CompiledClassList
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new CssBuilder("input-input-control")
|
||||||
|
.AddClass(ClassList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A space separated list of class names, added on top of the default class list.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string? ClassList { get; set; }
|
||||||
|
|
||||||
public override ValueTask FocusAsync()
|
public override ValueTask FocusAsync()
|
||||||
{
|
{
|
||||||
@ -128,10 +143,10 @@ public partial class TextField<T> : DebouncedInput<T>
|
|||||||
{
|
{
|
||||||
if (_mask != null)
|
if (_mask != null)
|
||||||
{
|
{
|
||||||
var textValue = Converter.Convert(value);
|
var textValue = base.Converter.Convert(value);
|
||||||
_mask.SetText(textValue);
|
_mask.SetText(textValue);
|
||||||
textValue = Mask.GetCleanText();
|
textValue = Mask.GetCleanText();
|
||||||
value = Converter.ConvertBack(textValue);
|
value = base.Converter.ConvertBack(textValue);
|
||||||
}
|
}
|
||||||
return base.SetValueAsync(value, updateText);
|
return base.SetValueAsync(value, updateText);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user