You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connected.Components/Components/TextField/TextField.razor.cs

155 lines
3.8 KiB

using Connected.Annotations;
using Connected.Utilities;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
namespace Connected.Components;
public partial class TextField<T> : DebouncedInput<T>
{
protected string Classname =>
new CssBuilder("mud-input-input-control")
.AddClass(Class)
.Build();
public Input<string> InputReference { get; private set; }
private Mask _maskReference;
/// <summary>
/// Type of the input element. It should be a valid HTML5 input type.
/// </summary>
[Parameter]
[Category(CategoryTypes.FormComponent.Behavior)]
public InputType InputType { get; set; } = InputType.Text;
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}"));
/// <summary>
/// Show clear button.
/// </summary>
[Parameter]
[Category(CategoryTypes.FormComponent.Behavior)]
public bool Clearable { get; set; } = false;
/// <summary>
/// Button click event for clear button. Called after text and value has been cleared.
/// </summary>
[Parameter] public EventCallback<MouseEventArgs> OnClearButtonClick { get; set; }
public override ValueTask FocusAsync()
{
if (_mask == null)
return InputReference.FocusAsync();
else
return _maskReference.FocusAsync();
}
public override ValueTask BlurAsync()
{
if (_mask == null)
return InputReference.BlurAsync();
else
return _maskReference.BlurAsync();
}
public override ValueTask SelectAsync()
{
if (_mask == null)
return InputReference.SelectAsync();
else
return _maskReference.SelectAsync();
}
public override ValueTask SelectRangeAsync(int pos1, int pos2)
{
if (_mask == null)
return InputReference.SelectRangeAsync(pos1, pos2);
else
return _maskReference.SelectRangeAsync(pos1, pos2);
}
protected override void ResetValue()
{
if (_mask == null)
InputReference.Reset();
else
_maskReference.Reset();
base.ResetValue();
}
/// <summary>
/// Clear the text field, set Value to default(T) and Text to null
/// </summary>
/// <returns></returns>
public Task Clear()
{
if (_mask == null)
return InputReference.SetText(null);
else
return _maskReference.Clear();
}
/// <summary>
/// Sets the input text from outside programmatically
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public async Task SetText(string text)
{
if (_mask == null)
{
if (InputReference != null)
await InputReference.SetText(text);
return;
}
await _maskReference.Clear();
_maskReference.OnPaste(text);
}
private IMask _mask = null;
/// <summary>
/// Provide a masking object. Built-in masks are PatternMask, MultiMask, RegexMask and BlockMask
/// Note: when Mask is set, TextField will ignore some properties such as Lines, Pattern or HideSpinButtons, OnKeyDown and OnKeyUp, etc.
/// </summary>
[Parameter]
[Category(CategoryTypes.General.Data)]
public IMask Mask
{
get => _maskReference?.MaskKind ?? _mask; // this might look strange, but it is absolutely necessary due to how Mask works.
set
{
_mask = value;
}
}
protected override Task SetValueAsync(T value, bool updateText = true)
{
if (_mask != null)
{
var textValue = Converter.Set(value);
_mask.SetText(textValue);
textValue = Mask.GetCleanText();
value = Converter.Get(textValue);
}
return base.SetValueAsync(value, updateText);
}
protected override Task SetTextAsync(string text, bool updateValue = true)
{
if (_mask != null)
{
_mask.SetText(text);
text = _mask.Text;
}
return base.SetTextAsync(text, updateValue);
}
private async Task OnMaskedValueChanged(string s)
{
await SetTextAsync(s);
}
}