// License: MIT // Copyright (c) 2019 Blazored - See https://github.com/Blazored // Copyright (c) 2020 Jonny Larsson and Meinrad Recheis using Connected.Annotations; using Connected.Utilities; using Microsoft.AspNetCore.Components; namespace Connected.Components; public partial class Dialog : UIComponent { protected string ContentClass => new CssBuilder("mud-dialog-content") .AddClass($"mud-dialog-no-side-padding", DisableSidePadding) .AddClass(ClassContent) .Build(); protected string ActionClass => new CssBuilder("mud-dialog-actions") .AddClass(ClassActions) .Build(); [CascadingParameter] private DialogInstance DialogInstance { get; set; } [Inject] public IDialogService DialogService { get; set; } /// /// Define the dialog title as a renderfragment (overrides Title) /// [Parameter] [Category(CategoryTypes.Dialog.Behavior)] public RenderFragment TitleContent { get; set; } /// /// Define the dialog body here /// [Parameter] [Category(CategoryTypes.Dialog.Behavior)] public RenderFragment DialogContent { get; set; } /// /// Define the action buttons here /// [Parameter] [Category(CategoryTypes.Dialog.Behavior)] public RenderFragment DialogActions { get; set; } /// /// Default options to pass to Show(), if none are explicitly provided. /// Typically useful on inline dialogs. /// [Parameter] [Category(CategoryTypes.Dialog.Misc)] // Behavior and Appearance public DialogOptions Options { get; set; } [Parameter] [Category(CategoryTypes.Dialog.Behavior)] public Action OnBackdropClick { get; set; } /// /// No padding at the sides /// [Parameter] [Category(CategoryTypes.Dialog.Appearance)] public bool DisableSidePadding { get; set; } /// /// CSS class that will be applied to the dialog content /// [Parameter] [Category(CategoryTypes.Dialog.Appearance)] public string ClassContent { get; set; } /// /// CSS class that will be applied to the action buttons container /// [Parameter] [Category(CategoryTypes.Dialog.Appearance)] public string ClassActions { get; set; } /// /// CSS styles to be applied to the dialog content /// [Parameter] [Category(CategoryTypes.Dialog.Appearance)] public string ContentStyle { get; set; } /// /// Bind this two-way to show and close an inlined dialog. Has no effect on opened dialogs /// [Parameter] [Category(CategoryTypes.Dialog.Behavior)] public bool IsVisible { get => _isVisible; set { if (_isVisible == value) return; _isVisible = value; IsVisibleChanged.InvokeAsync(value); } } private bool _isVisible; /// /// Raised when the inline dialog's display status changes. /// [Parameter] public EventCallback IsVisibleChanged { get; set; } /// /// Define the dialog title as a renderfragment (overrides Title) /// [Parameter] [Category(CategoryTypes.Dialog.Behavior)] public DefaultFocus DefaultFocus { get; set; } private bool IsInline => DialogInstance == null; private IDialogReference _reference; /// /// Show this inlined dialog /// /// /// /// public IDialogReference Show(string title = null, DialogOptions options = null) { if (!IsInline) throw new InvalidOperationException("You can only show an inlined dialog."); if (_reference != null) Close(); var parameters = new DialogParameters() { [nameof(Class)] = Class, [nameof(Style)] = Style, [nameof(Tag)] = Tag, [nameof(TitleContent)] = TitleContent, [nameof(DialogContent)] = DialogContent, [nameof(DialogActions)] = DialogActions, [nameof(DisableSidePadding)] = DisableSidePadding, [nameof(ClassContent)] = ClassContent, [nameof(ClassActions)] = ClassActions, [nameof(ContentStyle)] = ContentStyle, }; _reference = DialogService.Show(title, parameters, options ?? Options); _reference.Result.ContinueWith(t => { _isVisible = false; InvokeAsync(() => IsVisibleChanged.InvokeAsync(false)); }); return _reference; } protected override void OnAfterRender(bool firstRender) { if (IsInline) { if (_isVisible && _reference == null) { Show(); // if isVisible and we don't have any reference we need to call Show } else if (_reference != null) { if (IsVisible) (_reference.Dialog as Dialog)?.ForceUpdate(); // forward render update to instance else Close(); // if we still have reference but it's not visible call Close } } base.OnAfterRender(firstRender); } /// /// Used for forwarding state changes from inlined dialog to its instance /// internal void ForceUpdate() { StateHasChanged(); } /// /// Close the currently open inlined dialog /// /// public void Close(DialogResult result = null) { if (!IsInline || _reference == null) return; _reference.Close(result); _reference = null; } protected override void OnInitialized() { base.OnInitialized(); DialogInstance?.Register(this); } }