using Connected.Annotations;
using Connected.Utilities;
using Microsoft.AspNetCore.Components;
namespace Connected.Components;
public partial class ExpansionPanel : UIComponent, IDisposable
{
private bool _nextPanelExpanded;
private bool _isExpanded;
private bool _collapseIsExpanded;
[CascadingParameter] private ExpansionPanels Parent { get; set; }
protected string Classname =>
new CssBuilder("mud-expand-panel")
.AddClass("mud-panel-expanded", IsExpanded)
.AddClass("mud-panel-next-expanded", NextPanelExpanded)
.AddClass("mud-disabled", Disabled)
.AddClass($"mud-elevation-{Parent?.Elevation.ToString()}")
.AddClass($"mud-expand-panel-border", Parent?.DisableBorders != true)
.AddClass(Class)
.Build();
protected string PanelContentClassname =>
new CssBuilder("mud-expand-panel-content")
.AddClass("mud-expand-panel-gutters", DisableGutters || Parent?.DisableGutters == true)
.AddClass("mud-expand-panel-dense", Dense || Parent?.Dense == true)
.Build();
///
/// Explicitly sets the height for the Collapse element to override the css default.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Appearance)]
public int? MaxHeight { get; set; }
///
/// RenderFragment to be displayed in the expansion panel which will override header text if defined.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Behavior)]
public RenderFragment TitleContent { get; set; }
///
/// The text to be displayed in the expansion panel.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Behavior)]
public string Text { get; set; }
///
/// If true, expand icon will not show
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Appearance)]
public bool HideIcon { get; set; }
///
/// Custom hide icon.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Appearance)]
public string Icon { get; set; } = Icons.Material.Filled.ExpandMore;
///
/// If true, removes vertical padding from childcontent.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Appearance)]
public bool Dense { get; set; }
///
/// If true, the left and right padding is removed from childcontent.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Appearance)]
public bool DisableGutters { get; set; }
///
/// Raised when IsExpanded changes.
///
[Parameter] public EventCallback IsExpandedChanged { get; set; }
internal event Action NotifyIsExpandedChanged;
///
/// Expansion state of the panel (two-way bindable)
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Behavior)]
public bool IsExpanded
{
get => _isExpanded;
set
{
if (_isExpanded == value)
return;
_isExpanded = value;
NotifyIsExpandedChanged?.Invoke(this);
IsExpandedChanged.InvokeAsync(_isExpanded).ContinueWith(t =>
{
if (_collapseIsExpanded != _isExpanded)
{
_collapseIsExpanded = _isExpanded;
InvokeAsync(() => StateHasChanged());
}
});
}
}
///
/// Sets the initial expansion state. Do not use in combination with IsExpanded.
/// Combine with MultiExpansion to have more than one panel start open.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Behavior)]
public bool IsInitiallyExpanded { get; set; }
///
/// If true, the component will be disabled.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Behavior)]
public bool Disabled { get; set; }
///
/// Child content of component.
///
[Parameter]
[Category(CategoryTypes.ExpansionPanel.Behavior)]
public RenderFragment ChildContent { get; set; }
public bool NextPanelExpanded
{
get => _nextPanelExpanded;
set
{
if (_nextPanelExpanded == value)
return;
_nextPanelExpanded = value;
//InvokeAsync(StateHasChanged);
}
}
public void ToggleExpansion()
{
if (Disabled)
{
return;
}
IsExpanded = !IsExpanded;
}
public void Expand(bool update_parent = true)
{
if (update_parent)
IsExpanded = true;
else
{
_isExpanded = true;
_collapseIsExpanded = true;
IsExpandedChanged.InvokeAsync(_isExpanded);
}
}
public void Collapse(bool update_parent = true)
{
if (update_parent)
IsExpanded = false;
else
{
_isExpanded = false;
_collapseIsExpanded = false;
IsExpandedChanged.InvokeAsync(_isExpanded);
}
}
protected override void OnInitialized()
{
// NOTE: we can't throw here because we need to be able to instanciate the type for the API Docs to infer default values
//if (Parent == null)
// throw new ArgumentNullException(nameof(Parent), "ExpansionPanel must exist within a ExpansionPanels component");
base.OnInitialized();
if (!IsExpanded && IsInitiallyExpanded)
{
_isExpanded = true;
_collapseIsExpanded = true;
}
Parent?.AddPanel(this);
}
public void Dispose()
{
Parent?.RemovePanel(this);
}
}