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.Convert(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) { } } }