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.
143 lines
3.5 KiB
143 lines
3.5 KiB
using Connected.Annotations;
|
|
using Connected.Utilities;
|
|
using Connected.Utilities.Exceptions;
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
namespace Connected.Components;
|
|
|
|
public partial class RadioGroup<T> : FormComponent<T, T>, IRadioGroup
|
|
{
|
|
public RadioGroup() : base(new Converter<T, T>()) { }
|
|
|
|
private Radio<T> _selectedRadio;
|
|
|
|
private HashSet<Radio<T>> _radios = new();
|
|
|
|
protected string Classname =>
|
|
new CssBuilder("mud-input-control-boolean-input")
|
|
.AddClass(Class)
|
|
.Build();
|
|
|
|
private string GetInputClass() =>
|
|
new CssBuilder("mud-radio-group")
|
|
.AddClass(InputClass)
|
|
.Build();
|
|
|
|
/// <summary>
|
|
/// User class names for the input, separated by space
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Radio.Appearance)]
|
|
public string InputClass { get; set; }
|
|
|
|
/// <summary>
|
|
/// User style definitions for the input
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Radio.Appearance)]
|
|
public string InputStyle { get; set; }
|
|
|
|
[Parameter]
|
|
[Category(CategoryTypes.Radio.Behavior)]
|
|
public RenderFragment ChildContent { get; set; }
|
|
|
|
[Parameter]
|
|
[Category(CategoryTypes.Radio.Behavior)]
|
|
public string Name { get; set; } = Guid.NewGuid().ToString();
|
|
|
|
public void CheckGenericTypeMatch(object select_item)
|
|
{
|
|
var itemT = select_item.GetType().GenericTypeArguments[0];
|
|
if (itemT != typeof(T))
|
|
throw new GenericTypeMismatchException("MudRadioGroup", "MudRadio", typeof(T), itemT);
|
|
}
|
|
|
|
[Parameter]
|
|
[Category(CategoryTypes.Radio.Data)]
|
|
public T SelectedOption
|
|
{
|
|
get => _value;
|
|
set => SetSelectedOptionAsync(value, true).AndForget();
|
|
}
|
|
|
|
protected async Task SetSelectedOptionAsync(T option, bool updateRadio)
|
|
{
|
|
if (!OptionEquals(_value, option))
|
|
{
|
|
_value = option;
|
|
|
|
if (updateRadio)
|
|
await SetSelectedRadioAsync(_radios.FirstOrDefault(r => OptionEquals(r.Option, _value)), false);
|
|
|
|
await SelectedOptionChanged.InvokeAsync(_value);
|
|
|
|
BeginValidate();
|
|
FieldChanged(_value);
|
|
}
|
|
}
|
|
|
|
[Parameter]
|
|
public EventCallback<T> SelectedOptionChanged { get; set; }
|
|
|
|
internal Task SetSelectedRadioAsync(Radio<T> radio)
|
|
{
|
|
Touched = true;
|
|
return SetSelectedRadioAsync(radio, true);
|
|
}
|
|
|
|
protected async Task SetSelectedRadioAsync(Radio<T> radio, bool updateOption)
|
|
{
|
|
if (_selectedRadio != radio)
|
|
{
|
|
_selectedRadio = radio;
|
|
|
|
foreach (var item in _radios.ToArray())
|
|
item.SetChecked(item == _selectedRadio);
|
|
|
|
if (updateOption)
|
|
await SetSelectedOptionAsync(GetOptionOrDefault(_selectedRadio), false);
|
|
}
|
|
}
|
|
|
|
internal Task RegisterRadioAsync(Radio<T> radio)
|
|
{
|
|
_radios.Add(radio);
|
|
|
|
if (_selectedRadio == null)
|
|
{
|
|
if (OptionEquals(radio.Option, _value))
|
|
return SetSelectedRadioAsync(radio, false);
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
internal void UnregisterRadio(Radio<T> radio)
|
|
{
|
|
_radios.Remove(radio);
|
|
|
|
if (_selectedRadio == radio)
|
|
_selectedRadio = null;
|
|
}
|
|
|
|
protected override void ResetValue()
|
|
{
|
|
if (_selectedRadio != null)
|
|
{
|
|
_selectedRadio.SetChecked(false);
|
|
_selectedRadio = null;
|
|
}
|
|
|
|
base.ResetValue();
|
|
}
|
|
|
|
private static T GetOptionOrDefault(Radio<T> radio)
|
|
{
|
|
return radio != null ? radio.Option : default;
|
|
}
|
|
|
|
private static bool OptionEquals(T option1, T option2)
|
|
{
|
|
return EqualityComparer<T>.Default.Equals(option1, option2);
|
|
}
|
|
}
|