You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.7 KiB
201 lines
5.7 KiB
// 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; }
|
|
|
|
/// <summary>
|
|
/// Define the dialog title as a renderfragment (overrides Title)
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Behavior)]
|
|
public RenderFragment TitleContent { get; set; }
|
|
|
|
/// <summary>
|
|
/// Define the dialog body here
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Behavior)]
|
|
public RenderFragment DialogContent { get; set; }
|
|
|
|
/// <summary>
|
|
/// Define the action buttons here
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Behavior)]
|
|
public RenderFragment DialogActions { get; set; }
|
|
|
|
/// <summary>
|
|
/// Default options to pass to Show(), if none are explicitly provided.
|
|
/// Typically useful on inline dialogs.
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Misc)] // Behavior and Appearance
|
|
public DialogOptions Options { get; set; }
|
|
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Behavior)]
|
|
public Action OnBackdropClick { get; set; }
|
|
|
|
/// <summary>
|
|
/// No padding at the sides
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Appearance)]
|
|
public bool DisableSidePadding { get; set; }
|
|
|
|
/// <summary>
|
|
/// CSS class that will be applied to the dialog content
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Appearance)]
|
|
public string ClassContent { get; set; }
|
|
|
|
/// <summary>
|
|
/// CSS class that will be applied to the action buttons container
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Appearance)]
|
|
public string ClassActions { get; set; }
|
|
|
|
/// <summary>
|
|
/// CSS styles to be applied to the dialog content
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Appearance)]
|
|
public string ContentStyle { get; set; }
|
|
|
|
/// <summary>
|
|
/// Bind this two-way to show and close an inlined dialog. Has no effect on opened dialogs
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Behavior)]
|
|
public bool IsVisible
|
|
{
|
|
get => _isVisible;
|
|
set
|
|
{
|
|
if (_isVisible == value)
|
|
return;
|
|
_isVisible = value;
|
|
IsVisibleChanged.InvokeAsync(value);
|
|
}
|
|
}
|
|
private bool _isVisible;
|
|
|
|
/// <summary>
|
|
/// Raised when the inline dialog's display status changes.
|
|
/// </summary>
|
|
[Parameter] public EventCallback<bool> IsVisibleChanged { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
/// Define the dialog title as a renderfragment (overrides Title)
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.Dialog.Behavior)]
|
|
public DefaultFocus DefaultFocus { get; set; }
|
|
|
|
private bool IsInline => DialogInstance == null;
|
|
|
|
private IDialogReference _reference;
|
|
|
|
/// <summary>
|
|
/// Show this inlined dialog
|
|
/// </summary>
|
|
/// <param name="title"></param>
|
|
/// <param name="options"></param>
|
|
/// <returns></returns>
|
|
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<Dialog>(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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used for forwarding state changes from inlined dialog to its instance
|
|
/// </summary>
|
|
internal void ForceUpdate()
|
|
{
|
|
StateHasChanged();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close the currently open inlined dialog
|
|
/// </summary>
|
|
/// <param name="result"></param>
|
|
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);
|
|
}
|
|
}
|