using System.Threading.Tasks; using AntDesign.JsInterop; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; 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; } /// /// 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; } = AlertType.Default; /// /// 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 => Type == AlertType.Success ? "check-circle" : Type == AlertType.Info ? "info-circle" : Type == AlertType.Warning ? "exclamation-circle" : Type == AlertType.Error ? "close-circle" : null; /// /// 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; /// /// Sets the default classes. /// private void SetClassMap() { string prefixName = "ant-alert"; ClassMapper.Clear() .Add("ant-alert") .If($"{prefixName}-{Type}", () => !string.IsNullOrEmpty(Type)) .If($"{prefixName}-no-icon", () => !ShowIcon) .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) ; } /// /// Start-up code. /// protected override void OnInitialized() { base.OnInitialized(); if (Banner && string.IsNullOrEmpty(Type) && Icon == null) { ShowIcon = false; } SetClassMap(); } protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (firstRender) { Element 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; } } }