using System.Threading.Tasks; using AntDesign.JsInterop; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using System.Collections.Generic; namespace AntDesign { /// /// Alert component for feedback. /// public partial class Alert : AntDomComponentBase { /// /// Called when close animation is finished /// [Parameter] public EventCallback AfterClose { get; set; } /// /// Whether to show as banner /// [Parameter] public bool Banner { get; set; } = false; /// /// Whether Alert can be closed /// [Parameter] public bool Closable { get; set; } = false; /// /// Close text to show /// [Parameter] public string CloseText { get; set; } /// /// Additional content of Alert /// [Parameter] public string Description { get; set; } /// /// Custom icon, effective when showIcon is true /// [Parameter] public RenderFragment Icon { get; set; } /// /// Content of Alert /// [Parameter] public string Message { get; set; } [Parameter] public RenderFragment MessageTemplate { get; set; } /// /// Whether to show icon. /// [Parameter] public bool? ShowIcon { get; set; } /// /// Type of Alert styles, options: success, info, warning, error /// [Parameter] public string Type { get; set; } /// /// Callback when Alert is closed. /// [Parameter] public EventCallback OnClose { get; set; } /// /// Additional Content /// [Parameter] public RenderFragment ChildContent { get; set; } /// /// Icon to show. /// protected string IconType => CalcType switch { AlertType.Success => "check-circle", AlertType.Info => "info-circle", AlertType.Warning => "exclamation-circle", AlertType.Error => "close-circle", _ => "exclamation-circle", }; /// /// Indicator if the component is closed or not. /// private bool _isClosed; /// /// Just before we close the component we set this indicator to show a closing animation. /// private bool _isClosing; private int _motionStage; private int _height; private string _innerStyle = string.Empty; private bool IsShowIcon => (Banner && ShowIcon == null) ? true : ShowIcon == true; private string CalcType => Type ?? (Banner ? AlertType.Warning : AlertType.Info); /// /// Sets the default classes. /// private void SetClassMap() { string prefixName = "ant-alert"; ClassMapper .Add("ant-alert") .GetIf(() => $"{prefixName}-{CalcType}", () => !string.IsNullOrEmpty(CalcType)) .If($"{prefixName}-no-icon", () => !IsShowIcon) .If($"{prefixName}-closable", () => Closable) .If($"{prefixName}-banner", () => Banner) .If($"{prefixName}-with-description", () => !string.IsNullOrEmpty(Description) || ChildContent != null) .If($"{prefixName}-motion", () => _isClosing) .If($"{prefixName}-motion-leave", () => _isClosing) .If($"{prefixName}-motion-leave-active", () => _isClosing && _motionStage == 1) .If($"{prefixName}-rtl", () => RTL) ; } /// /// Start-up code. /// protected override void OnInitialized() { base.OnInitialized(); SetClassMap(); } protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (firstRender) { HtmlElement element = await JsInvokeAsync(JSInteropConstants.GetDomInfo, Ref); _height = element.ClientHeight; } } /// /// Handles the close callback. /// /// /// protected async Task OnCloseHandler(MouseEventArgs args) { if (OnClose.HasDelegate) { await OnClose.InvokeAsync(args); } await PlayMotion(); if (AfterClose.HasDelegate) { await AfterClose.InvokeAsync(args); } } private async Task PlayMotion() { _isClosing = true; _innerStyle = $"max-height:{_height}px;"; await InvokeAsync(StateHasChanged); _motionStage = 1; await InvokeAsync(StateHasChanged); await Task.Delay(50); _innerStyle = string.Empty; await InvokeAsync(StateHasChanged); await Task.Delay(300); _isClosed = true; } } }