using Connected.Annotations;
using Connected.Utilities;
using Microsoft.AspNetCore.Components;
namespace Connected.Components;
///
/// Represents an option of a select or multi-select. To be used inside MudSelect.
///
public partial class SelectItem : SelectItemBase, IDisposable
{
private String GetCssClasses() => new CssBuilder()
.AddClass(Class)
.Build();
private ISelect _parent;
internal string ItemId { get; } = "_" + Guid.NewGuid().ToString().Substring(0, 8);
///
/// The parent select component
///
[CascadingParameter]
internal ISelect IMudSelect
{
get => _parent;
set
{
_parent = value;
if (_parent == null)
return;
_parent.CheckGenericTypeMatch(this);
if (Select == null)
return;
bool isSelected = Select.Add(this);
if (_parent.MultiSelection)
{
Select.SelectionChangedFromOutside += OnUpdateSelectionStateFromOutside;
InvokeAsync(() => OnUpdateSelectionStateFromOutside(Select.SelectedValues));
}
else
{
IsSelected = isSelected;
}
}
}
private IShadowSelect _shadowParent;
private bool _isSelected;
[CascadingParameter]
internal IShadowSelect ParentShadow
{
get => _shadowParent;
set
{
_shadowParent = value;
((Select)_shadowParent)?.RegisterShadowItem(this);
}
}
///
/// Select items with HideContent==true are only there to register their RenderFragment with the select but
/// wont render and have no other purpose!
///
[CascadingParameter(Name = "HideContent")]
internal bool HideContent { get; set; }
internal Select Select => (Select)IMudSelect;
private void OnUpdateSelectionStateFromOutside(IEnumerable selection)
{
if (selection == null)
return;
var old_is_selected = IsSelected;
IsSelected = selection.Contains(Value);
if (old_is_selected != IsSelected)
InvokeAsync(StateHasChanged);
}
///
/// A user-defined option that can be selected
///
[Parameter]
[Category(CategoryTypes.FormComponent.Behavior)]
public T Value { get; set; }
///
/// Mirrors the MultiSelection status of the parent select
///
protected bool MultiSelection
{
get
{
if (Select == null)
return false;
return Select.MultiSelection;
}
}
///
/// Selected state of the option. Only works if the parent is a mulit-select
///
internal bool IsSelected
{
get => _isSelected;
set
{
_isSelected = value;
}
}
///
/// The checkbox icon reflects the multi-select option's state
///
protected string CheckBoxIcon
{
get
{
if (!MultiSelection)
return null;
return IsSelected ? Icons.Material.Filled.CheckBox : Icons.Material.Filled.CheckBoxOutlineBlank;
}
}
protected string DisplayString
{
get
{
var converter = Select?.Converter;
if (converter == null)
return $"{Value}";
return converter.Set(Value);
}
}
private void OnClicked()
{
if (MultiSelection)
IsSelected = !IsSelected;
Select?.SelectOption(Value);
InvokeAsync(StateHasChanged);
}
public void Dispose()
{
try
{
Select?.Remove(this);
((Select)_shadowParent)?.UnregisterShadowItem(this);
}
catch (Exception) { }
}
}